]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Implement EVPN enable/disable
authorvivek <vivek@cumulusnetworks.com>
Mon, 15 May 2017 21:30:19 +0000 (14:30 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 12 Jul 2017 16:36:35 +0000 (12:36 -0400)
Implement the command 'advertise-all-vni' under the EVPN address-family
in order to allow the local system to learn about local VNIs (and MACs
and Neighbors corresponding to those VNIs) and exchange with other EVPN
speakers.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
Reviewed-by: Dinesh Dutt <ddutt@cumulusnetworks.com>
bgpd/bgp_evpn.c
bgpd/bgp_evpn.h
bgpd/bgp_evpn_vty.c
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgp_zebra.h

index 6e6e696a9a32249c9246c4a39603b671353d291c..0e191ffff1cf453c5a6c35db28dbed1ee09fa45f 100644 (file)
@@ -112,6 +112,14 @@ import_rt_hash_cmp (const void *p1, const void *p2)
   return(memcmp(irt1->rt.val, irt2->rt.val, ECOMMUNITY_SIZE) == 0);
 }
 
+/*
+ * Cleanup specific VNI upon EVPN (advertise-all-vni) being disabled.
+ */
+static void
+cleanup_vni_on_disable (struct hash_backet *backet, struct bgp *bgp)
+{
+}
+
 /*
  * Free a VNI entry; iterator function called during cleanup.
  */
@@ -315,6 +323,18 @@ bgp_packet_mpattr_route_type_5(struct stream *s,
        return;
 }
 
+/*
+ * Cleanup EVPN information on disable - Need to delete and withdraw
+ * EVPN routes from peers.
+ */
+void
+bgp_evpn_cleanup_on_disable (struct bgp *bgp)
+{
+  hash_iterate (bgp->vnihash,
+                (void (*) (struct hash_backet *, void *))
+                cleanup_vni_on_disable, bgp);
+}
+
 /*
  * Cleanup EVPN information - invoked at the time of bgpd exit or when the
  * BGP instance (default) is being freed.
index 8a4e27c0cb0a5a49b7d77770e2f2c5a163d60db3..c87f3ffc779e27610ba42690d9cd28c1fd324345 100644 (file)
@@ -29,6 +29,8 @@ bgp_packet_mpattr_route_type_5(struct stream *s,
                               struct prefix *p, struct prefix_rd *prd,
                               mpls_label_t *label, struct attr *attr);
 
+extern void
+bgp_evpn_cleanup_on_disable (struct bgp *bgp);
 extern void
 bgp_evpn_cleanup (struct bgp *bgp);
 extern void
index d22a07ed31f66f1fd00cdbd0c63e2ee0e98ebb81..ac1faf9de17aad075db1ec66ad0eb28379c9b9de 100644 (file)
@@ -31,6 +31,8 @@
 #include "bgpd/bgp_vpn.h"
 #include "bgpd/bgp_evpn_vty.h"
 #include "bgpd/bgp_evpn.h"
+#include "bgpd/bgp_evpn_private.h"
+#include "bgpd/bgp_zebra.h"
 
 #define SHOW_DISPLAY_STANDARD 0
 #define SHOW_DISPLAY_TAGS 1
@@ -716,22 +718,71 @@ DEFUN(no_evpnrt5_network,
                                     argv[idx_ethtag]->arg);
 }
 
+/*
+ * EVPN (VNI advertisement) enabled. Register with zebra.
+ */
+static void
+evpn_set_advertise_all_vni (struct bgp *bgp)
+{
+  bgp->advertise_all_vni = 1;
+  bgp_zebra_advertise_all_vni (bgp, bgp->advertise_all_vni);
+}
+
+/*
+ * EVPN (VNI advertisement) disabled. De-register with zebra. Cleanup VNI
+ * cache, EVPN routes (delete and withdraw from peers).
+ */
+static void
+evpn_unset_advertise_all_vni (struct bgp *bgp)
+{
+  bgp->advertise_all_vni = 0;
+  bgp_zebra_advertise_all_vni (bgp, bgp->advertise_all_vni);
+  bgp_evpn_cleanup_on_disable (bgp);
+}
+
+DEFUN (bgp_evpn_advertise_all_vni,
+       bgp_evpn_advertise_all_vni_cmd,
+       "advertise-all-vni",
+       "Advertise All local VNIs\n")
+{
+  struct bgp *bgp = VTY_GET_CONTEXT(bgp);
+
+  if (!bgp)
+    return CMD_WARNING;
+  evpn_set_advertise_all_vni (bgp);
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_bgp_evpn_advertise_all_vni,
+       no_bgp_evpn_advertise_all_vni_cmd,
+       "no advertise-all-vni",
+       NO_STR
+       "Advertise All local VNIs\n")
+{
+  struct bgp *bgp = VTY_GET_CONTEXT(bgp);
+
+  if (!bgp)
+    return CMD_WARNING;
+  evpn_unset_advertise_all_vni (bgp);
+  return CMD_SUCCESS;
+}
+
 void bgp_ethernetvpn_init(void)
 {
-       install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_cmd);
-       install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_cmd);
-       install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_tags_cmd);
-       install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_tags_cmd);
-       install_element(VIEW_NODE,
-                       &show_ip_bgp_l2vpn_evpn_all_neighbor_routes_cmd);
-       install_element(VIEW_NODE,
-                       &show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd);
-       install_element(VIEW_NODE,
-                       &show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd);
-       install_element(VIEW_NODE,
-                       &show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd);
-       install_element(VIEW_NODE, &show_ip_bgp_evpn_rd_overlay_cmd);
-       install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_overlay_cmd);
-       install_element(BGP_EVPN_NODE, &no_evpnrt5_network_cmd);
-       install_element(BGP_EVPN_NODE, &evpnrt5_network_cmd);
+  install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_cmd);
+  install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_cmd);
+  install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_tags_cmd);
+  install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_tags_cmd);
+  install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_neighbor_routes_cmd);
+  install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_rd_neighbor_routes_cmd);
+  install_element(VIEW_NODE,
+                  &show_ip_bgp_l2vpn_evpn_all_neighbor_advertised_routes_cmd);
+  install_element(VIEW_NODE,
+                  &show_ip_bgp_l2vpn_evpn_rd_neighbor_advertised_routes_cmd);
+  install_element(VIEW_NODE, &show_ip_bgp_evpn_rd_overlay_cmd);
+  install_element(VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_overlay_cmd);
+  install_element(BGP_EVPN_NODE, &no_evpnrt5_network_cmd);
+  install_element(BGP_EVPN_NODE, &evpnrt5_network_cmd);
+  install_element (BGP_EVPN_NODE, &bgp_evpn_advertise_all_vni_cmd);
+  install_element (BGP_EVPN_NODE, &no_bgp_evpn_advertise_all_vni_cmd);
 }
