bgpd: Regularise BGP NLRI sanity checks a bit

* bgp_route.h: (bgp_nlri_sanity_check) The bulk of the args are equivalent
  to a (struct bgp_nlri), consolidate.
* bgp_route.c: (bgp_nlri_sanity_check) Make this a frontend for all afi/safis.
  Including SAFI_MPLS_LABELED_VPN.
  (bgp_nlri_sanity_check_ip) Regular IP NLRI sanity check based on the
  existing code, and adjusted for (struct bgp_nlri *) arg.
* bgp_attr.c: (bgp_mp_reach_parse) Adjust for passing (struct bgp_nlri *)
  to bgp_nlri_sanity_check.
  Get rid of special-casing to not sanity check VPN.
  (bgp_mp_unreach_parse) Ditto.

* bgp_mplsvpn.c: Use the same VPN parsing code for both the sanity
  check and the actual parse.

  (bgp_nlri_parse_vpn) renamed to bgp_nlri_parse_vpn_body and made
  internal.

  (bgp_nlri_parse_vpn_body) Added (bool) argument to control whether it
  is sanity checking or whether it should update routing state for each
  NLRI.  Send a NOTIFY and reset the session, if there's a parsing
  error, as bgp_nlri_sanity_check_ip does, and as is required by the
  RFC.

  (bgp_nlri_parse_vpn) now a wrapper to call _body with update.

  (bgp_nlri_sanity_check_vpn) wrapper to call parser without
  updating.

* bgp_mplsvpn.h: (bgp_nlri_sanity_check_vpn) export for
  bgp_nlri_sanity_check.

* bgp_packet.c: (bgp_update_receive) Adjust for bgp_nlri_sanity_check
  argument changes.

* test/bgp_mp_attr_test.c: Extend to also test the NLRI parsing functions,
  if the initial MP-attr parsing has succeeded.  Fix the NLRI in the
  VPN cases.  Add further VPN tests.

* tests/bgpd.tests/testbgpmpattr.exp: Add the new test cases.

This commit a joint effort of:

Lou Berger <lberger@labn.net>
Donald Sharp <sharpd@cumulusnetworks.com>
Paul Jakma <paul.jakma@hpe.com> / <paul@jakma.org>
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 888f11a..98571da 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1725,23 +1725,20 @@
                  __func__, peer->host);
       return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
     }
- 
-  if (safi != SAFI_MPLS_LABELED_VPN)
-    {
-      ret = bgp_nlri_sanity_check (peer, afi, safi, stream_pnt (s), nlri_len);
-      if (ret < 0) 
-        {
-          zlog_info ("%s: (%s) NLRI doesn't pass sanity check",
-                     __func__, peer->host);
-	  return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
-	}
-    }
-
+  
   mp_update->afi = afi;
   mp_update->safi = safi;
   mp_update->nlri = stream_pnt (s);
   mp_update->length = nlri_len;
 
+  ret = bgp_nlri_sanity_check (peer, mp_update);
+  if (ret < 0) 
+    {
+      zlog_info ("%s: (%s) NLRI doesn't pass sanity check",
+                 __func__, peer->host);
+      return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
+    }
+
   stream_forward_getp (s, nlri_len);
 
   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MP_REACH_NLRI);
@@ -1759,7 +1756,6 @@
   afi_t afi;
   safi_t safi;
   u_int16_t withdraw_len;
-  int ret;
   struct peer *const peer = args->peer;  
   struct attr *const attr = args->attr;
   const bgp_size_t length = args->length;
@@ -1775,18 +1771,14 @@
   
   withdraw_len = length - BGP_MP_UNREACH_MIN_SIZE;
 
-  if (safi != SAFI_MPLS_LABELED_VPN)
-    {
-      ret = bgp_nlri_sanity_check (peer, afi, safi, stream_pnt (s), withdraw_len);
-      if (ret < 0)
-	return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
-    }
-
   mp_withdraw->afi = afi;
   mp_withdraw->safi = safi;
   mp_withdraw->nlri = stream_pnt (s);
   mp_withdraw->length = withdraw_len;
 
+  if (bgp_nlri_sanity_check (peer, mp_withdraw) < 0)
+    return BGP_ATTR_PARSE_ERROR_NOTIFYPLS;
+
   stream_forward_getp (s, withdraw_len);
 
   attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MP_UNREACH_NLRI);