]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: l3vni/rmac association with bgp vrf
authorMitesh Kanjariya <mitesh@cumulusnetworks.com>
Mon, 9 Oct 2017 00:46:08 +0000 (17:46 -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.h
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgpd.h

index 7c87c9b3b3cd4f647d93acd064652dc16555c745..a477da78d9d8be4da290df0eb1e435339e049f57 100644 (file)
@@ -2772,6 +2772,94 @@ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac,
        return 0;
 }
 
+int bgp_evpn_local_l3vni_add(vni_t l3vni,
+                            vrf_id_t vrf_id,
+                            struct ethaddr *rmac)
+{
+       struct bgp *bgp_vrf = NULL; /* bgp VRF instance */
+       struct bgp *bgp_def = NULL; /* default bgp instance */
+       as_t as = 0;
+
+       /* get the default instamce - required to get the AS number for VRF
+        * auto-creation*/
+       bgp_def = bgp_get_default();
+       if (!bgp_def) {
+               zlog_err("Cannot process L3VNI  %u ADD - default BGP instance not yet created",
+                        l3vni);
+               return -1;
+       }
+       as = bgp_def->as;
+
+       /* if the BGP vrf instance doesnt exist - create one */
+       bgp_vrf = bgp_lookup_by_vrf_id(vrf_id);
+       if (!bgp_vrf) {
+
+               int ret = 0;
+
+               ret = bgp_get(&bgp_vrf, &as, vrf_id_to_name(vrf_id),
+                             BGP_INSTANCE_TYPE_VRF);
+               switch (ret) {
+               case BGP_ERR_MULTIPLE_INSTANCE_NOT_SET:
+                       zlog_err("'bgp multiple-instance' not present\n");
+                       return -1;
+               case BGP_ERR_AS_MISMATCH:
+                       zlog_err("BGP is already running; AS is %u\n", as);
+                       return -1;
+               case BGP_ERR_INSTANCE_MISMATCH:
+                       zlog_err("BGP instance name and AS number mismatch\n");
+                       return -1;
+               }
+
+               /* mark as auto created */
+               SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO);
+       }
+
+       /* associate with l3vni */
+       bgp_vrf->l3vni = l3vni;
+
+       /* set the router mac - to be used in mac-ip routes for this vrf */
+       memcpy(&bgp_vrf->rmac, rmac, sizeof(struct ethaddr));
+
+       //TODO_MITESH: auto derive RD/RT
+
+       //TODO_MITESH: update all the local mac-ip routes with l3vni/rmac info
+
+       //TODO_MITESH: import all the remote routes to VRF
+
+       return 0;
+}
+
+int bgp_evpn_local_l3vni_del(vni_t l3vni,
+                            vrf_id_t vrf_id)
+{
+       struct bgp *bgp_vrf = NULL; /* bgp vrf instance */
+
+       bgp_vrf = bgp_lookup_by_vrf_id(vrf_id);
+       if (!bgp_vrf) {
+               zlog_err("Cannot process L3VNI %u Del - Could not find BGP instance",
+                        l3vni);
+               return -1;
+       }
+
+       /* remove the l3vni from vrf instance */
+       bgp_vrf->l3vni = 0;
+
+       /* remove the Rmac from the BGP vrf */
+       memset(&bgp_vrf->rmac, 0, sizeof(struct ethaddr));
+
+       /* TODO_MITESH: delete auto RD/RT */
+
+       /* TODO_MITESH: update all local mac-ip routes */
+
+       /* TODO_MITESH: unimport remote routes from VRF */
+
+       /* Delete the instance if it was autocreated */
+       if (CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_AUTO))
+               bgp_delete(bgp_vrf);
+
+       return 0;
+}
+
 /*
  * Handle del of a local VNI.
  */
index 829dbfa4e15c5b368dc702c308807081f1ac9aa2..42b9ebc5c5798f7baac084c80992269e62562967 100644 (file)
@@ -45,6 +45,8 @@ extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
 extern int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni,
                                    struct ethaddr *mac, struct ipaddr *ip,
                                    u_char flags);
+extern int bgp_evpn_local_l3vni_add(vni_t, vrf_id_t, struct ethaddr *);
+extern int bgp_evpn_local_l3vni_del(vni_t, vrf_id_t);
 extern int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni);
 extern int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni,
                                  struct in_addr originator_ip,
