diff options
36 files changed, 429 insertions, 124 deletions
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index bbc30365c7..733dcc72a2 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -316,6 +316,14 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, if (make_prefix(afi, pi, &p) < 0) return 1; + /* + * If path is learnt from an interface based peer, + * set the ifindex to peer's interface index so that + * correct nexthop can be found in nexthop tree. + */ + if (pi->peer->conf_if) + ifindex = pi->peer->su.sin6.sin6_scope_id; + if (!is_bgp_static_route && orig_prefix && prefix_same(&p, orig_prefix)) { if (BGP_DEBUG(nht, NHT)) { diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 457db79c43..3b3cbb28a9 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -6610,6 +6610,7 @@ int bgp_static_set(struct vty *vty, bool negate, const char *ip_str, } if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN) { + memset(&prd, 0, sizeof(prd)); ret = str2prefix_rd(rd_str, &prd); if (!ret) { vty_out(vty, "%% Malformed rd\n"); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 1c99495e6c..4e142faad4 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -6163,6 +6163,7 @@ DEFPY_YANG( char xpath_value[XPATH_MAXLEN]; as_t as_configured_value; char replace_value[ASN_STRING_MAX_SIZE * 2]; + int ret; if (configured_asn_str && !asn_str2asn(configured_asn_str, &as_configured_value)) { @@ -6181,7 +6182,9 @@ DEFPY_YANG( "%s/rmap-set-action/frr-bgp-route-map:replace-as-path", xpath); nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, str); - return nb_cli_apply_changes(vty, NULL); + ret = nb_cli_apply_changes(vty, NULL); + XFREE(MTYPE_TMP, str); + return ret; } DEFPY_YANG( diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index 49b7f51286..7502bf2ec6 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -1080,8 +1080,7 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp, safi_t safi; struct bpacket_attr_vec_arr vecarr; bool addpath_capable = false; - uint8_t default_originate_label[4] = {0x80, 0x00, 0x00}; - mpls_label_t *label = NULL; + mpls_label_t label = MPLS_LABEL_IMPLICIT_NULL; uint32_t num_labels = 0; if (DISABLE_BGP_ANNOUNCE) @@ -1097,7 +1096,11 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp, addpath_capable = bgp_addpath_encode_tx(peer, afi, safi); if (safi == SAFI_LABELED_UNICAST) { - label = (mpls_label_t *)default_originate_label; + label = mpls_lse_encode((afi == AFI_IP) + ? MPLS_LABEL_IPV4_EXPLICIT_NULL + : MPLS_LABEL_IPV6_EXPLICIT_NULL, + 0, 0, 1); + bgp_set_valid_label(&label); num_labels = 1; } @@ -1142,10 +1145,12 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp, /* Make place for total attribute length. */ pos = stream_get_endp(s); stream_putw(s, 0); - total_attr_len = bgp_packet_attribute( - NULL, peer, s, attr, &vecarr, &p, afi, safi, from, NULL, label, - num_labels, addpath_capable, - BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, NULL); + total_attr_len = + bgp_packet_attribute(NULL, peer, s, attr, &vecarr, &p, afi, + safi, from, NULL, &label, num_labels, + addpath_capable, + BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, + NULL); /* Set Total Path Attribute Length. */ stream_putw_at(s, pos, total_attr_len); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 9c09ca0efd..be0fe42837 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -2001,8 +2001,8 @@ DEFUN (bgp_confederation_identifier, "bgp confederation identifier ASNUM", BGP_STR "AS confederation parameters\n" - AS_STR - "Set routing domain confederation AS\n") + "Set routing domain confederation AS\n" + AS_STR) { VTY_DECLVAR_CONTEXT(bgp, bgp); int idx_number = 3; @@ -2024,8 +2024,8 @@ DEFUN (no_bgp_confederation_identifier, NO_STR BGP_STR "AS confederation parameters\n" - AS_STR - "Set routing domain confederation AS\n") + "Set routing domain confederation AS\n" + AS_STR) { VTY_DECLVAR_CONTEXT(bgp, bgp); bgp_confederation_id_unset(bgp); diff --git a/lib/command_match.c b/lib/command_match.c index ff3c48fc31..f740b72600 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -566,9 +566,9 @@ static int score_precedence(enum cmd_token_type type) case IPV6_PREFIX_TKN: case MAC_TKN: case MAC_PREFIX_TKN: - case ASNUM_TKN: case RANGE_TKN: return 2; + case ASNUM_TKN: case WORD_TKN: return 3; case VARIABLE_TKN: diff --git a/lib/event.c b/lib/event.c index b971bd70e6..4b4ca9d7ea 100644 --- a/lib/event.c +++ b/lib/event.c @@ -355,7 +355,7 @@ DEFPY (service_cputime_stats, DEFPY (service_cputime_warning, service_cputime_warning_cmd, - "[no] service cputime-warning (1-4294967295)", + "[no] service cputime-warning ![(1-4294967295)]", NO_STR "Set up miscellaneous service\n" "Warn for tasks exceeding CPU usage threshold\n" @@ -368,16 +368,9 @@ DEFPY (service_cputime_warning, return CMD_SUCCESS; } -ALIAS (service_cputime_warning, - no_service_cputime_warning_cmd, - "no service cputime-warning", - NO_STR - "Set up miscellaneous service\n" - "Warn for tasks exceeding CPU usage threshold\n") - DEFPY (service_walltime_warning, service_walltime_warning_cmd, - "[no] service walltime-warning (1-4294967295)", + "[no] service walltime-warning ![(1-4294967295)]", NO_STR "Set up miscellaneous service\n" "Warn for tasks exceeding total wallclock threshold\n" @@ -390,13 +383,6 @@ DEFPY (service_walltime_warning, return CMD_SUCCESS; } -ALIAS (service_walltime_warning, - no_service_walltime_warning_cmd, - "no service walltime-warning", - NO_STR - "Set up miscellaneous service\n" - "Warn for tasks exceeding total wallclock threshold\n") - static void show_thread_poll_helper(struct vty *vty, struct event_loop *m) { const char *name = m->name ? m->name : "main"; @@ -525,9 +511,7 @@ void event_cmd_init(void) install_element(CONFIG_NODE, &service_cputime_stats_cmd); install_element(CONFIG_NODE, &service_cputime_warning_cmd); - install_element(CONFIG_NODE, &no_service_cputime_warning_cmd); install_element(CONFIG_NODE, &service_walltime_warning_cmd); - install_element(CONFIG_NODE, &no_service_walltime_warning_cmd); install_element(VIEW_NODE, &show_thread_timers_cmd); } diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c index 5d1f08314b..6814798bf5 100644 --- a/pimd/pim_msg.c +++ b/pimd/pim_msg.c @@ -196,7 +196,32 @@ size_t pim_msg_get_jp_group_size(struct list *sources) __func__, up->sg_str); for (ALL_LIST_ELEMENTS_RO(up->sources, up_node, child)) { - if (!PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags)) { + /* + * PIM VXLAN is weird + * It auto creates the S,G and populates a bunch + * of flags that make it look like a SPT prune should + * be sent. But this regularly scheduled join + * for the *,G in the VXLAN setup can happen at + * scheduled times *before* the null register + * is received by the RP to cause it to initiate + * the S,G joins toward the source. Let's just + * assume that if this is a SRC VXLAN ORIG route + * and no actual ifchannels( joins ) have been + * created then do not send the embedded prune + * Why you may ask? Well if the prune is S,G + * RPT Prune is received *before* the join + * from the RP( if it flows to this routers + * upstream interface ) then we'll just wisely + * create a mroute with an empty oil on + * the upstream intermediate router preventing + * packets from flowing to the RP + */ + if (PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(child->flags) && + listcount(child->ifchannels) == 0) { + if (PIM_DEBUG_PIM_PACKETS) + zlog_debug("%s: %s Vxlan originated S,G route with no ifchannels, not adding prune to compound message", + __func__, child->sg_str); + } else if (!PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags)) { /* If we are using SPT and the SPT and RPT IIFs * are different we can prune the source off * of the RPT. diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c index 5f0f2a5933..4e8e5f0df7 100644 --- a/pimd/pim_nht.c +++ b/pimd/pim_nht.c @@ -31,6 +31,8 @@ #include "pim_zlookup.h" #include "pim_rp.h" #include "pim_addr.h" +#include "pim_register.h" +#include "pim_vxlan.h" /** * pim_sendmsg_zebra_rnh -- Format and send a nexthop register/Unregister @@ -399,17 +401,28 @@ static void pim_update_rp_nh(struct pim_instance *pim, { struct listnode *node = NULL; struct rp_info *rp_info = NULL; + struct interface *ifp; /*Traverse RP list and update each RP Nexthop info */ for (ALL_LIST_ELEMENTS_RO(pnc->rp_list, node, rp_info)) { if (pim_rpf_addr_is_inaddr_any(&rp_info->rp)) continue; + ifp = rp_info->rp.source_nexthop.interface; // Compute PIM RPF using cached nexthop if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, rp_info->rp.rpf_addr, &rp_info->group, 1)) pim_rp_nexthop_del(rp_info); + + /* + * If we transition from no path to a path + * we need to search through all the vxlan's + * that use this rp and send NULL registers + * for all the vxlan S,G streams + */ + if (!ifp && rp_info->rp.source_nexthop.interface) + pim_vxlan_rp_info_is_alive(pim, &rp_info->rp); } } @@ -436,17 +449,27 @@ static int pim_update_upstream_nh_helper(struct hash_bucket *bucket, void *arg) (rpf_result == PIM_RPF_FAILURE && old.source_nexthop.interface)) pim_zebra_upstream_rpf_changed(pim, up, &old); + /* + * If we are a VXLAN source and we are transitioning from not + * having an outgoing interface to having an outgoing interface + * let's immediately send the null pim register + */ + if (!old.source_nexthop.interface && up->rpf.source_nexthop.interface && + PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(up->flags) && + (up->reg_state == PIM_REG_NOINFO || up->reg_state == PIM_REG_JOIN)) { + pim_null_register_send(up); + } if (PIM_DEBUG_PIM_NHT) { - zlog_debug( - "%s: NHT upstream %s(%s) old ifp %s new ifp %s", - __func__, up->sg_str, pim->vrf->name, - old.source_nexthop.interface ? old.source_nexthop - .interface->name - : "Unknown", - up->rpf.source_nexthop.interface ? up->rpf.source_nexthop - .interface->name - : "Unknown"); + zlog_debug("%s: NHT upstream %s(%s) old ifp %s new ifp %s rpf_result: %d", + __func__, up->sg_str, pim->vrf->name, + old.source_nexthop.interface ? old.source_nexthop + .interface->name + : "Unknown", + up->rpf.source_nexthop.interface ? up->rpf.source_nexthop + .interface->name + : "Unknown", + rpf_result); } return HASHWALK_CONTINUE; diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index a8d087bf49..fd99e77761 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -912,6 +912,7 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim, false /*update_mroute*/); rpf_result = pim_rpf_update(pim, up, NULL, __func__); if (rpf_result == PIM_RPF_FAILURE) { + up->channel_oil->oil_inherited_rescan = 1; if (PIM_DEBUG_PIM_TRACE) zlog_debug( "%s: Attempting to create upstream(%s), Unable to RPF for source", diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c index 8df3c90f00..9650da89a8 100644 --- a/pimd/pim_vxlan.c +++ b/pimd/pim_vxlan.c @@ -32,6 +32,41 @@ static void pim_vxlan_work_timer_setup(bool start); static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim, struct interface *ifp); +/* + * The rp info has gone from no path to having a + * path. Let's immediately send out the null pim register + * as that else we will be sitting for up to 60 seconds waiting + * for it too pop. Which is not cool. + */ +void pim_vxlan_rp_info_is_alive(struct pim_instance *pim, + struct pim_rpf *rpg_changed) +{ + struct listnode *listnode; + struct pim_vxlan_sg *vxlan_sg; + struct pim_rpf *rpg; + + /* + * No vxlan here, move along, nothing to see + */ + if (!vxlan_info.work_list) + return; + + for (listnode = vxlan_info.work_list->head; listnode; + listnode = listnode->next) { + vxlan_sg = listgetdata(listnode); + + rpg = RP(pim, vxlan_sg->up->sg.grp); + + /* + * If the rp is the same we should send + */ + if (rpg == rpg_changed) { + zlog_debug("VXLAN RP INFO is alive sending"); + pim_null_register_send(vxlan_sg->up); + } + } +} + /*************************** vxlan work list ********************************** * A work list is maintained for staggered generation of pim null register * messages for vxlan SG entries that are in a reg_join state. @@ -66,6 +101,7 @@ static void pim_vxlan_do_reg_work(void) for (; listnode; listnode = listnode->next) { vxlan_sg = (struct pim_vxlan_sg *)listnode->data; + if (vxlan_sg->up && (vxlan_sg->up->reg_state == PIM_REG_JOIN)) { if (PIM_DEBUG_VXLAN) zlog_debug("vxlan SG %s periodic NULL register", diff --git a/pimd/pim_vxlan.h b/pimd/pim_vxlan.h index 9a135ca6b8..5039bf6540 100644 --- a/pimd/pim_vxlan.h +++ b/pimd/pim_vxlan.h @@ -135,6 +135,9 @@ extern bool pim_vxlan_do_mlag_reg(void); extern void pim_vxlan_inherit_mlag_flags(struct pim_instance *pim, struct pim_upstream *up, bool inherit); +extern void pim_vxlan_rp_info_is_alive(struct pim_instance *pim, + struct pim_rpf *rpg_changed); + /* Shutdown of PIM stop the thread */ extern void pim_vxlan_terminate(void); #endif /* PIM_VXLAN_H */ diff --git a/tests/topotests/bgp_evpn_mh/leaf1/evpn.conf b/tests/topotests/bgp_evpn_mh/leaf1/evpn.conf new file mode 100644 index 0000000000..33b6d08aba --- /dev/null +++ b/tests/topotests/bgp_evpn_mh/leaf1/evpn.conf @@ -0,0 +1,21 @@ +frr defaults datacenter +! +router bgp 65101 + bgp router-id 192.168.100.13 + no bgp ebgp-requires-policy + neighbor 192.168.50.1 remote-as external + neighbor 192.168.51.1 remote-as external + neighbor 192.168.1.2 remote-as external + neighbor 192.168.2.2 remote-as external + neighbor 192.168.3.2 remote-as external + neighbor 192.168.4.2 remote-as external + redistribute connected + address-family l2vpn evpn + neighbor 192.168.50.1 activate + neighbor 192.168.51.1 activate + neighbor 192.168.1.2 activate + neighbor 192.168.2.2 activate + neighbor 192.168.3.2 activate + neighbor 192.168.4.2 activate + exit-address-family +! diff --git a/tests/topotests/bgp_evpn_mh/leaf1/pim.conf b/tests/topotests/bgp_evpn_mh/leaf1/pim.conf new file mode 100644 index 0000000000..a4de64d1fb --- /dev/null +++ b/tests/topotests/bgp_evpn_mh/leaf1/pim.conf @@ -0,0 +1,26 @@ +#debug pim packet +#debug pim packet register +#debug pim event +#debug pim trace +ip pim ecmp +ip pim rp 192.168.100.13 +ip pim spt-switchover infinity-and-beyond +! +int leaf1-eth0 + ip pim +! +int leaf1-eth1 + ip pim +! +int leaf1-eth2 + ip pim +! +int leaf1-eth3 + ip pim +! +int leaf1-eth4 + ip pim +! +int leaf1-eth5 + ip pim +! diff --git a/tests/topotests/bgp_evpn_mh/leaf1/zebra.conf b/tests/topotests/bgp_evpn_mh/leaf1/zebra.conf new file mode 100644 index 0000000000..f666f98abc --- /dev/null +++ b/tests/topotests/bgp_evpn_mh/leaf1/zebra.conf @@ -0,0 +1,30 @@ +# spine 1 connection +int leaf1-eth0 + description spine1 connection + ip addr 192.168.50.2/24 + +#spine 2 connection +int leaf1-eth1 + description spine2 connection + ip addr 192.168.51.2/24 + +#torm11 connection +int leaf1-eth2 + description torm11 connection + ip addr 192.168.1.1/24 +! +#torm12 connection +int leaf1-eth3 + description torm12 connection + ip addr 192.168.2.1/24 +! +#torm21 connection +int leaf1-eth4 + description torm21 connection + ip addr 192.168.3.1/24 +! +#torm22 connection +int leaf1-eth5 + descriptoin torm22 connection + ip addr 192.168.4.1/24 +! diff --git a/tests/topotests/bgp_evpn_mh/leaf2/evpn.conf b/tests/topotests/bgp_evpn_mh/leaf2/evpn.conf new file mode 100644 index 0000000000..428998b0fe --- /dev/null +++ b/tests/topotests/bgp_evpn_mh/leaf2/evpn.conf @@ -0,0 +1,21 @@ +frr defaults datacenter +! +router bgp 65101 + bgp router-id 192.168.100.14 + no bgp ebgp-requires-policy + neighbor 192.168.61.1 remote-as external + neighbor 192.168.51.1 remote-as external + neighbor 192.168.5.2 remote-as external + neighbor 192.168.6.2 remote-as external + neighbor 192.168.7.2 remote-as external + neighbor 192.168.8.2 remote-as external + redistribute connected + address-family l2vpn evpn + neighbor 192.168.61.1 activate + neighbor 192.168.51.1 activate + neighbor 192.168.5.2 activate + neighbor 192.168.6.2 activate + neighbor 192.168.7.2 activate + neighbor 192.168.8.2 activate + exit-address-family +! diff --git a/tests/topotests/bgp_evpn_mh/leaf2/pim.conf b/tests/topotests/bgp_evpn_mh/leaf2/pim.conf new file mode 100644 index 0000000000..3abd9698f5 --- /dev/null +++ b/tests/topotests/bgp_evpn_mh/leaf2/pim.conf @@ -0,0 +1,20 @@ +#debug pim packet register +#debug pim packet +#debug pim event +#debug pim trace +ip pim ecmp +ip pim rp 192.168.100.13 +ip pim spt-switchover infinity-and-beyond +! +int leaf2-eth0 + ip pim +! +int leaf2-eth1 + ip pim +! +int leaf2-eth2 + ip pim +! +int leaf2-eth3 + ip pim +! diff --git a/tests/topotests/bgp_evpn_mh/leaf2/zebra.conf b/tests/topotests/bgp_evpn_mh/leaf2/zebra.conf new file mode 100644 index 0000000000..ff680cf764 --- /dev/null +++ b/tests/topotests/bgp_evpn_mh/leaf2/zebra.conf @@ -0,0 +1,24 @@ +# spine1 connection +int leaf2-eth0 + ip addr 192.168.51.2/24 +! +# spine2 connection +int leaf2-eth1 + ip addr 192.168.61.2/24 +! +#torm11 connection +int leaf2-eth2 + ip addr 192.168.5.1/24 +! +#torm12 connection +int leaf2-eth3 + ip addr 192.168.6.1/24 +! +#torm21 connection +int leaf2-eth4 + ip addr 192.168.7.1/24 +! +#torm22 connection +int leaf2-eth5 + ip addr 192.168.8.1/24 +! diff --git a/tests/topotests/bgp_evpn_mh/spine1/evpn.conf b/tests/topotests/bgp_evpn_mh/spine1/evpn.conf index 2e26f60f44..b9fce46ea4 100644 --- a/tests/topotests/bgp_evpn_mh/spine1/evpn.conf +++ b/tests/topotests/bgp_evpn_mh/spine1/evpn.conf @@ -3,15 +3,11 @@ frr defaults datacenter router bgp 65001 bgp router-id 192.168.100.13 no bgp ebgp-requires-policy - neighbor 192.168.1.2 remote-as external - neighbor 192.168.2.2 remote-as external - neighbor 192.168.3.2 remote-as external - neighbor 192.168.4.2 remote-as external + neighbor 192.168.50.2 remote-as external + neighbor 192.168.51.2 remote-as external redistribute connected address-family l2vpn evpn - neighbor 192.168.1.2 activate - neighbor 192.168.2.2 activate - neighbor 192.168.3.2 activate - neighbor 192.168.4.2 activate + neighbor 192.168.50.2 activate + neighbor 192.168.51.2 activate exit-address-family ! diff --git a/tests/topotests/bgp_evpn_mh/spine1/pim.conf b/tests/topotests/bgp_evpn_mh/spine1/pim.conf index 68e686e8c7..018d244e4d 100644 --- a/tests/topotests/bgp_evpn_mh/spine1/pim.conf +++ b/tests/topotests/bgp_evpn_mh/spine1/pim.conf @@ -1,4 +1,10 @@ +ip pim ecmp ip pim rp 192.168.100.13 +#debug pim packets +#debug pim packet register +#debug pim event +#debug pim trace +#debug pim vxlan ip pim spt-switchover infinity-and-beyond ! int lo @@ -10,9 +16,3 @@ int spine1-eth0 int spine1-eth1 ip pim ! -int spine1-eth2 - ip pim -! -int spine1-eth3 - ip pim -! diff --git a/tests/topotests/bgp_evpn_mh/spine1/zebra.conf b/tests/topotests/bgp_evpn_mh/spine1/zebra.conf index 80e9e5a263..607a5e8e32 100644 --- a/tests/topotests/bgp_evpn_mh/spine1/zebra.conf +++ b/tests/topotests/bgp_evpn_mh/spine1/zebra.conf @@ -1,14 +1,10 @@ +# leaf1 connection int spine1-eth0 - ip addr 192.168.1.1/24 + ip addr 192.168.50.1/24 ! +# leaf2 connection int spine1-eth1 - ip addr 192.168.2.1/24 -! -int spine1-eth2 - ip addr 192.168.3.1/24 -! -int spine1-eth3 - ip addr 192.168.4.1/24 + ip addr 192.168.51.1/24 ! int lo ip addr 192.168.100.13/32 diff --git a/tests/topotests/bgp_evpn_mh/spine2/evpn.conf b/tests/topotests/bgp_evpn_mh/spine2/evpn.conf index ec2e789276..1430e10b68 100644 --- a/tests/topotests/bgp_evpn_mh/spine2/evpn.conf +++ b/tests/topotests/bgp_evpn_mh/spine2/evpn.conf @@ -3,15 +3,11 @@ frr defaults datacenter router bgp 65001 bgp router-id 192.168.100.14 no bgp ebgp-requires-policy - neighbor 192.168.5.2 remote-as external - neighbor 192.168.6.2 remote-as external - neighbor 192.168.7.2 remote-as external - neighbor 192.168.8.2 remote-as external + neighbor 192.168.60.2 remote-as external + neighbor 192.168.61.2 remote-as external redistribute connected address-family l2vpn evpn - neighbor 192.168.5.2 activate - neighbor 192.168.6.2 activate - neighbor 192.168.7.2 activate - neighbor 192.168.8.2 activate + neighbor 192.168.60.2 activate + neighbor 192.168.61.2 activate exit-address-family ! diff --git a/tests/topotests/bgp_evpn_mh/spine2/pim.conf b/tests/topotests/bgp_evpn_mh/spine2/pim.conf index c1566240e6..0ece2ff539 100644 --- a/tests/topotests/bgp_evpn_mh/spine2/pim.conf +++ b/tests/topotests/bgp_evpn_mh/spine2/pim.conf @@ -1,3 +1,4 @@ +ip pim ecmp ip pim rp 192.168.100.13 ip pim spt-switchover infinity-and-beyond ! @@ -10,9 +11,3 @@ int spine2-eth0 int spine2-eth1 ip pim ! -int spine2-eth2 - ip pim -! -int spine2-eth3 - ip pim -! diff --git a/tests/topotests/bgp_evpn_mh/spine2/zebra.conf b/tests/topotests/bgp_evpn_mh/spine2/zebra.conf index 1cd1df8c81..c8cec14e62 100644 --- a/tests/topotests/bgp_evpn_mh/spine2/zebra.conf +++ b/tests/topotests/bgp_evpn_mh/spine2/zebra.conf @@ -1,14 +1,12 @@ +# leaf1 connection int spine2-eth0 - ip addr 192.168.5.1/24 + description leaf1 connection + ip addr 192.168.60.1/24 ! +# leaf2 connection int spine2-eth1 - ip addr 192.168.6.1/24 -! -int spine2-eth2 - ip addr 192.168.7.1/24 -! -int spine2-eth3 - ip addr 192.168.8.1/24 + description leaf2 connection + ip addr 192.168.61.1/24 ! int lo ip addr 192.168.100.14/32 diff --git a/tests/topotests/bgp_evpn_mh/test_evpn_mh.py b/tests/topotests/bgp_evpn_mh/test_evpn_mh.py index 0bde5d5a9f..ec5227809e 100644 --- a/tests/topotests/bgp_evpn_mh/test_evpn_mh.py +++ b/tests/topotests/bgp_evpn_mh/test_evpn_mh.py @@ -58,6 +58,8 @@ def build_topo(tgen): tgen.add_router("spine1") tgen.add_router("spine2") + tgen.add_router("leaf1") + tgen.add_router("leaf2") tgen.add_router("torm11") tgen.add_router("torm12") tgen.add_router("torm21") @@ -71,88 +73,109 @@ def build_topo(tgen): # First switch is for a dummy interface (for local network) ##################### spine1 ######################## - # spine1-eth0 is connected to torm11-eth0 + # spine1-eth0 is connected to leaf1-eth0 switch = tgen.add_switch("sw1") switch.add_link(tgen.gears["spine1"]) - switch.add_link(tgen.gears["torm11"]) + switch.add_link(tgen.gears["leaf1"]) - # spine1-eth1 is connected to torm12-eth0 + # spine1-eth1 is connected to leaf2-eth0 switch = tgen.add_switch("sw2") switch.add_link(tgen.gears["spine1"]) - switch.add_link(tgen.gears["torm12"]) + switch.add_link(tgen.gears["leaf2"]) - # spine1-eth2 is connected to torm21-eth0 + # spine2-eth0 is connected to leaf1-eth1 switch = tgen.add_switch("sw3") - switch.add_link(tgen.gears["spine1"]) - switch.add_link(tgen.gears["torm21"]) + switch.add_link(tgen.gears["spine2"]) + switch.add_link(tgen.gears["leaf1"]) - # spine1-eth3 is connected to torm22-eth0 + # spine2-eth1 is connected to leaf2-eth1 switch = tgen.add_switch("sw4") - switch.add_link(tgen.gears["spine1"]) - switch.add_link(tgen.gears["torm22"]) + switch.add_link(tgen.gears["spine2"]) + switch.add_link(tgen.gears["leaf2"]) - ##################### spine2 ######################## - # spine2-eth0 is connected to torm11-eth1 + ################## leaf1 ########################## + # leaf1-eth2 is connected to torm11-eth0 switch = tgen.add_switch("sw5") - switch.add_link(tgen.gears["spine2"]) + switch.add_link(tgen.gears["leaf1"]) switch.add_link(tgen.gears["torm11"]) - # spine2-eth1 is connected to torm12-eth1 + # leaf1-eth3 is connected to torm12-eth0 switch = tgen.add_switch("sw6") - switch.add_link(tgen.gears["spine2"]) + switch.add_link(tgen.gears["leaf1"]) switch.add_link(tgen.gears["torm12"]) - # spine2-eth2 is connected to torm21-eth1 + # leaf1-eth4 is connected to torm21-eth0 switch = tgen.add_switch("sw7") - switch.add_link(tgen.gears["spine2"]) + switch.add_link(tgen.gears["leaf1"]) switch.add_link(tgen.gears["torm21"]) - # spine2-eth3 is connected to torm22-eth1 + # leaf1-eth5 is connected to torm22-eth0 switch = tgen.add_switch("sw8") - switch.add_link(tgen.gears["spine2"]) + switch.add_link(tgen.gears["leaf1"]) + switch.add_link(tgen.gears["torm22"]) + + ##################### leaf2 ######################## + # leaf2-eth2 is connected to torm11-eth1 + switch = tgen.add_switch("sw9") + switch.add_link(tgen.gears["leaf2"]) + switch.add_link(tgen.gears["torm11"]) + + # leaf2-eth3 is connected to torm12-eth1 + switch = tgen.add_switch("sw10") + switch.add_link(tgen.gears["leaf2"]) + switch.add_link(tgen.gears["torm12"]) + + # leaf2-eth4 is connected to torm21-eth1 + switch = tgen.add_switch("sw11") + switch.add_link(tgen.gears["leaf2"]) + switch.add_link(tgen.gears["torm21"]) + + # leaf2-eth5 is connected to torm22-eth1 + switch = tgen.add_switch("sw12") + switch.add_link(tgen.gears["leaf2"]) switch.add_link(tgen.gears["torm22"]) ##################### torm11 ######################## # torm11-eth2 is connected to hostd11-eth0 - switch = tgen.add_switch("sw9") + switch = tgen.add_switch("sw13") switch.add_link(tgen.gears["torm11"]) switch.add_link(tgen.gears["hostd11"]) # torm11-eth3 is connected to hostd12-eth0 - switch = tgen.add_switch("sw10") + switch = tgen.add_switch("sw14") switch.add_link(tgen.gears["torm11"]) switch.add_link(tgen.gears["hostd12"]) ##################### torm12 ######################## # torm12-eth2 is connected to hostd11-eth1 - switch = tgen.add_switch("sw11") + switch = tgen.add_switch("sw15") switch.add_link(tgen.gears["torm12"]) switch.add_link(tgen.gears["hostd11"]) # torm12-eth3 is connected to hostd12-eth1 - switch = tgen.add_switch("sw12") + switch = tgen.add_switch("sw16") switch.add_link(tgen.gears["torm12"]) switch.add_link(tgen.gears["hostd12"]) ##################### torm21 ######################## # torm21-eth2 is connected to hostd21-eth0 - switch = tgen.add_switch("sw13") + switch = tgen.add_switch("sw17") switch.add_link(tgen.gears["torm21"]) switch.add_link(tgen.gears["hostd21"]) # torm21-eth3 is connected to hostd22-eth0 - switch = tgen.add_switch("sw14") + switch = tgen.add_switch("sw18") switch.add_link(tgen.gears["torm21"]) switch.add_link(tgen.gears["hostd22"]) ##################### torm22 ######################## # torm22-eth2 is connected to hostd21-eth1 - switch = tgen.add_switch("sw15") + switch = tgen.add_switch("sw19") switch.add_link(tgen.gears["torm22"]) switch.add_link(tgen.gears["hostd21"]) # torm22-eth3 is connected to hostd22-eth1 - switch = tgen.add_switch("sw16") + switch = tgen.add_switch("sw20") switch.add_link(tgen.gears["torm22"]) switch.add_link(tgen.gears["hostd22"]) @@ -591,7 +614,7 @@ def ping_anycast_gw(tgen): "--interface=" + intf, 'Ether(dst="ff:ff:ff:ff:ff:ff")/ARP(pdst="{}")'.format(ipaddr), ] - for name in ("hostd11", "hostd21"): + for name in ("hostd11", "hostd21", "hostd12", "hostd22"): host = tgen.net.hosts[name] _, stdout, _ = host.cmd_status(ping_cmd, warn=False, stderr=subprocess.STDOUT) stdout = stdout.strip() diff --git a/tests/topotests/bgp_evpn_mh/torm11/pim.conf b/tests/topotests/bgp_evpn_mh/torm11/pim.conf index fbba735873..a5d45dabc7 100644 --- a/tests/topotests/bgp_evpn_mh/torm11/pim.conf +++ b/tests/topotests/bgp_evpn_mh/torm11/pim.conf @@ -1,4 +1,10 @@ ! +#debug pim packet +#debug pim packet register +#debug pim trace +#debug pim event +#debug pim vxlan +ip pim ecmp ip pim rp 192.168.100.13 239.1.1.0/24 ip pim spt-switchover infinity-and-beyond ! diff --git a/tests/topotests/bgp_evpn_mh/torm12/pim.conf b/tests/topotests/bgp_evpn_mh/torm12/pim.conf index 3dd63b44ca..7e09ba7e21 100644 --- a/tests/topotests/bgp_evpn_mh/torm12/pim.conf +++ b/tests/topotests/bgp_evpn_mh/torm12/pim.conf @@ -1,4 +1,10 @@ +#debug pim packet +#debug pim packet register +#debug pim trace +#debug pim event +#debug pim vxlan ! +ip pim ecmp ip pim rp 192.168.100.13 239.1.1.0/24 ip pim spt-switchover infinity-and-beyond ! diff --git a/tests/topotests/bgp_evpn_mh/torm21/pim.conf b/tests/topotests/bgp_evpn_mh/torm21/pim.conf index 71aa91a06d..6996d74ad8 100644 --- a/tests/topotests/bgp_evpn_mh/torm21/pim.conf +++ b/tests/topotests/bgp_evpn_mh/torm21/pim.conf @@ -1,4 +1,10 @@ +#debug pim packet +#debug pim packet register +#debug pim trace +#debug pim event +#debug pim vxlan ! +ip pim ecmp ip pim rp 192.168.100.13 239.1.1.0/24 ip pim spt-switchover infinity-and-beyond ! diff --git a/tests/topotests/bgp_evpn_mh/torm22/pim.conf b/tests/topotests/bgp_evpn_mh/torm22/pim.conf index 46f330f5cd..6256e0e8cf 100644 --- a/tests/topotests/bgp_evpn_mh/torm22/pim.conf +++ b/tests/topotests/bgp_evpn_mh/torm22/pim.conf @@ -1,4 +1,10 @@ +#debug pim packet +#debug pim packet register +#debug pim trace +#debug pim event +#debug pim vxlan ! +ip pim ecmp ip pim rp 192.168.100.13 239.1.1.0/24 ip pim spt-switchover infinity-and-beyond ! diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/r1/bgpd.conf b/tests/topotests/bgp_labeled_unicast_default_originate/r1/bgpd.conf index 75a4aa6ab3..d0d13909a7 100644 --- a/tests/topotests/bgp_labeled_unicast_default_originate/r1/bgpd.conf +++ b/tests/topotests/bgp_labeled_unicast_default_originate/r1/bgpd.conf @@ -1,18 +1,32 @@ ! router bgp 65001 no bgp default ipv4-unicast + no bgp default ipv6-unicast no bgp ebgp-requires-policy neighbor 192.168.12.2 remote-as external neighbor 192.168.12.2 timers 1 3 neighbor 192.168.12.2 timers connect 1 + neighbor 2001:db8:12::2 remote-as external + neighbor 2001:db8:12::2 timers 1 3 + neighbor 2001:db8:12::2 timers connect 1 address-family ipv4 unicast redistribute connected exit-address-family + ! + address-family ipv6 unicast + redistribute connected + exit-address-family + ! address-family ipv4 labeled-unicast neighbor 192.168.12.2 activate neighbor 192.168.12.2 default-originate route-map r2 exit-address-family ! + address-family ipv6 labeled-unicast + neighbor 2001:db8:12::2 activate + neighbor 2001:db8:12::2 default-originate route-map r2 + exit-address-family + ! ! route-map r2 permit 10 set community 65001:65001 diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/r1/zebra.conf b/tests/topotests/bgp_labeled_unicast_default_originate/r1/zebra.conf index 8eab7805df..686b0755c3 100644 --- a/tests/topotests/bgp_labeled_unicast_default_originate/r1/zebra.conf +++ b/tests/topotests/bgp_labeled_unicast_default_originate/r1/zebra.conf @@ -1,4 +1,5 @@ ! interface r1-eth0 ip address 192.168.12.1/24 + ipv6 address 2001:db8:12::1/64 ! diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/r2/bgpd.conf b/tests/topotests/bgp_labeled_unicast_default_originate/r2/bgpd.conf index c81ba9fe02..1498dffc93 100644 --- a/tests/topotests/bgp_labeled_unicast_default_originate/r2/bgpd.conf +++ b/tests/topotests/bgp_labeled_unicast_default_originate/r2/bgpd.conf @@ -2,10 +2,18 @@ router bgp 65002 no bgp ebgp-requires-policy no bgp default ipv4-unicast + no bgp default ipv6-unicast neighbor 192.168.12.1 remote-as external neighbor 192.168.12.1 timers 1 3 neighbor 192.168.12.1 timers connect 1 + neighbor 2001:db8:12::1 remote-as external + neighbor 2001:db8:12::1 timers 1 3 + neighbor 2001:db8:12::1 timers connect 1 address-family ipv4 labeled-unicast neighbor 192.168.12.1 activate exit-address-family + ! + address-family ipv6 labeled-unicast + neighbor 2001:db8:12::1 activate + exit-address-family ! diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/r2/zebra.conf b/tests/topotests/bgp_labeled_unicast_default_originate/r2/zebra.conf index d7dfd899cc..cb5c55ef0f 100644 --- a/tests/topotests/bgp_labeled_unicast_default_originate/r2/zebra.conf +++ b/tests/topotests/bgp_labeled_unicast_default_originate/r2/zebra.conf @@ -1,4 +1,5 @@ ! interface r2-eth0 ip address 192.168.12.2/24 + ipv6 address 2001:db8:12::2/64 ! diff --git a/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py b/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py index c3ccefb569..34c23d9b6f 100644 --- a/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py +++ b/tests/topotests/bgp_labeled_unicast_default_originate/test_bgp_labeled_unicast_default_originate.py @@ -82,7 +82,7 @@ def test_bgp_labeled_unicast_default_originate(): _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) assert result is None, "Failed to advertise default route for labeled-unicast" - def _bgp_check_received_routes(): + def _bgp_check_received_ipv4_routes(): output = json.loads( r2.vtysh_cmd("show bgp ipv4 labeled-unicast 0.0.0.0/0 json") ) @@ -94,14 +94,35 @@ def test_bgp_labeled_unicast_default_originate(): "community": { "string": "65001:65001", }, + "remoteLabel": 0, } ] } return topotest.json_cmp(output, expected) - test_func = functools.partial(_bgp_check_received_routes) + test_func = functools.partial(_bgp_check_received_ipv4_routes) _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) - assert result is None, "Failed to receive default route for labeled-unicast" + assert result is None, "Failed to receive IPv4 default route for labeled-unicast" + + def _bgp_check_received_ipv6_routes(): + output = json.loads(r2.vtysh_cmd("show bgp ipv6 labeled-unicast ::/0 json")) + expected = { + "paths": [ + { + "valid": True, + "metric": 666, + "community": { + "string": "65001:65001", + }, + "remoteLabel": 2, + } + ] + } + return topotest.json_cmp(output, expected) + + test_func = functools.partial(_bgp_check_received_ipv6_routes) + _, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5) + assert result is None, "Failed to receive IPv6 default route for labeled-unicast" if __name__ == "__main__": diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 6254a93766..ae64d51283 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -484,8 +484,7 @@ void vtysh_config_parse_line(void *arg, const char *line) config = config_get(RPKI_NODE, line); else { if (strncmp(line, "log", strlen("log")) == 0 || - strncmp(line, "hostname", strlen("hostname")) == - 0 || + strncmp(line, "hostname", strlen("hostname")) == 0 || strncmp(line, "domainname", strlen("domainname")) == 0 || strncmp(line, "allow-reserved-ranges", @@ -497,12 +496,9 @@ void vtysh_config_parse_line(void *arg, const char *line) strlen("no ip prefix-list")) == 0 || strncmp(line, "no ipv6 prefix-list", strlen("no ipv6 prefix-list")) == 0 || - strncmp(line, "service ", strlen("service ")) == - 0 || - strncmp(line, "no service cputime-stats", - strlen("no service cputime-stats")) == 0 || - strncmp(line, "service cputime-warning", - strlen("service cputime-warning")) == 0) + strncmp(line, "service ", strlen("service ")) == 0 || + strncmp(line, "no service ", + strlen("no service ")) == 0) config_add_line_uniq(config_top, line); else config_add_line(config_top, line); diff --git a/zebra/interface.c b/zebra/interface.c index 2157680d58..90787f3aa0 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -200,6 +200,7 @@ static void if_nhg_dependents_release(const struct interface *ifp) static int if_zebra_delete_hook(struct interface *ifp) { struct zebra_if *zebra_if; + struct zebra_l2info_bond *bond; if (ifp->info) { zebra_if = ifp->info; @@ -217,6 +218,10 @@ static int if_zebra_delete_hook(struct interface *ifp) rtadv_if_fini(zebra_if); + bond = &zebra_if->bond_info; + if (bond && bond->mbr_zifs) + list_delete(&bond->mbr_zifs); + zebra_l2_bridge_if_cleanup(ifp); zebra_evpn_if_cleanup(zebra_if); zebra_evpn_mac_ifp_del(ifp); |
