]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: Allow non-default instance to be EVPN one
authorTuetuopay <tuetuopay@me.com>
Wed, 6 Mar 2019 18:09:25 +0000 (19:09 +0100)
committerTuetuopay <tuetuopay@me.com>
Tue, 19 Mar 2019 10:56:14 +0000 (11:56 +0100)
This makes the instance bearing the advertise-all-vni config option
register to zebra as the EVPN one, forwarding it the option.

Signed-off-by: Tuetuopay <tuetuopay@me.com>
Sponsored-by: Scaleway
bgpd/bgp_evpn.h
bgpd/bgp_evpn_vty.c
bgpd/bgp_main.c
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.h

index fbf30083e178f92cd7b95dfb07b06e24beea1f93..bcc524d5aa48f692af66dc9b173c740ead39bbd4 100644 (file)
@@ -31,7 +31,7 @@ static inline int is_evpn_enabled(void)
 {
        struct bgp *bgp = NULL;
 
-       bgp = bgp_get_default();
+       bgp = bgp_get_evpn();
        return bgp ? bgp->advertise_all_vni : 0;
 }
 
index 8437c4024eb31791933f0c701193426ebe119caa..9ac1af046a510ebb00c903d24a19f07e0b38ed8b 100644 (file)
@@ -2757,6 +2757,7 @@ static void evpn_unset_advertise_subnet(struct bgp *bgp, struct bgpevpn *vpn)
 static void evpn_set_advertise_all_vni(struct bgp *bgp)
 {
        bgp->advertise_all_vni = 1;
+       bgp_set_evpn(bgp);
        bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni);
 }
 
@@ -2767,6 +2768,7 @@ static void evpn_set_advertise_all_vni(struct bgp *bgp)
 static void evpn_unset_advertise_all_vni(struct bgp *bgp)
 {
        bgp->advertise_all_vni = 0;
+       bgp_set_evpn(bgp_get_default());
        bgp_zebra_advertise_all_vni(bgp, bgp->advertise_all_vni);
        bgp_evpn_cleanup_on_disable(bgp);
 }
@@ -2954,9 +2956,18 @@ DEFUN (bgp_evpn_advertise_all_vni,
        "Advertise All local VNIs\n")
 {
        struct bgp *bgp = VTY_GET_CONTEXT(bgp);
+       struct bgp *bgp_evpn = NULL;
 
        if (!bgp)
                return CMD_WARNING;
+
+       bgp_evpn = bgp_get_evpn();
+       if (bgp_evpn && bgp_evpn != bgp) {
+               vty_out(vty, "%% Please unconfigure EVPN in VRF %s\n",
+                       bgp_evpn->name);
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
        evpn_set_advertise_all_vni(bgp);
        return CMD_SUCCESS;
 }
index 47e7c1686fab5e97a7c4fd378de0799224d9b825..697889cc6b03b354b4a86d39f5651feb4a169c7b 100644 (file)
@@ -171,7 +171,7 @@ void sigusr1(void)
 */
 static __attribute__((__noreturn__)) void bgp_exit(int status)
 {
-       struct bgp *bgp, *bgp_default;
+       struct bgp *bgp, *bgp_default, *bgp_evpn;
        struct listnode *node, *nnode;
 
        /* it only makes sense for this to be called on a clean exit */
@@ -184,13 +184,16 @@ static __attribute__((__noreturn__)) void bgp_exit(int status)
        bgp_close();
 
        bgp_default = bgp_get_default();
+       bgp_evpn = bgp_get_evpn();
 
        /* reverse bgp_master_init */
        for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
-               if (bgp_default == bgp)
+               if (bgp_default == bgp || bgp_evpn == bgp)
                        continue;
                bgp_delete(bgp);
        }
+       if (bgp_evpn && bgp_evpn != bgp_default)
+               bgp_delete(bgp_evpn);
        if (bgp_default)
                bgp_delete(bgp_default);
 
index 5f0b20e029d410543602d83b4540de2e2a2057de..398735d7a4260d7204893b61e096e5e2390f8031 100644 (file)
@@ -1632,7 +1632,7 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
                        return CMD_WARNING;
 
 #if ENABLE_BGP_VNC
-               if (bgp->vrf_id == VRF_DEFAULT
+               if (bgp->advertise_all_vni
                    && type == ZEBRA_ROUTE_VNC_DIRECT) {
                        vnc_export_bgp_enable(
                                bgp, afi); /* only enables if mode bits cfg'd */
@@ -1794,7 +1794,7 @@ int bgp_redistribute_unset(struct bgp *bgp, afi_t afi, int type,
  * status. red lookup fails if there is no zebra connection.
  */
 #if ENABLE_BGP_VNC
-       if (bgp->vrf_id == VRF_DEFAULT && type == ZEBRA_ROUTE_VNC_DIRECT) {
+       if (bgp->advertise_all_vni && type == ZEBRA_ROUTE_VNC_DIRECT) {
                vnc_export_bgp_disable(bgp, afi);
        }
 #endif
@@ -1861,9 +1861,8 @@ void 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 && is_evpn_enabled())
+       /* For EVPN instance, register to learn about VNIs, if appropriate. */
+       if (bgp->advertise_all_vni)
                bgp_zebra_advertise_all_vni(bgp, 1);
 
        bgp_nht_register_nexthops(bgp);
@@ -1881,9 +1880,8 @@ void 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 && is_evpn_enabled())
+       /* For EVPN instance, unregister learning about VNIs, if appropriate. */
+       if (bgp->advertise_all_vni)
                bgp_zebra_advertise_all_vni(bgp, 0);
 
        /* Deregister for router-id, interfaces, redistributed routes. */
index d99b402e28b1c18c3a316acc69300a827177f135..8fcf417b3a2e11577be2e44d8557b688a768aa9f 100644 (file)
@@ -2872,6 +2872,12 @@ static struct bgp *bgp_create(as_t *as, const char *name,
                                   name, *as);
        }
 
+       /* Default the EVPN VRF to the default one */
+       if (inst_type == BGP_INSTANCE_TYPE_DEFAULT && !bgp_master.bgp_evpn) {
+               bgp_lock(bgp);
+               bm->bgp_evpn = bgp;
+       }
+
        bgp_lock(bgp);
        bgp->heuristic_coalesce = true;
        bgp->inst_type = inst_type;
@@ -3070,6 +3076,29 @@ struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id)
        return (vrf->info) ? (struct bgp *)vrf->info : NULL;
 }
 
