]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Regularise bgp_update_receive, add missing notifies and checks
authorPaul Jakma <paul.jakma@hpe.com>
Thu, 4 Feb 2016 13:27:04 +0000 (13:27 +0000)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 26 Oct 2016 13:36:08 +0000 (09:36 -0400)
* bgp_packet.c: (bgp_update_receive) Lots of repeated code, doing same
  thing for each AFI/SAFI.  Except when it doesn't, e.g.  the IPv4/VPN
  case was missing the EoR bgp_clear_stale_route call - the only action
  really needed for EoR.

  Make this function a lot more regular, using common, AFI/SAFI
  independent blocks so far as possible.

  Replace the 4 separate bgp_nlris with an array, indexed by an enum.

  The distinct blocks that handle calling bgp_nlri_parse for each
  different AFI/SAFI can now be replaced with a loop.

  Transmogrify the nlri SAFI from the SAFI_MPLS_LABELED_VPN code-point
  used on the wire, to the SAFI_MPLS_VPN safi_t enum we use internally
  as early as possible.

  The existing code was not necessarily sending a NOTIFY for NLRI
  parsing errors, if they arose via bgp_nlri_sanity_check.  Send the
  correct NOTIFY - INVAL_NETWORK for the classic NLRIs and OPT_ATTR_ERR
  for the MP ones.

  EoR can now be handled in one block.  The existing code seemed broken
  for EoR recognition in a number of ways:

  1.  A v4/unicast EoR should be an empty UPDATE.  However, it seemed
     to be treating an UPDATE with attributes, inc.  MP REACH/UNREACH,
     but no classic NLRIs, as a v4/uni EoR.

  2.  For other AFI/SAFIs, it was treating UPDATEs with no classic
     withraw and with a zero-length MP withdraw as EoRs.  However, that
     would mean an UPDATE packet _with_ update NLRIs and a 0-len MP
     withdraw could be classed as an EoR.

  This seems to be loose coding leading to ambiguous protocol
  situations and likely incorrect behaviour, rather than simply being
  liberal.  Be more strict about checking that an UPDATE really is an
  EoR and definitely is not trying to update any NLRIs.

  This same loose EoR parsing was noted by Chris Hall previously on
  list.

  (bgp_nlri_parse) Front end NLRI parse function, to fan-out to the correct
  parser for the AFI/SAFI.

* bgp_route.c: (bgp_nlri_sanity_check) We try convert NLRI safi to
  internal code-point ASAP, adjust switch for that.  Leave the wire
  code point in for defensive coding.

  (bgp_nlri_parse) rename to bgp_nlri_parse_ip.

* tests/bgp_mp_attr_test.c: Can just use bgp_nlri_parse frontend.

bgpd/bgp_packet.c
bgpd/bgp_packet.h
bgpd/bgp_route.c
bgpd/bgp_route.h
tests/bgp_mp_attr_test.c

index dd9740843f005b618f677fe89d42f6ffaa15bd2d..664c4b40bb6e91abc9d2c7c11688347205ffad5a 100644 (file)
@@ -1320,11 +1320,29 @@ bgp_update_explicit_eors (struct peer *peer)
   bgp_check_update_delay(peer->bgp);
 }
 
