]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: wire up VPNv6 protocol processing
authorLou Berger <lberger@labn.net>
Tue, 12 Jan 2016 18:41:55 +0000 (13:41 -0500)
committervivek <vivek@cumulusnetworks.com>
Tue, 7 Jun 2016 00:26:17 +0000 (17:26 -0700)
There wasn't much missing for VPNv6 to begin with; just a few bits of
de- & encoding and a few lists to be updated.

Signed-off-by: Lou Berger <lberger@labn.net>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
[Editorial note: Signed-off-by may imply an authorship claim, but need not]

Edited-by: Paul Jakma <paul.jakma@hpe.com> / <paul@jakma.org>
(cherry picked from commit 9da04bca0e994ec92b9242159bf27d89c6743354)

Conflicts:
bgpd/bgp_attr.c
bgpd/bgp_mplsvpn.c
bgpd/bgpd.c

bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_mplsvpn.c
bgpd/bgp_mplsvpn.h
bgpd/bgp_open.c
bgpd/bgp_packet.c
bgpd/bgp_vty.c
bgpd/bgpd.c

index 844bc0fd910af5ef5a8c0b19325668ba6a4fbf81..ad8c7641e44842e90b1ba5f5e8032839597c9d94 100644 (file)
@@ -1601,10 +1601,27 @@ bgp_mp_reach_parse (struct bgp_attr_parser_args *args,
       break;
 #ifdef HAVE_IPV6
     case BGP_ATTR_NHLEN_IPV6_GLOBAL:
+    case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
+      if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL)
+        {
+          stream_getl (s); /* RD high */
+          stream_getl (s); /* RD low */
+        }
       stream_get (&attre->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
       break;
     case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
+    case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL:
+      if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
+        {
+          stream_getl (s); /* RD high */
+          stream_getl (s); /* RD low */
+        }
       stream_get (&attre->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
+      if (attre->mp_nexthop_len == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL)
+        {
+          stream_getl (s); /* RD high */
+          stream_getl (s); /* RD low */
+        }
       stream_get (&attre->mp_nexthop_local, s, IPV6_MAX_BYTELEN);
       if (! IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local))
        {
index d71cb680520901f87f2705f46e3bd6cff7ef62f3..da9bfec497523747dd5c90400ea5027d1a8cfdcb 100644 (file)
@@ -49,9 +49,11 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 
 /* Valid lengths for mp_nexthop_len */
 #define BGP_ATTR_NHLEN_IPV4               IPV4_MAX_BYTELEN
-#define BGP_ATTR_NHLEN_VPNV4              12
+#define BGP_ATTR_NHLEN_VPNV4              8+IPV4_MAX_BYTELEN
 #define BGP_ATTR_NHLEN_IPV6_GLOBAL        IPV6_MAX_BYTELEN
 #define BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL (IPV6_MAX_BYTELEN * 2)
+#define BGP_ATTR_NHLEN_VPNV6_GLOBAL       8+IPV6_MAX_BYTELEN
+#define BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL ((8+IPV6_MAX_BYTELEN) * 2)
 
 /* Additional/uncommon BGP attributes.
  * lazily allocated as and when a struct attr
index 206d23f94f73f665508d4f7009c6d5cc91315352..9f27c9addb6d38e5d934095848bc43c681c6a62d 100644 (file)
@@ -93,13 +93,13 @@ decode_rd_ip (u_char *pnt, struct rd_ip *rd_ip)
 }
 
 int
-bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr, 
-                     struct bgp_nlri *packet)
+bgp_nlri_parse_vpn (struct peer *peer, struct attr *attr,
+                    struct bgp_nlri *packet)
 {
   u_char *pnt;
   u_char *lim;
   struct prefix p;
-  int psize;
+  int psize = 0;
   int prefixlen;
   u_int16_t type;
   struct rd_as rd_as;
@@ -219,10 +219,10 @@ bgp_nlri_parse_vpnv4 (struct peer *peer, struct attr *attr,
               psize - VPN_PREFIXLEN_MIN_BYTES);
 
       if (attr)
-       bgp_update (peer, &p, addpath_id, attr, AFI_IP, SAFI_MPLS_VPN,
+       bgp_update (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
                    ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt, 0);
       else
-       bgp_withdraw (peer, &p, addpath_id, attr, AFI_IP, SAFI_MPLS_VPN,
+       bgp_withdraw (peer, &p, addpath_id, attr, packet->afi, SAFI_MPLS_VPN,
                      ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, tagpnt);
     }
   /* Packet length consistency check. */
@@ -572,6 +572,7 @@ static int
 bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type,
                   void *output_arg, int tags, u_char use_json)
 {
+  afi_t afi = AFI_IP;
   struct bgp *bgp;
   struct bgp_table *table;
   struct bgp_node *rn;
@@ -616,7 +617,13 @@ bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type ty
       json_object_string_add(json_ocode, "incomplete", "?");
     }
 
- for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
+  if ((afi != AFI_IP) && (afi != AFI_IP6))
+    {
+      vty_out (vty, "Afi %d not supported%s", afi, VTY_NEWLINE);
+      return CMD_WARNING;
+    }
+
+  for (rn = bgp_table_top (bgp->rib[afi][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
     {
       if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
        continue;
index 0cb9decac7cb8b5459d6b6223f256d18a71598e1..4e9b317b71bdcfe412c83a9d860bea32bf2c28d4 100644 (file)
@@ -43,7 +43,7 @@ struct rd_ip
 };
 
 extern void bgp_mplsvpn_init (void);
-extern int bgp_nlri_parse_vpnv4 (struct peer *, struct attr *, struct bgp_nlri *);
+extern int bgp_nlri_parse_vpn (struct peer *, struct attr *, struct bgp_nlri *);
 extern u_int32_t decode_label (u_char *);
 extern int str2prefix_rd (const char *, struct prefix_rd *);
 extern int str2tag (const char *, u_char *);
index 1444a5837b0c95ce7f21db02735fac128a54b158..8be906d399732fc1ad2e827bdfa7fa02ef5a4a5c 100644 (file)
@@ -1124,7 +1124,8 @@ bgp_open_option_parse (struct peer *peer, u_char length, int *mp_capability)
          && ! peer->afc_nego[AFI_IP][SAFI_MULTICAST]
          && ! peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
          && ! peer->afc_nego[AFI_IP6][SAFI_UNICAST]
-         && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
+         && ! peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
+         && ! peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN])
        {
          zlog_err ("%s [Error] Configured AFI/SAFIs do not "
                    "overlap with received MP capabilities",
@@ -1316,6 +1317,18 @@ bgp_open_capability (struct stream *s, struct peer *peer)
       stream_putc (s, 0);
       stream_putc (s, SAFI_MULTICAST);
     }
+  /* IPv6 VPN. */
+  if (peer->afc[AFI_IP6][SAFI_MPLS_VPN])
+    {
+      peer->afc_adv[AFI_IP6][SAFI_MPLS_VPN] = 1;
+      stream_putc (s, BGP_OPEN_OPT_CAP);
+      stream_putc (s, CAPABILITY_CODE_MP_LEN + 2);
+      stream_putc (s, CAPABILITY_CODE_MP);
+      stream_putc (s, CAPABILITY_CODE_MP_LEN);
+      stream_putw (s, AFI_IP6);
+      stream_putc (s, 0);
+      stream_putc (s, SAFI_MPLS_LABELED_VPN);
+    }
 #endif /* HAVE_IPV6 */
 
   /* Route refresh. */
index 9d931da10dfba9b3a0434743e3c84713b3a0332e..02f5e82d4cf28bd1cf9615a2bb114884af29d764 100644 (file)
@@ -1528,12 +1528,12 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
   if (peer->afc_nego[AFI_IP][SAFI_MULTICAST])
     {
       if (mp_update.length
-         && mp_update.afi == AFI_IP 
+         && mp_update.afi == AFI_IP
          && mp_update.safi == SAFI_MULTICAST)
        bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
 
       if (mp_withdraw.length
-         && mp_withdraw.afi == AFI_IP 
+         && mp_withdraw.afi == AFI_IP
          && mp_withdraw.safi == SAFI_MULTICAST)
        bgp_nlri_parse (peer, NULL, &mp_withdraw);
 
@@ -1631,12 +1631,12 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
       if (mp_update.length 
          && mp_update.afi == AFI_IP 
          && mp_update.safi == SAFI_MPLS_LABELED_VPN)
-       bgp_nlri_parse_vpnv4 (peer, NLRI_ATTR_ARG, &mp_update);
+       bgp_nlri_parse_vpn (peer, NLRI_ATTR_ARG, &mp_update);
 
       if (mp_withdraw.length 
          && mp_withdraw.afi == AFI_IP 
          && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
-       bgp_nlri_parse_vpnv4 (peer, NULL, &mp_withdraw);
+       bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw);
 
       if (! withdraw_len
          && mp_withdraw.afi == AFI_IP
@@ -1656,6 +1656,35 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
            zlog_debug ("rcvd End-of-RIB for VPNv4 Unicast from %s", peer->host);
        }
     }
+  if (peer->afc[AFI_IP6][SAFI_MPLS_VPN])
+    {
+      if (mp_update.length
+         && mp_update.afi == AFI_IP6
+         && mp_update.safi == SAFI_MPLS_LABELED_VPN)
+       bgp_nlri_parse_vpn (peer, NLRI_ATTR_ARG, &mp_update);
+
+      if (mp_withdraw.length
+         && mp_withdraw.afi == AFI_IP6
+         && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
+       bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw);
+
+      if (! withdraw_len
+         && mp_withdraw.afi == AFI_IP6
+         && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
+         && mp_withdraw.length == 0)
+       {
+          /* End-of-RIB received */
+          if (!CHECK_FLAG (peer->af_sflags[AFI_IP6][SAFI_MPLS_VPN],
+                           PEER_STATUS_EOR_RECEIVED))
+            {
+             SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_MPLS_VPN], PEER_STATUS_EOR_RECEIVED);
+              bgp_update_explicit_eors(peer);
+            }
+
+          if (bgp_debug_neighbor_events(peer))
+           zlog_debug ("rcvd End-of-RIB for VPNv6 Unicast from %s", peer->host);
+       }
+    }
 
   /* Everything is done.  We unintern temporary structures which
      interned in bgp_attr_parse(). */
index 5041e64eebd2a1a061e4e8217006a53a16496acd..5fc0b75122b279efb40c85f5a721f6e2190a83b0 100644 (file)
@@ -10460,11 +10460,13 @@ afi_safi_print (afi_t afi, safi_t safi)
   else if (afi == AFI_IP && safi == SAFI_MULTICAST)
     return "IPv4 Multicast";
   else if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
-    return "VPNv4 Unicast";
+    return "VPN-IPv4 Unicast";
   else if (afi == AFI_IP6 && safi == SAFI_UNICAST)
     return "IPv6 Unicast";
   else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
     return "IPv6 Multicast";
+  else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN)
+    return "VPN-IPv6 Unicast";
   else
     return "Unknown";
 }