index 5515643ed1ae185fca4696c66df79ffe8937b35f..49a0f38db86dc668759ca15f0e1804cefdb45bbb 100644 (file)
@@ -6448,6 +6448,7 @@ DEFUN (show_bgp_vrfs,
        "Show BGP VRFs\n"
        JSON_STR)
 {
+       char buf[ETHER_ADDR_STRLEN];
        struct list *inst = bm->bgp;
        struct listnode *node;
        struct bgp *bgp;
@@ -6455,8 +6456,6 @@ DEFUN (show_bgp_vrfs,
        json_object *json = NULL;
        json_object *json_vrfs = NULL;
        int count = 0;
-       static char header[] =
-               "Type  Id     RouterId          #PeersCfg  #PeersEstb  Name";
 
        if (!bgp_option_check(BGP_OPT_MULTIPLE_INSTANCE)) {
                vty_out(vty, "BGP Multiple Instance is not enabled\n");
@@ -6482,7 +6481,10 @@ DEFUN (show_bgp_vrfs,
 
                count++;
                if (!uj && count == 1)
-                       vty_out(vty, "%s\n", header);
+                       vty_out(vty,
+                               "%4s  %-5s  %-16s  %9s  %10s  %-37s %-10s %-15s\n",
+                              "Type", "Id", "routerId", "#PeersVfg",
+                              "#PeersEstb", "Name", "L3-VNI", "Rmac");
 
                peers_cfg = peers_estb = 0;
                if (uj)
@@ -6516,11 +6518,17 @@ DEFUN (show_bgp_vrfs,
                        json_object_int_add(json_vrf, "numEstablishedPeers",
                                            peers_estb);
 
+                       json_object_int_add(json_vrf, "l3vni", bgp->l3vni);
+                       json_object_string_add(json_vrf, "rmac",
+                                              prefix_mac2str(&bgp->rmac, buf,
+                                                             sizeof(buf)));
                        json_object_object_add(json_vrfs, name, json_vrf);
                } else
-                       vty_out(vty, "%4s  %-5d  %-16s  %9u  %10u  %s\n", type,
-                               vrf_id_ui, inet_ntoa(bgp->router_id), peers_cfg,
-                               peers_estb, name);
+                       vty_out(vty,
+                               "%4s  %-5d  %-16s  %9u  %10u  %-37s %-10u %-15s\n",
+                               type, vrf_id_ui, inet_ntoa(bgp->router_id),
+                               peers_cfg, peers_estb, name, bgp->l3vni,
+                               prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
        }
 
        if (uj) {
index bd5312ad46331558c2fbeba12162324ffd952498..a660139a242f34d17871a7d5fd8d2282e51f71a1 100644 (file)
@@ -1675,6 +1675,35 @@ static void bgp_zebra_connected(struct zclient *zclient)
         */
 }
 
+static int bgp_zebra_process_local_l3vni(int cmd, struct zclient *zclient,
+                                        zebra_size_t length, vrf_id_t vrf_id)
+{
+       char buf[ETHER_ADDR_STRLEN];
+       vni_t l3vni;
+       struct ethaddr rmac;
+       struct stream *s;
+
+       memset(&rmac, 0, sizeof(struct ethaddr));
+       s = zclient->ibuf;
+       l3vni = stream_getl(s);
+       if (cmd == ZEBRA_L3VNI_ADD)
+               stream_get(&rmac, s, sizeof(struct ethaddr));
+
+       if (BGP_DEBUG(zebra, ZEBRA))
+               zlog_debug("Rx L3-VNI %s VRF %s VNI %u RMAC %s",
+                          (cmd == ZEBRA_L3VNI_ADD) ? "add" : "del",
+                          vrf_id_to_name(vrf_id),
+                          l3vni,
+                          prefix_mac2str(&rmac, buf, sizeof(buf)));
+
+       if (cmd == ZEBRA_L3VNI_ADD)
+               bgp_evpn_local_l3vni_add(l3vni, vrf_id, &rmac);
+       else
+               bgp_evpn_local_l3vni_del(l3vni, vrf_id);
+
+       return 0;
+}
+
 static int bgp_zebra_process_local_vni(int command, struct zclient *zclient,
                                       zebra_size_t length, vrf_id_t vrf_id)
 {
@@ -1788,6 +1817,8 @@ void bgp_zebra_init(struct thread_master *master)
        zclient->local_vni_del = bgp_zebra_process_local_vni;
        zclient->local_macip_add = bgp_zebra_process_local_macip;
        zclient->local_macip_del = bgp_zebra_process_local_macip;
+       zclient->local_l3vni_add = bgp_zebra_process_local_l3vni;
+       zclient->local_l3vni_del = bgp_zebra_process_local_l3vni;
 }
 
 void bgp_zebra_destroy(void)
index e5e363ef52252552b7b6aa15be32ed35ef780576..edcaed84a731a7aaa59d9c02c6844a013e042b84 100644 (file)
@@ -36,6 +36,7 @@
 #include "defaults.h"
 #include "bgp_memory.h"
 #include "bitfield.h"
+#include "vxlan.h"
 
 #define BGP_MAX_HOSTNAME 64    /* Linux max, is larger than most other sys */
 #define BGP_PEER_MAX_HASH_SIZE 16384
@@ -408,6 +409,16 @@ struct bgp {
        /* Id space for automatic RD derivation for an EVI */
        bitfield_t rd_idspace;
 
+       /* L3-VNI corresponding to this vrf */
+       vni_t l3vni;
+
+       /* router-mac to be used in mac-ip routes for this vrf */
+       struct ethaddr rmac;
+
+       /* vrf flags */
+       uint32_t vrf_flags;
+#define BGP_VRF_AUTO (1 << 0)
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(bgp)