]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: allow VPN next hop to be different AFI than NLRI next hop (Issue #71)
authorLou Berger <lberger@labn.net>
Sat, 14 Jan 2017 13:34:22 +0000 (08:34 -0500)
committerLou Berger <lberger@labn.net>
Tue, 17 Jan 2017 19:59:10 +0000 (14:59 -0500)
Signed-off-by: Lou Berger <lberger@labn.net>
bgpd/bgp_attr.c
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgp_updgrp_packet.c

index 2115fb5efc5b830c88b1f5e6741e0c29c3953a61..b1b245d42c5c2a8f3b796f7b2abc39988c909c59 100644 (file)
@@ -2643,6 +2643,8 @@ bgp_packet_mpattr_start (struct stream *s, afi_t afi, safi_t safi, afi_t nh_afi,
   stream_putw (s, afi);
   stream_putc (s, (safi == SAFI_MPLS_VPN) ? SAFI_MPLS_LABELED_VPN : safi);
 
+  if (nh_afi == AFI_MAX)
+    nh_afi = BGP_NEXTHOP_AFI_FROM_NHLEN(attr->extra->mp_nexthop_len);
   /* Nexthop */
   switch (nh_afi)
     {
@@ -2894,7 +2896,8 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer,
       size_t mpattrlen_pos = 0;
 
       mpattrlen_pos = bgp_packet_mpattr_start(s, afi, safi,
-                                    (peer_cap_enhe(peer) ? AFI_IP6 : afi),
+                                    (peer_cap_enhe(peer) ? AFI_IP6 :
+                                     AFI_MAX), /* get from NH */
                                     vecarr, attr);
       bgp_packet_mpattr_prefix(s, afi, safi, p, prd, tag,
                                addpath_encode, addpath_tx_id);
index 240dd32ef160bb30c5bf049d486ea3f0f947bb8c..023d1f8fdd1f38b460f177fadfbf08904b5a89f0 100644 (file)
@@ -1435,9 +1435,10 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
 
 #ifdef HAVE_IPV6
 #define NEXTHOP_IS_V6 (\
-    (safi != SAFI_ENCAP && \
+    (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
      (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
-    (safi == SAFI_ENCAP && attr->extra->mp_nexthop_len == 16))
+    ((safi == SAFI_ENCAP || safi != SAFI_MPLS_VPN) &&\
+     attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
 
   /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
    * the peer (group) is configured to receive link-local nexthop unchanged
index 63b18aa2d8fb7dfa1456c42f248849dcb1ba1791..3c7aa83a0e4da84276c201ad8c79a54c796cec24 100644 (file)
@@ -179,6 +179,10 @@ struct bgp_static
   u_char tag[3];
 };
 
+#define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen) \
+  ((nhlen) < IPV4_MAX_BYTELEN  ? 0 : \
+   ((nhlen) < IPV6_MAX_BYTELEN ? AFI_IP : AFI_IP6))
+
 #define BGP_ATTR_NEXTHOP_AFI_IP6(attr) \
   (! CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP)) && \
    (attr)->extra && ((attr)->extra->mp_nexthop_len == 16 || \
index 20bf28967d30cdfd6b7f0d421929deb660877a71..ce2e0dbca02159c4d414d6e3e6879783677578ab 100644 (file)
@@ -423,12 +423,11 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
       nhlen = stream_getc_from (s, vec->offset);
       if (paf->afi == AFI_IP || paf->afi == AFI_IP6)
         {
-          if (nhlen < IPV6_MAX_BYTELEN && !peer_cap_enhe(peer))
-            nhafi = AFI_IP;
-          else
+          nhafi = BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen);
+          if (peer_cap_enhe(peer))
             nhafi = AFI_IP6;
-          if (paf->safi == SAFI_MPLS_VPN &&     /* if VPN */
-              nhlen != 48)                      /* and ! GLOBAL_AND_LL */
+          if (paf->safi == SAFI_MPLS_VPN &&     /* if VPN && not global */
+              nhlen != BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
             nhafi = AFI_MAX;                    /* no change allowed */
         }
 
@@ -486,7 +485,7 @@ bpacket_reformat_for_peer (struct bpacket *pkt, struct peer_af *paf)
 
           if (bgp_debug_update(peer, NULL, NULL, 0))
             zlog_debug ("u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ nexthop %s%s",
-                    PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id,
+                        PAF_SUBGRP(paf)->update_group->id, PAF_SUBGRP(paf)->id,
                         peer->host, inet_ntoa (*mod_v4nh),
                         (nhlen == 12 ? " and RD" : ""));
        }
@@ -762,7 +761,8 @@ subgroup_update_packet (struct update_subgroup *subgrp)
 
          if (stream_empty (snlri))
            mpattrlen_pos = bgp_packet_mpattr_start (snlri, afi, safi,
-                                         (peer_cap_enhe(peer) ? AFI_IP6 : afi),
+                                         (peer_cap_enhe(peer) ? AFI_IP6 :
+                                          AFI_MAX), /* get from NH */
                                          &vecarr, adv->baa->attr);
           bgp_packet_mpattr_prefix (snlri, afi, safi, &rn->p, prd, tag,
                                     addpath_encode, addpath_tx_id);