From 25f2ca5307e4c7ad5a65cbf4639ee4d13a906cb4 Mon Sep 17 00:00:00 2001 From: vivek Date: Fri, 19 Jan 2018 09:29:49 -0800 Subject: [PATCH 1/9] bgpd: Ensure EVPN routes are not injected back into EVPN EVPN type-2 and type-5 routes received with a L3 VNI and corresponding RTs are installed into the appropriate BGP RIB. Ensure that these routes are not re-injected back into EVPN as type-5 routes when type-5 advertisement is enabled; only regular IPv4 routes (and IPv6 routes in future) in the RIB should be injected into EVPN. As a benefit of this change, no longer restrict that EVPN type-5 routes should be non-host routes - i.e., allow /32 IPv4 routes (and /128 IPv6 routes in future). Signed-off-by: Vivek Venkatraman Signed-off-by: Donald Sharp Signed-off-by: Mitesh Kanjariya Ticket: CM-19456 Reviewed By: CCR-7117 Testing Done: 1. Manual replication of problem and verification of fix 2. evpn-min --- bgpd/bgp_evpn.c | 25 ++++++++++++++++--------- bgpd/bgp_route.c | 6 ++++-- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index c7d5f8d111..a69c3465e3 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -3210,15 +3210,25 @@ void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, { struct bgp_table *table = NULL; struct bgp_node *rn = NULL; + struct bgp_info *ri; /* Bail out early if we don't have to advertise type-5 routes. */ if (!advertise_type5_routes(bgp_vrf, afi)) return; table = bgp_vrf->rib[afi][safi]; - for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) - bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p, afi, safi); - + for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { + /* Only care about "selected" routes - non-imported. */ + /* TODO: Support for AddPath for EVPN. */ + for (ri = rn->info; ri; ri = ri->next) { + if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) && + (!ri->extra || !ri->extra->parent)) { + bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p, + afi, safi); + break; + } + } + } } /* @@ -3239,10 +3249,6 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, struct prefix *p, if (!advertise_type5_routes(bgp_vrf, afi)) return; - /* only advertise subnet routes as type-5 */ - if (is_host_route(p)) - return; - build_type5_prefix_from_ip_prefix(&evp, p); ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr); if (ret) @@ -3270,11 +3276,12 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, table = bgp_vrf->rib[afi][safi]; for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) { /* Need to identify the "selected" route entry to use its - * attribute. + * attribute. Also, we only consider "non-imported" routes. * TODO: Support for AddPath for EVPN. */ for (ri = rn->info; ri; ri = ri->next) { - if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) { + if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED) && + (!ri->extra || !ri->extra->parent)) { bgp_evpn_advertise_type5_route(bgp_vrf, &rn->p, ri->attr, afi, safi); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 36e0c92482..fe2c5d11a1 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2225,11 +2225,13 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn, /* advertise/withdraw type-5 routes */ if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) { - if (new_select) + if (new_select && + (!new_select->extra || !new_select->extra->parent)) bgp_evpn_advertise_type5_route(bgp, &rn->p, new_select->attr, afi, safi); - else if (old_select) + else if (old_select && + (!old_select->extra || !old_select->extra->parent)) bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi); } From 2ca3a78b6835e4009913cbb8eb67f070bf1595b4 Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Wed, 7 Feb 2018 15:30:55 -0800 Subject: [PATCH 2/9] bgpd: enunciate the error message if user tries to configure 'router bgp' We need a better error message. "Multiple BGP processes are configured" doesnt makes sense anymore as with l3vni, we could have multiple auto configured bgp instances. Signed-off-by: Mitesh Kanjariya --- bgpd/bgp_vty.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 4a8eeb9121..6c06d72eb4 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -833,7 +833,7 @@ DEFUN_NOSH (router_bgp, if (listcount(bm->bgp) > 1) { vty_out(vty, - "%% Multiple BGP processes are configured\n"); + "%% Please specify ASN and VRF\n"); return CMD_WARNING_CONFIG_FAILED; } } @@ -909,7 +909,7 @@ DEFUN (no_router_bgp, if (listcount(bm->bgp) > 1) { vty_out(vty, - "%% Multiple BGP processes are configured\n"); + "%% Please specify ASN and VRF\n"); return CMD_WARNING_CONFIG_FAILED; } From d1911c2664cf84aa674d433396bbdecf2db9d3eb Mon Sep 17 00:00:00 2001 From: vivek Date: Wed, 24 Jan 2018 22:41:44 -0800 Subject: [PATCH 3/9] bgpd: Handle multiple simultaneous changes for a VNI correctly Ensure that if multiple parameters for a VNI change simultaneously, the changes are processed correctly. The changes of interest are the local tunnel IP address and the tenant VRF to which this VNI is attached. The former is used to originate type-3 routes as well as set the next hop of all routes, the latter helps to determine the route targets and VNIs to include in the route. Signed-off-by: Vivek Venkatraman Reviewed-by: Mitesh Kanjariya Ticket: CM-19099 Reviewed By: CCR-7102 Testing Done: 1. Manually reproduced problem and verified fix. 2. Additional trigger events tested with fix. --- bgpd/bgp_evpn.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index a69c3465e3..a50e3707ad 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1725,8 +1725,10 @@ static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) } /* - * There is a tunnel endpoint IP address change for this VNI, - * need to re-advertise routes with the new nexthop. + * There is a tunnel endpoint IP address change for this VNI, delete + * prior type-3 route (if needed) and update. + * Note: Route re-advertisement happens elsewhere after other processing + * other changes. */ static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn, struct in_addr originator_ip) @@ -1754,7 +1756,7 @@ static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn, /* Update the tunnel IP and re-advertise all routes for this VNI. */ vpn->originator_ip = originator_ip; - return update_routes_for_vni(bgp, vpn); + return 0; } /* @@ -4397,8 +4399,8 @@ int bgp_evpn_local_vni_del(struct bgp *bgp, vni_t vni) } /* - * Handle add (or update) of a local VNI. The only VNI change we care - * about is change to local-tunnel-ip. + * Handle add (or update) of a local VNI. The VNI changes we care + * about are for the local-tunnel-ip and the (tenant) VRF. */ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, struct in_addr originator_ip, @@ -4416,24 +4418,31 @@ int bgp_evpn_local_vni_add(struct bgp *bgp, vni_t vni, vpn = bgp_evpn_lookup_vni(bgp, vni); if (vpn) { - /* update tenant_vrf_id if required */ - if (vpn->tenant_vrf_id != tenant_vrf_id) { - bgpevpn_unlink_from_l3vni(vpn); - vpn->tenant_vrf_id = tenant_vrf_id; - bgpevpn_link_to_l3vni(vpn); - - /* update all routes with new export RT for VRFs */ - update_routes_for_vni(bgp, vpn); - } - if (is_vni_live(vpn) - && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip)) + && IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip) + && vpn->tenant_vrf_id == tenant_vrf_id) /* Probably some other param has changed that we don't * care about. */ return 0; - /* Local tunnel endpoint IP address has changed */ - handle_tunnel_ip_change(bgp, vpn, originator_ip); + /* Update tenant_vrf_id if it has changed. */ + if (vpn->tenant_vrf_id != tenant_vrf_id) { + bgpevpn_unlink_from_l3vni(vpn); + vpn->tenant_vrf_id = tenant_vrf_id; + bgpevpn_link_to_l3vni(vpn); + } + + /* If tunnel endpoint IP has changed, update (and delete prior + * type-3 route, if needed.) + */ + if (!IPV4_ADDR_SAME(&vpn->originator_ip, &originator_ip)) + handle_tunnel_ip_change(bgp, vpn, originator_ip); + + /* Update all routes with new endpoint IP and/or export RT + * for VRFs + */ + if (is_vni_live(vpn)) + update_routes_for_vni(bgp, vpn); } /* Create or update as appropriate. */ From 3b103fec6be8073eb5f4da86a8a45b8f6d7e708f Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Wed, 7 Feb 2018 14:46:04 -0800 Subject: [PATCH 4/9] vtysh/lib: write domainname to config file Ticket: CM-19626 Review: CCR-7170 Testing: Manual Signed-off-by: Mitesh Kanjariya --- lib/command.c | 3 +++ vtysh/vtysh_config.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/lib/command.c b/lib/command.c index d17f2c3d48..6870f4804b 100644 --- a/lib/command.c +++ b/lib/command.c @@ -500,6 +500,9 @@ static int config_write_host(struct vty *vty) if (cmd_hostname_get()) vty_out(vty, "hostname %s\n", cmd_hostname_get()); + if (cmd_domainname_get()) + vty_out(vty, "domainname %s\n", cmd_domainname_get()); + if (host.encrypt) { if (host.password_encrypt) vty_out(vty, "password 8 %s\n", host.password_encrypt); diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 967f855fbc..5ba749e66f 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -448,6 +448,11 @@ void vtysh_config_write() sprintf(line, "hostname %s", cmd_hostname_get()); vtysh_config_parse_line(NULL, line); } + + if (cmd_domainname_get()) { + sprintf(line, "domainname %s", cmd_domainname_get()); + vtysh_config_parse_line(NULL, line); + } if (vtysh_write_integrated == WRITE_INTEGRATED_NO) vtysh_config_parse_line(NULL, "no service integrated-vtysh-config"); From 01a6143bdababeae6349d8e2ba3560236038b2ba Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Wed, 13 Dec 2017 12:18:11 -0800 Subject: [PATCH 5/9] zebra: do not check if advertise-default-gw is on in no-advertise-default-gw flow Ticket: CM-19116 Review: CCR-7042 Testing: Manual Signed-off-by: Mitesh Kanjariya --- zebra/zebra_vxlan.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index fb1aebecc3..1e15529b00 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1852,20 +1852,18 @@ static int zvni_gw_macip_del(struct interface *ifp, zebra_vni_t *zvni, return -1; /* 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))); + 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); - } + /* 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); @@ -6760,6 +6758,10 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, struct interface *vlan_if = NULL; struct interface *vrr_if = NULL; + zvni = zvni_lookup(vni); + if (!zvni) + return 0; + if (IS_ZEBRA_DEBUG_VXLAN) zlog_debug( "EVPN gateway macip Adv %s on VNI %d , currently %s", @@ -6768,10 +6770,6 @@ int zebra_vxlan_advertise_gw_macip(struct zserv *client, u_short length, ? "enabled" : "disabled"); - zvni = zvni_lookup(vni); - if (!zvni) - return 0; - if (zvni->advertise_gw_macip == advertise) return 0; From 4ac71d4bea5f9a7b01d717ed6955f88035c92d9c Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Wed, 7 Feb 2018 13:18:49 -0800 Subject: [PATCH 6/9] zebra: fix 'show evpn vni' output removed an additional field 'local-tunnel-ip' from l2vnis o/p Ticket: CM-19670 Review: CCR-7167 Testing: Verified that the output is proper Signed-off-by: Mitesh Kanjariya --- zebra/zebra_vxlan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 1e15529b00..850ee50969 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -1129,7 +1129,8 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]) "%-10u %-4s %-21s %-8u %-8u %-15u %-37s\n", zvni->vni, "L2", zvni->vxlan_if ? zvni->vxlan_if->name : "unknown", - 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]; From bca63dc8baf1c309addf47df7ea0f1725e975dac Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Mon, 22 Jan 2018 18:12:13 -0800 Subject: [PATCH 7/9] zebra: Handle change to VxLAN tunnel (local) IP address for L3 VNI similar to what is done for L2 VNI. Ticket: CM-19195 Review: CCR-7122 Test: Manual Signed-of-by: Vivek Venkatraman --- zebra/zebra_vxlan.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 850ee50969..01d5e16556 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -6301,14 +6301,21 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) zebra_vxlan_process_l3vni_oper_down(zl3vni); zl3vni->svi_if = NULL; zl3vni->svi_if = zl3vni_map_to_svi_if(zl3vni); + zl3vni->local_vtep_ip = vxl->vtep_ip; if (is_l3vni_oper_up(zl3vni)) zebra_vxlan_process_l3vni_oper_up( zl3vni); } } - /* if we have a valid new master, process l3-vni oper up */ - if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) { + /* Update local tunnel IP. */ + zl3vni->local_vtep_ip = vxl->vtep_ip; + + /* if we have a valid new master or there is a change to the tunnel IP, + * process l3-vni oper up + */ + if (chgflags + & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE)) { if (is_l3vni_oper_up(zl3vni)) zebra_vxlan_process_l3vni_oper_up(zl3vni); } From 12eeac84ff34bd153f6d75f80aac1fa42c3f7db3 Mon Sep 17 00:00:00 2001 From: Mitesh Kanjariya Date: Mon, 29 Jan 2018 17:14:52 -0800 Subject: [PATCH 8/9] zebra: Handle local-ip change in a correct way for l3-vni Ticket: CM-19603 Review: CCR-7142 Testing: Manual Signed-off-by: Mitesh Kanjariya --- zebra/zebra_vxlan.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 01d5e16556..1a56b14466 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -6308,15 +6308,26 @@ int zebra_vxlan_if_update(struct interface *ifp, u_int16_t chgflags) } } + /* + * local-ip change - process oper down, associate with new + * local-ip and then process oper up again + */ + if (chgflags & ZEBRA_VXLIF_LOCAL_IP_CHANGE) { + if (if_is_operative(ifp)) { + zebra_vxlan_process_l3vni_oper_down(zl3vni); + zl3vni->local_vtep_ip = vxl->vtep_ip; + if (is_l3vni_oper_up(zl3vni)) + zebra_vxlan_process_l3vni_oper_up( + zl3vni); + } + } + /* Update local tunnel IP. */ zl3vni->local_vtep_ip = vxl->vtep_ip; - /* if we have a valid new master or there is a change to the tunnel IP, - * process l3-vni oper up - */ - if (chgflags - & (ZEBRA_VXLIF_MASTER_CHANGE | ZEBRA_VXLIF_LOCAL_IP_CHANGE)) { - if (is_l3vni_oper_up(zl3vni)) + /* if we have a valid new master, process l3-vni oper up */ + if (chgflags & ZEBRA_VXLIF_MASTER_CHANGE) { + if (if_is_operative(ifp) && is_l3vni_oper_up(zl3vni)) zebra_vxlan_process_l3vni_oper_up(zl3vni); } } else { From 7fdaec88941d66d831363d32084cc88c5b98ac6c Mon Sep 17 00:00:00 2001 From: mitesh Date: Fri, 9 Feb 2018 21:54:00 -0800 Subject: [PATCH 9/9] bgpd: update the VNI labels in type-2 routes when l3vni gets deleted When an l3-vni is enabled, type-2 routes are sent with 2 labels (l2vni and l3vni). When it gets deleted, we need to update type-2 routes and send them with only one label (l2vni). Signed-off-by: Mitesh Kanjariya --- bgpd/bgp_evpn.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index a50e3707ad..9b1ff8f6a9 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1209,6 +1209,23 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, && !CHECK_FLAG(tmp_ri->flags, BGP_INFO_REMOVED)) route_change = 0; else { + /* + * The attributes have changed, type-2 routes needs to + * be advertised with right labels. + */ + vni2label(vpn->vni, &label[0]); + if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) { + vni_t l3vni; + + l3vni = bgpevpn_get_l3vni(vpn); + if (l3vni) { + vni2label(l3vni, &label[1]); + num_labels++; + } + } + memcpy(&tmp_ri->extra->label, label, sizeof(label)); + tmp_ri->extra->num_labels = num_labels; + /* The attribute has changed. */ /* Add (or update) attribute to hash. */ attr_new = bgp_attr_intern(attr);