+/* Frontend for NLRI parsing, to fan-out to AFI/SAFI specific parsers */
+int
+bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
+{
+  switch (packet->safi)
+    {
+      case SAFI_UNICAST:
+      case SAFI_MULTICAST:
+        return bgp_nlri_parse_ip (peer, attr, packet);
+      case SAFI_MPLS_VPN:
+      case SAFI_MPLS_LABELED_VPN:
+        return bgp_nlri_parse_vpn (peer, attr, packet);
+      case SAFI_ENCAP:
+        return bgp_nlri_parse_encap (peer, attr, packet);
+    }
+  return -1;
+}
+
 /* Parse BGP Update packet and make attribute object. */
 static int
 bgp_update_receive (struct peer *peer, bgp_size_t size)
 {
-  int ret;
+  int ret, nlri_ret;
   u_char *end;
   struct stream *s;
   struct attr attr;
@@ -1332,12 +1350,17 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
   bgp_size_t attribute_len;
   bgp_size_t update_len;
   bgp_size_t withdraw_len;
-  struct bgp_nlri update;
-  struct bgp_nlri withdraw;
-  struct bgp_nlri mp_update;
-  struct bgp_nlri mp_withdraw;
   int num_pfx_adv, num_pfx_wd;
 
+  enum NLRI_TYPES {
+    NLRI_UPDATE,
+    NLRI_WITHDRAW,
+    NLRI_MP_UPDATE,
+    NLRI_MP_WITHDRAW,
+    NLRI_TYPE_MAX
+  };
+  struct bgp_nlri nlris[NLRI_TYPE_MAX];
+
   /* Status must be Established. */
   if (peer->status != Established) 
     {
@@ -1350,10 +1373,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
   /* Set initial values. */
   memset (&attr, 0, sizeof (struct attr));
   memset (&extra, 0, sizeof (struct attr_extra));
-  memset (&update, 0, sizeof (struct bgp_nlri));
-  memset (&withdraw, 0, sizeof (struct bgp_nlri));
-  memset (&mp_update, 0, sizeof (struct bgp_nlri));
-  memset (&mp_withdraw, 0, sizeof (struct bgp_nlri));
+  memset (&nlris, 0, sizeof (nlris));
   attr.extra = &extra;
   num_pfx_adv = num_pfx_wd = 0;
   memset (peer->rcvd_attr_str, 0, BUFSIZ);
@@ -1393,13 +1413,17 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
   /* Unfeasible Route packet format check. */
   if (withdraw_len > 0)
     {
-      withdraw.afi = AFI_IP;
-      withdraw.safi = SAFI_UNICAST;
-      withdraw.nlri = stream_pnt (s);
-      withdraw.length = withdraw_len;
-      ret = bgp_nlri_sanity_check (peer, &withdraw, &num_pfx_wd);
-      if (ret < 0)
-       return -1;
+      nlris[NLRI_WITHDRAW].afi = AFI_IP;
+      nlris[NLRI_WITHDRAW].safi = SAFI_UNICAST;
+      nlris[NLRI_WITHDRAW].nlri = stream_pnt (s);
+      nlris[NLRI_WITHDRAW].length = withdraw_len;
+
+      if (bgp_nlri_sanity_check (peer, &nlris[NLRI_WITHDRAW], &num_pfx_wd) < 0)
+        {
+          bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
+                           BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+          return -1;
+        }
 
       stream_forward_getp (s, withdraw_len);
     }
@@ -1446,7 +1470,7 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
   if (attribute_len)
     {
       attr_parse_ret = bgp_attr_parse (peer, &attr, attribute_len, 
-                           &mp_update, &mp_withdraw);
+                           &nlris[NLRI_MP_UPDATE], &nlris[NLRI_MP_WITHDRAW]);
       if (attr_parse_ret == BGP_ATTR_PARSE_ERROR)
        {
          bgp_attr_unintern_sub (&attr);
@@ -1478,15 +1502,17 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
   if (update_len)
     {
       /* Set NLRI portion to structure. */
-      update.afi = AFI_IP;
-      update.safi = SAFI_UNICAST;
-      update.nlri = stream_pnt (s);
-      update.length = update_len;
+      nlris[NLRI_UPDATE].afi = AFI_IP;
+      nlris[NLRI_UPDATE].safi = SAFI_UNICAST;
+      nlris[NLRI_UPDATE].nlri = stream_pnt (s);
+      nlris[NLRI_UPDATE].length = update_len;
 
       /* Check NLRI packet format and prefix length. */
-      ret = bgp_nlri_sanity_check (peer, &update, &num_pfx_adv);
+      ret = bgp_nlri_sanity_check (peer, &nlris[NLRI_UPDATE], &num_pfx_adv);
       if (ret < 0)
         {
+          bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
+                           BGP_NOTIFY_UPDATE_INVAL_NETWORK);
           bgp_attr_unintern_sub (&attr);
          return -1;
        }
@@ -1499,263 +1525,115 @@ bgp_update_receive (struct peer *peer, bgp_size_t size)
                peer->host, withdraw_len, num_pfx_wd, attribute_len,
                update_len, num_pfx_adv);
 
-  /* NLRI is processed only when the the corresponding address-family
-   * has been negotiated with the peer.
-   */
-  if (peer->afc_nego[AFI_IP][SAFI_UNICAST])
-    {
-      if (withdraw.length)
-       bgp_nlri_parse (peer, NULL, &withdraw);
-
-      if (update.length)
-        bgp_nlri_parse (peer, NLRI_ATTR_ARG, &update);
-
-      if (mp_update.length
-         && mp_update.afi == AFI_IP 
-         && mp_update.safi == SAFI_UNICAST)
-       bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
-
-      if (mp_withdraw.length
-         && mp_withdraw.afi == AFI_IP 
-         && mp_withdraw.safi == SAFI_UNICAST)
-       bgp_nlri_parse (peer, NULL, &mp_withdraw);
-
-      if (! attribute_len && ! withdraw_len)
-       {
-         /* End-of-RIB received */
-    if (!CHECK_FLAG(peer->af_sflags[AFI_IP][SAFI_UNICAST],
-                             PEER_STATUS_EOR_RECEIVED))
-      {
-        SET_FLAG (peer->af_sflags[AFI_IP][SAFI_UNICAST],
-                  PEER_STATUS_EOR_RECEIVED);
-        bgp_update_explicit_eors(peer);
-      }
-
-         /* NSF delete stale route */
-         if (peer->nsf[AFI_IP][SAFI_UNICAST])
-           bgp_clear_stale_route (peer, AFI_IP, SAFI_UNICAST);
-
-          if (bgp_debug_neighbor_events(peer))
-           zlog_debug ("rcvd End-of-RIB for IPv4 Unicast from %s", peer->host);
-       }
-    }
-  if (peer->afc_nego[AFI_IP][SAFI_MULTICAST])
-    {
-      if (mp_update.length
-         && 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.safi == SAFI_MULTICAST)
-       bgp_nlri_parse (peer, NULL, &mp_withdraw);
-
-      if (! withdraw_len
-         && mp_withdraw.afi == AFI_IP
-         && mp_withdraw.safi == SAFI_MULTICAST
-         && mp_withdraw.length == 0)
-       {
-         /* End-of-RIB received */
-    if (!CHECK_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
-                           PEER_STATUS_EOR_RECEIVED))
-      {
-        SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MULTICAST],
-                  PEER_STATUS_EOR_RECEIVED);
-        bgp_update_explicit_eors(peer);
-      }
+  /* Parse any given NLRIs */
+  for (int i = NLRI_UPDATE; i < NLRI_TYPE_MAX; i++)
+    {
+      /* We use afi and safi as indices into tables and what not. It would
+       * be impossible, at this time, to support unknown afi/safis. And
+       * anyway, the peer needs to be configured to enable the afi/safi
+       * explicitly which requires UI support.
+       *
+       * Ignore unknown afi/safi NLRIs.
+       *
+       * Note: This means nlri[x].afi/safi still can not be trusted for
+       * indexing later in this function!
+       *
+       * Note2: This will also remap the wire code-point for VPN safi to the
+       * internal safi_t point, as needs be.
+       */
+      if(!bgp_afi_safi_valid_indices (nlris[i].afi, &nlris[i].safi))
+        {
+          zlog_info ("%s [Info] UPDATE with unsupported AFI/SAFI %u/%u",
+                     peer->host, nlris[i].afi, nlris[i].safi);
+          continue;
+        }
 
-         /* NSF delete stale route */
-         if (peer->nsf[AFI_IP][SAFI_MULTICAST])
-           bgp_clear_stale_route (peer, AFI_IP, SAFI_MULTICAST);
+      /* NLRI is processed iff the peer if configured for the specific afi/safi */
+      if (!peer->afc[nlris[i].afi][nlris[i].safi])
+        {
+          zlog_info ("%s [Info] UPDATE for non-enabled AFI/SAFI %u/%u",
+                     peer->host, nlris[i].afi, nlris[i].safi);
+          continue;
+        }
 
-          if (bgp_debug_neighbor_events(peer))
-           zlog_debug ("rcvd End-of-RIB for IPv4 Multicast from %s", peer->host);
-       }
-    }
-  if (peer->afc_nego[AFI_IP6][SAFI_UNICAST])
-    {
-      if (mp_update.length 
-         && mp_update.afi == AFI_IP6 
-         && mp_update.safi == SAFI_UNICAST)
-       bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
-
-      if (mp_withdraw.length 
-         && mp_withdraw.afi == AFI_IP6 
-         && mp_withdraw.safi == SAFI_UNICAST)
-       bgp_nlri_parse (peer, NULL, &mp_withdraw);
-
-      if (! withdraw_len
-         && mp_withdraw.afi == AFI_IP6
-         && mp_withdraw.safi == SAFI_UNICAST
-         && mp_withdraw.length == 0)
-       {
-         /* End-of-RIB received */
-    if (!CHECK_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST],
-                           PEER_STATUS_EOR_RECEIVED))
-      {
-             SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_UNICAST], PEER_STATUS_EOR_RECEIVED);
-        bgp_update_explicit_eors(peer);
-      }
+      /* EoR handled later */
+      if (nlris[i].length == 0)
+        continue;
 
