diff options
56 files changed, 595 insertions, 395 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 4f756519ca..9521a9e912 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -1381,39 +1381,45 @@ static struct aspath *aspath_merge(struct aspath *as1, struct aspath *as2) /* Prepend as1 to as2. as2 should be uninterned aspath. */ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2) { - struct assegment *seg1; - struct assegment *seg2; + struct assegment *as1segtail; + struct assegment *as2segtail; + struct assegment *as2seghead; if (!as1 || !as2) return NULL; - seg1 = as1->segments; - seg2 = as2->segments; - /* If as2 is empty, only need to dupe as1's chain onto as2 */ - if (seg2 == NULL) { + if (as2->segments == NULL) { as2->segments = assegment_dup_all(as1->segments); aspath_str_update(as2, false); return as2; } /* If as1 is empty AS, no prepending to do. */ - if (seg1 == NULL) + if (as1->segments == NULL) return as2; /* find the tail as1's segment chain. */ - while (seg1 && seg1->next) - seg1 = seg1->next; + as1segtail = as1->segments; + while (as1segtail && as1segtail->next) + as1segtail = as1segtail->next; /* Delete any AS_CONFED_SEQUENCE segment from as2. */ - if (seg1->type == AS_SEQUENCE && seg2->type == AS_CONFED_SEQUENCE) + if (as1segtail->type == AS_SEQUENCE + && as2->segments->type == AS_CONFED_SEQUENCE) as2 = aspath_delete_confed_seq(as2); + if (!as2->segments) { + as2->segments = assegment_dup_all(as1->segments); + aspath_str_update(as2, false); + return as2; + } + /* Compare last segment type of as1 and first segment type of as2. */ - if (seg1->type != seg2->type) + if (as1segtail->type != as2->segments->type) return aspath_merge(as1, as2); - if (seg1->type == AS_SEQUENCE) { + if (as1segtail->type == AS_SEQUENCE) { /* We have two chains of segments, as1->segments and seg2, * and we have to attach them together, merging the attaching * segments together into one. @@ -1423,23 +1429,28 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2) * 3. attach chain after seg2 */ + /* save as2 head */ + as2seghead = as2->segments; + /* dupe as1 onto as2's head */ - seg1 = as2->segments = assegment_dup_all(as1->segments); + as2segtail = as2->segments = assegment_dup_all(as1->segments); - /* refind the tail of as2, reusing seg1 */ - while (seg1 && seg1->next) - seg1 = seg1->next; + /* refind the tail of as2 */ + while (as2segtail && as2segtail->next) + as2segtail = as2segtail->next; /* merge the old head, seg2, into tail, seg1 */ - seg1 = assegment_append_asns(seg1, seg2->as, seg2->length); + assegment_append_asns(as2segtail, as2seghead->as, + as2seghead->length); - /* bypass the merged seg2, and attach any chain after it to - * chain descending from as2's head + /* + * bypass the merged seg2, and attach any chain after it + * to chain descending from as2's head */ - seg1->next = seg2->next; + as2segtail->next = as2seghead->next; - /* seg2 is now referenceless and useless*/ - assegment_free(seg2); + /* as2->segments is now referenceless and useless */ + assegment_free(as2seghead); /* we've now prepended as1's segment chain to as2, merging * the inbetween AS_SEQUENCE of seg2 in the process diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 43adf34247..a6d985ab9f 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -11650,11 +11650,11 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group) conf = group->conf; if (conf->as_type == AS_SPECIFIED || conf->as_type == AS_EXTERNAL) { - vty_out(vty, "\nBGP peer-group %s, remote AS %d\n", group->name, - conf->as); + vty_out(vty, "\nBGP peer-group %s, remote AS %" PRIu32 "\n", + group->name, conf->as); } else if (conf->as_type == AS_INTERNAL) { - vty_out(vty, "\nBGP peer-group %s, remote AS %d\n", group->name, - group->bgp->as); + vty_out(vty, "\nBGP peer-group %s, remote AS %" PRIu32 "\n", + group->name, group->bgp->as); } else { vty_out(vty, "\nBGP peer-group %s\n", group->name); } diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst index 42a8250ae0..ef9ebe8ddc 100644 --- a/doc/user/routemap.rst +++ b/doc/user/routemap.rst @@ -38,11 +38,12 @@ to four distinct sets of clauses: the ordered entry in the route-map. See below. Call Action - Call to another route-map, after any :term:`Set Actions` have been carried out. - If the route-map called returns `deny` then processing of the route-map - finishes and the route is denied, regardless of the :term:Matching Policy` or - the :term:`Exit Policy`. If the called route-map returns `permit`, then - :term:`Matching Policy` and :term:`Exit Policy` govern further behaviour, as normal. + Call to another route-map, after any :term:`Set Actions` have been + carried out. If the route-map called returns `deny` then processing of + the route-map finishes and the route is denied, regardless of the + :term:`Matching Policy` or the :term:`Exit Policy`. If the called + route-map returns `permit`, then :term:`Matching Policy` and :term:`Exit + Policy` govern further behaviour, as normal. Exit Policy An entry may, optionally, specify an alternative :dfn:`Exit Policy` to diff --git a/eigrpd/eigrp_dump.c b/eigrpd/eigrp_dump.c index 876e1cac07..6033290914 100644 --- a/eigrpd/eigrp_dump.c +++ b/eigrpd/eigrp_dump.c @@ -301,14 +301,14 @@ void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn) } void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp, - struct eigrp_nexthop_entry *te, int *first) + struct eigrp_nexthop_entry *te, bool *first) { if (te->reported_distance == EIGRP_MAX_METRIC) return; if (*first) { show_ip_eigrp_prefix_entry(vty, te->prefix); - *first = 0; + *first = false; } if (te->adv_router == eigrp->neighbor_self) diff --git a/eigrpd/eigrp_dump.h b/eigrpd/eigrp_dump.h index 389ac1b5fd..34b55ab419 100644 --- a/eigrpd/eigrp_dump.h +++ b/eigrpd/eigrp_dump.h @@ -156,8 +156,9 @@ extern void show_ip_eigrp_neighbor_sub(struct vty *, struct eigrp_neighbor *, int); extern void show_ip_eigrp_prefix_entry(struct vty *, struct eigrp_prefix_entry *); -extern void show_ip_eigrp_nexthop_entry(struct vty *, struct eigrp *, - struct eigrp_nexthop_entry *, int *); +extern void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp, + struct eigrp_nexthop_entry *ne, + bool *first); extern void eigrp_debug_init(void); diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index e6cfe1deea..4ad1005f2f 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -114,6 +114,8 @@ int eigrp_if_delete_hook(struct interface *ifp) eigrp = ei->eigrp; listnode_delete(eigrp->eiflist, ei); + eigrp_fifo_free(ei->obuf); + XFREE(MTYPE_EIGRP_IF_INFO, ifp->info); ifp->info = NULL; @@ -265,16 +267,11 @@ void eigrp_if_stream_unset(struct eigrp_interface *ei) { struct eigrp *eigrp = ei->eigrp; - if (ei->obuf) { - eigrp_fifo_free(ei->obuf); - ei->obuf = NULL; - - if (ei->on_write_q) { - listnode_delete(eigrp->oi_write_q, ei); - if (list_isempty(eigrp->oi_write_q)) - thread_cancel(eigrp->t_write); - ei->on_write_q = 0; - } + if (ei->on_write_q) { + listnode_delete(eigrp->oi_write_q, ei); + if (list_isempty(eigrp->oi_write_q)) + thread_cancel(eigrp->t_write); + ei->on_write_q = 0; } } @@ -351,7 +348,6 @@ void eigrp_if_free(struct eigrp_interface *ei, int source) eigrp_if_down(ei); - list_delete(&ei->nbrs); listnode_delete(ei->eigrp->eiflist, ei); } diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c index 2d0ebf1bc5..23f5a705eb 100644 --- a/eigrpd/eigrp_topology.c +++ b/eigrpd/eigrp_topology.c @@ -161,7 +161,7 @@ void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node, listnode_add_sort(node->entries, entry); entry->prefix = node; - eigrp_zebra_route_add(node->destination, l); + eigrp_zebra_route_add(node->destination, l, node->fdistance); } list_delete(&l); @@ -477,7 +477,8 @@ void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix) successors = eigrp_topology_get_successor_max(prefix, eigrp->max_paths); if (successors) { - eigrp_zebra_route_add(prefix->destination, successors); + eigrp_zebra_route_add(prefix->destination, successors, + prefix->fdistance); for (ALL_LIST_ELEMENTS_RO(successors, node, entry)) entry->flags |= EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG; diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c index 474f683989..104f35244e 100644 --- a/eigrpd/eigrp_vty.c +++ b/eigrpd/eigrp_vty.c @@ -455,9 +455,33 @@ DEFUN (no_eigrp_neighbor, return CMD_SUCCESS; } -DEFUN (show_ip_eigrp_topology, - show_ip_eigrp_topology_cmd, - "show ip eigrp topology [all-links]", +static void eigrp_vty_display_prefix_entry(struct vty *vty, + struct eigrp *eigrp, + struct eigrp_prefix_entry *pe, + bool all) +{ + bool first = true; + struct eigrp_nexthop_entry *te; + struct listnode *node; + + for (ALL_LIST_ELEMENTS_RO(pe->entries, node, te)) { + if (all + || (((te->flags + & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) + == EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) + || ((te->flags + & EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG) + == EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG))) { + show_ip_eigrp_nexthop_entry(vty, eigrp, te, + &first); + first = false; + } + } +} + +DEFPY (show_ip_eigrp_topology_all, + show_ip_eigrp_topology_all_cmd, + "show ip eigrp topology [all-links$all]", SHOW_STR IP_STR "IP-EIGRP show commands\n" @@ -465,11 +489,8 @@ DEFUN (show_ip_eigrp_topology, "Show all links in topology table\n") { struct eigrp *eigrp; - struct listnode *node; struct eigrp_prefix_entry *tn; - struct eigrp_nexthop_entry *te; struct route_node *rn; - int first; eigrp = eigrp_lookup(); if (eigrp == NULL) { @@ -484,34 +505,62 @@ DEFUN (show_ip_eigrp_topology, continue; tn = rn->info; - first = 1; - for (ALL_LIST_ELEMENTS_RO(tn->entries, node, te)) { - if (argc == 5 - || (((te->flags - & EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) - == EIGRP_NEXTHOP_ENTRY_SUCCESSOR_FLAG) - || ((te->flags - & EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG) - == EIGRP_NEXTHOP_ENTRY_FSUCCESSOR_FLAG))) { - show_ip_eigrp_nexthop_entry(vty, eigrp, te, - &first); - first = 0; - } - } + eigrp_vty_display_prefix_entry(vty, eigrp, tn, + all ? true : false); } return CMD_SUCCESS; + } -ALIAS(show_ip_eigrp_topology, show_ip_eigrp_topology_detail_cmd, - "show ip eigrp topology <A.B.C.D|A.B.C.D/M|detail|summary>", - SHOW_STR IP_STR - "IP-EIGRP show commands\n" - "IP-EIGRP topology\n" - "Netwok to display information about\n" - "IP prefix <network>/<length>, e.g., 192.168.0.0/16\n" - "Show all links in topology table\n" - "Show a summary of the topology table\n") +DEFPY (show_ip_eigrp_topology, + show_ip_eigrp_topology_cmd, + "show ip eigrp topology <A.B.C.D$address|A.B.C.D/M$prefix>", + SHOW_STR + IP_STR + "IP-EIGRP show commands\n" + "IP-EIGRP topology\n" + "For a specific address\n" + "For a specific prefix\n") +{ + struct eigrp *eigrp; + struct eigrp_prefix_entry *tn; + struct route_node *rn; + struct prefix cmp; + + eigrp = eigrp_lookup(); + if (eigrp == NULL) { + vty_out(vty, " EIGRP Routing Process not enabled\n"); + return CMD_SUCCESS; + } + + show_ip_eigrp_topology_header(vty, eigrp); + + if (address_str) + prefix_str = address_str; + + if (str2prefix(prefix_str, &cmp) < 0) { + vty_out(vty, "%% Malformed address\n"); + return CMD_WARNING; + } + + rn = route_node_match(eigrp->topology_table, &cmp); + if (!rn) { + vty_out(vty, "%% Network not in table\n"); + return CMD_WARNING; + } + + if (!rn->info) { + vty_out(vty, "%% Network not in table\n"); + route_unlock_node(rn); + return CMD_WARNING; + } + + tn = rn->info; + eigrp_vty_display_prefix_entry(vty, eigrp, tn, argc == 5); + + return CMD_SUCCESS; +} DEFUN (show_ip_eigrp_interfaces, show_ip_eigrp_interfaces_cmd, @@ -1485,8 +1534,7 @@ void eigrp_vty_show_init(void) install_element(VIEW_NODE, &show_ip_eigrp_neighbors_cmd); install_element(VIEW_NODE, &show_ip_eigrp_topology_cmd); - - install_element(VIEW_NODE, &show_ip_eigrp_topology_detail_cmd); + install_element(VIEW_NODE, &show_ip_eigrp_topology_all_cmd); } /* eigrpd's interface node. */ diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c index a810e01468..09d876afaa 100644 --- a/eigrpd/eigrp_zebra.c +++ b/eigrpd/eigrp_zebra.c @@ -353,7 +353,8 @@ static struct interface *zebra_interface_if_lookup(struct stream *s) return if_lookup_by_name(ifname_tmp, VRF_DEFAULT); } -void eigrp_zebra_route_add(struct prefix *p, struct list *successors) +void eigrp_zebra_route_add(struct prefix *p, struct list *successors, + uint32_t distance) { struct zapi_route api; struct zapi_nexthop *api_nh; @@ -368,9 +369,11 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors) api.vrf_id = VRF_DEFAULT; api.type = ZEBRA_ROUTE_EIGRP; api.safi = SAFI_UNICAST; + api.metric = distance; memcpy(&api.prefix, p, sizeof(*p)); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); + SET_FLAG(api.message, ZAPI_MESSAGE_METRIC); /* Nexthop, ifindex, distance and metric information. */ for (ALL_LIST_ELEMENTS_RO(successors, node, te)) { diff --git a/eigrpd/eigrp_zebra.h b/eigrpd/eigrp_zebra.h index 1c418dddef..86b337cfe6 100644 --- a/eigrpd/eigrp_zebra.h +++ b/eigrpd/eigrp_zebra.h @@ -33,7 +33,8 @@ extern void eigrp_zebra_init(void); -extern void eigrp_zebra_route_add(struct prefix *, struct list *); +extern void eigrp_zebra_route_add(struct prefix *, struct list *, + uint32_t distance); extern void eigrp_zebra_route_delete(struct prefix *); extern int eigrp_redistribute_set(struct eigrp *, int, struct eigrp_metrics); extern int eigrp_redistribute_unset(struct eigrp *, int); diff --git a/lib/route_types.pl b/lib/route_types.pl index 7435272761..f297096633 100755 --- a/lib/route_types.pl +++ b/lib/route_types.pl @@ -121,7 +121,7 @@ sub codelist { } $str =~ s/ $//; push @lines, $str . "\\n\" \\\n"; - push @lines, " \" > - selected route, * - FIB route, q - queued route, f - failed route\\n\\n\""; + push @lines, " \" > - selected route, * - FIB route, q - queued route, r - rejected route\\n\\n\""; return join("", @lines); } diff --git a/lib/zclient.c b/lib/zclient.c index a01da77669..9db1dd74f2 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -414,9 +414,6 @@ void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id) /* We need router-id information. */ zebra_message_send(zclient, ZEBRA_ROUTER_ID_ADD, vrf_id); - /* We need interface information. */ - zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, vrf_id); - /* Set unwanted redistribute route. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) vrf_bitmap_set(zclient->redist[afi][zclient->redist_default], @@ -481,9 +478,6 @@ void zclient_send_dereg_requests(struct zclient *zclient, vrf_id_t vrf_id) /* We need router-id information. */ zebra_message_send(zclient, ZEBRA_ROUTER_ID_DELETE, vrf_id); - /* We need interface information. */ - zebra_message_send(zclient, ZEBRA_INTERFACE_DELETE, vrf_id); - /* Set unwanted redistribute route. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) vrf_bitmap_unset(zclient->redist[afi][zclient->redist_default], @@ -596,6 +590,8 @@ int zclient_start(struct zclient *zclient) zebra_hello_send(zclient); + zebra_message_send(zclient, ZEBRA_INTERFACE_ADD, VRF_DEFAULT); + /* Inform the successful connection. */ if (zclient->zebra_connected) (*zclient->zebra_connected)(zclient); diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 7089e21513..2c19d061a8 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -62,6 +62,10 @@ #include "pim_bfd.h" #include "bfd.h" +#ifndef VTYSH_EXTRACT_PL +#include "pimd/pim_cmd_clippy.c" +#endif + static struct cmd_node interface_node = { INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */ }; @@ -6394,6 +6398,31 @@ static int pim_cmd_interface_add(struct interface *ifp) return 1; } +DEFPY_HIDDEN (interface_ip_pim_activeactive, + interface_ip_pim_activeactive_cmd, + "[no$no] ip pim active-active", + NO_STR + IP_STR + PIM_STR + "Mark interface as Active-Active for MLAG operations, Hidden because not finished yet\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct pim_interface *pim_ifp; + + if (!no && !pim_cmd_interface_add(ifp)) { + vty_out(vty, "Could not enable PIM SM active-active on interface\n"); + return CMD_WARNING_CONFIG_FAILED; + } + + pim_ifp = ifp->info; + if (no) + pim_ifp->activeactive = false; + else + pim_ifp->activeactive = true; + + return CMD_SUCCESS; +} + DEFUN_HIDDEN (interface_ip_pim_ssm, interface_ip_pim_ssm_cmd, "ip pim ssm", @@ -8722,6 +8751,7 @@ void pim_cmd_init(void) &interface_ip_igmp_query_max_response_time_dsec_cmd); install_element(INTERFACE_NODE, &interface_no_ip_igmp_query_max_response_time_dsec_cmd); + install_element(INTERFACE_NODE, &interface_ip_pim_activeactive_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_ssm_cmd); install_element(INTERFACE_NODE, &interface_no_ip_pim_ssm_cmd); install_element(INTERFACE_NODE, &interface_ip_pim_sm_cmd); diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 0451ab1e71..6933f4d5bd 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -170,6 +170,8 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool igmp, bool pim, pim_ifp->sec_addr_list->cmp = (int (*)(void *, void *))pim_sec_addr_comp; + pim_ifp->activeactive = false; + RB_INIT(pim_ifchannel_rb, &pim_ifp->ifchannel_rb); ifp->info = pim_ifp; diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h index a7dc097f88..5066998cb5 100644 --- a/pimd/pim_iface.h +++ b/pimd/pim_iface.h @@ -124,6 +124,9 @@ struct pim_interface { /* boundary prefix-list */ char *boundary_oil_plist; + /* Turn on Active-Active for this interface */ + bool activeactive; + int64_t pim_ifstat_start; /* start timestamp for stats */ uint32_t pim_ifstat_hello_sent; uint32_t pim_ifstat_hello_sendfail; diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c index f6385a0ac9..6495788748 100644 --- a/pimd/pim_vty.c +++ b/pimd/pim_vty.c @@ -362,6 +362,9 @@ int pim_interface_config_write(struct vty *vty) } } + if (pim_ifp->activeactive) + vty_out(vty, " ip pim active-active\n"); + /* boundary */ if (pim_ifp->boundary_oil_plist) { vty_out(vty, diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index b7111cf7bf..11ca6e8a10 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -267,6 +267,27 @@ static int pim_zebra_if_state_down(int command, struct zclient *zclient, return 0; } +static int pim_zebra_interface_vrf_update(int command, struct zclient *zclient, + zebra_size_t length, vrf_id_t vrf_id) +{ + struct interface *ifp; + vrf_id_t new_vrf_id; + + ifp = zebra_interface_vrf_update_read(zclient->ibuf, vrf_id, + &new_vrf_id); + if (!ifp) + return 0; + + if (PIM_DEBUG_ZEBRA) + zlog_debug("%s: %s updating from %u to %u", + __PRETTY_FUNCTION__, + ifp->name, vrf_id, new_vrf_id); + + if_update_to_new_vrf(ifp, new_vrf_id); + + return 0; +} + #ifdef PIM_DEBUG_IFADDR_DUMP static void dump_if_address(struct interface *ifp) { @@ -762,6 +783,7 @@ void pim_zebra_init(void) zclient->interface_down = pim_zebra_if_state_down; zclient->interface_address_add = pim_zebra_if_address_add; zclient->interface_address_delete = pim_zebra_if_address_del; + zclient->interface_vrf_update = pim_zebra_interface_vrf_update; zclient->nexthop_update = pim_parse_nexthop_update; zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs); diff --git a/pimd/subdir.am b/pimd/subdir.am index 99701430c5..7d8df7d105 100644 --- a/pimd/subdir.am +++ b/pimd/subdir.am @@ -115,6 +115,9 @@ noinst_HEADERS += \ pimd/mtracebis_routeget.h \ # end +pimd/pim_cmd_clippy.c: $(CLIPPY_DEPS) +pimd/pim_cmd.$(OBJEXT): pimd/pim_cmd_clippy.c + pimd_pimd_LDADD = pimd/libpim.a lib/libfrr.la $(LIBCAP) pimd_pimd_SOURCES = pimd/pim_main.c diff --git a/tests/topotests/eigrp-topo1/r1/show_ip_route.json_ref b/tests/topotests/eigrp-topo1/r1/show_ip_route.json_ref index 36dd5da597..26fa7ca415 100644 --- a/tests/topotests/eigrp-topo1/r1/show_ip_route.json_ref +++ b/tests/topotests/eigrp-topo1/r1/show_ip_route.json_ref @@ -3,7 +3,7 @@ { "prefix":"192.168.1.0/24", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, @@ -31,7 +31,7 @@ "prefix":"192.168.3.0/24", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":33280, "nexthops":[ { "fib":true, @@ -47,7 +47,7 @@ { "prefix":"193.1.1.0/26", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, @@ -75,7 +75,7 @@ "prefix":"193.1.2.0/24", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":30720, "nexthops":[ { "fib":true, diff --git a/tests/topotests/eigrp-topo1/r2/show_ip_route.json_ref b/tests/topotests/eigrp-topo1/r2/show_ip_route.json_ref index 44903ce3ff..71c931b17a 100644 --- a/tests/topotests/eigrp-topo1/r2/show_ip_route.json_ref +++ b/tests/topotests/eigrp-topo1/r2/show_ip_route.json_ref @@ -4,7 +4,7 @@ "prefix":"192.168.1.0/24", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":30720, "nexthops":[ { "fib":true, @@ -21,7 +21,7 @@ "prefix":"192.168.3.0/24", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":30720, "nexthops":[ { "fib":true, @@ -37,7 +37,7 @@ { "prefix":"193.1.1.0/26", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, @@ -64,7 +64,7 @@ { "prefix":"193.1.2.0/24", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, diff --git a/tests/topotests/eigrp-topo1/r3/show_ip_route.json_ref b/tests/topotests/eigrp-topo1/r3/show_ip_route.json_ref index d80e1d97e6..5e0b79d811 100644 --- a/tests/topotests/eigrp-topo1/r3/show_ip_route.json_ref +++ b/tests/topotests/eigrp-topo1/r3/show_ip_route.json_ref @@ -4,7 +4,7 @@ "prefix":"192.168.1.0/24", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":33280, "nexthops":[ { "fib":true, @@ -38,7 +38,7 @@ { "prefix":"192.168.3.0/24", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, @@ -66,7 +66,7 @@ "prefix":"193.1.1.0/26", "protocol":"eigrp", "selected":true, - "metric":0, + "metric":30720, "nexthops":[ { "fib":true, @@ -82,7 +82,7 @@ { "prefix":"193.1.2.0/24", "protocol":"eigrp", - "metric":0, + "metric":28160, "nexthops":[ { "directlyConnected":true, diff --git a/tests/topotests/eigrp-topo1/test_eigrp_topo1.py b/tests/topotests/eigrp-topo1/test_eigrp_topo1.py index de8cb81f8f..8ea2f0b506 100755 --- a/tests/topotests/eigrp-topo1/test_eigrp_topo1.py +++ b/tests/topotests/eigrp-topo1/test_eigrp_topo1.py @@ -153,7 +153,6 @@ def test_eigrp_routes(): assertmsg = '"show ip eigrp topo" mismatches on {}'.format(router.name) assert topotest.json_cmp(actual, expected) is None, assertmsg - def test_zebra_ipv4_routingTable(): "Test 'show ip route'" diff --git a/zebra/debug.c b/zebra/debug.c index 0eb06d7f25..87999a1bbc 100644 --- a/zebra/debug.c +++ b/zebra/debug.c @@ -23,6 +23,10 @@ #include "command.h" #include "debug.h" +#ifndef VTYSH_EXTRACT_PL +#include "zebra/debug_clippy.c" +#endif + /* For debug statement. */ unsigned long zebra_debug_event; unsigned long zebra_debug_packet; @@ -34,6 +38,7 @@ unsigned long zebra_debug_mpls; unsigned long zebra_debug_vxlan; unsigned long zebra_debug_pw; unsigned long zebra_debug_dplane; +unsigned long zebra_debug_mlag; DEFINE_HOOK(zebra_debug_show_debugging, (struct vty *vty), (vty)); @@ -94,6 +99,8 @@ DEFUN_NOSH (show_debugging_zebra, vty_out(vty, " Zebra detailed dataplane debugging is on\n"); else if (IS_ZEBRA_DEBUG_DPLANE) vty_out(vty, " Zebra dataplane debugging is on\n"); + if (IS_ZEBRA_DEBUG_MLAG) + vty_out(vty, " Zebra mlag debugging is on\n"); hook_call(zebra_debug_show_debugging, vty); return CMD_SUCCESS; @@ -284,6 +291,21 @@ DEFUN (debug_zebra_dplane, return CMD_SUCCESS; } +DEFPY (debug_zebra_mlag, + debug_zebra_mlag_cmd, + "[no$no] debug zebra mlag", + NO_STR + DEBUG_STR + "Zebra configuration\n" + "Debug option set for mlag events\n") +{ + if (no) + UNSET_FLAG(zebra_debug_mlag, ZEBRA_DEBUG_MLAG); + else + SET_FLAG(zebra_debug_mlag, ZEBRA_DEBUG_MLAG); + return CMD_SUCCESS; +} + DEFUN (no_debug_zebra_events, no_debug_zebra_events_cmd, "no debug zebra events", @@ -507,6 +529,7 @@ void zebra_debug_init(void) zebra_debug_vxlan = 0; zebra_debug_pw = 0; zebra_debug_dplane = 0; + zebra_debug_mlag = 0; install_node(&debug_node, config_write_debug); @@ -523,6 +546,7 @@ void zebra_debug_init(void) install_element(ENABLE_NODE, &debug_zebra_rib_cmd); install_element(ENABLE_NODE, &debug_zebra_fpm_cmd); install_element(ENABLE_NODE, &debug_zebra_dplane_cmd); + install_element(ENABLE_NODE, &debug_zebra_mlag_cmd); install_element(ENABLE_NODE, &no_debug_zebra_events_cmd); install_element(ENABLE_NODE, &no_debug_zebra_nht_cmd); install_element(ENABLE_NODE, &no_debug_zebra_mpls_cmd); diff --git a/zebra/debug.h b/zebra/debug.h index cd15441ec8..c79cd96c21 100644 --- a/zebra/debug.h +++ b/zebra/debug.h @@ -51,6 +51,8 @@ #define ZEBRA_DEBUG_DPLANE 0x01 #define ZEBRA_DEBUG_DPLANE_DETAILED 0x02 +#define ZEBRA_DEBUG_MLAG 0x01 + /* Debug related macro. */ #define IS_ZEBRA_DEBUG_EVENT (zebra_debug_event & ZEBRA_DEBUG_EVENT) @@ -79,6 +81,8 @@ #define IS_ZEBRA_DEBUG_DPLANE_DETAIL \ (zebra_debug_dplane & ZEBRA_DEBUG_DPLANE_DETAILED) +#define IS_ZEBRA_DEBUG_MLAG (zebra_debug_mlag & ZEBRA_DEBUG_MLAG) + extern unsigned long zebra_debug_event; extern unsigned long zebra_debug_packet; extern unsigned long zebra_debug_kernel; @@ -89,6 +93,7 @@ extern unsigned long zebra_debug_mpls; extern unsigned long zebra_debug_vxlan; extern unsigned long zebra_debug_pw; extern unsigned long zebra_debug_dplane; +extern unsigned long zebra_debug_mlag; extern void zebra_debug_init(void); diff --git a/zebra/interface.c b/zebra/interface.c index 8bb5c6e8ef..c88aadc683 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -41,7 +41,7 @@ #include "zebra/interface.h" #include "zebra/rib.h" #include "zebra/rt.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/redistribute.h" #include "zebra/debug.h" #include "zebra/irdp.h" @@ -153,7 +153,7 @@ static int if_zebra_new_hook(struct interface *ifp) * of seconds and ask again. Hopefully it's all settled * down upon startup. */ - thread_add_timer(zebrad.master, if_zebra_speed_update, ifp, 15, + thread_add_timer(zrouter.master, if_zebra_speed_update, ifp, 15, &zebra_if->speed_update); return 0; } diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index ffc49d2c13..c0b772cd01 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -45,7 +45,7 @@ #include "zebra/interface.h" #include "zebra/rtadv.h" #include "zebra/rib.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/redistribute.h" #include "zebra/irdp.h" #include "zebra/zebra_errors.h" @@ -285,7 +285,7 @@ static void irdp_if_start(struct interface *ifp, int multicast, timer); irdp->t_advertise = NULL; - thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer, + thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer, &irdp->t_advertise); } diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index 9300ba6034..a9734056bc 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -56,7 +56,7 @@ #include "zebra/interface.h" #include "zebra/rtadv.h" #include "zebra/rib.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/redistribute.h" #include "zebra/irdp.h" #include "zebra/zebra_errors.h" @@ -113,7 +113,7 @@ int irdp_sock_init(void) }; t_irdp_raw = NULL; - thread_add_read(zebrad.master, irdp_read_raw, NULL, sock, &t_irdp_raw); + thread_add_read(zrouter.master, irdp_read_raw, NULL, sock, &t_irdp_raw); return sock; } @@ -245,7 +245,7 @@ int irdp_send_thread(struct thread *t_advert) timer); irdp->t_advertise = NULL; - thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer, + thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer, &irdp->t_advertise); return 0; } @@ -306,7 +306,7 @@ void process_solicit(struct interface *ifp) timer = (random() % MAX_RESPONSE_DELAY) + 1; irdp->t_advertise = NULL; - thread_add_timer(zebrad.master, irdp_send_thread, ifp, timer, + thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer, &irdp->t_advertise); } diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c index bebccd7168..774d84d66d 100644 --- a/zebra/irdp_packet.c +++ b/zebra/irdp_packet.c @@ -58,7 +58,7 @@ #include "zebra/interface.h" #include "zebra/rtadv.h" #include "zebra/rib.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/redistribute.h" #include "zebra/irdp.h" #include "zebra/zebra_errors.h" @@ -230,7 +230,7 @@ int irdp_read_raw(struct thread *r) int irdp_sock = THREAD_FD(r); t_irdp_raw = NULL; - thread_add_read(zebrad.master, irdp_read_raw, NULL, irdp_sock, + thread_add_read(zrouter.master, irdp_read_raw, NULL, irdp_sock, &t_irdp_raw); ret = irdp_recvmsg(irdp_sock, (uint8_t *)buf, IRDP_RX_BUF, &ifindex); diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index c88bfbb101..2f850c6338 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -43,7 +43,8 @@ #include "mpls.h" #include "lib_errors.h" -#include "zebra/zserv.h" +//#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/zebra_ns.h" #include "zebra/zebra_vrf.h" #include "zebra/rt.h" @@ -388,7 +389,7 @@ static int kernel_read(struct thread *thread) netlink_parse_info(netlink_information_fetch, &zns->netlink, &dp_info, 5, 0); zns->t_netlink = NULL; - thread_add_read(zebrad.master, kernel_read, zns, zns->netlink.sock, + thread_add_read(zrouter.master, kernel_read, zns, zns->netlink.sock, &zns->t_netlink); return 0; @@ -1158,7 +1159,7 @@ void kernel_init(struct zebra_ns *zns) zns->t_netlink = NULL; - thread_add_read(zebrad.master, kernel_read, zns, + thread_add_read(zrouter.master, kernel_read, zns, zns->netlink.sock, &zns->t_netlink); rt_netlink_init(); diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index acd7f911dc..792756efeb 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -43,7 +43,7 @@ #include "zebra/rt.h" #include "zebra/interface.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/debug.h" #include "zebra/kernel_socket.h" #include "zebra/rib.h" @@ -1372,7 +1372,7 @@ static int kernel_read(struct thread *thread) return 0; } - thread_add_read(zebrad.master, kernel_read, NULL, sock, NULL); + thread_add_read(zrouter.master, kernel_read, NULL, sock, NULL); if (IS_ZEBRA_DEBUG_KERNEL) rtmsg_debug(&buf.r.rtm); @@ -1445,7 +1445,7 @@ static void routing_socket(struct zebra_ns *zns) zlog_warn ("Can't set O_NONBLOCK to routing socket");*/ /* kernel_read needs rewrite. */ - thread_add_read(zebrad.master, kernel_read, NULL, routing_sock, NULL); + thread_add_read(zrouter.master, kernel_read, NULL, routing_sock, NULL); } /* Exported interface function. This function simply calls diff --git a/zebra/label_manager.c b/zebra/label_manager.c index 13472059a0..1b17845e41 100644 --- a/zebra/label_manager.c +++ b/zebra/label_manager.c @@ -34,7 +34,8 @@ #include "lib/zclient.h" #include "lib/libfrr.h" -#include "zebra/zserv.h" +//#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/label_manager.h" #include "zebra/zebra_errors.h" @@ -294,7 +295,7 @@ static int lm_zclient_connect(struct thread *t) if (zclient_socket_connect(zclient) < 0) { flog_err(EC_ZEBRA_LM_CLIENT_CONNECTION_FAILED, "Error connecting synchronous zclient!"); - thread_add_timer(zebrad.master, lm_zclient_connect, zclient, + thread_add_timer(zrouter.master, lm_zclient_connect, zclient, CONNECTION_DELAY, &zclient->t_connect); return -1; } @@ -318,7 +319,7 @@ static void lm_zclient_init(char *lm_zserv_path) lm_zserv_path); /* Set default values. */ - zclient = zclient_new(zebrad.master, &zclient_options_default); + zclient = zclient_new(zrouter.master, &zclient_options_default); zclient->privs = &zserv_privs; zclient->sock = -1; zclient->t_connect = NULL; diff --git a/zebra/main.c b/zebra/main.c index b54c36c109..c605050c57 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -62,12 +62,6 @@ #define ZEBRA_PTM_SUPPORT -/* Zebra instance */ -struct zebra_t zebrad = { - .rtm_table_default = 0, - .packets_to_process = ZEBRA_ZAPI_PACKETS_TO_PROCESS, -}; - /* process id. */ pid_t pid; @@ -156,10 +150,10 @@ static void sigint(void) zebra_dplane_pre_finish(); - for (ALL_LIST_ELEMENTS(zebrad.client_list, ln, nn, client)) + for (ALL_LIST_ELEMENTS(zrouter.client_list, ln, nn, client)) zserv_close_client(client); - list_delete_all_node(zebrad.client_list); + list_delete_all_node(zrouter.client_list); zebra_ptm_finish(); if (retain_mode) @@ -168,8 +162,8 @@ static void sigint(void) if (zvrf) SET_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN); } - if (zebrad.lsp_process_q) - work_queue_free_and_null(&zebrad.lsp_process_q); + if (zrouter.lsp_process_q) + work_queue_free_and_null(&zrouter.lsp_process_q); vrf_terminate(); ns_walk_func(zebra_ns_early_shutdown); @@ -179,7 +173,7 @@ static void sigint(void) prefix_list_reset(); route_map_finish(); - list_delete(&zebrad.client_list); + list_delete(&zrouter.client_list); /* Indicate that all new dplane work has been enqueued. When that * work is complete, the dataplane will enqueue an event @@ -202,9 +196,6 @@ int zebra_finalize(struct thread *dummy) /* Stop dplane thread and finish any cleanup */ zebra_dplane_shutdown(); - work_queue_free_and_null(&zebrad.ribq); - meta_queue_free(zebrad.mq); - zebra_router_terminate(); frr_fini(); @@ -391,7 +382,7 @@ int main(int argc, char **argv) } } - zebrad.master = frr_init(); + zrouter.master = frr_init(); /* Initialize pthread library */ frr_pthread_init(); @@ -479,7 +470,7 @@ int main(int argc, char **argv) #endif /* HANDLE_NETLINK_FUZZING */ - frr_run(zebrad.master); + frr_run(zrouter.master); /* Not reached... */ return 0; diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 2c5350fceb..f98a4c02c3 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -33,7 +33,7 @@ #include "srcdest_table.h" #include "zebra/rib.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/zebra_ns.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_routemap.h" @@ -173,7 +173,7 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p, return; } - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { send_redistribute = 0; if (is_default_prefix(p) @@ -246,7 +246,7 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p, return; } - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { if ((is_default_prefix(p) && vrf_bitmap_check(client->redist_default[afi], re->vrf_id)) @@ -405,12 +405,12 @@ void zebra_interface_up_update(struct interface *ifp) ifp->name, ifp->vrf_id); if (ifp->ptm_status || !ifp->ptm_enable) { - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) - if (vrf_bitmap_check(client->ifinfo, ifp->vrf_id)) { - zsend_interface_update(ZEBRA_INTERFACE_UP, - client, ifp); - zsend_interface_link_params(client, ifp); - } + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, + client)) { + zsend_interface_update(ZEBRA_INTERFACE_UP, + client, ifp); + zsend_interface_link_params(client, ifp); + } } } @@ -424,7 +424,7 @@ void zebra_interface_down_update(struct interface *ifp) zlog_debug("MESSAGE: ZEBRA_INTERFACE_DOWN %s(%u)", ifp->name, ifp->vrf_id); - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp); } } @@ -439,12 +439,11 @@ void zebra_interface_add_update(struct interface *ifp) zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADD %s(%u)", ifp->name, ifp->vrf_id); - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) - if (vrf_bitmap_check(client->ifinfo, ifp->vrf_id)) { - client->ifadd_cnt++; - zsend_interface_add(client, ifp); - zsend_interface_link_params(client, ifp); - } + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + client->ifadd_cnt++; + zsend_interface_add(client, ifp); + zsend_interface_link_params(client, ifp); + } } void zebra_interface_delete_update(struct interface *ifp) @@ -456,7 +455,7 @@ void zebra_interface_delete_update(struct interface *ifp) zlog_debug("MESSAGE: ZEBRA_INTERFACE_DELETE %s(%u)", ifp->name, ifp->vrf_id); - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { client->ifdel_cnt++; zsend_interface_delete(client, ifp); } @@ -488,7 +487,7 @@ void zebra_interface_address_add_update(struct interface *ifp, router_id_add_address(ifc); - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) { client->connected_rt_add_cnt++; zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_ADD, @@ -517,7 +516,7 @@ void zebra_interface_address_delete_update(struct interface *ifp, router_id_del_address(ifc); - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) { client->connected_rt_del_cnt++; zsend_interface_address(ZEBRA_INTERFACE_ADDRESS_DELETE, @@ -538,7 +537,7 @@ void zebra_interface_vrf_update_del(struct interface *ifp, vrf_id_t new_vrf_id) "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/DEL %s VRF Id %u -> %u", ifp->name, ifp->vrf_id, new_vrf_id); - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { /* Need to delete if the client is not interested in the new * VRF. */ zsend_interface_update(ZEBRA_INTERFACE_DOWN, client, ifp); @@ -561,7 +560,7 @@ void zebra_interface_vrf_update_add(struct interface *ifp, vrf_id_t old_vrf_id) "MESSAGE: ZEBRA_INTERFACE_VRF_UPDATE/ADD %s VRF Id %u -> %u", ifp->name, old_vrf_id, ifp->vrf_id); - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { /* Need to add if the client is interested in the new VRF. */ client->ifadd_cnt++; zsend_interface_add(client, ifp); @@ -613,7 +612,7 @@ int zebra_add_import_table_entry(struct route_node *rn, struct route_entry *re, newre->flags = re->flags; newre->metric = re->metric; newre->mtu = re->mtu; - newre->table = zebrad.rtm_table_default; + newre->table = zrouter.rtm_table_default; newre->nexthop_num = 0; newre->uptime = time(NULL); newre->instance = re->table; @@ -634,7 +633,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re) rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table, re->flags, &p, NULL, re->ng.nexthop, - zebrad.rtm_table_default, re->metric, re->distance, false); + zrouter.rtm_table_default, re->metric, re->distance, false); return 0; } @@ -649,7 +648,7 @@ int zebra_import_table(afi_t afi, uint32_t table_id, uint32_t distance, if (!is_zebra_valid_kernel_table(table_id) || ((table_id == RT_TABLE_MAIN) - || (table_id == zebrad.rtm_table_default))) + || (table_id == zrouter.rtm_table_default))) return (-1); if (afi >= AFI_MAX) @@ -812,7 +811,6 @@ void zebra_interface_parameters_update(struct interface *ifp) zlog_debug("MESSAGE: ZEBRA_INTERFACE_LINK_PARAMS %s(%u)", ifp->name, ifp->vrf_id); - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) - if (vrf_bitmap_check(client->ifinfo, ifp->vrf_id)) - zsend_interface_link_params(client, ifp); + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) + zsend_interface_link_params(client, ifp); } diff --git a/zebra/router-id.c b/zebra/router-id.c index c500f79a6c..569ffbab41 100644 --- a/zebra/router-id.c +++ b/zebra/router-id.c @@ -38,15 +38,12 @@ #include "rib.h" #include "vrf.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/zapi_msg.h" #include "zebra/zebra_vrf.h" #include "zebra/router-id.h" #include "zebra/redistribute.h" -/* master zebra server structure */ -extern struct zebra_t zebrad; - static struct connected *router_id_find_node(struct list *l, struct connected *ifc) { @@ -114,7 +111,7 @@ static void router_id_set(struct prefix *p, vrf_id_t vrf_id) router_id_get(&p2, vrf_id); - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) zsend_router_id_update(client, &p2, vrf_id); } @@ -145,7 +142,7 @@ void router_id_add_address(struct connected *ifc) if (prefix_same(&before, &after)) return; - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) zsend_router_id_update(client, &after, zvrf_id(zvrf)); } @@ -177,7 +174,7 @@ void router_id_del_address(struct connected *ifc) if (prefix_same(&before, &after)) return; - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) zsend_router_id_update(client, &after, zvrf_id(zvrf)); } diff --git a/zebra/rt.h b/zebra/rt.h index 0b14a3ef36..6d12d8ea2e 100644 --- a/zebra/rt.h +++ b/zebra/rt.h @@ -67,6 +67,8 @@ extern int kernel_del_mac(struct interface *ifp, vlanid_t vid, extern int kernel_add_neigh(struct interface *ifp, struct ipaddr *ip, struct ethaddr *mac, uint8_t flags); extern int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip); +extern int kernel_upd_neigh(struct interface *ifp, struct ipaddr *ip, + struct ethaddr *mac, uint8_t flags, uint16_t state); /* * Southbound Initialization routines to get initial starting diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index f69df1da89..3868412b20 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1140,8 +1140,7 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen, if (nexthop->type != NEXTHOP_TYPE_BLACKHOLE) addattr32(nlmsg, req_size, RTA_OIF, nexthop->ifindex); - if (nexthop->type == NEXTHOP_TYPE_IFINDEX - || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) { + if (nexthop->type == NEXTHOP_TYPE_IFINDEX) { if (cmd == RTM_NEWROUTE) { if (nexthop->rmap_src.ipv4.s_addr) addattr_l(nlmsg, req_size, RTA_PREFSRC, @@ -1157,23 +1156,6 @@ static void _netlink_route_build_singlepath(const char *routedesc, int bytelen, "nexthop via if %u(%u)", routedesc, nexthop->ifindex, nexthop->vrf_id); } - - if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) { - if (cmd == RTM_NEWROUTE) { - if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) - addattr_l(nlmsg, req_size, RTA_PREFSRC, - &nexthop->rmap_src.ipv6, bytelen); - else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) - addattr_l(nlmsg, req_size, RTA_PREFSRC, - &nexthop->src.ipv6, bytelen); - } - - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug( - "netlink_route_multipath() (%s): " - "nexthop via if %u(%u)", - routedesc, nexthop->ifindex, nexthop->vrf_id); - } } /* This function takes a nexthop as argument and @@ -1345,8 +1327,7 @@ static void _netlink_route_build_multipath(const char *routedesc, int bytelen, rtnh->rtnh_ifindex = nexthop->ifindex; /* ifindex */ - if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX - || nexthop->type == NEXTHOP_TYPE_IFINDEX) { + if (nexthop->type == NEXTHOP_TYPE_IFINDEX) { if (nexthop->rmap_src.ipv4.s_addr) *src = &nexthop->rmap_src; else if (nexthop->src.ipv4.s_addr) @@ -2720,12 +2701,12 @@ static int netlink_neigh_update2(struct interface *ifp, struct ipaddr *ip, addattr_l(&req.n, sizeof(req), NDA_LLADDR, mac, 6); if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("Tx %s family %s IF %s(%u) Neigh %s MAC %s flags 0x%x", + zlog_debug("Tx %s family %s IF %s(%u) Neigh %s MAC %s flags 0x%x state 0x%x", nl_msg_type_to_str(cmd), nl_family_to_str(req.ndm.ndm_family), ifp->name, ifp->ifindex, ipaddr2str(ip, buf, sizeof(buf)), mac ? prefix_mac2str(mac, buf2, sizeof(buf2)) - : "null", flags); + : "null", flags, state); return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); @@ -2756,6 +2737,13 @@ int kernel_del_neigh(struct interface *ifp, struct ipaddr *ip) return netlink_neigh_update2(ifp, ip, NULL, 0, 0, RTM_DELNEIGH); } +int kernel_upd_neigh(struct interface *ifp, struct ipaddr *ip, + struct ethaddr *mac, uint8_t flags, uint16_t state) +{ + return netlink_neigh_update2(ifp, ip, mac, flags, + state, RTM_NEWNEIGH); +} + /* * MPLS label forwarding table change via netlink interface, using dataplane * context information. diff --git a/zebra/rtadv.c b/zebra/rtadv.c index a22f6395c9..86edc6fb5e 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -1698,9 +1698,9 @@ static void rtadv_event(struct zebra_ns *zns, enum rtadv_event event, int val) switch (event) { case RTADV_START: - thread_add_read(zebrad.master, rtadv_read, zns, val, + thread_add_read(zrouter.master, rtadv_read, zns, val, &rtadv->ra_read); - thread_add_event(zebrad.master, rtadv_timer, zns, 0, + thread_add_event(zrouter.master, rtadv_timer, zns, 0, &rtadv->ra_timer); break; case RTADV_STOP: @@ -1714,15 +1714,15 @@ static void rtadv_event(struct zebra_ns *zns, enum rtadv_event event, int val) } break; case RTADV_TIMER: - thread_add_timer(zebrad.master, rtadv_timer, zns, val, + thread_add_timer(zrouter.master, rtadv_timer, zns, val, &rtadv->ra_timer); break; case RTADV_TIMER_MSEC: - thread_add_timer_msec(zebrad.master, rtadv_timer, zns, val, + thread_add_timer_msec(zrouter.master, rtadv_timer, zns, val, &rtadv->ra_timer); break; case RTADV_READ: - thread_add_read(zebrad.master, rtadv_read, zns, val, + thread_add_read(zrouter.master, rtadv_read, zns, val, &rtadv->ra_read); break; default: diff --git a/zebra/subdir.am b/zebra/subdir.am index daa7946bc0..1e36d020a3 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -95,6 +95,9 @@ zebra_zebra_SOURCES = \ zebra/zebra_errors.c \ # end +zebra/debug_clippy.c: $(CLIPPY_DEPS) +zebra/debug.$(OBJEXT): zebra/debug_clippy.c + zebra/zebra_mlag_clippy.c: $(CLIPPY_DEPS) zebra/zebra_mlag.$(OBJEXT): zebra/zebra_mlag_clippy.c diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 951a411f25..3bf03039b1 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -42,6 +42,7 @@ #include "lib/libfrr.h" #include "lib/sockopt.h" +#include "zebra/zebra_router.h" #include "zebra/rib.h" #include "zebra/zebra_memory.h" #include "zebra/zebra_ns.h" @@ -208,12 +209,6 @@ int zsend_interface_link_params(struct zserv *client, struct interface *ifp) { struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ); - /* Check this client need interface information. */ - if (!vrf_bitmap_check(client->ifinfo, ifp->vrf_id)) { - stream_free(s); - return 0; - } - if (!ifp->link_params) { stream_free(s); return 0; @@ -365,7 +360,7 @@ static void zebra_interface_nbr_address_add_update(struct interface *ifp, p->prefixlen, ifc->ifp->name); } - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_ADD, client, ifp, ifc); } @@ -389,7 +384,7 @@ static void zebra_interface_nbr_address_delete_update(struct interface *ifp, p->prefixlen, ifc->ifp->name); } - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) zsend_interface_nbr_address(ZEBRA_INTERFACE_NBR_ADDRESS_DELETE, client, ifp, ifc); } @@ -768,7 +763,7 @@ void zsend_rule_notify_owner(struct zebra_pbr_rule *rule, zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__, rule->rule.unique); - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) { + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) { if (rule->sock == client->sock) break; } @@ -804,7 +799,7 @@ void zsend_ipset_notify_owner(struct zebra_pbr_ipset *ipset, zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__, ipset->unique); - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) { + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) { if (ipset->sock == client->sock) break; } @@ -834,7 +829,7 @@ void zsend_ipset_entry_notify_owner(struct zebra_pbr_ipset_entry *ipset, zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__, ipset->unique); - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) { + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) { if (ipset->sock == client->sock) break; } @@ -864,7 +859,7 @@ void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable, zlog_debug("%s: Notifying %u", __PRETTY_FUNCTION__, iptable->unique); - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) { + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) { if (iptable->sock == client->sock) break; } @@ -1316,9 +1311,6 @@ static void zread_interface_add(ZAPI_HANDLER_ARGS) struct vrf *vrf; struct interface *ifp; - /* Interface information is needed. */ - vrf_bitmap_set(client->ifinfo, zvrf_id(zvrf)); - RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { FOR_ALL_INTERFACES (vrf, ifp) { /* Skip pseudo interface. */ @@ -1335,7 +1327,6 @@ static void zread_interface_add(ZAPI_HANDLER_ARGS) /* Unregister zebra server interface information. */ static void zread_interface_delete(ZAPI_HANDLER_ARGS) { - vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf)); } void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, @@ -1674,6 +1665,18 @@ static void zsend_capabilities(struct zserv *client, struct zebra_vrf *zvrf) zserv_send_message(client, s); } +void zsend_capabilities_all_clients(void) +{ + struct listnode *node, *nnode; + struct zebra_vrf *zvrf; + struct zserv *client; + + zvrf = vrf_info_lookup(VRF_DEFAULT); + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { + zsend_capabilities(client, zvrf); + } +} + /* Tie up route-type and client->sock */ static void zread_hello(ZAPI_HANDLER_ARGS) { @@ -1718,7 +1721,6 @@ static void zread_vrf_unregister(ZAPI_HANDLER_ARGS) vrf_bitmap_unset(client->redist[afi][i], zvrf_id(zvrf)); vrf_bitmap_unset(client->redist_default[afi], zvrf_id(zvrf)); } - vrf_bitmap_unset(client->ifinfo, zvrf_id(zvrf)); vrf_bitmap_unset(client->ridinfo, zvrf_id(zvrf)); } diff --git a/zebra/zapi_msg.h b/zebra/zapi_msg.h index 11b469e144..b770b8e881 100644 --- a/zebra/zapi_msg.h +++ b/zebra/zapi_msg.h @@ -84,3 +84,5 @@ extern void zsend_iptable_notify_owner(struct zebra_pbr_iptable *iptable, enum zapi_iptable_notify_owner note); extern void zserv_nexthop_num_warn(const char *caller, const struct prefix *p, const unsigned int nexthop_num); + +extern void zsend_capabilities_all_clients(void); diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 6fbad2f71e..15fcde2bbc 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -26,7 +26,7 @@ #include "lib/zebra.h" #include "zebra/zebra_router.h" #include "zebra/zebra_memory.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/zebra_dplane.h" #include "zebra/rt.h" #include "zebra/debug.h" @@ -1802,7 +1802,7 @@ static int dplane_check_shutdown_status(struct thread *event) /* We appear to be done - schedule a final callback event * for the zebra main pthread. */ - thread_add_event(zebrad.master, zebra_finalize, NULL, 0, NULL); + thread_add_event(zrouter.master, zebra_finalize, NULL, 0, NULL); } return 0; @@ -2052,7 +2052,7 @@ void zebra_dplane_shutdown(void) /* * Initialize the dataplane module during startup, internal/private version */ -static void zebra_dplane_init_internal(struct zebra_t *zebra) +static void zebra_dplane_init_internal(void) { memset(&zdplane_info, 0, sizeof(zdplane_info)); @@ -2101,6 +2101,6 @@ void zebra_dplane_start(void) */ void zebra_dplane_init(int (*results_fp)(struct dplane_ctx_q *)) { - zebra_dplane_init_internal(&zebrad); + zebra_dplane_init_internal(); zdplane_info.dg_results_cb = results_fp; } diff --git a/zebra/zebra_mlag.c b/zebra/zebra_mlag.c index 35be07c024..5012cc2a49 100644 --- a/zebra/zebra_mlag.c +++ b/zebra/zebra_mlag.c @@ -25,16 +25,17 @@ #include "hook.h" #include "zebra/zebra_mlag.h" +#include "zebra/zebra_router.h" +#include "zebra/zapi_msg.h" +#include "zebra/debug.h" #ifndef VTYSH_EXTRACT_PL #include "zebra/zebra_mlag_clippy.c" #endif -enum mlag_role role = MLAG_ROLE_NONE; - enum mlag_role zebra_mlag_get_role(void) { - return role; + return zrouter.mlag_info.role; } DEFUN_HIDDEN (show_mlag, @@ -47,7 +48,7 @@ DEFUN_HIDDEN (show_mlag, char buf[80]; vty_out(vty, "MLag is configured to: %s\n", - mlag_role2str(role, buf, sizeof(buf))); + mlag_role2str(zrouter.mlag_info.role, buf, sizeof(buf))); return CMD_SUCCESS; } @@ -62,12 +63,23 @@ DEFPY_HIDDEN (test_mlag, "Mlag is setup to be primary\n" "Mlag is setup to be the secondary\n") { + enum mlag_role orig = zrouter.mlag_info.role; + char buf1[80], buf2[80]; + if (none) - role = MLAG_ROLE_NONE; + zrouter.mlag_info.role = MLAG_ROLE_NONE; if (primary) - role = MLAG_ROLE_PRIMARY; + zrouter.mlag_info.role = MLAG_ROLE_PRIMARY; if (secondary) - role = MLAG_ROLE_SECONDARY; + zrouter.mlag_info.role = MLAG_ROLE_SECONDARY; + + if (IS_ZEBRA_DEBUG_MLAG) + zlog_debug("Test: Changing role from %s to %s", + mlag_role2str(orig, buf1, sizeof(buf1)), + mlag_role2str(orig, buf2, sizeof(buf2))); + + if (orig != zrouter.mlag_info.role) + zsend_capabilities_all_clients(); return CMD_SUCCESS; } diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index c255c68866..0aac7d7b12 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -40,6 +40,7 @@ #include "zebra/rt.h" #include "zebra/interface.h" #include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/redistribute.h" #include "zebra/debug.h" #include "zebra/zebra_memory.h" @@ -56,9 +57,6 @@ DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname") int mpls_enabled; -/* Default rtm_table for all clients */ -extern struct zebra_t zebrad; - /* static function declarations */ static void fec_evaluate(struct zebra_vrf *zvrf); @@ -126,7 +124,6 @@ static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp, static int snhlfe_del(zebra_snhlfe_t *snhlfe); static int snhlfe_del_all(zebra_slsp_t *slsp); static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size); -static int mpls_processq_init(struct zebra_t *zebra); /* Static functions */ @@ -1074,13 +1071,13 @@ static int lsp_processq_add(zebra_lsp_t *lsp) if (CHECK_FLAG(lsp->flags, LSP_FLAG_SCHEDULED)) return 0; - if (zebrad.lsp_process_q == NULL) { + if (zrouter.lsp_process_q == NULL) { flog_err(EC_ZEBRA_WQ_NONEXISTENT, "%s: work_queue does not exist!", __func__); return -1; } - work_queue_add(zebrad.lsp_process_q, lsp); + work_queue_add(zrouter.lsp_process_q, lsp); SET_FLAG(lsp->flags, LSP_FLAG_SCHEDULED); return 0; } @@ -1714,21 +1711,21 @@ static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size) /* * Initialize work queue for processing changed LSPs. */ -static int mpls_processq_init(struct zebra_t *zebra) +static int mpls_processq_init(void) { - zebra->lsp_process_q = work_queue_new(zebra->master, "LSP processing"); - if (!zebra->lsp_process_q) { + zrouter.lsp_process_q = work_queue_new(zrouter.master, "LSP processing"); + if (!zrouter.lsp_process_q) { flog_err(EC_ZEBRA_WQ_NONEXISTENT, "%s: could not initialise work queue!", __func__); return -1; } - zebra->lsp_process_q->spec.workfunc = &lsp_process; - zebra->lsp_process_q->spec.del_item_data = &lsp_processq_del; - zebra->lsp_process_q->spec.errorfunc = NULL; - zebra->lsp_process_q->spec.completion_func = &lsp_processq_complete; - zebra->lsp_process_q->spec.max_retries = 0; - zebra->lsp_process_q->spec.hold = 10; + zrouter.lsp_process_q->spec.workfunc = &lsp_process; + zrouter.lsp_process_q->spec.del_item_data = &lsp_processq_del; + zrouter.lsp_process_q->spec.errorfunc = NULL; + zrouter.lsp_process_q->spec.completion_func = &lsp_processq_complete; + zrouter.lsp_process_q->spec.max_retries = 0; + zrouter.lsp_process_q->spec.hold = 10; return 0; } @@ -3062,7 +3059,7 @@ void zebra_mpls_init(void) return; } - if (!mpls_processq_init(&zebrad)) + if (!mpls_processq_init()) mpls_enabled = 1; hook_register(zserv_client_close, zebra_mpls_cleanup_fecs_for_client); diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c index ef31fcf45d..476638591b 100644 --- a/zebra/zebra_netns_notify.c +++ b/zebra/zebra_netns_notify.c @@ -36,7 +36,7 @@ #include "memory.h" #include "lib_errors.h" -#include "zserv.h" +#include "zebra_router.h" #include "zebra_memory.h" #endif /* defined(HAVE_NETLINK) */ @@ -121,7 +121,7 @@ static int zebra_ns_continue_read(struct zebra_netns_info *zns_info, XFREE(MTYPE_NETNS_MISC, zns_info); return 0; } - thread_add_timer_msec(zebrad.master, zebra_ns_ready_read, + thread_add_timer_msec(zrouter.master, zebra_ns_ready_read, (void *)zns_info, ZEBRA_NS_POLLING_INTERVAL_MSEC, NULL); return 0; @@ -242,7 +242,7 @@ static int zebra_ns_notify_read(struct thread *t) ssize_t len; zebra_netns_notify_current = thread_add_read( - zebrad.master, zebra_ns_notify_read, NULL, fd_monitor, NULL); + zrouter.master, zebra_ns_notify_read, NULL, fd_monitor, NULL); len = read(fd_monitor, buf, sizeof(buf)); if (len < 0) { flog_err_sys(EC_ZEBRA_NS_NOTIFY_READ, @@ -284,7 +284,7 @@ static int zebra_ns_notify_read(struct thread *t) sizeof(struct zebra_netns_info)); netnsinfo->retries = ZEBRA_NS_POLLING_MAX_RETRIES; netnsinfo->netnspath = netnspath; - thread_add_timer_msec(zebrad.master, zebra_ns_ready_read, + thread_add_timer_msec(zrouter.master, zebra_ns_ready_read, (void *)netnsinfo, 0, NULL); } return 0; @@ -355,7 +355,7 @@ void zebra_ns_notify_init(void) safe_strerror(errno)); } zebra_netns_notify_current = thread_add_read( - zebrad.master, zebra_ns_notify_read, NULL, fd_monitor, NULL); + zrouter.master, zebra_ns_notify_read, NULL, fd_monitor, NULL); } void zebra_ns_notify_close(void) diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index e4a4adba05..1e942d6433 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -41,7 +41,7 @@ #include "zebra/zebra_errors.h" #include "zebra/zebra_ptm.h" #include "zebra/zebra_ptm_redistribute.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra_vrf.h" /* @@ -187,12 +187,12 @@ static int zebra_ptm_flush_messages(struct thread *thread) ptm_cb.ptm_sock = -1; zebra_ptm_reset_status(0); ptm_cb.t_timer = NULL; - thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, + thread_add_timer(zrouter.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); return (-1); case BUFFER_PENDING: ptm_cb.t_write = NULL; - thread_add_write(zebrad.master, zebra_ptm_flush_messages, NULL, + thread_add_write(zrouter.master, zebra_ptm_flush_messages, NULL, ptm_cb.ptm_sock, &ptm_cb.t_write); break; case BUFFER_EMPTY: @@ -213,14 +213,14 @@ static int zebra_ptm_send_message(char *data, int size) ptm_cb.ptm_sock = -1; zebra_ptm_reset_status(0); ptm_cb.t_timer = NULL; - thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, + thread_add_timer(zrouter.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); return -1; case BUFFER_EMPTY: THREAD_OFF(ptm_cb.t_write); break; case BUFFER_PENDING: - thread_add_write(zebrad.master, zebra_ptm_flush_messages, NULL, + thread_add_write(zrouter.master, zebra_ptm_flush_messages, NULL, ptm_cb.ptm_sock, &ptm_cb.t_write); break; } @@ -240,7 +240,7 @@ int zebra_ptm_connect(struct thread *t) if (ptm_cb.ptm_sock != -1) { if (init) { ptm_cb.t_read = NULL; - thread_add_read(zebrad.master, zebra_ptm_sock_read, + thread_add_read(zrouter.master, zebra_ptm_sock_read, NULL, ptm_cb.ptm_sock, &ptm_cb.t_read); zebra_bfd_peer_replay_req(); } @@ -252,7 +252,7 @@ int zebra_ptm_connect(struct thread *t) ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_MAX; ptm_cb.t_timer = NULL; - thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, + thread_add_timer(zrouter.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); } else if (ptm_cb.reconnect_time >= ZEBRA_PTM_RECONNECT_TIME_MAX) { ptm_cb.reconnect_time = ZEBRA_PTM_RECONNECT_TIME_INITIAL; @@ -657,14 +657,14 @@ int zebra_ptm_sock_read(struct thread *thread) ptm_cb.ptm_sock = -1; zebra_ptm_reset_status(0); ptm_cb.t_timer = NULL; - thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, + thread_add_timer(zrouter.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); return (-1); } ptm_cb.t_read = NULL; - thread_add_read(zebrad.master, zebra_ptm_sock_read, NULL, + thread_add_read(zrouter.master, zebra_ptm_sock_read, NULL, ptm_cb.ptm_sock, &ptm_cb.t_read); return 0; @@ -700,7 +700,7 @@ void zebra_ptm_bfd_dst_register(ZAPI_HANDLER_ARGS) if (ptm_cb.ptm_sock == -1) { ptm_cb.t_timer = NULL; - thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, + thread_add_timer(zrouter.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); return; } @@ -854,7 +854,7 @@ void zebra_ptm_bfd_dst_deregister(ZAPI_HANDLER_ARGS) if (ptm_cb.ptm_sock == -1) { ptm_cb.t_timer = NULL; - thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, + thread_add_timer(zrouter.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); return; } @@ -981,7 +981,7 @@ void zebra_ptm_bfd_client_register(ZAPI_HANDLER_ARGS) if (ptm_cb.ptm_sock == -1) { ptm_cb.t_timer = NULL; - thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, + thread_add_timer(zrouter.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); return; } @@ -1039,7 +1039,7 @@ int zebra_ptm_bfd_client_deregister(struct zserv *client) if (ptm_cb.ptm_sock == -1) { ptm_cb.t_timer = NULL; - thread_add_timer(zebrad.master, zebra_ptm_connect, NULL, + thread_add_timer(zrouter.master, zebra_ptm_connect, NULL, ptm_cb.reconnect_time, &ptm_cb.t_timer); return 0; } @@ -1276,7 +1276,7 @@ static void zebra_ptm_send_bfdd(struct stream *msg) } /* Send message to all running BFDd daemons. */ - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) { + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) { if (client->proto != ZEBRA_ROUTE_BFD) continue; @@ -1308,7 +1308,7 @@ static void zebra_ptm_send_clients(struct stream *msg) } /* Send message to all running client daemons. */ - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) { + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) { if (!IS_BFD_ENABLED_PROTOCOL(client->proto)) continue; diff --git a/zebra/zebra_ptm_redistribute.c b/zebra/zebra_ptm_redistribute.c index 3acbe3bf2c..01d5114b9f 100644 --- a/zebra/zebra_ptm_redistribute.c +++ b/zebra/zebra_ptm_redistribute.c @@ -22,7 +22,7 @@ #include "prefix.h" #include "vty.h" #include "stream.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/zapi_msg.h" #include "zebra/zebra_ptm.h" #include "zebra/zebra_ptm_redistribute.h" @@ -36,10 +36,6 @@ static int zsend_interface_bfd_update(int cmd, struct zserv *client, int blen; struct stream *s; - /* Check this client need interface information. */ - if (!vrf_bitmap_check(client->ifinfo, ifp->vrf_id)) - return 0; - s = stream_new(ZEBRA_MAX_PACKET_SIZ); zclient_create_header(s, cmd, vrf_id); @@ -76,7 +72,7 @@ void zebra_interface_bfd_update(struct interface *ifp, struct prefix *dp, struct listnode *node, *nnode; struct zserv *client; - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { if (!IS_BFD_ENABLED_PROTOCOL(client->proto)) continue; @@ -106,7 +102,7 @@ void zebra_bfd_peer_replay_req(void) struct listnode *node, *nnode; struct zserv *client; - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { if (!IS_BFD_ENABLED_PROTOCOL(client->proto)) continue; diff --git a/zebra/zebra_pw.c b/zebra/zebra_pw.c index fb9a40fe3d..2d6ec4ec01 100644 --- a/zebra/zebra_pw.c +++ b/zebra/zebra_pw.c @@ -27,7 +27,7 @@ #include "zebra/debug.h" #include "zebra/rib.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/zapi_msg.h" #include "zebra/zebra_rnh.h" #include "zebra/zebra_vrf.h" @@ -42,8 +42,6 @@ DEFINE_HOOK(pw_uninstall, (struct zebra_pw * pw), (pw)) #define MPLS_NO_LABEL MPLS_INVALID_LABEL -extern struct zebra_t zebrad; - static int zebra_pw_enabled(struct zebra_pw *); static void zebra_pw_install(struct zebra_pw *); static void zebra_pw_uninstall(struct zebra_pw *); @@ -213,7 +211,7 @@ void zebra_pw_install_failure(struct zebra_pw *pw) /* schedule to retry later */ THREAD_TIMER_OFF(pw->install_retry_timer); - thread_add_timer(zebrad.master, zebra_pw_install_retry, pw, + thread_add_timer(zrouter.master, zebra_pw_install_retry, pw, PW_INSTALL_RETRY_INTERVAL, &pw->install_retry_timer); zebra_pw_update_status(pw, PW_STATUS_DOWN); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 3a8ec0249a..73e4b981b5 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -163,7 +163,7 @@ int is_zebra_valid_kernel_table(uint32_t table_id) int is_zebra_main_routing_table(uint32_t table_id) { if ((table_id == RT_TABLE_MAIN) - || (table_id == zebrad.rtm_table_default)) + || (table_id == zrouter.rtm_table_default)) return 1; return 0; } @@ -2152,14 +2152,6 @@ static void do_nht_processing(void) } } -/* - * All meta queues have been processed. Trigger next-hop evaluation. - */ -static void meta_queue_process_complete(struct work_queue *dummy) -{ - do_nht_processing(); -} - /* Dispatch the meta queue by picking, processing and unlocking the next RN from * a non-empty sub-queue with lowest priority. wq is equal to zebra->ribq and * data @@ -2180,8 +2172,8 @@ static wq_item_status meta_queue_process(struct work_queue *dummy, void *data) queue_len, queue_limit); /* Ensure that the meta-queue is actually enqueued */ - if (work_queue_empty(zebrad.ribq)) - work_queue_add(zebrad.ribq, zebrad.mq); + if (work_queue_empty(zrouter.ribq)) + work_queue_add(zrouter.ribq, zrouter.mq); return WQ_QUEUE_BLOCKED; } @@ -2270,7 +2262,7 @@ void rib_queue_add(struct route_node *rn) return; } - if (zebrad.ribq == NULL) { + if (zrouter.ribq == NULL) { flog_err(EC_ZEBRA_WQ_NONEXISTENT, "%s: work_queue does not exist!", __func__); return; @@ -2284,10 +2276,10 @@ void rib_queue_add(struct route_node *rn) * holder, if necessary, then push the work into it in any case. * This semantics was introduced after 0.99.9 release. */ - if (work_queue_empty(zebrad.ribq)) - work_queue_add(zebrad.ribq, zebrad.mq); + if (work_queue_empty(zrouter.ribq)) + work_queue_add(zrouter.ribq, zrouter.mq); - rib_meta_queue_add(zebrad.mq, rn); + rib_meta_queue_add(zrouter.mq, rn); return; } @@ -2321,27 +2313,25 @@ void meta_queue_free(struct meta_queue *mq) } /* initialise zebra rib work queue */ -static void rib_queue_init(struct zebra_t *zebra) +static void rib_queue_init(void) { - assert(zebra); - - if (!(zebra->ribq = - work_queue_new(zebra->master, "route_node processing"))) { + if (!(zrouter.ribq = work_queue_new(zrouter.master, + "route_node processing"))) { flog_err(EC_ZEBRA_WQ_NONEXISTENT, "%s: could not initialise work queue!", __func__); return; } /* fill in the work queue spec */ - zebra->ribq->spec.workfunc = &meta_queue_process; - zebra->ribq->spec.errorfunc = NULL; - zebra->ribq->spec.completion_func = &meta_queue_process_complete; + zrouter.ribq->spec.workfunc = &meta_queue_process; + zrouter.ribq->spec.errorfunc = NULL; + zrouter.ribq->spec.completion_func = NULL; /* XXX: TODO: These should be runtime configurable via vty */ - zebra->ribq->spec.max_retries = 3; - zebra->ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME; - zebra->ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME; + zrouter.ribq->spec.max_retries = 3; + zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME; + zrouter.ribq->spec.retry = ZEBRA_RIB_PROCESS_RETRY_TIME; - if (!(zebra->mq = meta_queue_new())) { + if (!(zrouter.mq = meta_queue_new())) { flog_err(EC_ZEBRA_WQ_NONEXISTENT, "%s: could not initialise meta queue!", __func__); return; @@ -3313,7 +3303,7 @@ static int rib_dplane_results(struct dplane_ctx_q *ctxlist) pthread_mutex_unlock(&dplane_mutex); /* Ensure event is signalled to zebra main pthread */ - thread_add_event(zebrad.master, rib_process_dplane_results, NULL, 0, + thread_add_event(zrouter.master, rib_process_dplane_results, NULL, 0, &t_dplane); return 0; @@ -3322,7 +3312,7 @@ static int rib_dplane_results(struct dplane_ctx_q *ctxlist) /* Routing information base initialize. */ void rib_init(void) { - rib_queue_init(&zebrad); + rib_queue_init(); /* Init dataplane, and register for results */ pthread_mutex_init(&dplane_mutex, NULL); diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index bb323e33bb..7d72583dd8 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -33,7 +33,7 @@ #include "vrf.h" #include "frrstr.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" #include "zebra/redistribute.h" #include "zebra/debug.h" #include "zebra/zebra_rnh.h" @@ -1778,7 +1778,7 @@ static void zebra_route_map_mark_update(const char *rmap_name) /* rmap_update_timer of 0 means don't do route updates */ if (zebra_rmap_update_timer && !zebra_t_rmap_update) { zebra_t_rmap_update = NULL; - thread_add_timer(zebrad.master, zebra_route_map_update_timer, + thread_add_timer(zrouter.master, zebra_route_map_update_timer, NULL, zebra_rmap_update_timer, &zebra_t_rmap_update); } diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c index 3e94d6bca8..c3b861c242 100644 --- a/zebra/zebra_router.c +++ b/zebra/zebra_router.c @@ -188,6 +188,9 @@ void zebra_router_terminate(void) zebra_router_free_table(zrt); } + work_queue_free_and_null(&zrouter.ribq); + meta_queue_free(zrouter.mq); + zebra_vxlan_disable(); zebra_mlag_terminate(); @@ -206,6 +209,9 @@ void zebra_router_init(void) { zrouter.sequence_num = 0; + zrouter.rtm_table_default = 0; + zrouter.packets_to_process = ZEBRA_ZAPI_PACKETS_TO_PROCESS; + zebra_vxlan_init(); zebra_mlag_init(); diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index f63dcd984e..fb28495917 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -22,6 +22,8 @@ #ifndef __ZEBRA_ROUTER_H__ #define __ZEBRA_ROUTER_H__ +#include "lib/mlag.h" + #include "zebra/zebra_ns.h" /* @@ -44,7 +46,24 @@ RB_HEAD(zebra_router_table_head, zebra_router_table); RB_PROTOTYPE(zebra_router_table_head, zebra_router_table, zebra_router_table_entry, zebra_router_table_entry_compare) +struct zebra_mlag_info { + /* Role this zebra router is playing */ + enum mlag_role role; + + /* The peerlink being used for mlag */ + char *peerlink; + ifindex_t peerlink_ifindex; + + /* The system mac being used */ + struct ethaddr mac; +}; + struct zebra_router { + /* Thread master */ + struct thread_master *master; + + /* Lists of clients who have connected to us */ + struct list *client_list; struct zebra_router_table_head tables; @@ -65,6 +84,26 @@ struct zebra_router { /* A sequence number used for tracking routes */ _Atomic uint32_t sequence_num; + + /* The default table used for this router */ + uint32_t rtm_table_default; + + /* rib work queue */ +#define ZEBRA_RIB_PROCESS_HOLD_TIME 10 +#define ZEBRA_RIB_PROCESS_RETRY_TIME 1 + struct work_queue *ribq; + + /* Meta Queue Information */ + struct meta_queue *mq; + + /* LSP work queue */ + struct work_queue *lsp_process_q; + +#define ZEBRA_ZAPI_PACKETS_TO_PROCESS 1000 + _Atomic uint32_t packets_to_process; + + /* Mlag information for the router */ + struct zebra_mlag_info mlag_info; }; extern struct zebra_router zrouter; diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index f1458cb138..d18305495b 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -42,8 +42,6 @@ #include "zebra/zebra_netns_notify.h" #include "zebra/zebra_routemap.h" -extern struct zebra_t zebrad; - static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi, safi_t safi); static void zebra_rnhtable_node_cleanup(struct route_table *table, @@ -58,7 +56,7 @@ static void zebra_vrf_add_update(struct zebra_vrf *zvrf) if (IS_ZEBRA_DEBUG_EVENT) zlog_debug("MESSAGE: ZEBRA_VRF_ADD %s", zvrf_name(zvrf)); - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) zsend_vrf_add(client, zvrf); } @@ -70,7 +68,7 @@ static void zebra_vrf_delete_update(struct zebra_vrf *zvrf) if (IS_ZEBRA_DEBUG_EVENT) zlog_debug("MESSAGE: ZEBRA_VRF_DELETE %s", zvrf_name(zvrf)); - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) zsend_vrf_delete(client, zvrf); } @@ -189,13 +187,13 @@ static int zebra_vrf_disable(struct vrf *vrf) struct route_node *rnode; rib_dest_t *dest; - for (ALL_LIST_ELEMENTS(zebrad.mq->subq[i], lnode, nnode, + for (ALL_LIST_ELEMENTS(zrouter.mq->subq[i], lnode, nnode, rnode)) { dest = rib_dest_from_rnode(rnode); if (dest && rib_dest_vrf(dest) == zvrf) { route_unlock_node(rnode); - list_delete_node(zebrad.mq->subq[i], lnode); - zebrad.mq->size--; + list_delete_node(zrouter.mq->subq[i], lnode); + zrouter.mq->size--; } } } @@ -241,13 +239,13 @@ static int zebra_vrf_delete(struct vrf *vrf) struct route_node *rnode; rib_dest_t *dest; - for (ALL_LIST_ELEMENTS(zebrad.mq->subq[i], lnode, nnode, + for (ALL_LIST_ELEMENTS(zrouter.mq->subq[i], lnode, nnode, rnode)) { dest = rib_dest_from_rnode(rnode); if (dest && rib_dest_vrf(dest) == zvrf) { route_unlock_node(rnode); - list_delete_node(zebrad.mq->subq[i], lnode); - zebrad.mq->size--; + list_delete_node(zrouter.mq->subq[i], lnode); + zrouter.mq->size--; } } } @@ -326,14 +324,14 @@ struct route_table *zebra_vrf_table_with_table_id(afi_t afi, safi_t safi, if (vrf_id == VRF_DEFAULT) { if (table_id == RT_TABLE_MAIN - || table_id == zebrad.rtm_table_default) + || table_id == zrouter.rtm_table_default) table = zebra_vrf_table(afi, safi, vrf_id); else table = zebra_vrf_other_route_table(afi, table_id, vrf_id); } else if (vrf_is_backend_netns()) { if (table_id == RT_TABLE_MAIN - || table_id == zebrad.rtm_table_default) + || table_id == zrouter.rtm_table_default) table = zebra_vrf_table(afi, safi, vrf_id); else table = zebra_vrf_other_route_table(afi, table_id, @@ -439,9 +437,9 @@ struct route_table *zebra_vrf_other_route_table(afi_t afi, uint32_t table_id, return NULL; if ((table_id != RT_TABLE_MAIN) - && (table_id != zebrad.rtm_table_default)) { + && (table_id != zrouter.rtm_table_default)) { if (zvrf->table_id == RT_TABLE_MAIN || - zvrf->table_id == zebrad.rtm_table_default) { + zvrf->table_id == zrouter.rtm_table_default) { /* this VRF use default table * so in all cases, it does not use specific table * so it is possible to configure tables in this VRF diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 14288d7bc4..1833257863 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -174,7 +174,7 @@ static char re_status_output_char(struct route_entry *re, struct nexthop *nhop) if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED)) return 'q'; - return 'f'; + return 'r'; } if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED)) @@ -2456,7 +2456,7 @@ DEFUN_HIDDEN (zebra_packet_process, { uint32_t packets = strtoul(argv[2]->arg, NULL, 10); - atomic_store_explicit(&zebrad.packets_to_process, packets, + atomic_store_explicit(&zrouter.packets_to_process, packets, memory_order_relaxed); return CMD_SUCCESS; @@ -2470,7 +2470,7 @@ DEFUN_HIDDEN (no_zebra_packet_process, "Zapi Protocol\n" "Number of packets to process before relinquishing thread\n") { - atomic_store_explicit(&zebrad.packets_to_process, + atomic_store_explicit(&zrouter.packets_to_process, ZEBRA_ZAPI_PACKETS_TO_PROCESS, memory_order_relaxed); @@ -2485,7 +2485,7 @@ DEFUN_HIDDEN (zebra_workqueue_timer, "Time in milliseconds\n") { uint32_t timer = strtoul(argv[2]->arg, NULL, 10); - zebrad.ribq->spec.hold = timer; + zrouter.ribq->spec.hold = timer; return CMD_SUCCESS; } @@ -2498,7 +2498,7 @@ DEFUN_HIDDEN (no_zebra_workqueue_timer, "Work Queue\n" "Time in milliseconds\n") { - zebrad.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME; + zrouter.ribq->spec.hold = ZEBRA_RIB_PROCESS_HOLD_TIME; return CMD_SUCCESS; } @@ -2548,12 +2548,12 @@ static int config_write_protocol(struct vty *vty) if (zebra_rnh_ipv6_default_route) vty_out(vty, "ipv6 nht resolve-via-default\n"); - if (zebrad.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME) - vty_out(vty, "zebra work-queue %u\n", zebrad.ribq->spec.hold); + if (zrouter.ribq->spec.hold != ZEBRA_RIB_PROCESS_HOLD_TIME) + vty_out(vty, "zebra work-queue %u\n", zrouter.ribq->spec.hold); - if (zebrad.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS) + if (zrouter.packets_to_process != ZEBRA_ZAPI_PACKETS_TO_PROCESS) vty_out(vty, "zebra zapi-packets %u\n", - zebrad.packets_to_process); + zrouter.packets_to_process); enum multicast_mode ipv4_multicast_mode = multicast_mode_ipv4_get(); @@ -2581,7 +2581,7 @@ DEFUN (show_table, SHOW_STR "default routing table to use for all clients\n") { - vty_out(vty, "table %d\n", zebrad.rtm_table_default); + vty_out(vty, "table %d\n", zrouter.rtm_table_default); return CMD_SUCCESS; } @@ -2591,7 +2591,7 @@ DEFUN (config_table, "Configure target kernel routing table\n" "TABLE integer\n") { - zebrad.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10); + zrouter.rtm_table_default = strtol(argv[1]->arg, (char **)0, 10); return CMD_SUCCESS; } @@ -2602,7 +2602,7 @@ DEFUN (no_config_table, "Configure target kernel routing table\n" "TABLE integer\n") { - zebrad.rtm_table_default = 0; + zrouter.rtm_table_default = 0; return CMD_SUCCESS; } #endif @@ -2850,8 +2850,8 @@ DEFUN (zebra_show_routing_tables_summary, /* Table configuration write function. */ static int config_write_table(struct vty *vty) { - if (zebrad.rtm_table_default) - vty_out(vty, "table %d\n", zebrad.rtm_table_default); + if (zrouter.rtm_table_default) + vty_out(vty, "table %d\n", zrouter.rtm_table_default); return 0; } diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 49af4a9205..069da82850 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -50,7 +50,7 @@ #include "zebra/zebra_vrf.h" #include "zebra/zebra_vxlan.h" #include "zebra/zebra_vxlan_private.h" -#include "zebra/zserv.h" +#include "zebra/zebra_router.h" DEFINE_MTYPE_STATIC(ZEBRA, HOST_PREFIX, "host prefix"); DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash"); @@ -100,6 +100,7 @@ static int zvni_neigh_send_del_to_client(vni_t vni, struct ipaddr *ip, uint8_t flags, int state); static int zvni_neigh_install(zebra_vni_t *zvni, zebra_neigh_t *n); static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n); +static int zvni_neigh_probe(zebra_vni_t *zvni, zebra_neigh_t *n); static zebra_vni_t *zvni_from_svi(struct interface *ifp, struct interface *br_if); static struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if); @@ -510,7 +511,7 @@ static void zebra_vxlan_dup_addr_detect_for_mac(struct zebra_vrf *zvrf, sizeof(buf)), mac->flags, zvrf->dad_freeze_time); - thread_add_timer(zebrad.master, + thread_add_timer(zrouter.master, zebra_vxlan_dad_mac_auto_recovery_exp, mac, zvrf->dad_freeze_time, &mac->dad_mac_auto_recovery_timer); @@ -643,7 +644,7 @@ static void zebra_vxlan_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf, ipaddr2str(&nbr->ip, buf1, sizeof(buf1)), nbr->flags, zvrf->dad_freeze_time); - thread_add_timer(zebrad.master, + thread_add_timer(zrouter.master, zebra_vxlan_dad_ip_auto_recovery_exp, nbr, zvrf->dad_freeze_time, &nbr->dad_ip_auto_recovery_timer); @@ -2404,6 +2405,18 @@ static void zvni_process_neigh_on_remote_mac_del(zebra_vni_t *zvni, /* NOTE: Currently a NO-OP. */ } +static void zvni_probe_neigh_on_mac_add(zebra_vni_t *zvni, zebra_mac_t *zmac) +{ + zebra_neigh_t *nbr = NULL; + struct listnode *node = NULL; + + for (ALL_LIST_ELEMENTS_RO(zmac->neigh_list, node, nbr)) { + if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_LOCAL) && + IS_ZEBRA_NEIGH_INACTIVE(nbr)) + zvni_neigh_probe(zvni, nbr); + } +} + /* * Inform BGP about local neighbor addition. */ @@ -2501,6 +2514,32 @@ static int zvni_neigh_uninstall(zebra_vni_t *zvni, zebra_neigh_t *n) } /* + * Probe neighbor from the kernel. + */ +static int zvni_neigh_probe(zebra_vni_t *zvni, zebra_neigh_t *n) +{ + struct zebra_if *zif; + struct zebra_l2info_vxlan *vxl; + struct interface *vlan_if; + + zif = zvni->vxlan_if->info; + if (!zif) + return -1; + vxl = &zif->l2info.vxl; + + vlan_if = zvni_map_to_svi(vxl->access_vlan, zif->brslave_info.br_if); + if (!vlan_if) + return -1; + +#ifdef GNU_LINUX + return kernel_upd_neigh(vlan_if, &n->ip, &n->emac, + 0, NUD_PROBE); +#else + return 0; +#endif +} + +/* * Install neighbor hash entry - called upon access VLAN change. */ static void zvni_install_neigh_hash(struct hash_backet *backet, void *ctxt) @@ -5329,6 +5368,8 @@ static void process_remote_macip_add(vni_t vni, zvni_neigh_install(zvni, n); } + zvni_probe_neigh_on_mac_add(zvni, mac); + /* Update seq number. */ n->rem_seq = seq; } @@ -7029,6 +7070,7 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp, zebra_vni_t *zvni = NULL; zebra_mac_t *zmac = NULL; zebra_l3vni_t *zl3vni = NULL; + struct zebra_vrf *zvrf; /* check if this is a remote neigh entry corresponding to remote * next-hop @@ -7081,9 +7123,23 @@ int zebra_vxlan_handle_kernel_neigh_del(struct interface *ifp, return 0; } + zvrf = vrf_info_lookup(zvni->vxlan_if->vrf_id); + if (!zvrf) { + zlog_debug("%s: VNI %u vrf lookup failed.", + __PRETTY_FUNCTION__, zvni->vni); + return -1; + } + + /* In case of feeze action, if local neigh is in duplicate state, + * Mark the Neigh as inactive before sending delete request to BGPd, + * If BGPd has remote entry, it will re-install + */ + if (zvrf->dad_freeze && + CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)) + ZEBRA_NEIGH_SET_INACTIVE(n); + /* Remove neighbor from BGP. */ - zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, - 0, n->state); + zvni_neigh_send_del_to_client(zvni->vni, &n->ip, &n->emac, 0, n->state); /* Delete this neighbor entry. */ zvni_neigh_del(zvni, n); diff --git a/zebra/zserv.c b/zebra/zserv.c index 766dd54fb3..ad052d6a70 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -61,12 +61,16 @@ #include "zebra/zapi_msg.h" /* for zserv_handle_commands */ #include "zebra/zebra_vrf.h" /* for zebra_vrf_lookup_by_id, zvrf */ #include "zebra/zserv.h" /* for zserv */ +#include "zebra/zebra_router.h" #include "zebra/zebra_errors.h" /* for error messages */ /* clang-format on */ /* privileges */ extern struct zebra_privs_t zserv_privs; +/* The listener socket for clients connecting to us */ +static int zsock; + /* * Client thread events. * @@ -312,7 +316,7 @@ static int zserv_read(struct thread *thread) uint32_t p2p; struct zmsghdr hdr; - p2p_orig = atomic_load_explicit(&zebrad.packets_to_process, + p2p_orig = atomic_load_explicit(&zrouter.packets_to_process, memory_order_relaxed); cache = stream_fifo_new(); p2p = p2p_orig; @@ -481,9 +485,9 @@ static void zserv_client_event(struct zserv *client, * with the message is executed. This proceeds until there are no more messages, * an error occurs, or the processing limit is reached. * - * The client's I/O thread can push at most zebrad.packets_to_process messages + * The client's I/O thread can push at most zrouter.packets_to_process messages * onto the input buffer before notifying us there are packets to read. As long - * as we always process zebrad.packets_to_process messages here, then we can + * as we always process zrouter.packets_to_process messages here, then we can * rely on the read thread to handle queuing this task enough times to process * everything on the input queue. */ @@ -492,7 +496,7 @@ static int zserv_process_messages(struct thread *thread) struct zserv *client = THREAD_ARG(thread); struct stream *msg; struct stream_fifo *cache = stream_fifo_new(); - uint32_t p2p = zebrad.packets_to_process; + uint32_t p2p = zrouter.packets_to_process; bool need_resched = false; pthread_mutex_lock(&client->ibuf_mtx); @@ -622,7 +626,6 @@ static void zserv_client_free(struct zserv *client) vrf_bitmap_free(client->redist_default[afi]); } - vrf_bitmap_free(client->ifinfo); vrf_bitmap_free(client->ridinfo); XFREE(MTYPE_TMP, client); @@ -637,7 +640,7 @@ void zserv_close_client(struct zserv *client) zlog_debug("Closing client '%s'", zebra_route_string(client->proto)); - thread_cancel_event(zebrad.master, client); + thread_cancel_event(zrouter.master, client); THREAD_OFF(client->t_cleanup); THREAD_OFF(client->t_process); @@ -646,7 +649,7 @@ void zserv_close_client(struct zserv *client) client->pthread = NULL; /* remove from client list */ - listnode_delete(zebrad.client_list, client); + listnode_delete(zrouter.client_list, client); /* delete client */ zserv_client_free(client); @@ -695,7 +698,7 @@ static struct zserv *zserv_client_create(int sock) client->wb = buffer_new(0); /* Set table number. */ - client->rtm_table = zebrad.rtm_table_default; + client->rtm_table = zrouter.rtm_table_default; atomic_store_explicit(&client->connect_time, (uint32_t) monotime(NULL), memory_order_relaxed); @@ -706,14 +709,13 @@ static struct zserv *zserv_client_create(int sock) client->redist[afi][i] = vrf_bitmap_init(); client->redist_default[afi] = vrf_bitmap_init(); } - client->ifinfo = vrf_bitmap_init(); client->ridinfo = vrf_bitmap_init(); /* by default, it's not a synchronous client */ client->is_synchronous = 0; /* Add this client to linked list. */ - listnode_add(zebrad.client_list, client); + listnode_add(zrouter.client_list, client); struct frr_pthread_attr zclient_pthr_attrs = { .start = frr_pthread_attr_default.start, @@ -783,16 +785,16 @@ void zserv_start(char *path) old_mask = umask(0077); /* Make UNIX domain socket. */ - zebrad.sock = socket(sa.ss_family, SOCK_STREAM, 0); - if (zebrad.sock < 0) { + zsock = socket(sa.ss_family, SOCK_STREAM, 0); + if (zsock < 0) { flog_err_sys(EC_LIB_SOCKET, "Can't create zserv socket: %s", safe_strerror(errno)); return; } if (sa.ss_family != AF_UNIX) { - sockopt_reuseaddr(zebrad.sock); - sockopt_reuseport(zebrad.sock); + sockopt_reuseaddr(zsock); + sockopt_reuseport(zsock); } else { struct sockaddr_un *suna = (struct sockaddr_un *)&sa; if (suna->sun_path[0]) @@ -800,28 +802,28 @@ void zserv_start(char *path) } frr_elevate_privs(&zserv_privs) { - setsockopt_so_recvbuf(zebrad.sock, 1048576); - setsockopt_so_sendbuf(zebrad.sock, 1048576); + setsockopt_so_recvbuf(zsock, 1048576); + setsockopt_so_sendbuf(zsock, 1048576); } frr_elevate_privs((sa.ss_family != AF_UNIX) ? &zserv_privs : NULL) { - ret = bind(zebrad.sock, (struct sockaddr *)&sa, sa_len); + ret = bind(zsock, (struct sockaddr *)&sa, sa_len); } if (ret < 0) { flog_err_sys(EC_LIB_SOCKET, "Can't bind zserv socket on %s: %s", path, safe_strerror(errno)); - close(zebrad.sock); - zebrad.sock = -1; + close(zsock); + zsock = -1; return; } - ret = listen(zebrad.sock, 5); + ret = listen(zsock, 5); if (ret < 0) { flog_err_sys(EC_LIB_SOCKET, "Can't listen to zserv socket %s: %s", path, safe_strerror(errno)); - close(zebrad.sock); - zebrad.sock = -1; + close(zsock); + zsock = -1; return; } @@ -834,15 +836,15 @@ void zserv_event(struct zserv *client, enum zserv_event event) { switch (event) { case ZSERV_ACCEPT: - thread_add_read(zebrad.master, zserv_accept, NULL, zebrad.sock, + thread_add_read(zrouter.master, zserv_accept, NULL, zsock, NULL); break; case ZSERV_PROCESS_MESSAGES: - thread_add_event(zebrad.master, zserv_process_messages, client, + thread_add_event(zrouter.master, zserv_process_messages, client, 0, &client->t_process); break; case ZSERV_HANDLE_CLIENT_FAIL: - thread_add_event(zebrad.master, zserv_handle_client_fail, + thread_add_event(zrouter.master, zserv_handle_client_fail, client, 0, &client->t_cleanup); } } @@ -1002,7 +1004,7 @@ struct zserv *zserv_find_client(uint8_t proto, unsigned short instance) struct listnode *node, *nnode; struct zserv *client; - for (ALL_LIST_ELEMENTS(zebrad.client_list, node, nnode, client)) { + for (ALL_LIST_ELEMENTS(zrouter.client_list, node, nnode, client)) { if (client->proto == proto && client->instance == instance) return client; } @@ -1021,7 +1023,7 @@ DEFUN (show_zebra_client, struct listnode *node; struct zserv *client; - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) zebra_show_client_detail(vty, client); return CMD_SUCCESS; @@ -1044,7 +1046,7 @@ DEFUN (show_zebra_client_summary, vty_out(vty, "--------------------------------------------------------------------------------\n"); - for (ALL_LIST_ELEMENTS_RO(zebrad.client_list, node, client)) + for (ALL_LIST_ELEMENTS_RO(zrouter.client_list, node, client)) zebra_show_client_brief(vty, client); vty_out(vty, "Routes column shows (added+updated)/deleted\n"); @@ -1067,10 +1069,10 @@ void zserv_read_file(char *input) void zserv_init(void) { /* Client list init. */ - zebrad.client_list = list_new(); + zrouter.client_list = list_new(); /* Misc init. */ - zebrad.sock = -1; + zsock = -1; install_element(ENABLE_NODE, &show_zebra_client_cmd); install_element(ENABLE_NODE, &show_zebra_client_summary_cmd); diff --git a/zebra/zserv.h b/zebra/zserv.h index 041485cdc2..ac016e65f3 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -89,9 +89,6 @@ struct zserv { /* Redistribute default route flag. */ vrf_bitmap_t redist_default[AFI_MAX]; - /* Interface information. */ - vrf_bitmap_t ifinfo; - /* Router-id information. */ vrf_bitmap_t ridinfo; @@ -173,31 +170,6 @@ struct zserv { DECLARE_HOOK(zserv_client_connect, (struct zserv *client), (client)); DECLARE_KOOH(zserv_client_close, (struct zserv *client), (client)); -/* Zebra instance */ -struct zebra_t { - /* Thread master */ - struct thread_master *master; - struct list *client_list; - - /* Socket */ - int sock; - - /* default table */ - uint32_t rtm_table_default; - -/* rib work queue */ -#define ZEBRA_RIB_PROCESS_HOLD_TIME 10 -#define ZEBRA_RIB_PROCESS_RETRY_TIME 1 - struct work_queue *ribq; - struct meta_queue *mq; - - /* LSP work queue */ - struct work_queue *lsp_process_q; - -#define ZEBRA_ZAPI_PACKETS_TO_PROCESS 1000 - _Atomic uint32_t packets_to_process; -}; -extern struct zebra_t zebrad; extern unsigned int multipath_num; /* |