+/* Sets the BGP instance where EVPN is enabled */
+void bgp_set_evpn(struct bgp *bgp)
+{
+       if (bm->bgp_evpn == bgp)
+               return;
+
+       /* First, release the reference count we hold on the instance */
+       if (bm->bgp_evpn)
+               bgp_unlock(bm->bgp_evpn);
+
+       bm->bgp_evpn = bgp;
+
+       /* Increase the reference count on this new VRF */
+       if (bm->bgp_evpn)
+               bgp_lock(bm->bgp_evpn);
+}
+
+/* Returns the BGP instance where EVPN is enabled, if any */
+struct bgp *bgp_get_evpn(void)
+{
+       return bm->bgp_evpn;
+}
+
 /* handle socket creation or deletion, if necessary
  * this is called for all new BGP instances
  */
@@ -3354,6 +3383,14 @@ int bgp_delete(struct bgp *bgp)
        if (vrf)
                bgp_vrf_unlink(bgp, vrf);
 
+       /* Update EVPN VRF pointer */
+       if (bm->bgp_evpn == bgp) {
+               if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+                       bgp_set_evpn(NULL);
+               else
+                       bgp_set_evpn(bgp_get_default());
+       }
+
        thread_master_free_unused(bm->master);
        bgp_unlock(bgp); /* initial reference */
 
index c7d137c76c169bc8acddfd781a3293b29ab2f99c..f9c269e3e6e8b4974f530de893c4227f7dde3e8f 100644 (file)
@@ -150,6 +150,9 @@ struct bgp_master {
        /* dynamic mpls label allocation pool */
        struct labelpool labelpool;
 
+       /* BGP-EVPN VRF ID. Defaults to default VRF (if any) */
+       struct bgp* bgp_evpn;
+
        bool terminating;       /* global flag that sigint terminate seen */
        QOBJ_FIELDS
 };
@@ -1506,6 +1509,8 @@ extern struct bgp *bgp_get_default(void);
 extern struct bgp *bgp_lookup(as_t, const char *);
 extern struct bgp *bgp_lookup_by_name(const char *);
 extern struct bgp *bgp_lookup_by_vrf_id(vrf_id_t);
+extern struct bgp *bgp_get_evpn(void);
+extern void bgp_set_evpn(struct bgp *bgp);
 extern struct peer *peer_lookup(struct bgp *, union sockunion *);
 extern struct peer *peer_lookup_by_conf_if(struct bgp *, const char *);
 extern struct peer *peer_lookup_by_hostname(struct bgp *, const char *);