-         /* NSF delete stale route */
-         if (peer->nsf[AFI_IP6][SAFI_UNICAST])
-           bgp_clear_stale_route (peer, AFI_IP6, SAFI_UNICAST);
+      switch (i)
+        {
+          case NLRI_UPDATE:
+          case NLRI_MP_UPDATE:
+            nlri_ret = bgp_nlri_parse (peer, NLRI_ATTR_ARG, &nlris[i]);
+            break;
+          case NLRI_WITHDRAW:
+          case NLRI_MP_WITHDRAW:
+            nlri_ret = bgp_nlri_parse (peer, NULL, &nlris[i]);
+            break;
+          default:
+            nlri_ret = -1;
+        }
 
-          if (bgp_debug_neighbor_events(peer))
-           zlog_debug ("rcvd End-of-RIB for IPv6 Unicast from %s", peer->host);
-       }
+      if (nlri_ret < 0)
+        {
+          zlog_err("%s [Error] Error parsing NLRI", peer->host);
+          if (peer->status == Established)
+            bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
+                             i <= NLRI_WITHDRAW ? BGP_NOTIFY_UPDATE_INVAL_NETWORK
+                                                : BGP_NOTIFY_UPDATE_OPT_ATTR_ERR);
+          bgp_attr_unintern_sub (&attr);
+          return -1;
+        }
     }