index 83135fb5dcab801700a9f94c5c1c86f2c9053078..75b47399568015bca3be82b17b294e4070aee82b 100644 (file)
@@ -11286,6 +11286,8 @@ bgp_vty_init (void)
   install_element (BGP_VPNV4_NODE, &no_neighbor_route_reflector_client_cmd);
   install_element (BGP_VPNV6_NODE, &neighbor_route_reflector_client_cmd);
   install_element (BGP_VPNV6_NODE, &no_neighbor_route_reflector_client_cmd);
+  install_element (BGP_EVPN_NODE, &neighbor_route_reflector_client_cmd);
+  install_element (BGP_EVPN_NODE, &no_neighbor_route_reflector_client_cmd);
 
   /* "neighbor route-server" commands.*/
   install_element (BGP_NODE, &neighbor_route_server_client_hidden_cmd);
@@ -11659,6 +11661,8 @@ bgp_vty_init (void)
   install_element (BGP_VPNV4_NODE, &no_neighbor_allowas_in_cmd);
   install_element (BGP_VPNV6_NODE, &neighbor_allowas_in_cmd);
   install_element (BGP_VPNV6_NODE, &no_neighbor_allowas_in_cmd);
+  install_element (BGP_EVPN_NODE, &neighbor_allowas_in_cmd);
+  install_element (BGP_EVPN_NODE, &no_neighbor_allowas_in_cmd);
 
   /* address-family commands. */
   install_element (BGP_NODE, &address_family_ipv4_safi_cmd);
index 71a4d4317a91aa0d6dbebbb5111387c3ba5b1e73..19f0dd98ff461b8832387af14191447e849614a1 100644 (file)
@@ -2033,6 +2033,11 @@ bgp_zebra_instance_register (struct bgp *bgp)
 
   /* Register for router-id, interfaces, redistributed routes. */
   zclient_send_reg_requests (zclient, bgp->vrf_id);
+
+  /* For default instance, register to learn about VNIs, if appropriate. */
+  if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
+      && bgp->advertise_all_vni)
+    bgp_zebra_advertise_all_vni (bgp, 1);
 }
 
 /* Deregister this instance with Zebra. Invoked upon the instance
@@ -2048,6 +2053,11 @@ bgp_zebra_instance_deregister (struct bgp *bgp)
   if (BGP_DEBUG (zebra, ZEBRA))
     zlog_debug("Deregistering VRF %u", bgp->vrf_id);
 
+  /* For default instance, unregister learning about VNIs, if appropriate. */
+  if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
+      && bgp->advertise_all_vni)
+    bgp_zebra_advertise_all_vni (bgp, 0);
+
   /* Deregister for router-id, interfaces, redistributed routes. */
   zclient_send_dereg_requests (zclient, bgp->vrf_id);
 }
@@ -2080,6 +2090,29 @@ bgp_zebra_terminate_radv (struct bgp *bgp, struct peer *peer)
   zclient_send_interface_radv_req (zclient, bgp->vrf_id, peer->ifp, 0, 0);
 }
 
+int
+bgp_zebra_advertise_all_vni (struct bgp *bgp, int advertise)
+{
+  struct stream *s;
+
+  /* Check socket. */
+  if (!zclient || zclient->sock < 0)
+    return 0;
+
+  /* Don't try to register if Zebra doesn't know of this instance. */
+  if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
+    return 0;
+
+  s = zclient->obuf;
+  stream_reset (s);
+
+  zclient_create_header (s, ZEBRA_ADVERTISE_ALL_VNI, bgp->vrf_id);
+  stream_putc(s, advertise);
+  stream_putw_at (s, 0, stream_get_endp (s));
+
+  return zclient_send_message(zclient);
+}
+
 /* BGP has established connection with Zebra. */
 static void
 bgp_zebra_connected (struct zclient *zclient)
index 3d634ed695146d280ab63ffaf48e87227fabce6b..7ad1f706d682c084e6d4197baf36f9ec8b4062a6 100644 (file)
@@ -54,6 +54,8 @@ extern struct interface *if_lookup_by_ipv4_exact (struct in_addr *, vrf_id_t);
 extern struct interface *if_lookup_by_ipv6 (struct in6_addr *, ifindex_t, vrf_id_t);
 extern struct interface *if_lookup_by_ipv6_exact (struct in6_addr *, ifindex_t, vrf_id_t);
 
+extern int bgp_zebra_advertise_all_vni (struct bgp *, int); 
+
 extern int bgp_zebra_num_connects(void);
 
 #endif /* _QUAGGA_BGP_ZEBRA_H */