]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: link l2vnis(bgpevpn) to l3vni(vrf)
authorMitesh Kanjariya <mitesh@cumulusnetworks.com>
Mon, 9 Oct 2017 03:43:14 +0000 (20:43 -0700)
committerMitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
Thu, 14 Dec 2017 18:57:05 +0000 (10:57 -0800)
Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
bgpd/bgp_evpn.c
bgpd/bgp_evpn_private.h
bgpd/bgp_evpn_vty.c
bgpd/bgpd.h

index bf7d9a369ca3f0b861cf195b11e8dd6537078214..e23396e79cde468e9c585750357b8a666fd56209 100644 (file)
@@ -2738,6 +2738,10 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
                XFREE(MTYPE_BGP_EVPN, vpn);
                return NULL;
        }
+
+       /* add to l2vni list on corresponding vrf */
+       bgpevpn_link_to_l3vni(vpn);
+
        QOBJ_REG(vpn, bgpevpn);
        return vpn;
 }
@@ -2750,6 +2754,7 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
  */
 void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
 {
+       bgpevpn_unlink_from_l3vni(vpn);
        bgp_table_unlock(vpn->route_table);
        bgp_evpn_unmap_vni_from_its_rts(bgp, vpn);
        list_delete_and_null(&vpn->import_rtl);
@@ -2913,6 +2918,20 @@ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
        return 0;
 }
 
+static void link_l2vni_hash_to_l3vni(struct hash_backet *backet,
+                                    struct bgp *bgp_vrf)
+{
+       struct bgpevpn *vpn = NULL;
+       struct bgp *bgp_def = NULL;
+
+       bgp_def = bgp_get_default();
+       assert(bgp_def);
+
+       vpn = (struct bgpevpn *)backet->data;
+       if (vpn->tenant_vrf_id == bgp_vrf->vrf_id)
+               bgpevpn_link_to_l3vni(vpn);
+}
+
 int bgp_evpn_local_l3vni_add(vni_t l3vni,
                             vrf_id_t vrf_id,
                             struct ethaddr *rmac)
@@ -2967,6 +2986,12 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni,
        if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD))
                evpn_auto_rt_export_add_for_vrf(bgp_vrf);
 
+       /* link all corresponding l2vnis */
+       hash_iterate(bgp_def->vnihash,
+                    (void (*)(struct hash_backet *, void *))
+                       link_l2vni_hash_to_l3vni,
+                    bgp_vrf);
+
        //TODO_MITESH: update all the local mac-ip routes with l3vni/rmac info
 
        //TODO_MITESH: import all the remote routes to VRF
@@ -3068,8 +3093,11 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
        if (vpn) {
 
                /* update tenant_vrf_id if required */
-               if (vpn->tenant_vrf_id != tenant_vrf_id)
+               if (vpn->tenant_vrf_id != tenant_vrf_id) {
+                       bgpevpn_unlink_from_l3vni(vpn);
                        vpn->tenant_vrf_id = tenant_vrf_id;
+                       bgpevpn_link_to_l3vni(vpn);
+               }
 
                if (is_vni_live(vpn)
                    && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip))
@@ -3159,6 +3187,9 @@ void bgp_evpn_cleanup(struct bgp *bgp)
        if (bgp->vrf_export_rtl)
                list_delete(bgp->vrf_export_rtl);
        bgp->vrf_export_rtl = NULL;
+       if (bgp->l2vnis)
+               list_delete(bgp->l2vnis);
+       bgp->l2vnis = NULL;
        bf_free(bgp->rd_idspace);
 }
 
@@ -3183,6 +3214,9 @@ void bgp_evpn_init(struct bgp *bgp)
        bgp->vrf_export_rtl = list_new();
        bgp->vrf_export_rtl->cmp =
                (int (*)(void *, void *))evpn_route_target_cmp;
+       bgp->l2vnis = list_new();
+       bgp->l2vnis->cmp =
+               (int (*)(void *, void *))vni_hash_cmp;
        bf_init(bgp->rd_idspace, UINT16_MAX);
        /*assign 0th index in the bitfield, so that we start with id 1*/
        bf_assign_zero_index(bgp->rd_idspace);
index c5166890578aee3868cf0c40ab27d3871903023f..ca59c8ba425152d19ee85a87bad617f34762597c 100644 (file)
@@ -101,6 +101,26 @@ struct irt_node {
 #define RT_TYPE_EXPORT 2
 #define RT_TYPE_BOTH   3
 
+static inline void bgpevpn_unlink_from_l3vni(struct bgpevpn *vpn)
+{
+       struct bgp *bgp_vrf = NULL;
+
+       bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id);
+       if (!bgp_vrf || !bgp_vrf->l2vnis)
+               return;
+       listnode_delete(bgp_vrf->l2vnis, vpn);
+}
+
+static inline void bgpevpn_link_to_l3vni(struct bgpevpn *vpn)
+{
+       struct bgp *bgp_vrf = NULL;
+
+       bgp_vrf = bgp_lookup_by_vrf_id(vpn->tenant_vrf_id);
+       if (!bgp_vrf || !bgp_vrf->l2vnis)
+               return;
+       listnode_add_sort(bgp_vrf->l2vnis, vpn);
+}
+
 static inline int is_vni_configured(struct bgpevpn *vpn)
 {
        return (CHECK_FLAG(vpn->flags, VNI_FLAG_CFGD));
index 57a31866aa251dca57dbd3b33880acda497bab1e..fce887df2e6d32eb8274224e3e4df23e4224e0fc 100644 (file)
@@ -3081,7 +3081,7 @@ DEFUN (show_bgp_vrf_l3vni_info,
        const char *name = NULL;
        struct bgp *bgp = NULL;
        struct listnode *node = NULL;
-       //struct bgpevpn *vpn = NULL;
+       struct bgpevpn *vpn = NULL;
        struct ecommunity *ecom = NULL;
 
        name = argv[idx_vrf]->arg;
@@ -3096,11 +3096,11 @@ DEFUN (show_bgp_vrf_l3vni_info,
        vty_out(vty, "  L3-VNI: %u\n", bgp->l3vni);
        vty_out(vty, "  Rmac: %s\n",
                prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
-       /*vty_out(vty, "  L2-VNI List:\n");
+       vty_out(vty, "  L2-VNI List:\n");
        vty_out(vty, "    ");
        for (ALL_LIST_ELEMENTS_RO(bgp->l2vnis, node, vpn))
                vty_out(vty, "%u  ", vpn->vni);
-       vty_out(vty, "\n");*/
+       vty_out(vty, "\n");
        vty_out(vty, "  Export-RTs:\n");
        vty_out(vty, "    ");
        for (ALL_LIST_ELEMENTS_RO(bgp->vrf_export_rtl, node, ecom))
index b050f917c569d4ce466c0f571ad53aa299db8a51..c49e2b56b2d7ad0ed0b8c63e3f686e57b69c64e4 100644 (file)
@@ -427,6 +427,9 @@ struct bgp {
        /* export rt list for the vrf instance */
        struct list *vrf_export_rtl;
 
+       /* list of corresponding l2vnis (struct bgpevpn) */
+       struct list *l2vnis;
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(bgp)