Merge pull request #1700 from mkanjari/evpn-symm-routing-enhancements-2.0

EVPN Symmetric routing enhancements 2.0
This commit is contained in:
Renato Westphal 2018-02-09 21:20:27 -02:00 committed by GitHub
commit 1a6219e1a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 100 deletions

View File

@ -696,6 +696,56 @@ struct route_map_rule_cmd route_match_evpn_vni_cmd = {
"evpn vni", route_match_vni, route_match_vni_compile,
route_match_vni_free};
/* `match evpn route-type' */
/* Match function should return 1 if match is success else return
zero. */
static route_map_result_t route_match_evpn_route_type(void *rule,
struct prefix *prefix,
route_map_object_t type,
void *object)
{
u_char route_type = 0;
if (type == RMAP_BGP) {
route_type = *((u_char *)rule);
if (route_type == prefix->u.prefix_evpn.route_type)
return RMAP_MATCH;
}
return RMAP_NOMATCH;
}
/* Route map `route-type' match statement. */
static void *route_match_evpn_route_type_compile(const char *arg)
{
u_char *route_type = NULL;
route_type = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(u_char));
if (strncmp(arg, "ma", 2) == 0)
*route_type = BGP_EVPN_MAC_IP_ROUTE;
else if (strncmp(arg, "mu", 2) == 0)
*route_type = BGP_EVPN_IMET_ROUTE;
else
*route_type = BGP_EVPN_IP_PREFIX_ROUTE;
return route_type;
}
/* Free route map's compiled `route-type' value. */
static void route_match_evpn_route_type_free(void *rule)
{
XFREE(MTYPE_ROUTE_MAP_COMPILED, rule);
}
/* Route map commands for evpn route-type matching. */
struct route_map_rule_cmd route_match_evpn_route_type_cmd = {
"evpn route-type", route_match_evpn_route_type,
route_match_evpn_route_type_compile,
route_match_evpn_route_type_free};
/* `match local-preference LOCAL-PREF' */
/* Match function return 1 if match is success else return zero. */
@ -3132,6 +3182,36 @@ DEFUN (no_match_mac_address,
RMAP_EVENT_FILTER_DELETED);
}
DEFUN (match_evpn_route_type,
match_evpn_route_type_cmd,
"match evpn route-type <macip | multicast | prefix>",
MATCH_STR
EVPN_HELP_STR
"Match route-type\n"
"mac-ip route\n"
"IMET route\n"
"prefix route\n")
{
return bgp_route_match_add(vty, "evpn route-type", argv[3]->arg,
RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_evpn_route_type,
no_match_evpn_route_type_cmd,
"no match evpn route-type <macip | multicast | prefix>",
NO_STR
MATCH_STR
EVPN_HELP_STR
"Match route-type\n"
"mac-ip route\n"
"IMET route\n"
"prefix route\n")
{
return bgp_route_match_delete(vty, "evpn route-type", argv[4]->arg,
RMAP_EVENT_MATCH_DELETED);
}
DEFUN (match_evpn_vni,
match_evpn_vni_cmd,
"match evpn vni (1-16777215)",
@ -4534,6 +4614,7 @@ void bgp_route_map_init(void)
route_map_install_match(&route_match_tag_cmd);
route_map_install_match(&route_match_mac_address_cmd);
route_map_install_match(&route_match_evpn_vni_cmd);
route_map_install_match(&route_match_evpn_route_type_cmd);
route_map_install_set(&route_set_ip_nexthop_cmd);
route_map_install_set(&route_set_local_pref_cmd);
@ -4568,6 +4649,8 @@ void bgp_route_map_init(void)
install_element(RMAP_NODE, &no_match_mac_address_cmd);
install_element(RMAP_NODE, &match_evpn_vni_cmd);
install_element(RMAP_NODE, &no_match_evpn_vni_cmd);
install_element(RMAP_NODE, &match_evpn_route_type_cmd);
install_element(RMAP_NODE, &no_match_evpn_route_type_cmd);
install_element(RMAP_NODE, &match_aspath_cmd);
install_element(RMAP_NODE, &no_match_aspath_cmd);

View File

@ -128,7 +128,6 @@ static int zl3vni_rmac_uninstall(zebra_l3vni_t *zl3vni,
zebra_mac_t *zrmac);
/* l3-vni related APIs*/
static int is_vni_l3(vni_t);
static zebra_l3vni_t *zl3vni_lookup(vni_t vni);
static void *zl3vni_alloc(void *p);
static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id);
@ -2664,6 +2663,8 @@ static void zvni_build_hash_table()
zns = zebra_ns_lookup(NS_DEFAULT);
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
vni_t vni;
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
struct zebra_if *zif;
struct zebra_l2info_vxlan *vxl;
@ -2677,21 +2678,14 @@ static void zvni_build_hash_table()
vxl = &zif->l2info.vxl;
vni = vxl->vni;
if (is_vni_l3(vni)) {
zebra_l3vni_t *zl3vni = NULL;
/* L3-VNI and L2-VNI are handled seperately */
zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("create L3-VNI hash for Intf %s(%u) L3-VNI %u",
ifp->name, ifp->ifindex, vni);
zl3vni = zl3vni_lookup(vni);
if (!zl3vni) {
zlog_err(
"Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return;
}
/* associate with vxlan_if */
zl3vni->local_vtep_ip = vxl->vtep_ip;
zl3vni->vxlan_if = ifp;
@ -2707,8 +2701,6 @@ static void zvni_build_hash_table()
zebra_vxlan_process_l3vni_oper_up(zl3vni);
} else {
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
struct interface *vlan_if = NULL;
if (IS_ZEBRA_DEBUG_VXLAN)
@ -3460,16 +3452,6 @@ static int zl3vni_del(zebra_l3vni_t *zl3vni)
return 0;
}
static int is_vni_l3(vni_t vni)
{
zebra_l3vni_t *zl3vni = NULL;
zl3vni = zl3vni_lookup(vni);
if (zl3vni)
return 1;
return 0;
}
static struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
{
struct zebra_ns *zns = NULL;
@ -3506,6 +3488,9 @@ static struct interface *zl3vni_map_to_svi_if(zebra_l3vni_t *zl3vni)
struct zebra_if *zif = NULL; /* zebra_if for vxlan_if */
struct zebra_l2info_vxlan *vxl = NULL; /* l2 info for vxlan_if */
if (!zl3vni)
return NULL;
if (!zl3vni->vxlan_if)
return NULL;
@ -3678,6 +3663,9 @@ static int zl3vni_send_del_to_client(zebra_l3vni_t *zl3vni)
static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
{
if (!zl3vni)
return;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("L3-VNI %u is UP - send add to BGP",
zl3vni->vni);
@ -3688,6 +3676,9 @@ static void zebra_vxlan_process_l3vni_oper_up(zebra_l3vni_t *zl3vni)
static void zebra_vxlan_process_l3vni_oper_down(zebra_l3vni_t *zl3vni)
{
if (!zl3vni)
return;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("L3-VNI %u is Down - Send del to BGP",
zl3vni->vni);
@ -6019,6 +6010,8 @@ int zebra_vxlan_if_down(struct interface *ifp)
vni_t vni;
struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL;
zebra_l3vni_t *zl3vni = NULL;
zebra_vni_t *zvni;
/* Check if EVPN is enabled. */
if (!is_evpn_enabled())
@ -6029,30 +6022,16 @@ int zebra_vxlan_if_down(struct interface *ifp)
vxl = &zif->l2info.vxl;
vni = vxl->vni;
if (is_vni_l3(vni)) {
zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
/* process-if-down for l3-vni */
zebra_l3vni_t *zl3vni = NULL;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Intf %s(%u) L3-VNI %u is DOWN",
ifp->name, ifp->ifindex, vni);
zl3vni = zl3vni_lookup(vni);
if (!zl3vni) {
zlog_err(
"Failed to locate L3-VNI hash at DOWN, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return -1;
}
zebra_vxlan_process_l3vni_oper_down(zl3vni);
} else {
/* process if-down for l2-vni */
zebra_vni_t *zvni;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Intf %s(%u) L2-VNI %u is DOWN",
ifp->name, ifp->ifindex, vni);
@ -6089,6 +6068,8 @@ int zebra_vxlan_if_up(struct interface *ifp)
vni_t vni;
struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL;
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
/* Check if EVPN is enabled. */
if (!is_evpn_enabled())
@ -6099,23 +6080,13 @@ int zebra_vxlan_if_up(struct interface *ifp)
vxl = &zif->l2info.vxl;
vni = vxl->vni;
if (is_vni_l3(vni)) {
/* Handle L3-VNI add */
zebra_l3vni_t *zl3vni = NULL;
zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Intf %s(%u) L3-VNI %u is UP",
ifp->name, ifp->ifindex, vni);
zl3vni = zl3vni_lookup(vni);
if (!zl3vni) {
zlog_err(
"Failed to locate L3-VNI hash at UP, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return -1;
}
/* we need to associate with SVI, if any, we can associate with
* svi-if only after association with vxlan-intf is complete
*/
@ -6125,9 +6096,6 @@ int zebra_vxlan_if_up(struct interface *ifp)
zebra_vxlan_process_l3vni_oper_up(zl3vni);
} else {
/* Handle L2-VNI add */
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
struct interface *vlan_if = NULL;
if (IS_ZEBRA_DEBUG_VXLAN)
@ -6173,6 +6141,8 @@ int zebra_vxlan_if_del(struct interface *ifp)
vni_t vni;
struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL;
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
/* Check if EVPN is enabled. */
if (!is_evpn_enabled())
@ -6183,23 +6153,13 @@ int zebra_vxlan_if_del(struct interface *ifp)
vxl = &zif->l2info.vxl;
vni = vxl->vni;
if (is_vni_l3(vni)) {
/* process if-del for l3-vni */
zebra_l3vni_t *zl3vni = NULL;
zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Del L3-VNI %u intf %s(%u)",
vni, ifp->name, ifp->ifindex);
zl3vni = zl3vni_lookup(vni);
if (!zl3vni) {
zlog_err(
"Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return 0;
}
/* process oper-down for l3-vni */
zebra_vxlan_process_l3vni_oper_down(zl3vni);
@ -6209,9 +6169,6 @@ int zebra_vxlan_if_del(struct interface *ifp)
} else {
/* process if-del for l2-vni*/
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug("Del L2-VNI %u intf %s(%u)",
vni, ifp->name, ifp->ifindex);
@ -6247,7 +6204,6 @@ int zebra_vxlan_if_del(struct interface *ifp)
return -1;
}
}
return 0;
}
@ -6259,6 +6215,8 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
vni_t vni;
struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL;
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
/* Check if EVPN is enabled. */
if (!is_evpn_enabled())
@ -6269,16 +6227,8 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
vxl = &zif->l2info.vxl;
vni = vxl->vni;
if (is_vni_l3(vni)) {
zebra_l3vni_t *zl3vni = NULL;
zl3vni = zl3vni_lookup(vni);
if (!zl3vni) {
zlog_err(
"Failed to find L3-VNI hash on update, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return -1;
}
zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
@ -6314,7 +6264,6 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags)
zebra_vxlan_process_l3vni_oper_up(zl3vni);
}
} else {
zebra_vni_t *zvni = NULL;
/* Update VNI hash. */
zvni = zvni_lookup(vni);
@ -6405,6 +6354,8 @@ int zebra_vxlan_if_add(struct interface *ifp)
vni_t vni;
struct zebra_if *zif = NULL;
struct zebra_l2info_vxlan *vxl = NULL;
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
/* Check if EVPN is enabled. */
if (!is_evpn_enabled())
@ -6415,11 +6366,10 @@ int zebra_vxlan_if_add(struct interface *ifp)
vxl = &zif->l2info.vxl;
vni = vxl->vni;
if (is_vni_l3(vni)) {
zl3vni = zl3vni_lookup(vni);
if (zl3vni) {
/* process if-add for l3-vni*/
zebra_l3vni_t *zl3vni = NULL;
if (IS_ZEBRA_DEBUG_VXLAN)
zlog_debug(
"Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
@ -6427,20 +6377,6 @@ int zebra_vxlan_if_add(struct interface *ifp)
vxl->access_vlan, inet_ntoa(vxl->vtep_ip),
zif->brslave_info.bridge_ifindex);
/*
* we expect the l3-vni has entry to be present here.
* The only place l3-vni is created in zebra is vrf-vni mapping
* command. This might change when we have the switchd support
* for l3-vxlan interface.
*/
zl3vni = zl3vni_lookup(vni);
if (!zl3vni) {
zlog_err(
"Failed to locate L3-VNI hash at del, IF %s(%u) VNI %u",
ifp->name, ifp->ifindex, vni);
return 0;
}
/* associate with vxlan_if */
zl3vni->local_vtep_ip = vxl->vtep_ip;
zl3vni->vxlan_if = ifp;
@ -6454,8 +6390,6 @@ int zebra_vxlan_if_add(struct interface *ifp)
} else {
/* process if-add for l2-vni */
zebra_vni_t *zvni = NULL;
zebra_l3vni_t *zl3vni = NULL;
struct interface *vlan_if = NULL;
/* Create or update VNI hash. */