summaryrefslogtreecommitdiff
path: root/zebra/zebra_vxlan.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2018-02-08 11:46:29 +0100
committerGitHub <noreply@github.com>2018-02-08 11:46:29 +0100
commit8e71b98f72e843d4910abd02410f07fe1e6565cc (patch)
treea84f92632eb0deed948f6b961c489573ede1ac0b /zebra/zebra_vxlan.c
parent25236dd35df008a1484f2605299c8228ea1cfc5b (diff)
parent9d00a48754440cc9d4674e9b9405642edd983f0f (diff)
Merge pull request #1654 from mkanjari/evpn-symm-routing-enhancements
Evpn symmetric routing enhancements
Diffstat (limited to 'zebra/zebra_vxlan.c')
-rw-r--r--zebra/zebra_vxlan.c726
1 files changed, 518 insertions, 208 deletions
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 1690079f68..fb1aebecc3 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -46,7 +46,6 @@
#include "zebra/zebra_vxlan.h"
#include "zebra/zebra_memory.h"
#include "zebra/zebra_l2.h"
-#include "lib/json.h"
DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix");
DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
@@ -59,6 +58,9 @@ DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "VNI Neighbor");
/* static function declarations */
+static int ip_prefix_send_to_client(vrf_id_t vrf_id,
+ struct prefix *p,
+ uint16_t cmd);
static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json);
static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt);
static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
@@ -286,6 +288,12 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
: "Inactive");
}
}
+ if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
+ if (!json)
+ vty_out(vty, " Default-gateway");
+ else
+ json_object_boolean_true_add(json, "defaultGateway");
+ }
if (json == NULL)
vty_out(vty, "\n");
}
@@ -442,7 +450,8 @@ static void zl3vni_print_nh(zebra_neigh_t *n,
ipaddr2str(&n->ip, buf2, sizeof(buf2)));
vty_out(vty, " RMAC: %s\n",
prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
- vty_out(vty, " Host-List:\n");
+ vty_out(vty, " Refcount: %d\n", listcount(n->host_list));
+ vty_out(vty, " Prefixes:\n");
for (ALL_LIST_ELEMENTS_RO(n->host_list, node, p))
vty_out(vty, " %s\n",
prefix2str(p, buf2, sizeof(buf2)));
@@ -451,15 +460,16 @@ static void zl3vni_print_nh(zebra_neigh_t *n,
json_object_string_add(json, "ip",
ipaddr2str(&(n->ip), buf2,
sizeof(buf2)));
- json_object_string_add(json, "rmac",
+ json_object_string_add(json, "routerMac",
prefix_mac2str(&n->emac, buf2,
sizeof(buf2)));
+ json_object_int_add(json, "refCount", listcount(n->host_list));
for (ALL_LIST_ELEMENTS_RO(n->host_list, node, p))
json_object_array_add(json_hosts,
json_object_new_string(
prefix2str(p, buf2,
sizeof(buf2))));
- json_object_object_add(json, "hosts", json_hosts);
+ json_object_object_add(json, "prefixList", json_hosts);
}
}
@@ -479,24 +489,27 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac,
prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1)));
vty_out(vty, " Remote VTEP: %s\n",
inet_ntoa(zrmac->fwd_info.r_vtep_ip));
- vty_out(vty, " Host-List:\n");
+ vty_out(vty, " Refcount: %d\n", listcount(zrmac->host_list));
+ vty_out(vty, " Prefixes:\n");
for (ALL_LIST_ELEMENTS_RO(zrmac->host_list, node, p))
vty_out(vty, " %s\n",
prefix2str(p, buf2, sizeof(buf2)));
} else {
json_hosts = json_object_new_array();
- json_object_string_add(json, "Rmac",
+ json_object_string_add(json, "routerMac",
prefix_mac2str(&zrmac->macaddr,
buf1,
sizeof(buf1)));
- json_object_string_add(json, "vtep-ip",
+ json_object_string_add(json, "vtepIp",
inet_ntoa(zrmac->fwd_info.r_vtep_ip));
+ json_object_int_add(json, "refCount",
+ listcount(zrmac->host_list));
for (ALL_LIST_ELEMENTS_RO(zrmac->host_list, node, p))
json_object_array_add(json_hosts,
json_object_new_string(
prefix2str(p, buf2,
sizeof(buf2))));
- json_object_object_add(json, "hosts", json_hosts);
+ json_object_object_add(json, "prefixList", json_hosts);
}
}
@@ -534,6 +547,12 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
vty_out(vty, " Auto Mac ");
}
+ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
+ vty_out(vty, " Sticky Mac ");
+
+ if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
+ vty_out(vty, " Default-gateway Mac ");
+
vty_out(vty, "\n");
/* print all the associated neigh */
vty_out(vty, " Neighbors:\n");
@@ -739,17 +758,15 @@ static void zl3vni_print_nh_hash(struct hash_backet *backet,
return;
if (!json_vni) {
- vty_out(vty, "%-15s %-17s %6d\n",
+ vty_out(vty, "%-15s %-17s\n",
ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
- prefix_mac2str(&n->emac, buf1, sizeof(buf1)),
- listcount(n->host_list));
+ prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
} else {
- json_object_string_add(json_nh, "nexthop-ip",
+ json_object_string_add(json_nh, "nexthopIp",
ipaddr2str(&n->ip, buf2, sizeof(buf2)));
- json_object_string_add(json_nh, "rmac",
+ json_object_string_add(json_nh, "routerMac",
prefix_mac2str(&n->emac, buf1,
sizeof(buf1)));
- json_object_int_add(json_nh, "refCnt", listcount(n->host_list));
json_object_object_add(json_vni,
ipaddr2str(&(n->ip), buf2, sizeof(buf2)),
json_nh);
@@ -789,10 +806,9 @@ static void zl3vni_print_nh_hash_all_vni(struct hash_backet *backet,
if (json == NULL) {
vty_out(vty, "\nVNI %u #Next-Hops %u\n\n",
zl3vni->vni, num_nh);
- vty_out(vty, "%-15s %-17s %6s\n", "IP",
- "RMAC", "Refcnt");
+ vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
} else
- json_object_int_add(json_vni, "numNh", num_nh);
+ json_object_int_add(json_vni, "numNextHops", num_nh);
memset(&wctx, 0, sizeof(struct nh_walk_ctx));
wctx.vty = vty;
@@ -833,10 +849,9 @@ static void zl3vni_print_rmac_hash_all_vni(struct hash_backet *backet,
}
if (json == NULL) {
- vty_out(vty, "\nVNI %u #MACs %u\n\n",
+ vty_out(vty, "\nVNI %u #RMACs %u\n\n",
zl3vni->vni, num_rmacs);
- vty_out(vty, "%-17s %-21s %-6s\n", "MAC",
- "Remote VTEP", "Refcnt");
+ vty_out(vty, "%-17s %-21s\n", "RMAC", "Remote VTEP");
} else
json_object_int_add(json_vni, "numRmacs", num_rmacs);
@@ -872,18 +887,15 @@ static void zl3vni_print_rmac_hash(struct hash_backet *backet,
return;
if (!json) {
- vty_out(vty, "%-17s %-21s %-6d\n",
+ vty_out(vty, "%-17s %-21s\n",
prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
- inet_ntoa(zrmac->fwd_info.r_vtep_ip),
- listcount(zrmac->host_list));
+ inet_ntoa(zrmac->fwd_info.r_vtep_ip));
} else {
- json_object_string_add(json_rmac, "rmac",
+ json_object_string_add(json_rmac, "routerMac",
prefix_mac2str(&zrmac->macaddr, buf,
sizeof(buf)));
- json_object_string_add(json_rmac, "vtep-ip",
+ json_object_string_add(json_rmac, "vtepIp",
inet_ntoa(zrmac->fwd_info.r_vtep_ip));
- json_object_int_add(json_rmac, "refcnt",
- listcount(zrmac->host_list));
json_object_object_add(json,
prefix_mac2str(&zrmac->macaddr, buf,
sizeof(buf)),
@@ -906,7 +918,10 @@ static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx)
if (!json) {
vty_out(vty, "VNI: %u\n", zl3vni->vni);
- vty_out(vty, " Local Vtep Ip: %s",
+ vty_out(vty, " Type: %s\n", "L3");
+ vty_out(vty, " Tenant VRF: %s\n",
+ zl3vni_vrf_name(zl3vni));
+ vty_out(vty, " Local Vtep Ip: %s\n",
inet_ntoa(zl3vni->local_vtep_ip));
vty_out(vty, " Vxlan-Intf: %s\n",
zl3vni_vxlan_if_name(zl3vni));
@@ -914,35 +929,34 @@ static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx)
zl3vni_svi_if_name(zl3vni));
vty_out(vty, " State: %s\n",
zl3vni_state2str(zl3vni));
- vty_out(vty, " Vrf: %s\n",
- zl3vni_vrf_name(zl3vni));
- vty_out(vty, " Rmac: %s\n",
+ vty_out(vty, " Router MAC: %s\n",
zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
- vty_out(vty, " L2-VNIs: ");
+ vty_out(vty, " L2 VNIs: ");
for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zvni))
vty_out(vty, "%u ", zvni->vni);
vty_out(vty, "\n");
} else {
json_vni_list = json_object_new_array();
json_object_int_add(json, "vni", zl3vni->vni);
- json_object_string_add(json, "local-vtep-ip",
+ json_object_string_add(json, "type", "L3");
+ json_object_string_add(json, "localVtepIp",
inet_ntoa(zl3vni->local_vtep_ip));
- json_object_string_add(json, "vxlan-intf",
+ json_object_string_add(json, "vxlanIntf",
zl3vni_vxlan_if_name(zl3vni));
- json_object_string_add(json, "svi-if",
+ json_object_string_add(json, "sviIntf",
zl3vni_svi_if_name(zl3vni));
json_object_string_add(json, "state",
zl3vni_state2str(zl3vni));
json_object_string_add(json, "vrf",
zl3vni_vrf_name(zl3vni));
- json_object_string_add(json, "rmac",
+ json_object_string_add(json, "routerMac",
zl3vni_rmac2str(zl3vni, buf,
sizeof(buf)));
for (ALL_LIST_ELEMENTS(zl3vni->l2vnis, node, nnode, zvni)) {
json_object_array_add(json_vni_list,
json_object_new_int(zvni->vni));
}
- json_object_object_add(json, "l2-vnis", json_vni_list);
+ json_object_object_add(json, "l2Vnis", json_vni_list);
}
}
@@ -964,9 +978,11 @@ static void zvni_print(zebra_vni_t *zvni, void **ctxt)
if (json == NULL) {
vty_out(vty, "VNI: %u\n", zvni->vni);
- vty_out(vty, " VRF: %s\n", vrf_id_to_name(zvni->vrf_id));
+ vty_out(vty, " Type: %s\n", "L2");
+ vty_out(vty, " Tenant VRF: %s\n", vrf_id_to_name(zvni->vrf_id));
} else {
json_object_int_add(json, "vni", zvni->vni);
+ json_object_string_add(json, "type", "L2");
json_object_string_add(json, "vrf",
vrf_id_to_name(zvni->vrf_id));
}
@@ -978,11 +994,13 @@ static void zvni_print(zebra_vni_t *zvni, void **ctxt)
}
num_macs = num_valid_macs(zvni);
num_neigh = hashcount(zvni->neigh_table);
- if (json == NULL)
- vty_out(vty, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
- zvni->vxlan_if->name, zvni->vxlan_if->ifindex,
+ if (json == NULL) {
+ vty_out(vty, " VxLAN interface: %s\n",
+ zvni->vxlan_if->name);
+ vty_out(vty, " VxLAN ifIndex: %u\n", zvni->vxlan_if->ifindex);
+ vty_out(vty," Local VTEP IP: %s\n",
inet_ntoa(zvni->local_vtep_ip));
- else {
+ } else {
json_object_string_add(json, "vxlanInterface",
zvni->vxlan_if->name);
json_object_int_add(json, "ifindex", zvni->vxlan_if->ifindex);
@@ -1033,7 +1051,6 @@ static void zvni_print(zebra_vni_t *zvni, void **ctxt)
static void zl3vni_print_hash(struct hash_backet *backet,
void *ctx[])
{
- char buf[ETHER_ADDR_STRLEN];
struct vty *vty = NULL;
json_object *json = NULL;
json_object *json_vni = NULL;
@@ -1047,33 +1064,30 @@ static void zl3vni_print_hash(struct hash_backet *backet,
return;
if (!json) {
- vty_out(vty, "%-10u %-15s %-20s %-20s %-5s %-37s %-18s\n",
- zl3vni->vni,
- inet_ntoa(zl3vni->local_vtep_ip),
+ vty_out(vty,
+ "%-10u %-4s %-21s %-8lu %-8lu %-15s %-37s\n",
+ zl3vni->vni, "L3",
zl3vni_vxlan_if_name(zl3vni),
- zl3vni_svi_if_name(zl3vni),
- zl3vni_state2str(zl3vni),
- zl3vni_vrf_name(zl3vni),
- zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
+ hashcount(zl3vni->rmac_table),
+ hashcount(zl3vni->nh_table),
+ "n/a",
+ zl3vni_vrf_name(zl3vni));
} else {
char vni_str[VNI_STR_LEN];
snprintf(vni_str, VNI_STR_LEN, "%u", zl3vni->vni);
json_vni = json_object_new_object();
json_object_int_add(json_vni, "vni", zl3vni->vni);
- json_object_string_add(json_vni, "local-ip",
- inet_ntoa(zl3vni->local_vtep_ip));
- json_object_string_add(json_vni, "vxlan-if",
+ json_object_string_add(json_vni, "vxlanIf",
zl3vni_vxlan_if_name(zl3vni));
- json_object_string_add(json_vni, "svi-if",
- zl3vni_svi_if_name(zl3vni));
- json_object_string_add(json_vni, "state",
- zl3vni_state2str(zl3vni));
- json_object_string_add(json_vni, "vrf",
+ json_object_int_add(json_vni, "numMacs",
+ hashcount(zl3vni->rmac_table));
+ json_object_int_add(json_vni, "numArpNd",
+ hashcount(zl3vni->nh_table));
+ json_object_string_add(json_vni, "numRemoteVteps", "n/a");
+ json_object_string_add(json_vni, "type", "L3");
+ json_object_string_add(json_vni, "tenantVrf",
zl3vni_vrf_name(zl3vni));
- json_object_string_add(json_vni, "rmac",
- zl3vni_rmac2str(zl3vni, buf,
- sizeof(buf)));
json_object_object_add(json, vni_str, json_vni);
}
@@ -1111,24 +1125,26 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[])
num_macs = num_valid_macs(zvni);
num_neigh = hashcount(zvni->neigh_table);
if (json == NULL)
- vty_out(vty, "%-10u %-21s %-15s %-8u %-8u %-15u %-37s\n",
- zvni->vni,
+ vty_out(vty,
+ "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n",
+ zvni->vni, "L2",
zvni->vxlan_if ? zvni->vxlan_if->name : "unknown",
- inet_ntoa(zvni->local_vtep_ip), num_macs, num_neigh,
- num_vteps,
+ num_macs, num_neigh, num_vteps,
vrf_id_to_name(zvni->vrf_id));
else {
char vni_str[VNI_STR_LEN];
snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
json_vni = json_object_new_object();
+ json_object_int_add(json_vni, "vni", zvni->vni);
+ json_object_string_add(json_vni, "type", "L2");
json_object_string_add(json_vni, "vxlanIf",
zvni->vxlan_if ? zvni->vxlan_if->name
: "unknown");
- json_object_string_add(json_vni, "vtepIp",
- inet_ntoa(zvni->local_vtep_ip));
json_object_int_add(json_vni, "numMacs", num_macs);
json_object_int_add(json_vni, "numArpNd", num_neigh);
json_object_int_add(json_vni, "numRemoteVteps", num_vteps);
+ json_object_string_add(json_vni, "tenantVrf",
+ vrf_id_to_name(zvni->vrf_id));
if (num_vteps) {
json_vtep_list = json_object_new_array();
for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
@@ -1409,7 +1425,7 @@ static void zvni_process_neigh_on_local_mac_add(zebra_vni_t *zvni,
ZEBRA_NEIGH_SET_ACTIVE(n);
zvni_neigh_send_add_to_client(
- zvni->vni, &n->ip, &n->emac, 0);
+ zvni->vni, &n->ip, &n->emac, n->flags);
} else {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
@@ -1519,8 +1535,14 @@ static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni,
*/
static int zvni_neigh_send_add_to_client(vni_t vni,
struct ipaddr *ip,
- struct ethaddr *macaddr, u_char flags)
+ struct ethaddr *macaddr,
+ u_char neigh_flags)
{
+ u_char flags = 0;
+
+ if (CHECK_FLAG(neigh_flags, ZEBRA_NEIGH_DEF_GW))
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+
return zvni_macip_send_msg_to_client(vni, macaddr, ip, flags,
ZEBRA_MACIP_ADD);
}
@@ -1692,7 +1714,37 @@ static int zvni_add_macip_for_intf(struct interface *ifp, zebra_vni_t *zvni)
zvni_gw_macip_add(ifp, zvni, &macaddr, &ip);
}
+ return 0;
+}
+
+
+static int zvni_advertise_subnet(zebra_vni_t *zvni,
+ struct interface *ifp,
+ int advertise)
+{
+ struct listnode *cnode = NULL, *cnnode = NULL;
+ struct connected *c = NULL;
+ struct ethaddr macaddr;
+
+ memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
+
+ for (ALL_LIST_ELEMENTS(ifp->connected, cnode, cnnode, c)) {
+ struct prefix p;
+ memcpy(&p, c->address, sizeof(struct prefix));
+
+ /* skip link local address */
+ if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
+ continue;
+
+ apply_mask(&p);
+ if (advertise)
+ ip_prefix_send_to_client(ifp->vrf_id, &p,
+ ZEBRA_IP_PREFIX_ROUTE_ADD);
+ else
+ ip_prefix_send_to_client(ifp->vrf_id, &p,
+ ZEBRA_IP_PREFIX_ROUTE_DEL);
+ }
return 0;
}
@@ -1729,6 +1781,7 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
/* Set "local" forwarding info. */
SET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
SET_FLAG(mac->flags, ZEBRA_MAC_AUTO);
+ SET_FLAG(mac->flags, ZEBRA_MAC_DEF_GW);
memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
mac->fwd_info.local.ifindex = ifp->ifindex;
mac->fwd_info.local.vid = vxl->access_vlan;
@@ -1748,9 +1801,14 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
/* Set "local" forwarding info. */
SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
+ SET_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW);
memcpy(&n->emac, macaddr, ETH_ALEN);
n->ifindex = ifp->ifindex;
+ /* Only advertise in BGP if the knob is enabled */
+ if (!advertise_gw_macip_enabled(zvni))
+ return 0;
+
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s add to BGP",
@@ -1759,7 +1817,7 @@ static int zvni_gw_macip_add(struct interface *ifp, zebra_vni_t *zvni,
ipaddr2str(ip, buf2, sizeof(buf2)));
zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr,
- ZEBRA_MAC_TYPE_GW);
+ n->flags);
return 0;
}
@@ -1793,16 +1851,21 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni,
if (!CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL))
return -1;
- if (IS_ZEBRA_DEBUG_VXLAN)
- zlog_debug(
- "SVI %s(%u) L2-VNI %u, sending GW MAC %s IP %s del to BGP",
- ifp->name, ifp->ifindex, zvni->vni,
- prefix_mac2str(&(n->emac), buf1, sizeof(buf1)),
- ipaddr2str(ip, buf2, sizeof(buf2)));
-
- /* Remove neighbor from BGP. */
- zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
- ZEBRA_MAC_TYPE_GW);
+ /* only need to delete the entry from bgp if we sent it before */
+ if (advertise_gw_macip_enabled(zvni)) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("%u:SVI %s(%u) VNI %u, sending GW MAC %s IP %s del to BGP",
+ ifp->vrf_id, ifp->name,
+ ifp->ifindex, zvni->vni,
+ prefix_mac2str(&(n->emac),
+ NULL,
+ ETHER_ADDR_STRLEN),
+ ipaddr2str(ip, buf2, sizeof(buf2)));
+
+ /* Remove neighbor from BGP. */
+ zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac,
+ ZEBRA_MACIP_TYPE_GW);
+ }
/* Delete this neighbor entry. */
zvni_neigh_del(zvni, n);
@@ -1869,9 +1932,6 @@ static void zvni_gw_macip_add_for_vni_hash(struct hash_backet *backet,
if (!zvni)
return;
- if (!advertise_gw_macip_enabled(zvni))
- return;
-
ifp = zvni->vxlan_if;
if (!ifp)
return;
@@ -1985,7 +2045,6 @@ static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
{
struct mac_walk_ctx *wctx = arg;
zebra_mac_t *mac = backet->data;
- u_char sticky = 0;
if (((wctx->flags & DEL_LOCAL_MAC) && (mac->flags & ZEBRA_MAC_LOCAL))
|| ((wctx->flags & DEL_REMOTE_MAC)
@@ -1995,11 +2054,9 @@ static int zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
&& IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
&wctx->r_vtep_ip))) {
if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
- sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1
- : 0;
zvni_mac_send_del_to_client(
wctx->zvni->vni, &mac->macaddr,
- (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
+ mac->flags);
}
if (wctx->uninstall)
@@ -2074,8 +2131,16 @@ static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *mac)
* Inform BGP about local MAC addition.
*/
static int zvni_mac_send_add_to_client(vni_t vni,
- struct ethaddr *macaddr, u_char flags)
+ struct ethaddr *macaddr,
+ u_char mac_flags)
{
+ u_char flags = 0;
+
+ if (CHECK_FLAG(mac_flags, ZEBRA_MAC_STICKY))
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
+ if (CHECK_FLAG(mac_flags, ZEBRA_MAC_DEF_GW))
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+
return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
ZEBRA_MACIP_ADD);
}
@@ -2084,8 +2149,16 @@ static int zvni_mac_send_add_to_client(vni_t vni,
* Inform BGP about local MAC deletion.
*/
static int zvni_mac_send_del_to_client(vni_t vni,
- struct ethaddr *macaddr, u_char flags)
+ struct ethaddr *macaddr,
+ u_char mac_flags)
{
+ u_char flags = 0;
+
+ if (CHECK_FLAG(mac_flags, ZEBRA_MAC_STICKY))
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
+ if (CHECK_FLAG(mac_flags, ZEBRA_MAC_DEF_GW))
+ SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
+
return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
ZEBRA_MACIP_DEL);
}
@@ -2393,15 +2466,13 @@ static void zvni_read_mac_neigh(zebra_vni_t *zvni,
vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if);
if (vlan_if) {
- if (advertise_gw_macip_enabled(zvni)) {
- /* Add SVI MAC-IP */
- zvni_add_macip_for_intf(vlan_if, zvni);
+ /* Add SVI MAC-IP */
+ zvni_add_macip_for_intf(vlan_if, zvni);
- /* Add VRR MAC-IP - if any*/
- vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
- if (vrr_if)
- zvni_add_macip_for_intf(vrr_if, zvni);
- }
+ /* Add VRR MAC-IP - if any*/
+ vrr_if = zebra_get_vrr_intf_for_svi(vlan_if);
+ if (vrr_if)
+ zvni_add_macip_for_intf(vrr_if, zvni);
neigh_read_for_vlan(zns, vlan_if);
}
@@ -2795,17 +2866,19 @@ static int zvni_vtep_uninstall(zebra_vni_t *zvni, struct in_addr *vtep_ip)
/*
* Cleanup VNI/VTEP and update kernel
*/
-static void zvni_cleanup_all(struct hash_backet *backet, void *zvrf)
+static void zvni_cleanup_all(struct hash_backet *backet, void *arg)
{
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
+ struct zebra_vrf *zvrf = (struct zebra_vrf *)arg;
zvni = (zebra_vni_t *)backet->data;
if (!zvni)
return;
/* remove from l3-vni list */
- zl3vni = zl3vni_from_vrf(zvni->vrf_id);
+ if (zvrf->l3vni)
+ zl3vni = zl3vni_lookup(zvrf->l3vni);
if (zl3vni)
listnode_delete(zl3vni->l2vnis, zvni);
@@ -3158,13 +3231,13 @@ static int zl3vni_nh_install(zebra_l3vni_t *zl3vni,
static int zl3vni_nh_uninstall(zebra_l3vni_t *zl3vni,
zebra_neigh_t *n)
{
- if (!is_l3vni_oper_up(zl3vni))
- return -1;
-
if (!(n->flags & ZEBRA_NEIGH_REMOTE) ||
!(n->flags & ZEBRA_NEIGH_REMOTE_NH))
return 0;
+ if (!zl3vni->svi_if || !if_is_operative(zl3vni->svi_if))
+ return 0;
+
return kernel_del_neigh(zl3vni->svi_if, &n->ip);
}
@@ -3712,6 +3785,63 @@ static void zl3vni_del_nh_hash_entry(struct hash_backet *backet,
zl3vni_nh_del(zl3vni, n);
}
+static int ip_prefix_send_to_client(vrf_id_t vrf_id,
+ struct prefix *p,
+ uint16_t cmd)
+{
+ struct zserv *client = NULL;
+ struct stream *s = NULL;
+ char buf[PREFIX_STRLEN];
+
+ client = zebra_find_client(ZEBRA_ROUTE_BGP, 0);
+ /* BGP may not be running. */
+ if (!client)
+ return 0;
+
+ s = client->obuf;
+ stream_reset(s);
+
+ zclient_create_header(s, cmd, vrf_id);
+ stream_put(s, p, sizeof(struct prefix));
+
+ /* Write packet size. */
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "Send ip prefix %s %s on vrf %s",
+ prefix2str(p, buf, sizeof(buf)),
+ (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
+ vrf_id_to_name(vrf_id));
+
+ if (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD)
+ client->prefixadd_cnt++;
+ else
+ client->prefixdel_cnt++;
+
+ return zebra_server_send_message(client);
+}
+
+/* re-add remote rmac if needed */
+static int zebra_vxlan_readd_remote_rmac(zebra_l3vni_t *zl3vni,
+ struct ethaddr *rmac)
+{
+ char buf[ETHER_ADDR_STRLEN];
+ zebra_mac_t *zrmac = NULL;
+
+ zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
+ if (!zrmac)
+ return 0;
+
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("Del remote RMAC %s L3VNI %u - readd",
+ prefix_mac2str(rmac, buf, sizeof(buf)),
+ zl3vni->vni);
+
+ zl3vni_rmac_install(zl3vni, zrmac);
+ return 0;
+}
+
/* Public functions */
/* handle evpn route in vrf table */
@@ -3834,8 +3964,7 @@ void zebra_vxlan_print_rmacs_l3vni(struct vty *vty,
vty_out(vty,
"Number of Remote RMACs known for this VNI: %u\n",
num_rmacs);
- vty_out(vty, "%-17s %-21s %-6s\n", "MAC",
- "Remote VTEP", "Refcnt");
+ vty_out(vty, "%-17s %-21s\n", "MAC", "Remote VTEP");
} else
json_object_int_add(json, "numRmacs", num_rmacs);
@@ -3966,10 +4095,9 @@ void zebra_vxlan_print_nh_l3vni(struct vty *vty,
vty_out(vty,
"Number of NH Neighbors known for this VNI: %u\n",
num_nh);
- vty_out(vty, "%-15s %-17s %6s\n", "IP",
- "RMAC", "Refcnt");
+ vty_out(vty, "%-15s %-17s\n", "IP", "RMAC");
} else
- json_object_int_add(json, "numNh", num_nh);
+ json_object_int_add(json, "numNextHops", num_nh);
hash_iterate(zl3vni->nh_table, zl3vni_print_nh_hash, &wctx);
@@ -4053,52 +4181,40 @@ void zebra_vxlan_print_l3vni(struct vty *vty, vni_t vni, u_char use_json)
}
}
-/*
- * Display L3 VNI hash table (VTY command handler).
- */
-void zebra_vxlan_print_l3vnis(struct vty *vty, u_char use_json)
+void zebra_vxlan_print_vrf_vni(struct vty *vty, struct zebra_vrf *zvrf,
+ json_object *json_vrfs)
{
- u_int32_t num_vnis;
- void *args[2];
- json_object *json = NULL;
- struct zebra_ns *zns = NULL;
-
- if (!is_evpn_enabled()) {
- if (use_json)
- vty_out(vty, "{}\n");
- return;
- }
-
- zns = zebra_ns_lookup(NS_DEFAULT);
- assert(zns);
+ char buf[ETHER_ADDR_STRLEN];
+ zebra_l3vni_t *zl3vni = NULL;
- num_vnis = hashcount(zns->l3vni_table);
- if (!num_vnis) {
- if (use_json)
- vty_out(vty, "{}\n");
+ zl3vni = zl3vni_lookup(zvrf->l3vni);
+ if (!zl3vni)
return;
- }
- if (use_json) {
- json = json_object_new_object();
- json_object_int_add(json, "numVnis", num_vnis);
+ if (!json_vrfs) {
+ vty_out(vty, "%-37s %-10u %-20s %-20s %-5s %-18s\n",
+ zvrf_name(zvrf),
+ zl3vni->vni,
+ zl3vni_vxlan_if_name(zl3vni),
+ zl3vni_svi_if_name(zl3vni),
+ zl3vni_state2str(zl3vni),
+ zl3vni_rmac2str(zl3vni, buf, sizeof(buf)));
} else {
- vty_out(vty, "Number of L3 VNIs: %u\n", num_vnis);
- vty_out(vty, "%-10s %-15s %-20s %-20s %-5s %-37s %-18s\n",
- "VNI", "Local-ip", "Vx-intf", "L3-SVI", "State",
- "VRF", "Rmac");
- }
-
- args[0] = vty;
- args[1] = json;
- hash_iterate(zns->l3vni_table,
- (void (*)(struct hash_backet *, void *))zl3vni_print_hash,
- args);
-
- if (use_json) {
- vty_out(vty, "%s\n", json_object_to_json_string_ext(
- json, JSON_C_TO_STRING_PRETTY));
- json_object_free(json);
+ json_object *json_vrf = NULL;
+ json_vrf = json_object_new_object();
+ json_object_string_add(json_vrf, "vrf",
+ zvrf_name(zvrf));
+ json_object_int_add(json_vrf, "vni", zl3vni->vni);
+ json_object_string_add(json_vrf, "vxlanIntf",
+ zl3vni_vxlan_if_name(zl3vni));
+ json_object_string_add(json_vrf, "sviIntf",
+ zl3vni_svi_if_name(zl3vni));
+ json_object_string_add(json_vrf, "state",
+ zl3vni_state2str(zl3vni));
+ json_object_string_add(json_vrf, "routerMac",
+ zl3vni_rmac2str(zl3vni, buf,
+ sizeof(buf)));
+ json_object_array_add(json_vrfs, json_vrf);
}
}
@@ -4467,25 +4583,45 @@ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
u_char use_json)
{
- zebra_vni_t *zvni;
json_object *json = NULL;
void *args[2];
if (!is_evpn_enabled())
return;
- zvni = zvni_lookup(vni);
- if (!zvni) {
- if (use_json)
- vty_out(vty, "{}\n");
- else
- vty_out(vty, "%% VNI %u does not exist\n", vni);
- return;
- }
+
if (use_json)
json = json_object_new_object();
args[0] = vty;
args[1] = json;
- zvni_print(zvni, (void *)args);
+
+ if (is_vni_l3(vni)) {
+ zebra_l3vni_t *zl3vni = NULL;
+
+ zl3vni = zl3vni_lookup(vni);
+ if (!zl3vni) {
+ if (use_json)
+ vty_out(vty, "{}\n");
+ else
+ vty_out(vty, "%% VNI %u does not exist\n", vni);
+ return;
+ }
+
+ zl3vni_print(zl3vni, (void *)args);
+ } else {
+ zebra_vni_t *zvni;
+
+ zvni = zvni_lookup(vni);
+ if (!zvni) {
+ if (use_json)
+ vty_out(vty, "{}\n");
+ else
+ vty_out(vty, "%% VNI %u does not exist\n", vni);
+ return;
+ }
+
+ zvni_print(zvni, (void *)args);
+ }
+
if (use_json) {
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
@@ -4493,44 +4629,91 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
}
}
-/*
- * Display VNI hash table (VTY command handler).
- */
-void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
- u_char use_json)
+/* Display all global details for EVPN */
+void zebra_vxlan_print_evpn(struct vty *vty, u_char uj)
{
- u_int32_t num_vnis;
+ int num_l2vnis = 0;
+ int num_l3vnis = 0;
+ int num_vnis = 0;
json_object *json = NULL;
- void *args[2];
+ struct zebra_ns *zns = NULL;
+ struct zebra_vrf *zvrf = NULL;
if (!is_evpn_enabled())
return;
- num_vnis = hashcount(zvrf->vni_table);
- if (!num_vnis) {
- if (use_json)
- vty_out(vty, "{}\n");
+
+ zns = zebra_ns_lookup(NS_DEFAULT);
+ if (!zns)
return;
- }
- if (use_json) {
+
+ zvrf = vrf_info_lookup(VRF_DEFAULT);
+ if (!zvrf)
+ return;
+
+ num_l3vnis = hashcount(zns->l3vni_table);
+ num_l2vnis = hashcount(zvrf->vni_table);
+ num_vnis = num_l2vnis + num_l3vnis;
+
+ if (uj) {
json = json_object_new_object();
json_object_string_add(json, "advertiseGatewayMacip",
zvrf->advertise_gw_macip ? "Yes" : "No");
json_object_int_add(json, "numVnis", num_vnis);
+ json_object_int_add(json, "numL2Vnis", num_l2vnis);
+ json_object_int_add(json, "numL3Vnis", num_l3vnis);
} else {
+ vty_out(vty, "L2 VNIs: %u\n", num_l2vnis);
+ vty_out(vty, "L3 VNIs: %u\n", num_l3vnis);
vty_out(vty, "Advertise gateway mac-ip: %s\n",
zvrf->advertise_gw_macip ? "Yes" : "No");
- vty_out(vty, "Number of VNIs: %u\n", num_vnis);
- vty_out(vty, "%-10s %-21s %-15s %-8s %-8s %-15s %-37s\n", "VNI",
- "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
- "# Remote VTEPs", "VRF");
}
+
+ if (uj) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
+/*
+ * Display VNI hash table (VTY command handler).
+ */
+void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
+ u_char use_json)
+{
+ json_object *json = NULL;
+ struct zebra_ns *zns = NULL;
+ void *args[2];
+
+ if (!is_evpn_enabled())
+ return;
+
+ zns = zebra_ns_lookup(NS_DEFAULT);
+ if (!zns)
+ return;
+
+
+ if (use_json)
+ json = json_object_new_object();
+ else
+ vty_out(vty,
+ "%-10s %-4s %-21s %-8s %-8s %-15s %-37s\n",
+ "VNI", "Type", "VxLAN IF", "# MACs",
+ "# ARPs", "# Remote VTEPs", "Tenant VRF");
+
args[0] = vty;
args[1] = json;
+ /* Display all L2-VNIs */
hash_iterate(zvrf->vni_table,
(void (*)(struct hash_backet *, void *))zvni_print_hash,
args);
+ /* Display all L3-VNIs */
+ hash_iterate(zns->l3vni_table,
+ (void (*)(struct hash_backet *, void *))zl3vni_print_hash,
+ args);
+
if (use_json) {
vty_out(vty, "%s\n", json_object_to_json_string_ext(
json, JSON_C_TO_STRING_PRETTY));
@@ -4768,7 +4951,7 @@ int zebra_vxlan_local_neigh_add_update(struct interface *ifp,
zvni->vni);
ZEBRA_NEIGH_SET_ACTIVE(n);
- return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, 0);
+ return zvni_neigh_send_add_to_client(zvni->vni, ip, macaddr, n->flags);
}
@@ -4879,6 +5062,17 @@ int zebra_vxlan_remote_macip_del(struct zserv *client, u_short length,
if (!mac && !n)
continue;
+ /* Ignore the delete if this mac is a gateway mac-ip */
+ if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL) &&
+ CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW)) {
+ zlog_err("%u: Ignore Del for MAC %s neigh %s on VNI %u as it is configured as a default gateway",
+ zvrf_id(zvrf),
+ prefix_mac2str(&macaddr, buf, sizeof(buf)),
+ ipaddr2str(&ip, buf1, sizeof(buf1)),
+ vni);
+ continue;
+ }
+
/* Uninstall remote neighbor or MAC. */
if (n) {
/* When the MAC changes for an IP, it is possible the
@@ -4936,7 +5130,8 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
int update_mac = 0, update_neigh = 0;
char buf[ETHER_ADDR_STRLEN];
char buf1[INET6_ADDRSTRLEN];
- u_char sticky;
+ u_char sticky = 0;
+ u_char flags = 0;
struct interface *ifp = NULL;
struct zebra_if *zif = NULL;
@@ -4973,17 +5168,17 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
l += IPV4_MAX_BYTELEN;
- /* Get 'sticky' flag. */
- STREAM_GETC(s, sticky);
+ /* Get flags - sticky mac and/or gateway mac */
+ flags = stream_getc(s);
+ sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
l++;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
- "Recv MACIP Add %sMAC %s IP %s VNI %u Remote VTEP %s from %s",
- sticky ? "sticky " : "",
+ "Recv MACIP Add MAC %s IP %s VNI %u Remote VTEP %s with flags 0x%x from %s",
prefix_mac2str(&macaddr, buf, sizeof(buf)),
ipaddr2str(&ip, buf1, sizeof(buf1)), vni,
- inet_ntoa(vtep_ip),
+ inet_ntoa(vtep_ip), flags,
zebra_route_string(client->proto));
/* Locate VNI hash entry - expected to exist. */
@@ -5025,13 +5220,26 @@ int zebra_vxlan_remote_macip_add(struct zserv *client, u_short length,
zvni_vtep_install(zvni, &vtep_ip);
}
- /* First, check if the remote MAC is unknown or has a change. If
- * so,
- * that needs to be updated first. Note that client could
- * install
- * MAC and MACIP separately or just install the latter.
- */
mac = zvni_mac_lookup(zvni, &macaddr);
+
+ /* Ignore the update if the mac is already present
+ as a gateway mac */
+ if (mac && CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW) &&
+ CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW)) {
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug("%u:Ignore MAC %s IP %s on VNI %u as MAC is already configured as gateway mac",
+ zvrf_id(zvrf),
+ prefix_mac2str(&macaddr,
+ buf, sizeof(buf)),
+ ipaddr2str(&ip, buf1,
+ sizeof(buf1)), vni);
+ continue;
+ }
+
+ /* check if the remote MAC is unknown or has a change.
+ * If so, that needs to be updated first. Note that client could
+ * install MAC and MACIP separately or just install the latter.
+ */
if (!mac || !CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)
|| (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0)
!= sticky
@@ -5146,7 +5354,6 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp,
zebra_vni_t *zvni;
zebra_mac_t *mac;
char buf[ETHER_ADDR_STRLEN];
- u_char sticky;
zif = ifp->info;
assert(zif);
@@ -5178,9 +5385,7 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp,
ifp->name, ifp->ifindex, vni);
/* Remove MAC from BGP. */
- sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
- zvni_mac_send_del_to_client(zvni->vni, macaddr,
- (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
+ zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
/*
* If there are no neigh associated with the mac delete the mac
@@ -5205,11 +5410,12 @@ int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
struct interface *br_if,
struct ethaddr *macaddr, vlanid_t vid)
{
- struct zebra_if *zif;
- struct zebra_l2info_vxlan *vxl;
+ struct zebra_if *zif = NULL;
+ struct zebra_l2info_vxlan *vxl = NULL;
vni_t vni;
- zebra_vni_t *zvni;
- zebra_mac_t *mac;
+ zebra_vni_t *zvni = NULL;
+ zebra_l3vni_t *zl3vni = NULL;
+ zebra_mac_t *mac = NULL;
char buf[ETHER_ADDR_STRLEN];
zif = ifp->info;
@@ -5221,6 +5427,11 @@ int zebra_vxlan_check_readd_remote_mac(struct interface *ifp,
if (!is_evpn_enabled())
return 0;
+ /* check if this is a remote RMAC and readd simillar to remote macs */
+ zl3vni = zl3vni_lookup(vni);
+ if (zl3vni)
+ return zebra_vxlan_readd_remote_rmac(zl3vni, macaddr);
+
/* Locate hash entry; it is expected to exist. */
zvni = zvni_lookup(vni);
if (!zvni)
@@ -5253,7 +5464,6 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
zebra_vni_t *zvni;
zebra_mac_t *mac;
char buf[ETHER_ADDR_STRLEN];
- u_char sticky;
/* We are interested in MACs only on ports or (port, VLAN) that
* map to a VNI.
@@ -5282,9 +5492,7 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
return 0;
/* Remove MAC from BGP. */
- sticky = CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY) ? 1 : 0;
- zvni_mac_send_del_to_client(zvni->vni, macaddr,
- (sticky ? ZEBRA_MAC_TYPE_STICKY : 0));
+ zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
/* Update all the neigh entries associated with this mac */
zvni_process_neigh_on_local_mac_del(zvni, mac);
@@ -5423,7 +5631,7 @@ int zebra_vxlan_local_mac_add_update(struct interface *ifp,
if (add) {
zvni_process_neigh_on_local_mac_add(zvni, mac);
return zvni_mac_send_add_to_client(zvni->vni, macaddr,
- sticky);
+ mac->flags);
}
return 0;
@@ -5687,10 +5895,6 @@ int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
}
- /* check if we are advertising gw macip routes */
- if (!advertise_gw_macip_enabled(zvni))
- return 0;
-
memcpy(&macaddr.octet, ifp->hw_addr, ETH_ALEN);
if (p->family == AF_INET) {
@@ -6394,17 +6598,115 @@ int zebra_vxlan_process_vrf_vni_cmd(struct zebra_vrf *zvrf,
return 0;
}
-int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
+int zebra_vxlan_vrf_enable(struct zebra_vrf *zvrf)
{
zebra_l3vni_t *zl3vni = NULL;
- zl3vni = zl3vni_from_vrf(zvrf_id(zvrf));
+ if (zvrf->l3vni)
+ zl3vni = zl3vni_lookup(zvrf->l3vni);
if (!zl3vni)
return 0;
+ zl3vni->vrf_id = zvrf_id(zvrf);
+ if (is_l3vni_oper_up(zl3vni))
+ zebra_vxlan_process_l3vni_oper_up(zl3vni);
+ return 0;
+}
+
+int zebra_vxlan_vrf_disable(struct zebra_vrf *zvrf)
+{
+ zebra_l3vni_t *zl3vni = NULL;
+
+ if (zvrf->l3vni)
+ zl3vni = zl3vni_lookup(zvrf->l3vni);
+ if (!zl3vni)
+ return 0;
+
+ zl3vni->vrf_id = VRF_UNKNOWN;
zebra_vxlan_process_l3vni_oper_down(zl3vni);
+ return 0;
+}
+
+int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
+{
+ zebra_l3vni_t *zl3vni = NULL;
+ vni_t vni;
+
+ if (zvrf->l3vni)
+ zl3vni = zl3vni_lookup(zvrf->l3vni);
+ if (!zl3vni)
+ return 0;
+
+ vni = zl3vni->vni;
zl3vni_del(zl3vni);
- zebra_vxlan_handle_vni_transition(zvrf, zl3vni->vni, 0);
+ zebra_vxlan_handle_vni_transition(zvrf, vni, 0);
+
+ return 0;
+}
+
+/*
+ * Handle message from client to enable/disable advertisement of g/w macip
+ * routes
+ */
+int zebra_vxlan_advertise_subnet(struct zserv *client, u_short length,
+ struct zebra_vrf *zvrf)
+{
+ struct stream *s;
+ int advertise;
+ vni_t vni = 0;
+ zebra_vni_t *zvni = NULL;
+ struct interface *ifp = NULL;
+ struct zebra_if *zif = NULL;
+ struct zebra_l2info_vxlan zl2_info;
+ struct interface *vlan_if = NULL;
+
+ if (zvrf_id(zvrf) != VRF_DEFAULT) {
+ zlog_err("EVPN GW-MACIP Adv for non-default VRF %u",
+ zvrf_id(zvrf));
+ return -1;
+ }
+
+ s = client->ibuf;
+ advertise = stream_getc(s);
+ vni = stream_get3(s);
+
+ zvni = zvni_lookup(vni);
+ if (!zvni)
+ return 0;
+
+ if (zvni->advertise_subnet == advertise)
+ return 0;
+
+ if (IS_ZEBRA_DEBUG_VXLAN)
+ zlog_debug(
+ "EVPN subnet Adv %s on VNI %d , currently %s",
+ advertise ? "enabled" : "disabled", vni,
+ zvni->advertise_subnet ? "enabled" : "disabled");
+
+
+ zvni->advertise_subnet = advertise;
+
+ ifp = zvni->vxlan_if;
+ if (!ifp)
+ return 0;
+
+ zif = ifp->info;
+
+ /* If down or not mapped to a bridge, we're done. */
+ if (!if_is_operative(ifp) || !zif->brslave_info.br_if)
+ return 0;
+
+ zl2_info = zif->l2info.vxl;
+
+ vlan_if = zvni_map_to_svi(zl2_info.access_vlan,
+ zif->brslave_info.br_if);
+ if (!vlan_if)
+ return 0;
+
+ if (zvni->advertise_subnet)
+ zvni_advertise_subnet(zvni, vlan_if, 1);
+ else
+ zvni_advertise_subnet(zvni, vlan_if, 0);
return 0;
}
@@ -6590,6 +6892,14 @@ void zebra_vxlan_init_tables(struct zebra_vrf *zvrf)
"Zebra VRF VNI Table");
}
+/* Cleanup VNI info, but don't free the table. */
+void zebra_vxlan_cleanup_tables(struct zebra_vrf *zvrf)
+{
+ if (!zvrf)
+ return;
+ hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf);
+}
+
/* Close all VNI handling */
void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
{