From: Mitesh Kanjariya Date: Mon, 9 Oct 2017 00:46:08 +0000 (-0700) Subject: bgpd: l3vni/rmac association with bgp vrf X-Git-Tag: frr-4.0-dev~58^2~73 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=fe1dc5a37476ba955528864b176dddcf63255b20;p=mirror%2Ffrr.git bgpd: l3vni/rmac association with bgp vrf Signed-off-by: Mitesh Kanjariya --- diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 7c87c9b3b3..a477da78d9 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -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. */ diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 829dbfa4e1..42b9ebc5c5 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -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, diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 5515643ed1..49a0f38db8 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -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) { diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index bd5312ad46..a660139a24 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -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) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index e5e363ef52..edcaed84a7 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -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)