diff options
39 files changed, 815 insertions, 448 deletions
diff --git a/babeld/.gitignore b/babeld/.gitignore index 71ef6786c7..abb4d9321a 100644 --- a/babeld/.gitignore +++ b/babeld/.gitignore @@ -5,3 +5,4 @@ !Makefile !subdir.am !.gitignore +*_clippy.c diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 00fb58e576..cc50898017 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -42,6 +42,10 @@ THE SOFTWARE. #include "xroute.h" #include "babel_errors.h" +#ifndef VTYSH_EXTRACT_PL +#include "babeld/babel_interface_clippy.c" +#endif + DEFINE_MTYPE_STATIC(BABELD, BABEL_IF, "Babel Interface"); #define IS_ENABLE(ifp) (babel_enable_if_lookup(ifp->name) >= 0) @@ -307,9 +311,10 @@ babel_set_wired_internal(babel_interface_nfo *babel_ifp, int wired) } /* [Interface Command] Tell the interface is wire. */ -DEFUN (babel_set_wired, +DEFPY (babel_set_wired, babel_set_wired_cmd, - "babel wired", + "[no] babel wired", + NO_STR "Babel interface commands\n" "Enable wired optimizations\n") { @@ -319,14 +324,15 @@ DEFUN (babel_set_wired, babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); - babel_set_wired_internal(babel_ifp, 1); + babel_set_wired_internal(babel_ifp, no ? 0 : 1); return CMD_SUCCESS; } /* [Interface Command] Tell the interface is wireless (default). */ -DEFUN (babel_set_wireless, +DEFPY (babel_set_wireless, babel_set_wireless_cmd, - "babel wireless", + "[no] babel wireless", + NO_STR "Babel interface commands\n" "Disable wired optimizations (assume wireless)\n") { @@ -336,34 +342,17 @@ DEFUN (babel_set_wireless, babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); - babel_set_wired_internal(babel_ifp, 0); + babel_set_wired_internal(babel_ifp, no ? 1 : 0); return CMD_SUCCESS; } /* [Interface Command] Enable split horizon. */ -DEFUN (babel_split_horizon, +DEFPY (babel_split_horizon, babel_split_horizon_cmd, - "babel split-horizon", - "Babel interface commands\n" - "Enable split horizon processing\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - babel_interface_nfo *babel_ifp; - - babel_ifp = babel_get_if_nfo(ifp); - - assert (babel_ifp != NULL); - babel_ifp->flags |= BABEL_IF_SPLIT_HORIZON; - return CMD_SUCCESS; -} - -/* [Interface Command] Disable split horizon (default). */ -DEFUN (no_babel_split_horizon, - no_babel_split_horizon_cmd, - "no babel split-horizon", + "[no] babel split-horizon", NO_STR "Babel interface commands\n" - "Disable split horizon processing\n") + "Enable split horizon processing\n") { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; @@ -371,213 +360,180 @@ DEFUN (no_babel_split_horizon, babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); - babel_ifp->flags &= ~BABEL_IF_SPLIT_HORIZON; + if (!no) + SET_FLAG(babel_ifp->flags, BABEL_IF_SPLIT_HORIZON); + else + UNSET_FLAG(babel_ifp->flags, BABEL_IF_SPLIT_HORIZON); return CMD_SUCCESS; } /* [Interface Command]. */ -DEFUN (babel_set_hello_interval, +DEFPY (babel_set_hello_interval, babel_set_hello_interval_cmd, - "babel hello-interval (20-655340)", + "[no] babel hello-interval (20-655340)", + NO_STR "Babel interface commands\n" "Time between scheduled hellos\n" "Milliseconds\n") { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; - int interval; - - interval = strtoul(argv[2]->arg, NULL, 10); babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); - babel_ifp->hello_interval = interval; + babel_ifp->hello_interval = no ? + BABEL_DEFAULT_HELLO_INTERVAL : hello_interval; return CMD_SUCCESS; } /* [Interface Command]. */ -DEFUN (babel_set_update_interval, +DEFPY (babel_set_update_interval, babel_set_update_interval_cmd, - "babel update-interval (20-655340)", + "[no] babel update-interval (20-655340)", + NO_STR "Babel interface commands\n" "Time between scheduled updates\n" "Milliseconds\n") { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; - int interval; - - interval = strtoul(argv[2]->arg, NULL, 10); babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); - babel_ifp->update_interval = interval; + babel_ifp->update_interval = no ? + BABEL_DEFAULT_UPDATE_INTERVAL : update_interval; return CMD_SUCCESS; } -DEFUN (babel_set_rxcost, +DEFPY (babel_set_rxcost, babel_set_rxcost_cmd, - "babel rxcost (1-65534)", + "[no] babel rxcost (1-65534)", + NO_STR "Babel interface commands\n" "Rxcost multiplier\n" "Units\n") { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; - int rxcost; - - rxcost = strtoul(argv[2]->arg, NULL, 10); babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); + if (no) + rxcost = CHECK_FLAG(babel_ifp->flags, BABEL_IF_WIRED) ? + BABEL_DEFAULT_RXCOST_WIRED : BABEL_DEFAULT_RXCOST_WIRELESS; + babel_ifp->cost = rxcost; return CMD_SUCCESS; } -DEFUN (babel_set_rtt_decay, +DEFPY (babel_set_rtt_decay, babel_set_rtt_decay_cmd, - "babel rtt-decay (1-256)", + "[no] babel rtt-decay (1-256)", + NO_STR "Babel interface commands\n" "Decay factor for exponential moving average of RTT samples\n" "Units of 1/256\n") { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; - int decay; - - decay = strtoul(argv[2]->arg, NULL, 10); babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); - babel_ifp->rtt_decay = decay; + babel_ifp->rtt_decay = no ? BABEL_DEFAULT_RTT_DECAY : rtt_decay; return CMD_SUCCESS; } -DEFUN (babel_set_rtt_min, +DEFPY (babel_set_rtt_min, babel_set_rtt_min_cmd, - "babel rtt-min (1-65535)", + "[no] babel rtt-min (1-65535)", + NO_STR "Babel interface commands\n" "Minimum RTT starting for increasing cost\n" "Milliseconds\n") { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; - int rtt; - - rtt = strtoul(argv[2]->arg, NULL, 10); babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); /* The value is entered in milliseconds but stored as microseconds. */ - babel_ifp->rtt_min = rtt * 1000; + babel_ifp->rtt_min = no ? BABEL_DEFAULT_RTT_MIN : rtt_min * 1000; return CMD_SUCCESS; } -DEFUN (babel_set_rtt_max, +DEFPY (babel_set_rtt_max, babel_set_rtt_max_cmd, - "babel rtt-max (1-65535)", + "[no] babel rtt-max (1-65535)", + NO_STR "Babel interface commands\n" "Maximum RTT\n" "Milliseconds\n") { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; - int rtt; - - rtt = strtoul(argv[2]->arg, NULL, 10); babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); /* The value is entered in milliseconds but stored as microseconds. */ - babel_ifp->rtt_max = rtt * 1000; + babel_ifp->rtt_max = no ? BABEL_DEFAULT_RTT_MAX : rtt_max * 1000; return CMD_SUCCESS; } -DEFUN (babel_set_max_rtt_penalty, +DEFPY (babel_set_max_rtt_penalty, babel_set_max_rtt_penalty_cmd, - "babel max-rtt-penalty (0-65535)", + "[no] babel max-rtt-penalty (0-65535)", + NO_STR "Babel interface commands\n" "Maximum additional cost due to RTT\n" "Milliseconds\n") { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; - int penalty; - - penalty = strtoul(argv[2]->arg, NULL, 10); babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); - babel_ifp->max_rtt_penalty = penalty; + babel_ifp->max_rtt_penalty = no ? + BABEL_DEFAULT_MAX_RTT_PENALTY : max_rtt_penalty; return CMD_SUCCESS; } -DEFUN (babel_set_enable_timestamps, +DEFPY (babel_set_enable_timestamps, babel_set_enable_timestamps_cmd, - "babel enable-timestamps", - "Babel interface commands\n" - "Enable timestamps\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - babel_interface_nfo *babel_ifp; - - babel_ifp = babel_get_if_nfo(ifp); - assert (babel_ifp != NULL); - - babel_ifp->flags |= BABEL_IF_TIMESTAMPS; - return CMD_SUCCESS; -} - -DEFUN (no_babel_set_enable_timestamps, - no_babel_set_enable_timestamps_cmd, - "no babel enable-timestamps", + "[no] babel enable-timestamps", NO_STR "Babel interface commands\n" - "Disable timestamps\n") + "Enable timestamps\n") { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); - - babel_ifp->flags &= ~BABEL_IF_TIMESTAMPS; + if (!no) + SET_FLAG(babel_ifp->flags, BABEL_IF_TIMESTAMPS); + else + UNSET_FLAG(babel_ifp->flags, BABEL_IF_TIMESTAMPS); return CMD_SUCCESS; } -DEFUN (babel_set_channel, +DEFPY (babel_set_channel, babel_set_channel_cmd, - "babel channel (1-254)", - "Babel interface commands\n" - "Channel number for diversity routing\n" - "Number\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - babel_interface_nfo *babel_ifp; - int channel; - - channel = strtoul(argv[2]->arg, NULL, 10); - - babel_ifp = babel_get_if_nfo(ifp); - assert (babel_ifp != NULL); - - babel_ifp->channel = channel; - return CMD_SUCCESS; -} - -DEFUN (babel_set_channel_interfering, - babel_set_channel_interfering_cmd, - "babel channel interfering", + "[no] babel channel <(1-254)$ch|interfering$interfering|" + "noninterfering$noninterfering>", + NO_STR "Babel interface commands\n" "Channel number for diversity routing\n" - "Mark channel as interfering\n") + "Number\n" + "Mark channel as interfering\n" + "Mark channel as noninterfering\n" + ) { VTY_DECLVAR_CONTEXT(interface, ifp); babel_interface_nfo *babel_ifp; @@ -585,24 +541,15 @@ DEFUN (babel_set_channel_interfering, babel_ifp = babel_get_if_nfo(ifp); assert (babel_ifp != NULL); - babel_ifp->channel = BABEL_IF_CHANNEL_INTERFERING; - return CMD_SUCCESS; -} - -DEFUN (babel_set_channel_noninterfering, - babel_set_channel_noninterfering_cmd, - "babel channel noninterfering", - "Babel interface commands\n" - "Channel number for diversity routing\n" - "Mark channel as noninterfering\n") -{ - VTY_DECLVAR_CONTEXT(interface, ifp); - babel_interface_nfo *babel_ifp; - - babel_ifp = babel_get_if_nfo(ifp); - assert (babel_ifp != NULL); + if (no) + ch = CHECK_FLAG(babel_ifp->flags, BABEL_IF_WIRED) ? + BABEL_IF_CHANNEL_NONINTERFERING : BABEL_IF_CHANNEL_INTERFERING; + else if (interfering) + ch = BABEL_IF_CHANNEL_INTERFERING; + else if (noninterfering) + ch = BABEL_IF_CHANNEL_NONINTERFERING; - babel_ifp->channel = BABEL_IF_CHANNEL_NONINTERFERING; + babel_ifp->channel = ch; return CMD_SUCCESS; } @@ -1239,7 +1186,6 @@ babel_if_init(void) install_element(BABEL_NODE, &babel_network_cmd); install_element(BABEL_NODE, &no_babel_network_cmd); install_element(INTERFACE_NODE, &babel_split_horizon_cmd); - install_element(INTERFACE_NODE, &no_babel_split_horizon_cmd); install_element(INTERFACE_NODE, &babel_set_wired_cmd); install_element(INTERFACE_NODE, &babel_set_wireless_cmd); install_element(INTERFACE_NODE, &babel_set_hello_interval_cmd); @@ -1251,9 +1197,6 @@ babel_if_init(void) install_element(INTERFACE_NODE, &babel_set_rtt_max_cmd); install_element(INTERFACE_NODE, &babel_set_max_rtt_penalty_cmd); install_element(INTERFACE_NODE, &babel_set_enable_timestamps_cmd); - install_element(INTERFACE_NODE, &no_babel_set_enable_timestamps_cmd); - install_element(INTERFACE_NODE, &babel_set_channel_interfering_cmd); - install_element(INTERFACE_NODE, &babel_set_channel_noninterfering_cmd); /* "show babel ..." commands */ install_element(VIEW_NODE, &show_babel_interface_cmd); diff --git a/babeld/babeld.c b/babeld/babeld.c index dfdc924cbd..34e1a4318b 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -47,6 +47,10 @@ THE SOFTWARE. #include "babel_zebra.h" #include "babel_errors.h" +#ifndef VTYSH_EXTRACT_PL +#include "babeld/babeld_clippy.c" +#endif + DEFINE_MGROUP(BABELD, "babeld"); DEFINE_MTYPE_STATIC(BABELD, BABEL, "Babel Structure"); @@ -662,50 +666,42 @@ DEFUN (no_babel_diversity, } /* [Babel Command] */ -DEFUN (babel_diversity_factor, +DEFPY (babel_diversity_factor, babel_diversity_factor_cmd, - "babel diversity-factor (1-256)", + "[no] babel diversity-factor (1-256)$factor", + NO_STR "Babel commands\n" "Set the diversity factor.\n" "Factor in units of 1/256.\n") { - int factor; - - factor = strtoul(argv[2]->arg, NULL, 10); - - diversity_factor = factor; + diversity_factor = no ? BABEL_DEFAULT_DIVERSITY_FACTOR : factor; return CMD_SUCCESS; } /* [Babel Command] */ -DEFUN (babel_set_resend_delay, +DEFPY (babel_set_resend_delay, babel_set_resend_delay_cmd, - "babel resend-delay (20-655340)", + "[no] babel resend-delay (20-655340)$delay", + NO_STR "Babel commands\n" "Time before resending a message\n" "Milliseconds\n") { - int interval; - - interval = strtoul(argv[2]->arg, NULL, 10); - - resend_delay = interval; + resend_delay = no ? BABEL_DEFAULT_RESEND_DELAY : delay; return CMD_SUCCESS; } /* [Babel Command] */ -DEFUN (babel_set_smoothing_half_life, +DEFPY (babel_set_smoothing_half_life, babel_set_smoothing_half_life_cmd, - "babel smoothing-half-life (0-65534)", + "[no] babel smoothing-half-life (0-65534)$seconds", + NO_STR "Babel commands\n" "Smoothing half-life\n" "Seconds (0 to disable)\n") { - int seconds; - - seconds = strtoul(argv[2]->arg, NULL, 10); - - change_smoothing_half_life(seconds); + change_smoothing_half_life(no ? BABEL_DEFAULT_SMOOTHING_HALF_LIFE + : seconds); return CMD_SUCCESS; } diff --git a/babeld/subdir.am b/babeld/subdir.am index 4b9037283c..d2d425218b 100644 --- a/babeld/subdir.am +++ b/babeld/subdir.am @@ -43,4 +43,8 @@ noinst_HEADERS += \ babeld/xroute.h \ # end +clippy_scan += \ + babeld/babel_interface.c \ + babeld/babeld.c + babeld_babeld_LDADD = lib/libfrr.la $(LIBCAP) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index e60c1bb8dc..392b558805 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -5097,18 +5097,29 @@ void bgp_dump_routes_attr(struct stream *s, struct bgp_path_info *bpi, } void bgp_path_attribute_discard_vty(struct vty *vty, struct peer *peer, - const char *discard_attrs) + const char *discard_attrs, bool set) { int i, num_attributes; char **attributes; afi_t afi; safi_t safi; - if (discard_attrs) { - frrstr_split(discard_attrs, " ", &attributes, &num_attributes); + /* If `no` command specified without arbitrary attributes, + * then flush all. + */ + if (!discard_attrs) { for (i = 0; i < BGP_ATTR_MAX; i++) peer->discard_attrs[i] = false; + goto discard_soft_clear; + } + + if (discard_attrs) { + frrstr_split(discard_attrs, " ", &attributes, &num_attributes); + + if (set) + for (i = 0; i < BGP_ATTR_MAX; i++) + peer->discard_attrs[i] = false; for (i = 0; i < num_attributes; i++) { uint8_t attr_num = strtoul(attributes[i], NULL, 10); @@ -5142,10 +5153,10 @@ void bgp_path_attribute_discard_vty(struct vty *vty, struct peer *peer, continue; } - peer->discard_attrs[attr_num] = true; + peer->discard_attrs[attr_num] = set; } XFREE(MTYPE_TMP, attributes); - + discard_soft_clear: /* Configuring path attributes to be discarded will trigger * an inbound Route Refresh to ensure that the routing table * is up to date. diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index cb0bf4a43c..33283f4bf6 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -415,7 +415,7 @@ extern void attr_show_all(struct vty *vty); extern unsigned long int attr_count(void); extern unsigned long int attr_unknown_count(void); extern void bgp_path_attribute_discard_vty(struct vty *vty, struct peer *peer, - const char *discard_attrs); + const char *discard_attrs, bool set); /* Cluster list prototypes. */ extern bool cluster_loop_check(struct cluster_list *cluster, diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 664619078a..56bbaf4194 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -327,7 +327,8 @@ void bgp_damp_info_free(struct bgp_damp_info *bdi, int withdraw, afi_t afi, XFREE(MTYPE_BGP_DAMP_INFO, bdi); } -static void bgp_damp_parameter_set(int hlife, int reuse, int sup, int maxsup, +static void bgp_damp_parameter_set(time_t hlife, unsigned int reuse, + unsigned int sup, time_t maxsup, struct bgp_damp_config *bdc) { double reuse_max_ratio; diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 286f47b2bc..c9e935668e 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -2119,10 +2119,11 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, char buf3[ESI_STR_LEN]; zlog_debug( - "VRF %s vni %u type-2 route evp %pFX RMAC %pEA nexthop %pI4 esi %s", + "VRF %s vni %u type-%u route evp %pFX RMAC %pEA nexthop %pI4 esi %s", vpn->bgp_vrf ? vrf_id_to_name(vpn->bgp_vrf->vrf_id) - : " ", - vpn->vni, p, &attr.rmac, &attr.mp_nexthop_global_in, + : "None", + vpn->vni, p->prefix.route_type, p, &attr.rmac, + &attr.mp_nexthop_global_in, esi_to_str(esi, buf3, sizeof(buf3))); } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 59d8544953..3f07e53bb6 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2273,8 +2273,12 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi, && peer->shared_network && (from == bgp->peer_self || peer->sort == BGP_PEER_EBGP))) { - attr->mp_nexthop_len = - BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL; + if (safi == SAFI_MPLS_VPN) + attr->mp_nexthop_len = + BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL; + else + attr->mp_nexthop_len = + BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL; } /* Clear off link-local nexthop in source, whenever it is not diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 1ce2eb4352..d00bdd2571 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -3585,7 +3585,8 @@ route_set_ipv6_nexthop_local(void *rule, const struct prefix *p, void *object) path->attr->mp_nexthop_local = *address; /* Set nexthop length. */ - if (path->attr->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) + if (path->attr->mp_nexthop_len != BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL && + path->attr->mp_nexthop_len != BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) path->attr->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL; SET_FLAG(path->attr->rmap_change_flags, diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 5772900ce4..5738d9ef68 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -8787,7 +8787,34 @@ DEFPY(neighbor_path_attribute_discard, if (idx) discard_attrs = argv_concat(argv, argc, idx); - bgp_path_attribute_discard_vty(vty, peer, discard_attrs); + bgp_path_attribute_discard_vty(vty, peer, discard_attrs, true); + + return CMD_SUCCESS; +} + +DEFPY(no_neighbor_path_attribute_discard, + no_neighbor_path_attribute_discard_cmd, + "no neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor path-attribute discard [(1-255)]", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Manipulate path attributes from incoming UPDATE messages\n" + "Drop specified attributes from incoming UPDATE messages\n" + "Attribute number\n") +{ + struct peer *peer; + int idx = 0; + const char *discard_attrs = NULL; + + peer = peer_and_group_lookup_vty(vty, neighbor); + if (!peer) + return CMD_WARNING_CONFIG_FAILED; + + argv_find(argv, argc, "(1-255)", &idx); + if (idx) + discard_attrs = argv[idx]->arg; + + bgp_path_attribute_discard_vty(vty, peer, discard_attrs, false); return CMD_SUCCESS; } @@ -19541,6 +19568,7 @@ void bgp_vty_init(void) /* "neighbor path-attribute discard" commands. */ install_element(BGP_NODE, &neighbor_path_attribute_discard_cmd); + install_element(BGP_NODE, &no_neighbor_path_attribute_discard_cmd); /* "neighbor passive" commands. */ install_element(BGP_NODE, &neighbor_passive_cmd); diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index 28987b4af6..891d282307 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -37,6 +37,7 @@ #include "if.h" #include "table.h" #include "memory.h" +#include "network.h" #include "command.h" #include "stream.h" #include "log.h" @@ -83,7 +84,7 @@ struct eigrp_interface *eigrp_if_new(struct eigrp *eigrp, struct interface *ifp, /* Initialize neighbor list. */ ei->nbrs = list_new(); - ei->crypt_seqnum = time(NULL); + ei->crypt_seqnum = frr_sequence32_next(); /* Initialize lists */ for (i = 0; i < EIGRP_FILTER_MAX; i++) { diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c index 4f4e6dc730..c5653d0348 100644 --- a/isisd/isis_nb.c +++ b/isisd/isis_nb.c @@ -1107,6 +1107,66 @@ const struct frr_yang_module_info frr_isisd_info = { } }, { + .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid", + .cbs = { + .get_next = lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_get_next, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/af", + .cbs = { + .get_elem = lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_af_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/value", + .cbs = { + .get_elem = lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_value_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/weight", + .cbs = { + .get_elem = lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_weight_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/protection-requested", + .cbs = { + .get_elem = lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_protection_requested_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid", + .cbs = { + .get_next = lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_get_next, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/af", + .cbs = { + .get_elem = lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_af_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/value", + .cbs = { + .get_elem = lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_value_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/weight", + .cbs = { + .get_elem = lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_weight_get_elem, + } + }, + { + .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/protection-requested", + .cbs = { + .get_elem = lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_protection_requested_get_elem, + } + }, + { .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis/event-counters/adjacency-changes", .cbs = { .get_elem = lib_interface_state_isis_event_counters_adjacency_changes_get_elem, diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h index a9f2eaea95..380ce4f251 100644 --- a/isisd/isis_nb.h +++ b/isisd/isis_nb.h @@ -369,6 +369,36 @@ lib_interface_state_isis_adjacencies_adjacency_neighbor_priority_get_elem( struct nb_cb_get_elem_args *args); struct yang_data *lib_interface_state_isis_adjacencies_adjacency_state_get_elem( struct nb_cb_get_elem_args *args); +const void * +lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_get_next( + struct nb_cb_get_next_args *args); +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_af_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_value_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_weight_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_protection_requested_get_elem( + struct nb_cb_get_elem_args *args); +const void * +lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_get_next( + struct nb_cb_get_next_args *args); +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_af_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_value_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_weight_get_elem( + struct nb_cb_get_elem_args *args); +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_protection_requested_get_elem( + struct nb_cb_get_elem_args *args); struct yang_data * lib_interface_state_isis_event_counters_adjacency_changes_get_elem( struct nb_cb_get_elem_args *args); diff --git a/isisd/isis_nb_state.c b/isisd/isis_nb_state.c index 4e325ed8da..5b1fc6e1d2 100644 --- a/isisd/isis_nb_state.c +++ b/isisd/isis_nb_state.c @@ -216,6 +216,228 @@ struct yang_data *lib_interface_state_isis_adjacencies_adjacency_state_get_elem( /* * XPath: + * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid + */ +const void * +lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_get_next( + struct nb_cb_get_next_args *args) +{ + const struct isis_adjacency *adj = args->parent_list_entry; + const struct sr_adjacency *sra = args->list_entry, *sra_next = NULL; + struct listnode *node, *node_next; + + if (args->list_entry == NULL) + sra_next = listnode_head(adj->adj_sids); + else { + node = listnode_lookup(adj->adj_sids, sra); + node_next = listnextnode(node); + if (node_next) + sra_next = listgetdata(node_next); + } + + return sra_next; +} + +/* + * XPath: + * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/af + */ +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_af_get_elem( + struct nb_cb_get_elem_args *args) +{ + const struct sr_adjacency *sra = args->list_entry; + + switch (sra->adj->circuit->circ_type) { + case CIRCUIT_T_BROADCAST: + /* Adjacency SID is not published with circuit type Broadcast */ + return NULL; + case CIRCUIT_T_P2P: + return yang_data_new_uint8(args->xpath, sra->u.adj_sid->family); + } + + return NULL; +} + +/* + * XPath: + * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/value + */ +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_value_get_elem( + struct nb_cb_get_elem_args *args) +{ + const struct sr_adjacency *sra = args->list_entry; + + switch (sra->adj->circuit->circ_type) { + case CIRCUIT_T_BROADCAST: + /* Adjacency SID is not published with circuit type Broadcast */ + return NULL; + case CIRCUIT_T_P2P: + return yang_data_new_uint32(args->xpath, sra->u.adj_sid->sid); + } + + return NULL; +} + +/* + * XPath: + * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/weight + */ +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_weight_get_elem( + struct nb_cb_get_elem_args *args) +{ + const struct sr_adjacency *sra = args->list_entry; + + switch (sra->adj->circuit->circ_type) { + case CIRCUIT_T_BROADCAST: + /* Adjacency SID is not published with circuit type Broadcast */ + return NULL; + case CIRCUIT_T_P2P: + return yang_data_new_uint8(args->xpath, sra->u.adj_sid->weight); + } + + return NULL; +} + +/* + * XPath: + * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/adjacency-sids/adjacency-sid/protection-requested + */ +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_adjacency_sids_adjacency_sid_protection_requested_get_elem( + struct nb_cb_get_elem_args *args) +{ + const struct sr_adjacency *sra = args->list_entry; + + switch (sra->adj->circuit->circ_type) { + case CIRCUIT_T_BROADCAST: + /* Adjacency SID is not published with circuit type Broadcast */ + return NULL; + case CIRCUIT_T_P2P: + return yang_data_new_bool(args->xpath, + sra->u.adj_sid->flags & + EXT_SUBTLV_LINK_ADJ_SID_BFLG); + } + + return NULL; +} + +/* + * XPath: + * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid + */ +const void * +lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_get_next( + struct nb_cb_get_next_args *args) +{ + const struct isis_adjacency *adj = args->parent_list_entry; + const struct sr_adjacency *sra = args->list_entry, *sra_next = NULL; + struct listnode *node, *node_next; + + if (args->list_entry == NULL) + sra_next = listnode_head(adj->adj_sids); + else { + node = listnode_lookup(adj->adj_sids, sra); + node_next = listnextnode(node); + if (node_next) + sra_next = listgetdata(node_next); + } + + return sra_next; +} + +/* + * XPath: + * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/af + */ +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_af_get_elem( + struct nb_cb_get_elem_args *args) +{ + const struct sr_adjacency *sra = args->list_entry; + + switch (sra->adj->circuit->circ_type) { + case CIRCUIT_T_BROADCAST: + return yang_data_new_uint8(args->xpath, + sra->u.ladj_sid->family); + case CIRCUIT_T_P2P: + /* LAN adjacency SID is not published with circuit type P2P */ + return NULL; + } + + return NULL; +} + +/* + * XPath: + * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/value + */ +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_value_get_elem( + struct nb_cb_get_elem_args *args) +{ + const struct sr_adjacency *sra = args->list_entry; + + switch (sra->adj->circuit->circ_type) { + case CIRCUIT_T_BROADCAST: + return yang_data_new_uint32(args->xpath, sra->u.ladj_sid->sid); + case CIRCUIT_T_P2P: + /* LAN adjacency SID is not published with circuit type P2P */ + return NULL; + } + + return NULL; +} + +/* + * XPath: + * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/weight + */ +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_weight_get_elem( + struct nb_cb_get_elem_args *args) +{ + const struct sr_adjacency *sra = args->list_entry; + + switch (sra->adj->circuit->circ_type) { + case CIRCUIT_T_BROADCAST: + return yang_data_new_uint8(args->xpath, + sra->u.ladj_sid->weight); + case CIRCUIT_T_P2P: + /* LAN adjacency SID is not published with circuit type P2P */ + return NULL; + } + + return NULL; +} + +/* + * XPath: + * /frr-interface:lib/interface/state/frr-isisd:isis/adjacencies/adjacency/lan-adjacency-sids/lan-adjacency-sid/protection-requested + */ +struct yang_data * +lib_interface_state_isis_adjacencies_adjacency_lan_adjacency_sids_lan_adjacency_sid_protection_requested_get_elem( + struct nb_cb_get_elem_args *args) +{ + const struct sr_adjacency *sra = args->list_entry; + + switch (sra->adj->circuit->circ_type) { + case CIRCUIT_T_BROADCAST: + return yang_data_new_bool(args->xpath, + sra->u.ladj_sid->flags & + EXT_SUBTLV_LINK_ADJ_SID_BFLG); + case CIRCUIT_T_P2P: + /* LAN adjacency SID is not published with circuit type P2P */ + return NULL; + } + + return NULL; +} + +/* + * XPath: * /frr-interface:lib/interface/state/frr-isisd:isis/event-counters/adjacency-changes */ struct yang_data * diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 89e751b4e6..a6eef75e7e 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -2714,12 +2714,14 @@ void isis_spf_init(void) void isis_spf_print(struct isis_spftree *spftree, struct vty *vty) { + uint64_t last_run_duration = spftree->last_run_duration; + vty_out(vty, " last run elapsed : "); vty_out_timestr(vty, spftree->last_run_timestamp); vty_out(vty, "\n"); - vty_out(vty, " last run duration : %u usec\n", - (uint32_t)spftree->last_run_duration); + vty_out(vty, " last run duration : %" PRIu64 " usec\n", + last_run_duration); vty_out(vty, " run count : %u\n", spftree->runcount); } diff --git a/ldpd/logmsg.c b/ldpd/logmsg.c index ff9294f9d2..e16006b892 100644 --- a/ldpd/logmsg.c +++ b/ldpd/logmsg.c @@ -137,7 +137,7 @@ log_time(time_t t) char *buf; static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */ static int idx = 0; - unsigned int sec, min, hrs, day, week; + uint64_t sec, min, hrs, day, week; buf = tfbuf[idx++]; if (idx == TF_BUFS) @@ -155,11 +155,17 @@ log_time(time_t t) week /= 7; if (week > 0) - snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs); + snprintfrr(buf, TF_LEN, + "%02" PRIu64 "w%01" PRIu64 "d%02" PRIu64 "h", week, + day, hrs); else if (day > 0) - snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min); + snprintfrr(buf, TF_LEN, + "%01" PRIu64 "d%02" PRIu64 "h%02" PRIu64 "m", day, + hrs, min); else - snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec); + snprintfrr(buf, TF_LEN, + "%02" PRIu64 ":%02" PRIu64 ":%02" PRIu64, hrs, min, + sec); return (buf); } @@ -129,8 +129,6 @@ struct bfd_sessions_global { struct thread_master *tm; /** Pointer to zebra client data structure. */ struct zclient *zc; - /** Zebra next hop tracking (NHT) client. */ - struct zclient *nht_zclient; /** Debugging state. */ bool debugging; @@ -147,31 +145,10 @@ static const struct in6_addr i6a_zero; /* * Prototypes */ -static void bfd_nht_zclient_connect(struct thread *thread); - -static void bfd_nht_zclient_connected(struct zclient *zclient); -static int bfd_nht_update(ZAPI_CALLBACK_ARGS); static void bfd_source_cache_get(struct bfd_session_params *session); static void bfd_source_cache_put(struct bfd_session_params *session); -static inline void -bfd_source_cache_register(const struct bfd_source_cache *source) -{ - zclient_send_rnh(bsglobal.nht_zclient, ZEBRA_NEXTHOP_REGISTER, - &source->address, SAFI_UNICAST, false, false, - source->vrf_id); -} - -static inline void -bfd_source_cache_unregister(const struct bfd_source_cache *source) -{ - zclient_send_rnh(bsglobal.nht_zclient, ZEBRA_NEXTHOP_UNREGISTER, - &source->address, SAFI_UNICAST, false, false, - source->vrf_id); -} - - /* * bfd_get_peer_info - Extract the Peer information for which the BFD session * went down from the message sent from Zebra to clients. @@ -1074,20 +1051,11 @@ static int bfd_protocol_integration_finish(void) if (!SLIST_EMPTY(&bsglobal.source_list)) zlog_warn("BFD integration source cache not empty"); - zclient_stop(bsglobal.nht_zclient); - zclient_free(bsglobal.nht_zclient); - return 0; } -static zclient_handler *const bfd_nht_handlers[] = { - [ZEBRA_NEXTHOP_UPDATE] = bfd_nht_update, -}; - void bfd_protocol_integration_init(struct zclient *zc, struct thread_master *tm) { - struct zclient_options bfd_nht_options = zclient_options_default; - /* Initialize data structure. */ TAILQ_INIT(&bsglobal.bsplist); SLIST_INIT(&bsglobal.source_list); @@ -1102,16 +1070,6 @@ void bfd_protocol_integration_init(struct zclient *zc, struct thread_master *tm) /* Send the client registration */ bfd_client_sendmsg(zc, ZEBRA_BFD_CLIENT_REGISTER, VRF_DEFAULT); - /* Start NHT client (for automatic source decisions). */ - bsglobal.nht_zclient = - zclient_new(tm, &bfd_nht_options, bfd_nht_handlers, - array_size(bfd_nht_handlers)); - bsglobal.nht_zclient->sock = -1; - bsglobal.nht_zclient->privs = zc->privs; - bsglobal.nht_zclient->zebra_connected = bfd_nht_zclient_connected; - thread_add_timer(tm, bfd_nht_zclient_connect, bsglobal.nht_zclient, 1, - &bsglobal.nht_zclient->t_connect); - hook_register(frr_fini, bfd_protocol_integration_finish); } @@ -1252,8 +1210,6 @@ static void bfd_source_cache_get(struct bfd_session_params *session) session->source_cache = source; source->refcount = 1; - bfd_source_cache_register(source); - return; } @@ -1268,7 +1224,6 @@ static void bfd_source_cache_put(struct bfd_session_params *session) return; } - bfd_source_cache_unregister(session->source_cache); SLIST_REMOVE(&bsglobal.source_list, session->source_cache, bfd_source_cache, entry); XFREE(MTYPE_BFD_SOURCE, session->source_cache); @@ -1378,59 +1333,19 @@ static bool bfd_source_cache_update(struct bfd_source_cache *source, return false; } -static void bfd_nht_zclient_connect(struct thread *thread) -{ - struct zclient *zclient = THREAD_ARG(thread); - - if (bsglobal.debugging) - zlog_debug("BFD NHT zclient connection attempt"); - - if (zclient_start(zclient) == -1) { - if (bsglobal.debugging) - zlog_debug("BFD NHT zclient connection failed"); - - thread_add_timer(bsglobal.tm, bfd_nht_zclient_connect, zclient, - 3, &zclient->t_connect); - return; - } - - if (bsglobal.debugging) - zlog_debug("BFD NHT zclient connection succeeded"); -} - -static void bfd_nht_zclient_connected(struct zclient *zclient) -{ - struct bfd_source_cache *source; - - if (bsglobal.debugging) - zlog_debug("BFD NHT zclient connected"); - - SLIST_FOREACH (source, &bsglobal.source_list, entry) - bfd_source_cache_register(source); -} - -static int bfd_nht_update(ZAPI_CALLBACK_ARGS) +int bfd_nht_update(const struct prefix *match, const struct zapi_route *route) { struct bfd_source_cache *source; - struct zapi_route route; - struct prefix match; - - if (!zapi_nexthop_update_decode(zclient->ibuf, &match, &route)) { - zlog_warn("BFD NHT update decode failure"); - return 0; - } - if (cmd != ZEBRA_NEXTHOP_UPDATE) - return 0; if (bsglobal.debugging) - zlog_debug("BFD NHT update for %pFX", &route.prefix); + zlog_debug("BFD NHT update for %pFX", &route->prefix); SLIST_FOREACH (source, &bsglobal.source_list, entry) { - if (source->vrf_id != route.vrf_id) + if (source->vrf_id != route->vrf_id) continue; - if (!prefix_same(&match, &source->address)) + if (!prefix_same(match, &source->address)) continue; - if (bfd_source_cache_update(source, &route)) + if (bfd_source_cache_update(source, route)) bfd_source_cache_update_sessions(source); } @@ -473,6 +473,13 @@ extern bool bfd_protocol_integration_debug(void); */ extern bool bfd_protocol_integration_shutting_down(void); +/* Update nexthop-tracking (nht) information for BFD auto source selection. + * The function must be called from the daemon callback function + * that deals with the ZEBRA_NEXTHOP_UPDATE zclient command + */ +extern int bfd_nht_update(const struct prefix *match, + const struct zapi_route *route); + #ifdef __cplusplus } #endif diff --git a/lib/filter_cli.c b/lib/filter_cli.c index e0f0f177e5..296c05b9f4 100644 --- a/lib/filter_cli.c +++ b/lib/filter_cli.c @@ -66,16 +66,21 @@ static int acl_get_seq_cb(const struct lyd_node *dnode, void *arg) * * \param[in] vty shell context with the candidate configuration. * \param[in] xpath the XPath to look for the sequence leaf. - * \returns next unused sequence number. + * \returns next unused sequence number, -1 if out of range when adding. */ -static long acl_get_seq(struct vty *vty, const char *xpath) +static int64_t acl_get_seq(struct vty *vty, const char *xpath, bool is_remove) { int64_t seq = 0; yang_dnode_iterate(acl_get_seq_cb, &seq, vty->candidate_config->dnode, "%s/entry", xpath); - return seq + 5; + seq += 5; + if (!is_remove && seq > UINT32_MAX) { + vty_out(vty, "%% Malformed sequence value\n"); + return -1; + } + return seq; } static int acl_remove_if_empty(struct vty *vty, const char *iptype, @@ -98,7 +103,7 @@ static int acl_remove_if_empty(struct vty *vty, const char *iptype, * NOTE: if the list is empty it will return the first sequence * number: 5. */ - if (acl_get_seq(vty, xpath) != 5) + if (acl_get_seq(vty, xpath, true) != 5) return CMD_SUCCESS; /* Nobody is using this list, lets remove it. */ @@ -174,16 +179,19 @@ DEFPY_YANG( */ snprintf(xpath, sizeof(xpath), "/frr-filter:lib/access-list[type='ipv4'][name='%s']", name); - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); if (seq_str == NULL) { /* Use XPath to find the next sequence number. */ - sseq = acl_get_seq(vty, xpath); + sseq = acl_get_seq(vty, xpath, false); + if (sseq < 0) + return CMD_WARNING_CONFIG_FAILED; + snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%" PRId64 "']", xpath, sseq); } else snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%s']", xpath, seq_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, "./action", NB_OP_MODIFY, action); @@ -321,16 +329,19 @@ DEFPY_YANG( */ snprintf(xpath, sizeof(xpath), "/frr-filter:lib/access-list[type='ipv4'][name='%s']", name); - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); if (seq_str == NULL) { /* Use XPath to find the next sequence number. */ - sseq = acl_get_seq(vty, xpath); + sseq = acl_get_seq(vty, xpath, false); + if (sseq < 0) + return CMD_WARNING_CONFIG_FAILED; + snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%" PRId64 "']", xpath, sseq); } else snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%s']", xpath, seq_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, "./action", NB_OP_MODIFY, action); @@ -483,16 +494,19 @@ DEFPY_YANG( */ snprintf(xpath, sizeof(xpath), "/frr-filter:lib/access-list[type='ipv4'][name='%s']", name); - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); if (seq_str == NULL) { /* Use XPath to find the next sequence number. */ - sseq = acl_get_seq(vty, xpath); + sseq = acl_get_seq(vty, xpath, false); + if (sseq < 0) + return CMD_WARNING_CONFIG_FAILED; + snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%" PRId64 "']", xpath, sseq); } else snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%s']", xpath, seq_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, "./action", NB_OP_MODIFY, action); @@ -670,16 +684,19 @@ DEFPY_YANG( */ snprintf(xpath, sizeof(xpath), "/frr-filter:lib/access-list[type='ipv6'][name='%s']", name); - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); if (seq_str == NULL) { /* Use XPath to find the next sequence number. */ - sseq = acl_get_seq(vty, xpath); + sseq = acl_get_seq(vty, xpath, false); + if (sseq < 0) + return CMD_WARNING_CONFIG_FAILED; + snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%" PRId64 "']", xpath, sseq); } else snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%s']", xpath, seq_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, "./action", NB_OP_MODIFY, action); @@ -857,16 +874,19 @@ DEFPY_YANG( */ snprintf(xpath, sizeof(xpath), "/frr-filter:lib/access-list[type='mac'][name='%s']", name); - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); if (seq_str == NULL) { /* Use XPath to find the next sequence number. */ - sseq = acl_get_seq(vty, xpath); + sseq = acl_get_seq(vty, xpath, false); + if (sseq < 0) + return CMD_WARNING_CONFIG_FAILED; + snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%" PRId64 "']", xpath, sseq); } else snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%s']", xpath, seq_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, "./action", NB_OP_MODIFY, action); @@ -1167,7 +1187,7 @@ static int plist_remove_if_empty(struct vty *vty, const char *iptype, * NOTE: if the list is empty it will return the first sequence * number: 5. */ - if (acl_get_seq(vty, xpath) != 5) + if (acl_get_seq(vty, xpath, true) != 5) return CMD_SUCCESS; /* Nobody is using this list, lets remove it. */ @@ -1275,16 +1295,19 @@ DEFPY_YANG( */ snprintf(xpath, sizeof(xpath), "/frr-filter:lib/prefix-list[type='ipv4'][name='%s']", name); - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); if (seq_str == NULL) { /* Use XPath to find the next sequence number. */ - sseq = acl_get_seq(vty, xpath); + sseq = acl_get_seq(vty, xpath, false); + if (sseq < 0) + return CMD_WARNING_CONFIG_FAILED; + snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%" PRId64 "']", xpath, sseq); } else snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%s']", xpath, seq_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, "./action", NB_OP_MODIFY, action); @@ -1476,16 +1499,19 @@ DEFPY_YANG( */ snprintf(xpath, sizeof(xpath), "/frr-filter:lib/prefix-list[type='ipv6'][name='%s']", name); - nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); if (seq_str == NULL) { /* Use XPath to find the next sequence number. */ - sseq = acl_get_seq(vty, xpath); + sseq = acl_get_seq(vty, xpath, false); + if (sseq < 0) + return CMD_WARNING_CONFIG_FAILED; + snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%" PRId64 "']", xpath, sseq); } else snprintfrr(xpath_entry, sizeof(xpath_entry), "%s/entry[sequence='%s']", xpath, seq_str); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL); nb_cli_enqueue_change(vty, "./action", NB_OP_MODIFY, action); diff --git a/lib/network.c b/lib/network.c index b60ad9a57c..cd62b8b593 100644 --- a/lib/network.c +++ b/lib/network.c @@ -122,3 +122,24 @@ float ntohf(float net) { return htonf(net); } + +uint64_t frr_sequence_next(void) +{ + static uint64_t last_sequence; + struct timespec ts; + + (void)clock_gettime(CLOCK_MONOTONIC, &ts); + if (last_sequence == (uint64_t)ts.tv_sec) { + last_sequence++; + return last_sequence; + } + + last_sequence = ts.tv_sec; + return last_sequence; +} + +uint32_t frr_sequence32_next(void) +{ + /* coverity[Y2K38_SAFETY] */ + return (uint32_t)frr_sequence_next(); +} diff --git a/lib/network.h b/lib/network.h index 10ed917572..c163eab8f7 100644 --- a/lib/network.h +++ b/lib/network.h @@ -82,6 +82,24 @@ extern float ntohf(float); #endif /** + * Generate a sequence number using monotonic clock with a same second call + * protection to help guarantee a unique incremental sequence number that never + * goes back (except when wrapping/overflow). + * + * **NOTE** this function is not thread safe since it uses `static` variable. + * + * This function and `frr_sequence32_next` should be used to initialize + * sequence numbers without directly calling other `time_t` returning + * functions because of `time_t` truncation warnings. + * + * \returns `uint64_t` number based on the monotonic clock. + */ +extern uint64_t frr_sequence_next(void); + +/** Same as `frr_sequence_next` but returns truncated number. */ +extern uint32_t frr_sequence32_next(void); + +/** * Helper function that returns a random long value. The main purpose of * this function is to hide a `random()` call that gets flagged by coverity * scan and put it into one place. diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index fb54ebab15..3d29a65d1b 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -28,6 +28,7 @@ #include "linklist.h" #include "lib_errors.h" #include "checksum.h" +#include "network.h" #include "ospf6_proto.h" #include "ospf6_lsa.h" @@ -2300,7 +2301,7 @@ static uint16_t ospf6_make_dbdesc(struct ospf6_neighbor *on, struct stream *s) /* if this is initial one, initialize sequence number for DbDesc */ if (CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT) && (on->dbdesc_seqnum == 0)) { - on->dbdesc_seqnum = monotime(NULL); + on->dbdesc_seqnum = frr_sequence32_next(); } /* reserved */ diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index a0b14e73ee..831906b908 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -30,6 +30,7 @@ #include "command.h" #include "stream.h" #include "log.h" +#include "network.h" #include "zclient.h" #include "bfd.h" #include "ldp_sync.h" @@ -274,7 +275,7 @@ struct ospf_interface *ospf_if_new(struct ospf *ospf, struct interface *ifp, oi->t_ls_upd_event = NULL; oi->t_ls_ack_direct = NULL; - oi->crypt_seqnum = time(NULL); + oi->crypt_seqnum = frr_sequence32_next(); ospf_opaque_type9_lsa_init(oi); diff --git a/pimd/mtracebis_netlink.c b/pimd/mtracebis_netlink.c index 81e28f2407..9bdf949007 100644 --- a/pimd/mtracebis_netlink.c +++ b/pimd/mtracebis_netlink.c @@ -92,7 +92,7 @@ int rtnl_open_byproto(struct rtnl_handle *rth, unsigned subscriptions, rth->local.nl_family); return -1; } - rth->seq = (uint32_t)time(NULL); + rth->seq = getpid(); return 0; } diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 316247adb3..85e4b1c033 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -211,6 +211,9 @@ static int static_zebra_nexthop_update(ZAPI_CALLBACK_ARGS) return 1; } + if (zclient->bfd_integration) + bfd_nht_update(&matched, &nhr); + if (matched.family == AF_INET6) afi = AFI_IP6; diff --git a/vtysh/subdir.am b/vtysh/subdir.am index cc2a70ade6..72204201d9 100644 --- a/vtysh/subdir.am +++ b/vtysh/subdir.am @@ -37,4 +37,5 @@ $(vtysh_vtysh_OBJECTS): vtysh/vtysh_daemons.h CLEANFILES += vtysh/vtysh_daemons.h vtysh/vtysh_daemons.h: + mkdir -p vtysh $(PERL) $(top_srcdir)/vtysh/daemons.pl $(vtysh_daemons) > vtysh/vtysh_daemons.h diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang index 380fce3859..5483410d04 100644 --- a/yang/frr-isisd.yang +++ b/yang/frr-isisd.yang @@ -881,6 +881,9 @@ module frr-isisd { description "This leaf describes the state of the interface."; } + + uses adjacency-sids; + uses lan-adjacency-sids; } } } @@ -1004,6 +1007,76 @@ module frr-isisd { } } + grouping adjacency-sids { + description + "IS-IS segment routing adjacency SID grouping."; + container adjacency-sids { + description + "This container lists the information of adjacency SID."; + list adjacency-sid { + leaf af { + type uint8; + description + "This leaf describes the protocol-family associated with the + adjacency SID."; + } + + leaf value { + type uint32; + description + "This leaf describes the value of adjacency SID."; + } + + leaf weight { + type uint8; + description + "This leaf describes the weight of the adjacency SID."; + } + + leaf protection-requested { + type boolean; + description + "This leaf describes if the adjacency SID must be protected."; + } + } + } + } + + grouping lan-adjacency-sids { + description + "IS-IS segment routing LAN adjacency SID grouping."; + container lan-adjacency-sids { + description + "This container lists the information of LAN adjacency SID."; + list lan-adjacency-sid { + leaf af { + type uint8; + description + "This leaf describes the protocol-family associated with the + LAN adjacency SID."; + } + + leaf value { + type uint32; + description + "This leaf describes the value of LAN adjacency SID."; + } + + leaf weight { + type uint8; + description + "This leaf describes the weight of the LAN adjacency SID."; + } + + leaf protection-requested { + type boolean; + description + "This leaf describes if the LAN adjacency SID must be protected."; + } + } + } + } + container isis { description "Configuration of the IS-IS routing daemon."; diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c index af75ddf742..0a9fecc9df 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c @@ -89,7 +89,7 @@ struct fpm_nl_ctx { * When a FPM server connection becomes a bottleneck, we must keep the * data plane contexts until we get a chance to process them. */ - struct dplane_ctx_q ctxqueue; + struct dplane_ctx_list_head ctxqueue; pthread_mutex_t ctxqueue_mutex; /* data plane events. */ @@ -1473,7 +1473,7 @@ static int fpm_nl_start(struct zebra_dplane_provider *prov) fnc->socket = -1; fnc->disabled = true; fnc->prov = prov; - TAILQ_INIT(&fnc->ctxqueue); + dplane_ctx_q_init(&fnc->ctxqueue); pthread_mutex_init(&fnc->ctxqueue_mutex, NULL); /* Set default values. */ diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 54d9561e2b..42afe61469 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -202,13 +202,13 @@ struct nl_batch { const struct zebra_dplane_info *zns; - struct dplane_ctx_q ctx_list; + struct dplane_ctx_list_head ctx_list; /* * Pointer to the queue of completed contexts outbound back * towards the dataplane module. */ - struct dplane_ctx_q *ctx_out_q; + struct dplane_ctx_list_head *ctx_out_q; }; int netlink_config_write_helper(struct vty *vty) @@ -1446,10 +1446,11 @@ static void nl_batch_reset(struct nl_batch *bth) bth->msgcnt = 0; bth->zns = NULL; - TAILQ_INIT(&(bth->ctx_list)); + dplane_ctx_q_init(&(bth->ctx_list)); } -static void nl_batch_init(struct nl_batch *bth, struct dplane_ctx_q *ctx_out_q) +static void nl_batch_init(struct nl_batch *bth, + struct dplane_ctx_list_head *ctx_out_q) { /* * If the size of the buffer has changed, free and then allocate a new @@ -1665,14 +1666,14 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth, return FRR_NETLINK_ERROR; } -void kernel_update_multi(struct dplane_ctx_q *ctx_list) +void kernel_update_multi(struct dplane_ctx_list_head *ctx_list) { struct nl_batch batch; struct zebra_dplane_ctx *ctx; - struct dplane_ctx_q handled_list; + struct dplane_ctx_list_head handled_list; enum netlink_msg_status res; - TAILQ_INIT(&handled_list); + dplane_ctx_q_init(&handled_list); nl_batch_init(&batch, &handled_list); while (true) { @@ -1703,7 +1704,7 @@ void kernel_update_multi(struct dplane_ctx_q *ctx_list) nl_batch_send(&batch); - TAILQ_INIT(ctx_list); + dplane_ctx_q_init(ctx_list); dplane_ctx_list_append(ctx_list, &handled_list); } diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index f84d31cc44..684ccc3ed5 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1516,13 +1516,13 @@ int kernel_dplane_read(struct zebra_dplane_info *info) return 0; } -void kernel_update_multi(struct dplane_ctx_q *ctx_list) +void kernel_update_multi(struct dplane_ctx_list_head *ctx_list) { struct zebra_dplane_ctx *ctx; - struct dplane_ctx_q handled_list; + struct dplane_ctx_list_head handled_list; enum zebra_dplane_result res = ZEBRA_DPLANE_REQUEST_SUCCESS; - TAILQ_INIT(&handled_list); + dplane_ctx_q_init(&handled_list); while (true) { ctx = dplane_ctx_dequeue(ctx_list); @@ -1642,7 +1642,7 @@ void kernel_update_multi(struct dplane_ctx_q *ctx_list) dplane_ctx_enqueue_tail(&handled_list, ctx); } - TAILQ_INIT(ctx_list); + dplane_ctx_q_init(ctx_list); dplane_ctx_list_append(ctx_list, &handled_list); } diff --git a/zebra/rt.h b/zebra/rt.h index 4cf4c9d780..6f4dd48a54 100644 --- a/zebra/rt.h +++ b/zebra/rt.h @@ -121,7 +121,7 @@ extern int kernel_del_mac_nhg(uint32_t nhg_id); /* * Message batching interface. */ -extern void kernel_update_multi(struct dplane_ctx_q *ctx_list); +extern void kernel_update_multi(struct dplane_ctx_list_head *ctx_list); /* * Called by the dplane pthread to read incoming OS messages and dispatch them. diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 1a090c78e3..79d79d74be 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -223,7 +223,7 @@ static inline bool is_selfroute(int proto) return false; } -static inline int zebra2proto(int proto) +int zebra2proto(int proto) { switch (proto) { case ZEBRA_ROUTE_BABEL: diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index 351f98a2ca..8506367ae4 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -150,6 +150,9 @@ const char *ifa_flags2str(uint32_t flags, char *buf, size_t buflen); const char *nh_flags2str(uint32_t flags, char *buf, size_t buflen); void nl_dump(void *msg, size_t msglen); + +extern int zebra2proto(int proto); + #endif /* NETLINK_DEBUG */ #ifdef __cplusplus diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index 739f6adce9..7db8fba95b 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -26,7 +26,6 @@ #include "lib/frratomic.h" #include "lib/frr_pthread.h" #include "lib/memory.h" -#include "lib/queue.h" #include "lib/zebra.h" #include "zebra/netconf_netlink.h" #include "zebra/zebra_router.h" @@ -103,7 +102,7 @@ struct dplane_intf_extra { uint32_t flags; uint32_t status; - TAILQ_ENTRY(dplane_intf_extra) link; + struct dplane_intf_extra_list_item dlink; }; /* @@ -152,7 +151,7 @@ struct dplane_route_info { struct nexthop_group old_backup_ng; /* Optional list of extra interface info */ - TAILQ_HEAD(dp_intf_extra_q, dplane_intf_extra) intf_extra_q; + struct dplane_intf_extra_list_head intf_extra_list; }; /* @@ -415,7 +414,7 @@ struct zebra_dplane_ctx { struct zebra_dplane_info zd_ns_info; /* Embedded list linkage */ - TAILQ_ENTRY(zebra_dplane_ctx) zd_q_entries; + struct dplane_ctx_list_item zd_entries; }; /* Flag that can be set by a pre-kernel provider as a signal that an update @@ -423,6 +422,12 @@ struct zebra_dplane_ctx { */ #define DPLANE_CTX_FLAG_NO_KERNEL 0x01 +/* List types declared now that the structs involved are defined. */ +DECLARE_DLIST(dplane_ctx_list, struct zebra_dplane_ctx, zd_entries); +DECLARE_DLIST(dplane_intf_extra_list, struct dplane_intf_extra, dlink); + +/* List for dplane plugins/providers */ +PREDECL_DLIST(dplane_prov_list); /* * Registration block for one dataplane provider. @@ -461,17 +466,20 @@ struct zebra_dplane_provider { _Atomic uint32_t dp_error_counter; /* Queue of contexts inbound to the provider */ - struct dplane_ctx_q dp_ctx_in_q; + struct dplane_ctx_list_head dp_ctx_in_list; /* Queue of completed contexts outbound from the provider back * towards the dataplane module. */ - struct dplane_ctx_q dp_ctx_out_q; + struct dplane_ctx_list_head dp_ctx_out_list; /* Embedded list linkage for provider objects */ - TAILQ_ENTRY(zebra_dplane_provider) dp_prov_link; + struct dplane_prov_list_item dp_link; }; +/* Declare list of providers/plugins */ +DECLARE_DLIST(dplane_prov_list, struct zebra_dplane_provider, dp_link); + /* Declare types for list of zns info objects */ PREDECL_DLIST(zns_info_list); @@ -496,7 +504,7 @@ static struct zebra_dplane_globals { pthread_mutex_t dg_mutex; /* Results callback registered by zebra 'core' */ - int (*dg_results_cb)(struct dplane_ctx_q *ctxlist); + int (*dg_results_cb)(struct dplane_ctx_list_head *ctxlist); /* Sentinel for beginning of shutdown */ volatile bool dg_is_shutdown; @@ -505,10 +513,10 @@ static struct zebra_dplane_globals { volatile bool dg_run; /* Update context queue inbound to the dataplane */ - TAILQ_HEAD(zdg_ctx_q, zebra_dplane_ctx) dg_update_ctx_q; + struct dplane_ctx_list_head dg_update_list; /* Ordered list of providers */ - TAILQ_HEAD(zdg_prov_q, zebra_dplane_provider) dg_providers_q; + struct dplane_prov_list_head dg_providers; /* List of info about each zns */ struct zns_info_list_head dg_zns_list; @@ -668,7 +676,7 @@ void dplane_enable_sys_route_notifs(void) */ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) { - struct dplane_intf_extra *if_extra, *if_tmp; + struct dplane_intf_extra *if_extra; /* * Some internal allocations may need to be freed, depending on @@ -713,12 +721,9 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) } /* Optional extra interface info */ - TAILQ_FOREACH_SAFE(if_extra, &ctx->u.rinfo.intf_extra_q, - link, if_tmp) { - TAILQ_REMOVE(&ctx->u.rinfo.intf_extra_q, if_extra, - link); + while ((if_extra = dplane_intf_extra_list_pop( + &ctx->u.rinfo.intf_extra_list))) XFREE(MTYPE_DP_INTF, if_extra); - } break; @@ -885,39 +890,40 @@ void dplane_ctx_fini(struct zebra_dplane_ctx **pctx) dplane_ctx_free(pctx); } +/* Init a list of contexts */ +void dplane_ctx_q_init(struct dplane_ctx_list_head *q) +{ + dplane_ctx_list_init(q); +} + /* Enqueue a context block */ -void dplane_ctx_enqueue_tail(struct dplane_ctx_q *q, +void dplane_ctx_enqueue_tail(struct dplane_ctx_list_head *list, const struct zebra_dplane_ctx *ctx) { - TAILQ_INSERT_TAIL(q, (struct zebra_dplane_ctx *)ctx, zd_q_entries); + dplane_ctx_list_add_tail(list, (struct zebra_dplane_ctx *)ctx); } /* Append a list of context blocks to another list */ -void dplane_ctx_list_append(struct dplane_ctx_q *to_list, - struct dplane_ctx_q *from_list) +void dplane_ctx_list_append(struct dplane_ctx_list_head *to_list, + struct dplane_ctx_list_head *from_list) { - if (TAILQ_FIRST(from_list)) { - TAILQ_CONCAT(to_list, from_list, zd_q_entries); + struct zebra_dplane_ctx *ctx; - /* And clear 'from' list */ - TAILQ_INIT(from_list); - } + while ((ctx = dplane_ctx_list_pop(from_list)) != NULL) + dplane_ctx_list_add_tail(to_list, ctx); } -struct zebra_dplane_ctx *dplane_ctx_get_head(struct dplane_ctx_q *q) +struct zebra_dplane_ctx *dplane_ctx_get_head(struct dplane_ctx_list_head *q) { - struct zebra_dplane_ctx *ctx = TAILQ_FIRST(q); + struct zebra_dplane_ctx *ctx = dplane_ctx_list_first(q); return ctx; } /* Dequeue a context block from the head of a list */ -struct zebra_dplane_ctx *dplane_ctx_dequeue(struct dplane_ctx_q *q) +struct zebra_dplane_ctx *dplane_ctx_dequeue(struct dplane_ctx_list_head *q) { - struct zebra_dplane_ctx *ctx = TAILQ_FIRST(q); - - if (ctx) - TAILQ_REMOVE(q, ctx, zd_q_entries); + struct zebra_dplane_ctx *ctx = dplane_ctx_list_pop(q); return ctx; } @@ -2597,14 +2603,16 @@ void dplane_ctx_rule_set_dp_flow_ptr(struct zebra_dplane_ctx *ctx, const struct dplane_intf_extra * dplane_ctx_get_intf_extra(const struct zebra_dplane_ctx *ctx) { - return TAILQ_FIRST(&ctx->u.rinfo.intf_extra_q); + return dplane_intf_extra_list_const_first( + &ctx->u.rinfo.intf_extra_list); } const struct dplane_intf_extra * dplane_ctx_intf_extra_next(const struct zebra_dplane_ctx *ctx, const struct dplane_intf_extra *ptr) { - return TAILQ_NEXT(ptr, link); + return dplane_intf_extra_list_const_next(&ctx->u.rinfo.intf_extra_list, + ptr); } vrf_id_t dplane_intf_extra_get_vrfid(const struct dplane_intf_extra *ptr) @@ -2793,7 +2801,7 @@ int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx, if (!ctx || !re) return ret; - TAILQ_INIT(&ctx->u.rinfo.intf_extra_q); + dplane_intf_extra_list_init(&ctx->u.rinfo.intf_extra_list); ctx->zd_op = op; ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS; @@ -2896,8 +2904,9 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, if_extra->flags = ifp->flags; if_extra->status = ifp->status; - TAILQ_INSERT_TAIL(&ctx->u.rinfo.intf_extra_q, - if_extra, link); + dplane_intf_extra_list_add_tail( + &ctx->u.rinfo.intf_extra_list, + if_extra); } } @@ -3622,8 +3631,7 @@ static int dplane_update_enqueue(struct zebra_dplane_ctx *ctx) /* Enqueue for processing by the dataplane pthread */ DPLANE_LOCK(); { - TAILQ_INSERT_TAIL(&zdplane_info.dg_update_ctx_q, ctx, - zd_q_entries); + dplane_ctx_list_add_tail(&zdplane_info.dg_update_list, ctx); } DPLANE_UNLOCK(); @@ -5520,7 +5528,7 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed) vty_out(vty, "Zebra dataplane providers:\n"); DPLANE_LOCK(); - prov = TAILQ_FIRST(&zdplane_info.dg_providers_q); + prov = dplane_prov_list_first(&zdplane_info.dg_providers); DPLANE_UNLOCK(); /* Show counters, useful info from each registered provider */ @@ -5544,7 +5552,7 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed) out, out_q, out_max); DPLANE_LOCK(); - prov = TAILQ_NEXT(prov, dp_prov_link); + prov = dplane_prov_list_next(&zdplane_info.dg_providers, prov); DPLANE_UNLOCK(); } @@ -5595,8 +5603,8 @@ int dplane_provider_register(const char *name, p = XCALLOC(MTYPE_DP_PROV, sizeof(struct zebra_dplane_provider)); pthread_mutex_init(&(p->dp_mutex), NULL); - TAILQ_INIT(&(p->dp_ctx_in_q)); - TAILQ_INIT(&(p->dp_ctx_out_q)); + dplane_ctx_list_init(&p->dp_ctx_in_list); + dplane_ctx_list_init(&p->dp_ctx_out_list); p->dp_flags = flags; p->dp_priority = prio; @@ -5617,16 +5625,15 @@ int dplane_provider_register(const char *name, "provider-%u", p->dp_id); /* Insert into list ordered by priority */ - TAILQ_FOREACH(last, &zdplane_info.dg_providers_q, dp_prov_link) { + frr_each (dplane_prov_list, &zdplane_info.dg_providers, last) { if (last->dp_priority > p->dp_priority) break; } if (last) - TAILQ_INSERT_BEFORE(last, p, dp_prov_link); + dplane_prov_list_add_after(&zdplane_info.dg_providers, last, p); else - TAILQ_INSERT_TAIL(&zdplane_info.dg_providers_q, p, - dp_prov_link); + dplane_prov_list_add_tail(&zdplane_info.dg_providers, p); /* And unlock */ DPLANE_UNLOCK(); @@ -5688,10 +5695,8 @@ struct zebra_dplane_ctx *dplane_provider_dequeue_in_ctx( dplane_provider_lock(prov); - ctx = TAILQ_FIRST(&(prov->dp_ctx_in_q)); + ctx = dplane_ctx_list_pop(&(prov->dp_ctx_in_list)); if (ctx) { - TAILQ_REMOVE(&(prov->dp_ctx_in_q), ctx, zd_q_entries); - atomic_fetch_sub_explicit(&prov->dp_in_queued, 1, memory_order_relaxed); } @@ -5705,7 +5710,7 @@ struct zebra_dplane_ctx *dplane_provider_dequeue_in_ctx( * Dequeue work to a list, return count */ int dplane_provider_dequeue_in_list(struct zebra_dplane_provider *prov, - struct dplane_ctx_q *listp) + struct dplane_ctx_list_head *listp) { int limit, ret; struct zebra_dplane_ctx *ctx; @@ -5715,14 +5720,11 @@ int dplane_provider_dequeue_in_list(struct zebra_dplane_provider *prov, dplane_provider_lock(prov); for (ret = 0; ret < limit; ret++) { - ctx = TAILQ_FIRST(&(prov->dp_ctx_in_q)); - if (ctx) { - TAILQ_REMOVE(&(prov->dp_ctx_in_q), ctx, zd_q_entries); - - TAILQ_INSERT_TAIL(listp, ctx, zd_q_entries); - } else { + ctx = dplane_ctx_list_pop(&(prov->dp_ctx_in_list)); + if (ctx) + dplane_ctx_list_add_tail(listp, ctx); + else break; - } } if (ret > 0) @@ -5750,8 +5752,7 @@ void dplane_provider_enqueue_out_ctx(struct zebra_dplane_provider *prov, dplane_provider_lock(prov); - TAILQ_INSERT_TAIL(&(prov->dp_ctx_out_q), ctx, - zd_q_entries); + dplane_ctx_list_add_tail(&(prov->dp_ctx_out_list), ctx); /* Maintain out-queue counters */ atomic_fetch_add_explicit(&(prov->dp_out_queued), 1, @@ -5921,12 +5922,12 @@ int dplane_provider_work_ready(void) */ void dplane_provider_enqueue_to_zebra(struct zebra_dplane_ctx *ctx) { - struct dplane_ctx_q temp_list; + struct dplane_ctx_list_head temp_list; /* Zebra's api takes a list, so we need to use a temporary list */ - TAILQ_INIT(&temp_list); + dplane_ctx_list_init(&temp_list); - TAILQ_INSERT_TAIL(&temp_list, ctx, zd_q_entries); + dplane_ctx_list_add_tail(&temp_list, ctx); (zdplane_info.dg_results_cb)(&temp_list); } @@ -6321,11 +6322,11 @@ void dplane_rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, */ static int kernel_dplane_process_func(struct zebra_dplane_provider *prov) { - struct zebra_dplane_ctx *ctx, *tctx; - struct dplane_ctx_q work_list; + struct zebra_dplane_ctx *ctx; + struct dplane_ctx_list_head work_list; int counter, limit; - TAILQ_INIT(&work_list); + dplane_ctx_list_init(&work_list); limit = dplane_provider_get_work_limit(prov); @@ -6351,15 +6352,14 @@ static int kernel_dplane_process_func(struct zebra_dplane_provider *prov) == DPLANE_OP_IPSET_ENTRY_DELETE)) kernel_dplane_process_ipset_entry(prov, ctx); else - TAILQ_INSERT_TAIL(&work_list, ctx, zd_q_entries); + dplane_ctx_list_add_tail(&work_list, ctx); } kernel_update_multi(&work_list); - TAILQ_FOREACH_SAFE (ctx, &work_list, zd_q_entries, tctx) { + while ((ctx = dplane_ctx_list_pop(&work_list)) != NULL) { kernel_dplane_handle_result(ctx); - TAILQ_REMOVE(&work_list, ctx, zd_q_entries); dplane_provider_enqueue_out_ctx(prov, ctx); } @@ -6486,10 +6486,10 @@ static void dplane_provider_init(void) int dplane_clean_ctx_queue(bool (*context_cb)(struct zebra_dplane_ctx *ctx, void *arg), void *val) { - struct zebra_dplane_ctx *ctx, *temp; - struct dplane_ctx_q work_list; + struct zebra_dplane_ctx *ctx; + struct dplane_ctx_list_head work_list; - TAILQ_INIT(&work_list); + dplane_ctx_list_init(&work_list); if (context_cb == NULL) return AOK; @@ -6497,12 +6497,10 @@ int dplane_clean_ctx_queue(bool (*context_cb)(struct zebra_dplane_ctx *ctx, /* Walk the pending context queue under the dplane lock. */ DPLANE_LOCK(); - TAILQ_FOREACH_SAFE(ctx, &zdplane_info.dg_update_ctx_q, zd_q_entries, - temp) { + frr_each_safe (dplane_ctx_list, &zdplane_info.dg_update_list, ctx) { if (context_cb(ctx, val)) { - TAILQ_REMOVE(&zdplane_info.dg_update_ctx_q, ctx, - zd_q_entries); - TAILQ_INSERT_TAIL(&work_list, ctx, zd_q_entries); + dplane_ctx_list_del(&zdplane_info.dg_update_list, ctx); + dplane_ctx_list_add_tail(&work_list, ctx); } } @@ -6511,10 +6509,8 @@ int dplane_clean_ctx_queue(bool (*context_cb)(struct zebra_dplane_ctx *ctx, /* Now free any contexts selected by the caller, without holding * the lock. */ - TAILQ_FOREACH_SAFE(ctx, &work_list, zd_q_entries, temp) { - TAILQ_REMOVE(&work_list, ctx, zd_q_entries); + while ((ctx = dplane_ctx_list_pop(&work_list)) != NULL) dplane_ctx_fini(&ctx); - } return AOK; } @@ -6552,7 +6548,7 @@ void zebra_dplane_pre_finish(void) zdplane_info.dg_is_shutdown = true; /* Notify provider(s) of pending shutdown. */ - TAILQ_FOREACH(prov, &zdplane_info.dg_providers_q, dp_prov_link) { + frr_each (dplane_prov_list, &zdplane_info.dg_providers, prov) { if (prov->dp_fini == NULL) continue; @@ -6575,8 +6571,8 @@ static bool dplane_work_pending(void) */ DPLANE_LOCK(); { - ctx = TAILQ_FIRST(&zdplane_info.dg_update_ctx_q); - prov = TAILQ_FIRST(&zdplane_info.dg_providers_q); + ctx = dplane_ctx_list_first(&zdplane_info.dg_update_list); + prov = dplane_prov_list_first(&zdplane_info.dg_providers); } DPLANE_UNLOCK(); @@ -6587,9 +6583,9 @@ static bool dplane_work_pending(void) dplane_provider_lock(prov); - ctx = TAILQ_FIRST(&(prov->dp_ctx_in_q)); + ctx = dplane_ctx_list_first(&(prov->dp_ctx_in_list)); if (ctx == NULL) - ctx = TAILQ_FIRST(&(prov->dp_ctx_out_q)); + ctx = dplane_ctx_list_first(&(prov->dp_ctx_out_list)); dplane_provider_unlock(prov); @@ -6597,7 +6593,7 @@ static bool dplane_work_pending(void) break; DPLANE_LOCK(); - prov = TAILQ_NEXT(prov, dp_prov_link); + prov = dplane_prov_list_next(&zdplane_info.dg_providers, prov); DPLANE_UNLOCK(); } @@ -6683,10 +6679,10 @@ void zebra_dplane_finish(void) */ static void dplane_thread_loop(struct thread *event) { - struct dplane_ctx_q work_list; - struct dplane_ctx_q error_list; + struct dplane_ctx_list_head work_list; + struct dplane_ctx_list_head error_list; struct zebra_dplane_provider *prov; - struct zebra_dplane_ctx *ctx, *tctx; + struct zebra_dplane_ctx *ctx; int limit, counter, error_counter; uint64_t curr, high; bool reschedule = false; @@ -6695,8 +6691,9 @@ static void dplane_thread_loop(struct thread *event) limit = zdplane_info.dg_updates_per_cycle; /* Init temporary lists used to move contexts among providers */ - TAILQ_INIT(&work_list); - TAILQ_INIT(&error_list); + dplane_ctx_list_init(&work_list); + dplane_ctx_list_init(&error_list); + error_counter = 0; /* Check for zebra shutdown */ @@ -6709,18 +6706,15 @@ static void dplane_thread_loop(struct thread *event) DPLANE_LOCK(); /* Locate initial registered provider */ - prov = TAILQ_FIRST(&zdplane_info.dg_providers_q); + prov = dplane_prov_list_first(&zdplane_info.dg_providers); /* Move new work from incoming list to temp list */ for (counter = 0; counter < limit; counter++) { - ctx = TAILQ_FIRST(&zdplane_info.dg_update_ctx_q); + ctx = dplane_ctx_list_pop(&zdplane_info.dg_update_list); if (ctx) { - TAILQ_REMOVE(&zdplane_info.dg_update_ctx_q, ctx, - zd_q_entries); - ctx->zd_provider = prov->dp_id; - TAILQ_INSERT_TAIL(&work_list, ctx, zd_q_entries); + dplane_ctx_list_add_tail(&work_list, ctx); } else { break; } @@ -6750,7 +6744,7 @@ static void dplane_thread_loop(struct thread *event) /* Capture current provider id in each context; check for * error status. */ - TAILQ_FOREACH_SAFE(ctx, &work_list, zd_q_entries, tctx) { + frr_each_safe (dplane_ctx_list, &work_list, ctx) { if (dplane_ctx_get_status(ctx) == ZEBRA_DPLANE_REQUEST_SUCCESS) { ctx->zd_provider = prov->dp_id; @@ -6764,9 +6758,8 @@ static void dplane_thread_loop(struct thread *event) /* Move to error list; will be returned * zebra main. */ - TAILQ_REMOVE(&work_list, ctx, zd_q_entries); - TAILQ_INSERT_TAIL(&error_list, - ctx, zd_q_entries); + dplane_ctx_list_del(&work_list, ctx); + dplane_ctx_list_add_tail(&error_list, ctx); error_counter++; } } @@ -6774,9 +6767,8 @@ static void dplane_thread_loop(struct thread *event) /* Enqueue new work to the provider */ dplane_provider_lock(prov); - if (TAILQ_FIRST(&work_list)) - TAILQ_CONCAT(&(prov->dp_ctx_in_q), &work_list, - zd_q_entries); + while ((ctx = dplane_ctx_list_pop(&work_list)) != NULL) + dplane_ctx_list_add_tail(&(prov->dp_ctx_in_list), ctx); atomic_fetch_add_explicit(&prov->dp_in_counter, counter, memory_order_relaxed); @@ -6795,7 +6787,7 @@ static void dplane_thread_loop(struct thread *event) /* Reset the temp list (though the 'concat' may have done this * already), and the counter */ - TAILQ_INIT(&work_list); + dplane_ctx_list_init(&work_list); counter = 0; /* Call into the provider code. Note that this is @@ -6812,13 +6804,9 @@ static void dplane_thread_loop(struct thread *event) dplane_provider_lock(prov); while (counter < limit) { - ctx = TAILQ_FIRST(&(prov->dp_ctx_out_q)); + ctx = dplane_ctx_list_pop(&(prov->dp_ctx_out_list)); if (ctx) { - TAILQ_REMOVE(&(prov->dp_ctx_out_q), ctx, - zd_q_entries); - - TAILQ_INSERT_TAIL(&work_list, - ctx, zd_q_entries); + dplane_ctx_list_add_tail(&work_list, ctx); counter++; } else break; @@ -6835,7 +6823,7 @@ static void dplane_thread_loop(struct thread *event) /* Locate next provider */ DPLANE_LOCK(); - prov = TAILQ_NEXT(prov, dp_prov_link); + prov = dplane_prov_list_next(&zdplane_info.dg_providers, prov); DPLANE_UNLOCK(); } @@ -6861,12 +6849,12 @@ static void dplane_thread_loop(struct thread *event) /* Call through to zebra main */ (zdplane_info.dg_results_cb)(&error_list); - TAILQ_INIT(&error_list); + dplane_ctx_list_init(&error_list); /* Call through to zebra main */ (zdplane_info.dg_results_cb)(&work_list); - TAILQ_INIT(&work_list); + dplane_ctx_list_init(&work_list); } /* @@ -6899,7 +6887,7 @@ void zebra_dplane_shutdown(void) * Note that this call is in the main pthread, so providers must * be prepared for that. */ - TAILQ_FOREACH(dp, &zdplane_info.dg_providers_q, dp_prov_link) { + frr_each (dplane_prov_list, &zdplane_info.dg_providers, dp) { if (dp->dp_fini == NULL) continue; @@ -6920,8 +6908,9 @@ static void zebra_dplane_init_internal(void) pthread_mutex_init(&zdplane_info.dg_mutex, NULL); - TAILQ_INIT(&zdplane_info.dg_update_ctx_q); - TAILQ_INIT(&zdplane_info.dg_providers_q); + dplane_prov_list_init(&zdplane_info.dg_providers); + + dplane_ctx_list_init(&zdplane_info.dg_update_list); zns_info_list_init(&zdplane_info.dg_zns_list); zdplane_info.dg_updates_per_cycle = DPLANE_DEFAULT_NEW_WORK; @@ -6970,7 +6959,7 @@ void zebra_dplane_start(void) /* Call start callbacks for registered providers */ DPLANE_LOCK(); - prov = TAILQ_FIRST(&zdplane_info.dg_providers_q); + prov = dplane_prov_list_first(&zdplane_info.dg_providers); DPLANE_UNLOCK(); while (prov) { @@ -6980,7 +6969,7 @@ void zebra_dplane_start(void) /* Locate next provider */ DPLANE_LOCK(); - prov = TAILQ_NEXT(prov, dp_prov_link); + prov = dplane_prov_list_next(&zdplane_info.dg_providers, prov); DPLANE_UNLOCK(); } @@ -6990,7 +6979,7 @@ void zebra_dplane_start(void) /* * Initialize the dataplane module at startup; called by zebra rib_init() */ -void zebra_dplane_init(int (*results_fp)(struct dplane_ctx_q *)) +void zebra_dplane_init(int (*results_fp)(struct dplane_ctx_list_head *)) { zebra_dplane_init_internal(); zdplane_info.dg_results_cb = results_fp; diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index 51f6f3d897..ae13243a16 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -24,7 +24,6 @@ #include "lib/prefix.h" #include "lib/nexthop.h" #include "lib/nexthop_group.h" -#include "lib/queue.h" #include "lib/vlan.h" #include "zebra/zebra_ns.h" #include "zebra/rib.h" @@ -265,14 +264,15 @@ void dplane_enable_sys_route_notifs(void); * they cannot share existing global data structures safely. */ -/* Define a tailq list type for context blocks. The list is exposed/public, +/* Define a list type for context blocks. The list is exposed/public, * but the internal linkage in the context struct is private, so there * are accessor apis that support enqueue and dequeue. */ -TAILQ_HEAD(dplane_ctx_q, zebra_dplane_ctx); + +PREDECL_DLIST(dplane_ctx_list); /* Declare a type for (optional) extended interface info objects. */ -TAILQ_HEAD(dplane_intf_extra_q, dplane_intf_extra); +PREDECL_DLIST(dplane_intf_extra_list); /* Allocate a context object */ struct zebra_dplane_ctx *dplane_ctx_alloc(void); @@ -300,18 +300,21 @@ void dplane_ctx_fini(struct zebra_dplane_ctx **pctx); /* Enqueue a context block to caller's tailq. This exists so that the * context struct can remain opaque. */ -void dplane_ctx_enqueue_tail(struct dplane_ctx_q *q, +void dplane_ctx_enqueue_tail(struct dplane_ctx_list_head *q, const struct zebra_dplane_ctx *ctx); /* Append a list of context blocks to another list - again, just keeping * the context struct opaque. */ -void dplane_ctx_list_append(struct dplane_ctx_q *to_list, - struct dplane_ctx_q *from_list); +void dplane_ctx_list_append(struct dplane_ctx_list_head *to_list, + struct dplane_ctx_list_head *from_list); /* Dequeue a context block from the head of caller's tailq */ -struct zebra_dplane_ctx *dplane_ctx_dequeue(struct dplane_ctx_q *q); -struct zebra_dplane_ctx *dplane_ctx_get_head(struct dplane_ctx_q *q); +struct zebra_dplane_ctx *dplane_ctx_dequeue(struct dplane_ctx_list_head *q); +struct zebra_dplane_ctx *dplane_ctx_get_head(struct dplane_ctx_list_head *q); + +/* Init a list of contexts */ +void dplane_ctx_q_init(struct dplane_ctx_list_head *q); /* * Accessors for information from the context object @@ -1036,7 +1039,7 @@ struct zebra_dplane_ctx *dplane_provider_dequeue_in_ctx( /* Dequeue work to a list, maintain counter and locking, return count */ int dplane_provider_dequeue_in_list(struct zebra_dplane_provider *prov, - struct dplane_ctx_q *listp); + struct dplane_ctx_list_head *listp); /* Current completed work queue length */ uint32_t dplane_provider_out_ctx_queue_len(struct zebra_dplane_provider *prov); @@ -1061,7 +1064,7 @@ void dplane_enable_intf_extra_info(void); * so the expectation is that the contexts are queued for the zebra * main pthread. */ -void zebra_dplane_init(int (*) (struct dplane_ctx_q *)); +void zebra_dplane_init(int (*)(struct dplane_ctx_list_head *)); /* * Start the dataplane pthread. This step needs to be run later than the diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c index 628d4a2a87..06c45578a6 100644 --- a/zebra/zebra_fpm_netlink.c +++ b/zebra/zebra_fpm_netlink.c @@ -253,14 +253,7 @@ static int netlink_route_info_add_nh(struct netlink_route_info *ri, */ static uint8_t netlink_proto_from_route_type(int type) { - switch (type) { - case ZEBRA_ROUTE_KERNEL: - case ZEBRA_ROUTE_CONNECT: - return RTPROT_KERNEL; - - default: - return RTPROT_ZEBRA; - } + return zebra2proto(type); } /* diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c index 73d585c1a3..8905b72ec5 100644 --- a/zebra/zebra_netns_id.c +++ b/zebra/zebra_netns_id.c @@ -23,6 +23,7 @@ #include "vrf.h" #include "log.h" #include "lib_errors.h" +#include "network.h" #include "zebra/rib.h" #include "zebra/zebra_dplane.h" @@ -73,7 +74,7 @@ static struct nlmsghdr *initiate_nlh(char *buf, unsigned int *seq, int type) nlh->nlmsg_flags = NLM_F_REQUEST; if (type == RTM_NEWNSID) nlh->nlmsg_flags |= NLM_F_ACK; - nlh->nlmsg_seq = *seq = time(NULL); + nlh->nlmsg_seq = *seq = frr_sequence32_next(); return nlh; } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 81910f68b7..d5375105a9 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -72,7 +72,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, WQ_WRAPPER, "WQ wrapper"); */ static pthread_mutex_t dplane_mutex; static struct thread *t_dplane; -static struct dplane_ctx_q rib_dplane_q; +static struct dplane_ctx_list_head rib_dplane_q; DEFINE_HOOK(rib_update, (struct route_node * rn, const char *reason), (rn, reason)); @@ -4613,13 +4613,13 @@ static void handle_pw_result(struct zebra_dplane_ctx *ctx) static void rib_process_dplane_results(struct thread *thread) { struct zebra_dplane_ctx *ctx; - struct dplane_ctx_q ctxlist; + struct dplane_ctx_list_head ctxlist; bool shut_p = false; /* Dequeue a list of completed updates with one lock/unlock cycle */ do { - TAILQ_INIT(&ctxlist); + dplane_ctx_q_init(&ctxlist); /* Take lock controlling queue of results */ frr_with_mutex (&dplane_mutex) { @@ -4788,7 +4788,7 @@ static void rib_process_dplane_results(struct thread *thread) * the dataplane pthread. We enqueue the results here for processing by * the main thread later. */ -static int rib_dplane_results(struct dplane_ctx_q *ctxlist) +static int rib_dplane_results(struct dplane_ctx_list_head *ctxlist) { /* Take lock controlling queue of results */ frr_with_mutex (&dplane_mutex) { @@ -4833,7 +4833,7 @@ void rib_init(void) /* Init dataplane, and register for results */ pthread_mutex_init(&dplane_mutex, NULL); - TAILQ_INIT(&rib_dplane_q); + dplane_ctx_q_init(&rib_dplane_q); zebra_dplane_init(rib_dplane_results); } |
