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.
*/
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.
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
#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
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);
}
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);
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);
/* 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
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);
}
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)
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 */