-  if (peer->afc_nego[AFI_IP6][SAFI_MULTICAST])
-    {
-      if (mp_update.length 
-         && mp_update.afi == AFI_IP6 
-         && mp_update.safi == SAFI_MULTICAST)
-       bgp_nlri_parse (peer, NLRI_ATTR_ARG, &mp_update);
-
-      if (mp_withdraw.length 
-         && mp_withdraw.afi == AFI_IP6 
-         && mp_withdraw.safi == SAFI_MULTICAST)
-       bgp_nlri_parse (peer, NULL, &mp_withdraw);
-
-      if (! withdraw_len
-         && mp_withdraw.afi == AFI_IP6
-         && mp_withdraw.safi == SAFI_MULTICAST
-         && mp_withdraw.length == 0)
-       {
-         /* End-of-RIB received */
-    if (!CHECK_FLAG (peer->af_sflags[AFI_IP6][SAFI_MULTICAST],
-                           PEER_STATUS_EOR_RECEIVED))
-      {
-             SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_MULTICAST], PEER_STATUS_EOR_RECEIVED);
-        bgp_update_explicit_eors(peer);
-      }
-
 
-         /* NSF delete stale route */
-         if (peer->nsf[AFI_IP6][SAFI_MULTICAST])
-           bgp_clear_stale_route (peer, AFI_IP6, SAFI_MULTICAST);
-
-          if (bgp_debug_neighbor_events(peer))
-           zlog_debug ("rcvd End-of-RIB for IPv6 Multicast from %s", peer->host);
-       }
-    }
-  if (peer->afc_nego[AFI_IP][SAFI_MPLS_VPN])
-    {
-      if (mp_update.length 
-         && mp_update.afi == AFI_IP 
-         && 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_IP 
-         && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN)
-       bgp_nlri_parse_vpn (peer, NULL, &mp_withdraw);
-
-      if (! withdraw_len
-         && mp_withdraw.afi == AFI_IP
-         && mp_withdraw.safi == SAFI_MPLS_LABELED_VPN
-         && mp_withdraw.length == 0)
-       {
+  /* EoR checks
+   *
+   * Non-MP IPv4/Unicast EoR is a completely empty UPDATE
+   * and MP EoR should have only an empty MP_UNREACH
+   */
+  if (!update_len && !withdraw_len
+      && nlris[NLRI_MP_UPDATE].length == 0)
+    {
+      afi_t afi = 0;
+      safi_t safi;
 
-          /* End-of-RIB received */
-          if (!CHECK_FLAG (peer->af_sflags[AFI_IP][SAFI_MPLS_VPN],
-                           PEER_STATUS_EOR_RECEIVED))
-            {
-             SET_FLAG (peer->af_sflags[AFI_IP][SAFI_MPLS_VPN], PEER_STATUS_EOR_RECEIVED);
-              bgp_update_explicit_eors(peer);
-            }
+      /* Non-MP IPv4/Unicast is a completely emtpy UPDATE - already checked
+       * update and withdraw NLRI lengths are 0.
+       */
+      if (!attribute_len)
+        {
+          afi = AFI_IP;
+          safi = SAFI_UNICAST;
+        }
+      else if (attr.flag == BGP_ATTR_MP_UNREACH_NLRI
+               && nlris[NLRI_MP_WITHDRAW].length == 0
+               && bgp_afi_safi_valid_indices (nlris[NLRI_MP_WITHDRAW].afi,
+                                              &nlris[NLRI_MP_WITHDRAW].safi))
+        {
+          afi = nlris[NLRI_MP_WITHDRAW].afi;
+          safi = nlris[NLRI_MP_WITHDRAW].safi;
+        }
 
-          if (bgp_debug_neighbor_events(peer))
-           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)
-       {
+      if (afi && peer->afc[afi][safi])
+        {
           /* End-of-RIB received */
-          if (!CHECK_FLAG (peer->af_sflags[AFI_IP6][SAFI_MPLS_VPN],
-                           PEER_STATUS_EOR_RECEIVED))
+          if (!CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_EOR_RECEIVED))
             {
-             SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_MPLS_VPN], PEER_STATUS_EOR_RECEIVED);
+              SET_FLAG (peer->af_sflags[afi][safi],
+                        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);
-       }
-    }
-  if (peer->afc[AFI_IP][SAFI_ENCAP])
-    {
-      if (mp_update.length
-         && mp_update.afi == AFI_IP
-         && mp_update.safi == SAFI_ENCAP)
-       bgp_nlri_parse_encap (peer, NLRI_ATTR_ARG, &mp_update);
-
-      if (mp_withdraw.length
-         && mp_withdraw.afi == AFI_IP
-         && mp_withdraw.safi == SAFI_ENCAP)
-       bgp_nlri_parse_encap (peer, NULL, &mp_withdraw);
-
-      if (! withdraw_len
-         && mp_withdraw.afi == AFI_IP
-         && mp_withdraw.safi == SAFI_ENCAP
-         && mp_withdraw.length == 0)
-       {
-         /* End-of-RIB received */
-          if (!CHECK_FLAG (peer->af_sflags[AFI_IP][SAFI_ENCAP],
-                           PEER_STATUS_EOR_RECEIVED))
-            {
-             SET_FLAG (peer->af_sflags[AFI_IP][SAFI_ENCAP], PEER_STATUS_EOR_RECEIVED);
-              bgp_update_explicit_eors(peer);
-            }
+          /* NSF delete stale route */
+          if (peer->nsf[afi][safi])
+            bgp_clear_stale_route (peer, afi, safi);
 
           if (bgp_debug_neighbor_events(peer))
-           zlog_debug ("rcvd End-of-RIB for IPv4 Encap from %s", peer->host);
-       }
-    }
-  if (peer->afc[AFI_IP6][SAFI_ENCAP])
-    {
-      if (mp_update.length 
-         && mp_update.afi == AFI_IP6 
-         && mp_update.safi == SAFI_ENCAP)
-       bgp_nlri_parse_encap (peer, NLRI_ATTR_ARG, &mp_update);
-
-      if (mp_withdraw.length 
-         && mp_withdraw.afi == AFI_IP6
-         && mp_withdraw.safi == SAFI_ENCAP)
-       bgp_nlri_parse_encap (peer, NULL, &mp_withdraw);
-
-      if (! withdraw_len
-         && mp_withdraw.afi == AFI_IP6
-         && mp_withdraw.safi == SAFI_ENCAP
-         && mp_withdraw.length == 0)
-       {
-         /* End-of-RIB received */
-          if (!CHECK_FLAG (peer->af_sflags[AFI_IP6][SAFI_ENCAP],
-                           PEER_STATUS_EOR_RECEIVED))
             {
-             SET_FLAG (peer->af_sflags[AFI_IP6][SAFI_ENCAP], PEER_STATUS_EOR_RECEIVED);
-              bgp_update_explicit_eors(peer);
+              zlog_debug ("rcvd End-of-RIB for %s from %s",
+                          afi_safi_print (afi, safi), peer->host);
             }
-
-          if (bgp_debug_neighbor_events(peer))
-           zlog_debug ("rcvd End-of-RIB for IPv6 Encap from %s", peer->host);
-       }
+        }
     }
 
   /* Everything is done.  We unintern temporary structures which
index b699866b014f40eb2e3e8a49a4fe544897a24c8f..78855c342580f6d94d475b3eb80537aac2a829a7 100644 (file)
@@ -54,6 +54,9 @@ extern void bgp_default_update_send (struct peer *, struct attr *,
 extern void bgp_default_withdraw_send (struct peer *, afi_t, safi_t);
 
 extern int bgp_capability_receive (struct peer *, bgp_size_t);
+
+extern int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *);
+
 extern void bgp_update_restarted_peers (struct peer *);
 extern void bgp_update_implicit_eors (struct peer *);
 extern void bgp_check_update_delay (struct bgp *);
index 57faf46f155ee2b8856cbd84a320151bbd09cad7..e744de10c4be5301098e138f53958bbe30b64c5f 100644 (file)
@@ -3405,7 +3405,8 @@ bgp_addpath_encode_rx (struct peer *peer, afi_t afi, safi_t safi)
 /* Parse NLRI stream.  Withdraw NLRI is recognized by NULL attr
    value. */
 int
-bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
+bgp_nlri_parse_ip (struct peer *peer, struct attr *attr,
+                   struct bgp_nlri *packet)
 {
   u_char *pnt;
   u_char *lim;
@@ -3619,6 +3620,7 @@ bgp_nlri_sanity_check (struct peer *peer, struct bgp_nlri *nlri, int *numpfx)
   switch (nlri->safi)
     {
       case SAFI_MPLS_LABELED_VPN:
+      case SAFI_MPLS_VPN:
         return bgp_nlri_sanity_check_vpn (peer, nlri, numpfx);
       case SAFI_UNICAST:
       case SAFI_MULTICAST:
index b76393ecd6e373cf6c9725401ead8f41ef815be6..5b1893cdd6147b6beb1a75ac58c3a5df246c2c1f 100644 (file)
@@ -265,7 +265,7 @@ extern void bgp_info_unset_flag (struct bgp_node *, struct bgp_info *, u_int32_t
 extern void bgp_info_path_with_addpath_rx_str (struct bgp_info *ri, char *buf);
 
 extern int bgp_nlri_sanity_check (struct peer *, struct bgp_nlri *, int *);
-extern int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *);
+extern int bgp_nlri_parse_ip (struct peer *, struct attr *, struct bgp_nlri *);
 
 extern int bgp_maximum_prefix_overflow (struct peer *, afi_t, safi_t, int);
 
index 2e6b892b7015eff55992136e7f73ff98a236d9fc..dfb8ed9f7ab9d16a353c6fa13c46758ef565dbc7 100644 (file)
@@ -34,6 +34,7 @@
 #include "bgpd/bgp_open.h"
 #include "bgpd/bgp_debug.h"
 #include "bgpd/bgp_route.h"
+#include "bgpd/bgp_packet.h"
 #include "bgpd/bgp_mplsvpn.h"
 #include "bgpd/bgp_nexthop.h"
 
@@ -725,16 +726,10 @@ parse_test (struct peer *peer, struct test_segment *t, int type)
   
   if (!parse_ret)
     {
-      int (*f) (struct peer *, struct attr *, struct bgp_nlri *)
-        = bgp_nlri_parse;
-      
-      if (t->safi == SAFI_MPLS_LABELED_VPN)
-        f = bgp_nlri_parse_vpn;
-      
       if (type == BGP_ATTR_MP_REACH_NLRI)
-        nlri_ret = f (peer, &attr, &nlri);
+        nlri_ret = bgp_nlri_parse (peer, &attr, &nlri);
       else
-        nlri_ret = f (peer, NULL, &nlri);
+        nlri_ret = bgp_nlri_parse (peer, NULL, &nlri);
     }
   
   handle_result (peer, t, parse_ret, nlri_ret);