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.
*/
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,
"Show BGP VRFs\n"
JSON_STR)
{
+ char buf[ETHER_ADDR_STRLEN];
struct list *inst = bm->bgp;
struct listnode *node;
struct bgp *bgp;
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");
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)
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) {
*/
}
+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)
{
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)
#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
/* 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)