@@ -11248,6 +11250,8 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
          || p->afc_recv[AFI_IP6][SAFI_UNICAST]
          || p->afc_adv[AFI_IP6][SAFI_MULTICAST]
          || p->afc_recv[AFI_IP6][SAFI_MULTICAST]
+         || p->afc_adv[AFI_IP6][SAFI_MPLS_VPN]
+         || p->afc_recv[AFI_IP6][SAFI_MPLS_VPN]
 #endif /* HAVE_IPV6 */
          || p->afc_adv[AFI_IP][SAFI_MPLS_VPN]
          || p->afc_recv[AFI_IP][SAFI_MPLS_VPN])
index fca6e5bb1b9d4010d5e722aba79501a8495a50f8..8c2c61f4cbbe33b4a6166999d9564f1e5ed534ae 100644 (file)
@@ -1545,6 +1545,8 @@ peer_as_change (struct peer *peer, as_t as, int as_specified)
                  PEER_FLAG_REFLECTOR_CLIENT);
       UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MULTICAST],
                  PEER_FLAG_REFLECTOR_CLIENT);
+      UNSET_FLAG (peer->af_flags[AFI_IP6][SAFI_MPLS_VPN],
+                 PEER_FLAG_REFLECTOR_CLIENT);
     }
 
   /* local-as reset */
@@ -3461,7 +3463,8 @@ peer_active (struct peer *peer)
       || peer->afc[AFI_IP][SAFI_MULTICAST]
       || peer->afc[AFI_IP][SAFI_MPLS_VPN]
       || peer->afc[AFI_IP6][SAFI_UNICAST]
-      || peer->afc[AFI_IP6][SAFI_MULTICAST])
+      || peer->afc[AFI_IP6][SAFI_MULTICAST]
+      || peer->afc[AFI_IP6][SAFI_MPLS_VPN])
     return 1;
   return 0;
 }
@@ -3474,7 +3477,8 @@ peer_active_nego (struct peer *peer)
       || peer->afc_nego[AFI_IP][SAFI_MULTICAST]
       || peer->afc_nego[AFI_IP][SAFI_MPLS_VPN]
       || peer->afc_nego[AFI_IP6][SAFI_UNICAST]
-      || peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
+      || peer->afc_nego[AFI_IP6][SAFI_MULTICAST]
+      || peer->afc_nego[AFI_IP6][SAFI_MPLS_VPN])
     return 1;
   return 0;
 }