summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babeld/babel_main.c6
-rw-r--r--bfdd/ptm_adapter.c3
-rw-r--r--bgpd/bgp_labelpool.c6
-rw-r--r--bgpd/bgp_nexthop.c33
-rw-r--r--bgpd/bgp_nexthop.h8
-rw-r--r--bgpd/bgp_nht.c38
-rw-r--r--bgpd/bgp_zebra.c6
-rw-r--r--bgpd/bgpd.h3
-rw-r--r--doc/developer/frr-release-procedure.rst7
-rw-r--r--doc/user/routemap.rst6
-rw-r--r--eigrpd/eigrp_interface.c6
-rw-r--r--isisd/isis_circuit.c6
-rw-r--r--isisd/isis_srv6.c13
-rw-r--r--isisd/isis_srv6.h6
-rw-r--r--ldpd/ldp_zebra.c5
-rw-r--r--lib/buffer.h26
-rw-r--r--lib/compiler.h4
-rw-r--r--lib/if.c38
-rw-r--r--lib/if.h67
-rw-r--r--lib/prefix.h26
-rw-r--r--lib/sockunion.h34
-rw-r--r--lib/workqueue.c30
-rw-r--r--lib/workqueue.h21
-rw-r--r--nhrpd/nhrp_main.c6
-rw-r--r--ospf6d/ospf6_interface.c6
-rw-r--r--ospfd/ospf_interface.c6
-rw-r--r--pathd/path_pcep.h1
-rw-r--r--pathd/path_pcep_cli.c43
-rw-r--r--pbrd/pbr_main.c6
-rw-r--r--pimd/pim_addr.h16
-rw-r--r--pimd/pim_iface.c6
-rw-r--r--ripd/rip_interface.c6
-rw-r--r--ripngd/ripng_interface.c6
-rw-r--r--sharpd/sharp_zebra.c6
-rw-r--r--staticd/static_zebra.c6
-rw-r--r--tests/lib/test_heavy_wq.c6
-rw-r--r--vrrpd/vrrp_zebra.c6
-rw-r--r--zebra/interface.c5
-rw-r--r--zebra/main.c4
-rw-r--r--zebra/redistribute.c4
-rw-r--r--zebra/rib.h2
-rw-r--r--zebra/rt_netlink.c7
-rw-r--r--zebra/zebra_router.h2
-rw-r--r--zebra/zebra_script.c1
-rw-r--r--zebra/zebra_vty.c15
45 files changed, 322 insertions, 242 deletions
diff --git a/babeld/babel_main.c b/babeld/babel_main.c
index b6126d5b7d..4ca649e2c2 100644
--- a/babeld/babel_main.c
+++ b/babeld/babel_main.c
@@ -182,8 +182,10 @@ main(int argc, char **argv)
change_smoothing_half_life(BABEL_DEFAULT_SMOOTHING_HALF_LIFE);
/* init some quagga's dependencies, and babeld's commands */
- if_zapi_callbacks(babel_ifp_create, babel_ifp_up,
- babel_ifp_down, babel_ifp_destroy);
+ hook_register_prio(if_real, 0, babel_ifp_create);
+ hook_register_prio(if_up, 0, babel_ifp_up);
+ hook_register_prio(if_down, 0, babel_ifp_down);
+ hook_register_prio(if_unreal, 0, babel_ifp_destroy);
babeld_quagga_init();
/* init zebra client's structure and it's commands */
/* this replace kernel_setup && kernel_setup_socket */
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index 9e7ed114ee..e6c2fb71f0 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -826,7 +826,8 @@ static zclient_handler *const bfd_handlers[] = {
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
{
- if_zapi_callbacks(bfd_ifp_create, NULL, NULL, bfd_ifp_destroy);
+ hook_register_prio(if_real, 0, bfd_ifp_create);
+ hook_register_prio(if_unreal, 0, bfd_ifp_destroy);
zclient = zclient_new(master, &zclient_options_default, bfd_handlers,
array_size(bfd_handlers));
assert(zclient != NULL);
diff --git a/bgpd/bgp_labelpool.c b/bgpd/bgp_labelpool.c
index b2bb49b943..bf2b3566b4 100644
--- a/bgpd/bgp_labelpool.c
+++ b/bgpd/bgp_labelpool.c
@@ -652,11 +652,7 @@ void bgp_lp_event_zebra_up(void)
}
/* round up */
- if (((float)labels_needed / (float)lp->next_chunksize) >
- (labels_needed / lp->next_chunksize))
- chunks_needed = (labels_needed / lp->next_chunksize) + 1;
- else
- chunks_needed = (labels_needed / lp->next_chunksize);
+ chunks_needed = (labels_needed + lp->next_chunksize - 1) / lp->next_chunksize;
labels_needed = chunks_needed * lp->next_chunksize;
/*
diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c
index 44241b8582..d12dc22330 100644
--- a/bgpd/bgp_nexthop.c
+++ b/bgpd/bgp_nexthop.c
@@ -58,8 +58,7 @@ void bnc_nexthop_free(struct bgp_nexthop_cache *bnc)
struct bgp_nexthop_cache *bnc_new(struct bgp_nexthop_cache_head *tree,
struct prefix *prefix, uint32_t srte_color,
- ifindex_t ifindex, bool import_check_table,
- bool nexthop_check_table)
+ ifindex_t ifindex)
{
struct bgp_nexthop_cache *bnc;
@@ -69,9 +68,6 @@ struct bgp_nexthop_cache *bnc_new(struct bgp_nexthop_cache_head *tree,
bnc->ifindex_ipv6_ll = ifindex;
bnc->srte_color = srte_color;
bnc->tree = tree;
- bnc->import_check_table = import_check_table;
- bnc->nexthop_check_table = nexthop_check_table;
-
LIST_INIT(&(bnc->paths));
bgp_nexthop_cache_add(tree, bnc);
@@ -972,7 +968,7 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
struct bgp_nexthop_cache *bnc, bool specific,
- bool import_check_table, json_object *json)
+ json_object *json)
{
char buf[PREFIX2STR_BUFFER];
time_t tbuf;
@@ -981,12 +977,6 @@ static void bgp_show_nexthop(struct vty *vty, struct bgp *bgp,
json_object *json_last_update = NULL;
json_object *json_nexthop = NULL;
- if (bnc->import_check_table && !import_check_table)
- return;
-
- if (bnc->nexthop_check_table && import_check_table)
- return;
-
peer = (struct peer *)bnc->nht_info;
if (json)
@@ -1113,14 +1103,16 @@ static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp,
else
vty_out(vty, "Current BGP nexthop cache:\n");
}
+ if (import_table)
+ tree = &bgp->import_check_table;
+ else
+ tree = &bgp->nexthop_cache_table;
- tree = &bgp->nexthop_cache_table;
if (afi == AFI_IP || afi == AFI_IP6) {
if (json)
json_afi = json_object_new_object();
frr_each (bgp_nexthop_cache, &(*tree)[afi], bnc) {
- bgp_show_nexthop(vty, bgp, bnc, detail, import_table,
- json_afi);
+ bgp_show_nexthop(vty, bgp, bnc, detail, json_afi);
found = true;
}
if (found && json)
@@ -1134,8 +1126,7 @@ static void bgp_show_nexthops(struct vty *vty, struct bgp *bgp,
if (json && (afi == AFI_IP || afi == AFI_IP6))
json_afi = json_object_new_object();
frr_each (bgp_nexthop_cache, &(*tree)[afi], bnc)
- bgp_show_nexthop(vty, bgp, bnc, detail, import_table,
- json_afi);
+ bgp_show_nexthop(vty, bgp, bnc, detail, json_afi);
if (json && (afi == AFI_IP || afi == AFI_IP6))
json_object_object_add(
json, (afi == AFI_IP) ? "ipv4" : "ipv6",
@@ -1171,15 +1162,15 @@ static int show_ip_bgp_nexthop_table(struct vty *vty, const char *name,
vty_out(vty, "nexthop address is malformed\n");
return CMD_WARNING;
}
- tree = &bgp->nexthop_cache_table;
+ tree = import_table ? &bgp->import_check_table
+ : &bgp->nexthop_cache_table;
if (json)
json_afi = json_object_new_object();
frr_each (bgp_nexthop_cache, &(*tree)[family2afi(nhop.family)],
bnc) {
if (prefix_cmp(&bnc->prefix, &nhop))
continue;
- bgp_show_nexthop(vty, bgp, bnc, true, import_table,
- json_afi);
+ bgp_show_nexthop(vty, bgp, bnc, true, json_afi);
found = true;
}
if (json)
@@ -1322,6 +1313,7 @@ void bgp_scan_init(struct bgp *bgp)
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
bgp_nexthop_cache_init(&bgp->nexthop_cache_table[afi]);
+ bgp_nexthop_cache_init(&bgp->import_check_table[afi]);
bgp->connected_table[afi] = bgp_table_init(bgp, afi,
SAFI_UNICAST);
}
@@ -1341,6 +1333,7 @@ void bgp_scan_finish(struct bgp *bgp)
for (afi = AFI_IP; afi < AFI_MAX; afi++) {
/* Only the current one needs to be reset. */
bgp_nexthop_cache_reset(&bgp->nexthop_cache_table[afi]);
+ bgp_nexthop_cache_reset(&bgp->import_check_table[afi]);
bgp->connected_table[afi]->route_table->cleanup =
bgp_connected_cleanup;
diff --git a/bgpd/bgp_nexthop.h b/bgpd/bgp_nexthop.h
index c1d4d088a3..49cbbaf885 100644
--- a/bgpd/bgp_nexthop.h
+++ b/bgpd/bgp_nexthop.h
@@ -91,9 +91,6 @@ struct bgp_nexthop_cache {
* nexthop.
*/
bool is_evpn_gwip_nexthop;
-
- bool import_check_table;
- bool nexthop_check_table;
};
extern int bgp_nexthop_cache_compare(const struct bgp_nexthop_cache *a,
@@ -135,9 +132,8 @@ extern bool bgp_nexthop_self(struct bgp *bgp, afi_t afi, uint8_t type,
struct bgp_dest *dest);
extern struct bgp_nexthop_cache *bnc_new(struct bgp_nexthop_cache_head *tree,
struct prefix *prefix,
- uint32_t srte_color, ifindex_t ifindex,
- bool import_check_table,
- bool nexthop_check_table);
+ uint32_t srte_color,
+ ifindex_t ifindex);
extern bool bnc_existing_for_prefix(struct bgp_nexthop_cache *bnc);
extern void bnc_free(struct bgp_nexthop_cache *bnc);
extern struct bgp_nexthop_cache *bnc_find(struct bgp_nexthop_cache_head *tree,
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index aa37303fca..60d6f74e14 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -378,12 +378,14 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
} else
return 0;
- tree = &bgp_nexthop->nexthop_cache_table[afi];
+ if (is_bgp_static_route)
+ tree = &bgp_nexthop->import_check_table[afi];
+ else
+ tree = &bgp_nexthop->nexthop_cache_table[afi];
bnc = bnc_find(tree, &p, srte_color, ifindex);
if (!bnc) {
- bnc = bnc_new(tree, &p, srte_color, ifindex,
- is_bgp_static_route, !is_bgp_static_route);
+ bnc = bnc_new(tree, &p, srte_color, ifindex);
bnc->bgp = bgp_nexthop;
if (BGP_DEBUG(nht, NHT))
zlog_debug("Allocated bnc %pFX(%d)(%u)(%s) peer %p",
@@ -391,11 +393,6 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
bnc->srte_color, bnc->bgp->name_pretty,
peer);
} else {
- if (is_bgp_static_route)
- bnc->import_check_table = true;
- else
- bnc->nexthop_check_table = true;
-
if (BGP_DEBUG(nht, NHT))
zlog_debug(
"Found existing bnc %pFX(%d)(%s) flags 0x%x ifindex %d #paths %d peer %p",
@@ -822,8 +819,12 @@ static void bgp_nht_ifp_handle(struct interface *ifp, bool up)
bgp_nht_ifp_table_handle(bgp, &bgp->nexthop_cache_table[AFI_IP], ifp,
up);
+ bgp_nht_ifp_table_handle(bgp, &bgp->import_check_table[AFI_IP], ifp,
+ up);
bgp_nht_ifp_table_handle(bgp, &bgp->nexthop_cache_table[AFI_IP6], ifp,
up);
+ bgp_nht_ifp_table_handle(bgp, &bgp->import_check_table[AFI_IP6], ifp,
+ up);
}
void bgp_nht_ifp_up(struct interface *ifp)
@@ -899,7 +900,7 @@ void bgp_nht_interface_events(struct peer *peer)
void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
{
struct bgp_nexthop_cache_head *tree = NULL;
- struct bgp_nexthop_cache *bnc_nhc;
+ struct bgp_nexthop_cache *bnc_nhc, *bnc_import;
struct bgp *bgp;
struct prefix match;
struct zapi_route nhr;
@@ -929,12 +930,19 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
zlog_debug(
"parse nexthop update %pFX(%u)(%s): bnc info not found for nexthop cache",
&nhr.prefix, nhr.srte_color, bgp->name_pretty);
- } else {
- if (bnc_nhc->nexthop_check_table)
- bgp_process_nexthop_update(bnc_nhc, &nhr, false);
- if (bnc_nhc->import_check_table)
- bgp_process_nexthop_update(bnc_nhc, &nhr, true);
- }
+ } else
+ bgp_process_nexthop_update(bnc_nhc, &nhr, false);
+
+ tree = &bgp->import_check_table[afi];
+
+ bnc_import = bnc_find(tree, &match, nhr.srte_color, 0);
+ if (!bnc_import) {
+ if (BGP_DEBUG(nht, NHT))
+ zlog_debug(
+ "parse nexthop update %pFX(%u)(%s): bnc info not found for import check",
+ &nhr.prefix, nhr.srte_color, bgp->name_pretty);
+ } else
+ bgp_process_nexthop_update(bnc_import, &nhr, true);
/*
* HACK: if any BGP route is dependant on an SR-policy that doesn't
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index ff8a87d76b..381acd803e 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -3442,8 +3442,10 @@ void bgp_zebra_init(struct event_loop *master, unsigned short instance)
options.synchronous = true;
zclient_num_connects = 0;
- if_zapi_callbacks(bgp_ifp_create, bgp_ifp_up,
- bgp_ifp_down, bgp_ifp_destroy);
+ hook_register_prio(if_real, 0, bgp_ifp_create);
+ hook_register_prio(if_up, 0, bgp_ifp_up);
+ hook_register_prio(if_down, 0, bgp_ifp_down);
+ hook_register_prio(if_unreal, 0, bgp_ifp_destroy);
/* Set default values. */
zclient = zclient_new(master, &zclient_options_default, bgp_handlers,
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index db3991cd07..a7860721e9 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -559,6 +559,9 @@ struct bgp {
/* Tree for next-hop lookup cache. */
struct bgp_nexthop_cache_head nexthop_cache_table[AFI_MAX];
+ /* Tree for import-check */
+ struct bgp_nexthop_cache_head import_check_table[AFI_MAX];
+
struct bgp_table *connected_table[AFI_MAX];
struct hash *address_hash;
diff --git a/doc/developer/frr-release-procedure.rst b/doc/developer/frr-release-procedure.rst
index 9378637ded..9dbc9b48d7 100644
--- a/doc/developer/frr-release-procedure.rst
+++ b/doc/developer/frr-release-procedure.rst
@@ -13,6 +13,13 @@ Stage 1 - Preparation
Note: use ``tools/release_notes.py`` to help draft release notes changelog
+ .. code-block:: console
+
+ ./tools/release_notes.py -b dev/9.1 -t frr-9.0.1
+
+ dev/9.1 is the branch to be renamed to stable/9.1, and frr-9.0.1 in this
+ example is the latest tag from which to generate the logs.
+
#. Checkout the existing ``dev/<version>`` branch.
.. code-block:: console
diff --git a/doc/user/routemap.rst b/doc/user/routemap.rst
index 3d43e74744..18a261d940 100644
--- a/doc/user/routemap.rst
+++ b/doc/user/routemap.rst
@@ -185,9 +185,11 @@ Route Map Match Command
Matches the specified `local-preference`.
-.. clicmd:: match community COMMUNITY_LIST
+.. clicmd:: match community COMMUNITY_LIST [<exact-match|any>]
- Matches the specified `community_list`
+ Matches the specified `community_list`. ``exact-match`` specifies to
+ do the exact matching of the communities, while ``any`` - can match any
+ community specified in COMMUNITY_LIST.
.. clicmd:: match peer IPV4_ADDR
diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c
index 7bb1617c19..fb8f47e723 100644
--- a/eigrpd/eigrp_interface.c
+++ b/eigrpd/eigrp_interface.c
@@ -202,8 +202,10 @@ struct list *eigrp_iflist;
void eigrp_if_init(void)
{
- if_zapi_callbacks(eigrp_ifp_create, eigrp_ifp_up,
- eigrp_ifp_down, eigrp_ifp_destroy);
+ hook_register_prio(if_real, 0, eigrp_ifp_create);
+ hook_register_prio(if_up, 0, eigrp_ifp_up);
+ hook_register_prio(if_down, 0, eigrp_ifp_down);
+ hook_register_prio(if_unreal, 0, eigrp_ifp_destroy);
/* Initialize Zebra interface data structure. */
// hook_register_prio(if_add, 0, eigrp_if_new);
hook_register_prio(if_del, 0, eigrp_if_delete_hook);
diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c
index ffa6ad3e40..3fca6b23d7 100644
--- a/isisd/isis_circuit.c
+++ b/isisd/isis_circuit.c
@@ -1680,6 +1680,8 @@ void isis_circuit_init(void)
#else
if_cmd_init_default();
#endif
- if_zapi_callbacks(isis_ifp_create, isis_ifp_up,
- isis_ifp_down, isis_ifp_destroy);
+ hook_register_prio(if_real, 0, isis_ifp_create);
+ hook_register_prio(if_up, 0, isis_ifp_up);
+ hook_register_prio(if_down, 0, isis_ifp_down);
+ hook_register_prio(if_unreal, 0, isis_ifp_destroy);
}
diff --git a/isisd/isis_srv6.c b/isisd/isis_srv6.c
index 0eb8ac3fb7..1b0c706946 100644
--- a/isisd/isis_srv6.c
+++ b/isisd/isis_srv6.c
@@ -183,7 +183,7 @@ void isis_srv6_interface_set(struct isis_area *area, const char *ifname)
isis_zebra_srv6_sid_uninstall(area, sid);
}
- strncpy(area->srv6db.config.srv6_ifname, ifname, IF_NAMESIZE - 1);
+ strlcpy(area->srv6db.config.srv6_ifname, ifname, sizeof(area->srv6db.config.srv6_ifname));
if (!if_lookup_by_name(area->srv6db.config.srv6_ifname, VRF_DEFAULT)) {
sr_debug("Interface %s not yet exist in data plane, deferring SIDs installation until it's created", area->srv6db.config.srv6_ifname);
@@ -777,6 +777,7 @@ void isis_srv6_area_init(struct isis_area *area)
srv6db->srv6_endx_sids = list_new();
/* Pull defaults from the YANG module */
+#ifndef FABRICD
srv6db->config.enabled = yang_get_default_bool("%s/enabled", ISIS_SRV6);
srv6db->config.max_seg_left_msd =
yang_get_default_uint8("%s/msd/node-msd/max-segs-left",
@@ -788,7 +789,15 @@ void isis_srv6_area_init(struct isis_area *area)
ISIS_SRV6);
srv6db->config.max_end_d_msd =
yang_get_default_uint8("%s/msd/node-msd/max-end-d", ISIS_SRV6);
- strncpy(srv6db->config.srv6_ifname, yang_get_default_string("%s/interface", ISIS_SRV6), IF_NAMESIZE - 1);
+ strlcpy(srv6db->config.srv6_ifname, yang_get_default_string("%s/interface", ISIS_SRV6), sizeof(srv6db->config.srv6_ifname));
+#else
+ srv6db->config.enabled = false;
+ srv6db->config.max_seg_left_msd = ISIS_DEFAULT_SRV6_MAX_SEG_LEFT_MSD;
+ srv6db->config.max_end_pop_msd = ISIS_DEFAULT_SRV6_MAX_END_POP_MSD;
+ srv6db->config.max_h_encaps_msd = ISIS_DEFAULT_SRV6_MAX_H_ENCAPS_MSD;
+ srv6db->config.max_end_d_msd = ISIS_DEFAULT_SRV6_MAX_END_D_MSD;
+ strlcpy(srv6db->config.srv6_ifname, ISIS_DEFAULT_SRV6_IFNAME, sizeof(srv6db->config.srv6_ifname));
+#endif
/* Initialize SRv6 Locator chunks list */
srv6db->srv6_locator_chunks = list_new();
diff --git a/isisd/isis_srv6.h b/isisd/isis_srv6.h
index 65c0978bc5..33864360c1 100644
--- a/isisd/isis_srv6.h
+++ b/isisd/isis_srv6.h
@@ -13,6 +13,12 @@
#include "lib/srv6.h"
#include "isisd/isis_tlvs.h"
+#define ISIS_DEFAULT_SRV6_MAX_SEG_LEFT_MSD 3
+#define ISIS_DEFAULT_SRV6_MAX_END_POP_MSD 3
+#define ISIS_DEFAULT_SRV6_MAX_H_ENCAPS_MSD 2
+#define ISIS_DEFAULT_SRV6_MAX_END_D_MSD 5
+#define ISIS_DEFAULT_SRV6_IFNAME "sr0"
+
/* SRv6 SID structure */
struct isis_srv6_sid_structure {
uint8_t loc_block_len;
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index 0fd5d4613c..a9814f18f8 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -682,7 +682,10 @@ static zclient_handler *const ldp_handlers[] = {
void ldp_zebra_init(struct event_loop *master)
{
- if_zapi_callbacks(ldp_ifp_create, ldp_ifp_up, ldp_ifp_down, ldp_ifp_destroy);
+ hook_register_prio(if_real, 0, ldp_ifp_create);
+ hook_register_prio(if_up, 0, ldp_ifp_up);
+ hook_register_prio(if_down, 0, ldp_ifp_down);
+ hook_register_prio(if_unreal, 0, ldp_ifp_destroy);
/* Set default values. */
zclient = zclient_new(master, &zclient_options_default, ldp_handlers,
diff --git a/lib/buffer.h b/lib/buffer.h
index 5d98c31dbc..a0b82d2121 100644
--- a/lib/buffer.h
+++ b/lib/buffer.h
@@ -14,21 +14,21 @@ extern "C" {
/* Create a new buffer. Memory will be allocated in chunks of the given
size. If the argument is 0, the library will supply a reasonable
default size suitable for buffering socket I/O. */
-extern struct buffer *buffer_new(size_t);
+extern struct buffer *buffer_new(size_t size);
/* Free all data in the buffer. */
-extern void buffer_reset(struct buffer *);
+extern void buffer_reset(struct buffer *b);
/* This function first calls buffer_reset to release all buffered data.
Then it frees the struct buffer itself. */
-extern void buffer_free(struct buffer *);
+extern void buffer_free(struct buffer *b);
/* Add the given data to the end of the buffer. */
-extern void buffer_put(struct buffer *, const void *, size_t);
+extern void buffer_put(struct buffer *b, const void *p, size_t size);
/* Add a single character to the end of the buffer. */
-extern void buffer_putc(struct buffer *, uint8_t);
+extern void buffer_putc(struct buffer *b, uint8_t c);
/* Add a NUL-terminated string to the end of the buffer. */
-extern void buffer_putstr(struct buffer *, const char *);
+extern void buffer_putstr(struct buffer *b, const char *str);
/* Add given data, inline-expanding \n to \r\n */
extern void buffer_put_crlf(struct buffer *b, const void *p, size_t size);
@@ -36,10 +36,10 @@ extern void buffer_put_crlf(struct buffer *b, const void *p, size_t size);
single NUL-terminated string allocated using XMALLOC(MTYPE_TMP). Note
that this function does not alter the state of the buffer, so the data
is still inside waiting to be flushed. */
-char *buffer_getstr(struct buffer *);
+char *buffer_getstr(struct buffer *b);
/* Returns 1 if there is no pending data in the buffer. Otherwise returns 0. */
-int buffer_empty(struct buffer *);
+int buffer_empty(struct buffer *b);
typedef enum {
/* An I/O error occurred. The buffer should be destroyed and the
@@ -59,12 +59,12 @@ typedef enum {
/* Try to write this data to the file descriptor. Any data that cannot
be written immediately is added to the buffer queue. */
-extern buffer_status_t buffer_write(struct buffer *, int fd, const void *,
- size_t);
+extern buffer_status_t buffer_write(struct buffer *b, int fd, const void *p,
+ size_t size);
/* This function attempts to flush some (but perhaps not all) of
the queued data to the given file descriptor. */
-extern buffer_status_t buffer_flush_available(struct buffer *, int fd);
+extern buffer_status_t buffer_flush_available(struct buffer *b, int fd);
/* The following 2 functions (buffer_flush_all and buffer_flush_window)
are for use in lib/vty.c only. They should not be used elsewhere. */
@@ -72,7 +72,7 @@ extern buffer_status_t buffer_flush_available(struct buffer *, int fd);
/* Call buffer_flush_available repeatedly until either all data has been
flushed, or an I/O error has been encountered, or the operation would
block. */
-extern buffer_status_t buffer_flush_all(struct buffer *, int fd);
+extern buffer_status_t buffer_flush_all(struct buffer *b, int fd);
/* Attempt to write enough data to the given fd to fill a window of the
given width and height (and remove the data written from the buffer).
@@ -85,7 +85,7 @@ extern buffer_status_t buffer_flush_all(struct buffer *, int fd);
to return -1 (because the logic for handling the erase and more features
is too complicated to retry the write later).
*/
-extern buffer_status_t buffer_flush_window(struct buffer *, int fd, int width,
+extern buffer_status_t buffer_flush_window(struct buffer *b, int fd, int width,
int height, int erase, int no_more);
#ifdef __cplusplus
diff --git a/lib/compiler.h b/lib/compiler.h
index 0a54c02d20..617b0c265b 100644
--- a/lib/compiler.h
+++ b/lib/compiler.h
@@ -424,10 +424,10 @@ _Static_assert(sizeof(_uint64_t) == 8 && sizeof(_int64_t) == 8,
* type.)
*/
#ifndef __cplusplus
-#define prefixtype(uname, typename, fieldname) typename *fieldname;
+#define uniontype(uname, typename, fieldname) typename *fieldname;
#define TRANSPARENT_UNION __attribute__((transparent_union))
#else
-#define prefixtype(uname, typename, fieldname) \
+#define uniontype(uname, typename, fieldname) \
typename *fieldname; \
uname(typename *x) \
{ \
diff --git a/lib/if.c b/lib/if.c
index 48c01af882..9e9cbd53a4 100644
--- a/lib/if.c
+++ b/lib/if.c
@@ -42,15 +42,14 @@ RB_GENERATE(if_index_head, interface, index_entry, if_cmp_index_func);
DEFINE_QOBJ_TYPE(interface);
-DEFINE_HOOK(if_add, (struct interface * ifp), (ifp));
-DEFINE_KOOH(if_del, (struct interface * ifp), (ifp));
+DEFINE_HOOK(if_add, (struct interface *ifp), (ifp));
+DEFINE_KOOH(if_del, (struct interface *ifp), (ifp));
-static struct interface_master{
- int (*create_hook)(struct interface *ifp);
- int (*up_hook)(struct interface *ifp);
- int (*down_hook)(struct interface *ifp);
- int (*destroy_hook)(struct interface *ifp);
-} ifp_master = { 0, };
+DEFINE_HOOK(if_real, (struct interface *ifp), (ifp));
+DEFINE_KOOH(if_unreal, (struct interface *ifp), (ifp));
+
+DEFINE_HOOK(if_up, (struct interface *ifp), (ifp));
+DEFINE_KOOH(if_down, (struct interface *ifp), (ifp));
/* Compare interface names, returning an integer greater than, equal to, or
* less than 0, (following the strcmp convention), according to the
@@ -180,14 +179,12 @@ static struct interface *if_new(struct vrf *vrf)
void if_new_via_zapi(struct interface *ifp)
{
- if (ifp_master.create_hook)
- (*ifp_master.create_hook)(ifp);
+ hook_call(if_real, ifp);
}
void if_destroy_via_zapi(struct interface *ifp)
{
- if (ifp_master.destroy_hook)
- (*ifp_master.destroy_hook)(ifp);
+ hook_call(if_unreal, ifp);
ifp->oldifindex = ifp->ifindex;
if_set_index(ifp, IFINDEX_INTERNAL);
@@ -198,14 +195,12 @@ void if_destroy_via_zapi(struct interface *ifp)
void if_up_via_zapi(struct interface *ifp)
{
- if (ifp_master.up_hook)
- (*ifp_master.up_hook)(ifp);
+ hook_call(if_up, ifp);
}
void if_down_via_zapi(struct interface *ifp)
{
- if (ifp_master.down_hook)
- (*ifp_master.down_hook)(ifp);
+ hook_call(if_down, ifp);
}
static struct interface *if_create_name(const char *name, struct vrf *vrf)
@@ -1477,17 +1472,6 @@ void if_cmd_init_default(void)
if_cmd_init(if_nb_config_write);
}
-void if_zapi_callbacks(int (*create)(struct interface *ifp),
- int (*up)(struct interface *ifp),
- int (*down)(struct interface *ifp),
- int (*destroy)(struct interface *ifp))
-{
- ifp_master.create_hook = create;
- ifp_master.up_hook = up;
- ifp_master.down_hook = down;
- ifp_master.destroy_hook = destroy;
-}
-
/* ------- Northbound callbacks ------- */
/*
diff --git a/lib/if.h b/lib/if.h
index f93f0e70b8..868766d645 100644
--- a/lib/if.h
+++ b/lib/if.h
@@ -386,8 +386,27 @@ DECLARE_QOBJ_TYPE(interface);
* can use 1000+ so they run after the daemon has initialised daemon-specific
* interface data
*/
-DECLARE_HOOK(if_add, (struct interface * ifp), (ifp));
-DECLARE_KOOH(if_del, (struct interface * ifp), (ifp));
+DECLARE_HOOK(if_add, (struct interface *ifp), (ifp));
+DECLARE_KOOH(if_del, (struct interface *ifp), (ifp));
+
+/* called (in daemons) when ZAPI tells us the interface actually exists
+ * (ifindex != IFINDEX_INTERNAL)
+ *
+ * WARNING: these 2 hooks NEVER CALLED inside zebra!
+ */
+DECLARE_HOOK(if_real, (struct interface *ifp), (ifp));
+DECLARE_KOOH(if_unreal, (struct interface *ifp), (ifp));
+
+/* called (in daemons) on state changes on interfaces. Whether this is admin
+ * state (= pure config) or carrier state (= hardware link plugged) depends on
+ * zebra's "link-detect" configuration. By default, it's carrier state, so
+ * this won't happen until the interface actually has a link.
+ *
+ * WARNING: these 2 hooks NEVER CALLED inside zebra!
+ */
+DECLARE_HOOK(if_up, (struct interface *ifp), (ifp));
+DECLARE_KOOH(if_down, (struct interface *ifp), (ifp));
+
#define METRIC_MAX (~0)
@@ -512,9 +531,9 @@ extern int if_cmp_name_func(const char *p1, const char *p2);
* This is useful for vrf route-leaking. So more than anything
* else think before you use VRF_UNKNOWN
*/
-extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
+extern void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id);
-extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
+extern struct interface *if_lookup_by_index(ifindex_t ifindex, vrf_id_t vrf_id);
extern struct interface *if_vrf_lookup_by_index_next(ifindex_t ifindex,
vrf_id_t vrf_id);
extern struct interface *if_lookup_address_local(const void *matchaddr,
@@ -545,7 +564,7 @@ extern int if_set_index(struct interface *ifp, ifindex_t ifindex);
/* Delete the interface, but do not free the structure, and leave it in the
interface list. It is often advisable to leave the pseudo interface
structure because there may be configuration information attached. */
-extern void if_delete_retain(struct interface *);
+extern void if_delete_retain(struct interface *ifp);
/* Delete and free the interface structure: calls if_delete_retain and then
deletes it from the interface list and frees the structure. */
@@ -563,13 +582,13 @@ extern int if_is_pointopoint(const struct interface *ifp);
extern int if_is_multicast(const struct interface *ifp);
extern void if_terminate(struct vrf *vrf);
extern void if_dump_all(void);
-extern const char *if_flag_dump(unsigned long);
-extern const char *if_link_type_str(enum zebra_link_type);
+extern const char *if_flag_dump(unsigned long flags);
+extern const char *if_link_type_str(enum zebra_link_type zlt);
/* Please use ifindex2ifname instead of if_indextoname where possible;
ifindex2ifname uses internal interface info, whereas if_indextoname must
make a system call. */
-extern const char *ifindex2ifname(ifindex_t, vrf_id_t vrf_id);
+extern const char *ifindex2ifname(ifindex_t ifindex, vrf_id_t vrf_id);
/* Please use ifname2ifindex instead of if_nametoindex where possible;
ifname2ifindex uses internal interface info, whereas if_nametoindex must
@@ -579,18 +598,20 @@ extern ifindex_t ifname2ifindex(const char *ifname, vrf_id_t vrf_id);
/* Connected address functions. */
extern struct connected *connected_new(void);
extern void connected_free(struct connected **connected);
-extern struct connected *
-connected_add_by_prefix(struct interface *, struct prefix *, struct prefix *);
-extern struct connected *connected_delete_by_prefix(struct interface *,
- struct prefix *);
-extern struct connected *connected_lookup_prefix(struct interface *,
- const struct prefix *);
-extern struct connected *connected_lookup_prefix_exact(struct interface *,
- const struct prefix *);
-extern unsigned int connected_count_by_family(struct interface *, int family);
+extern struct connected *connected_add_by_prefix(struct interface *ifp,
+ struct prefix *p,
+ struct prefix *dest);
+extern struct connected *connected_delete_by_prefix(struct interface *ifp,
+ struct prefix *p);
+extern struct connected *connected_lookup_prefix(struct interface *ifp,
+ const struct prefix *p);
+extern struct connected *connected_lookup_prefix_exact(struct interface *ifp,
+ const struct prefix *p);
+extern unsigned int connected_count_by_family(struct interface *ifp, int family);
extern struct nbr_connected *nbr_connected_new(void);
-extern void nbr_connected_free(struct nbr_connected *);
-struct nbr_connected *nbr_connected_check(struct interface *, struct prefix *);
+extern void nbr_connected_free(struct nbr_connected *connected);
+struct nbr_connected *nbr_connected_check(struct interface *ifp,
+ struct prefix *p);
struct connected *connected_get_linklocal(struct interface *ifp);
/* link parameters */
@@ -598,10 +619,10 @@ bool if_link_params_cmp(struct if_link_params *iflp1,
struct if_link_params *iflp2);
void if_link_params_copy(struct if_link_params *dst,
struct if_link_params *src);
-struct if_link_params *if_link_params_get(struct interface *);
+struct if_link_params *if_link_params_get(struct interface *ifp);
struct if_link_params *if_link_params_enable(struct interface *ifp);
struct if_link_params *if_link_params_init(struct interface *ifp);
-void if_link_params_free(struct interface *);
+void if_link_params_free(struct interface *ifp);
/* Northbound. */
struct vty;
@@ -609,10 +630,6 @@ extern void if_vty_config_start(struct vty *vty, struct interface *ifp);
extern void if_vty_config_end(struct vty *vty);
extern void if_cmd_init(int (*config_write)(struct vty *));
extern void if_cmd_init_default(void);
-extern void if_zapi_callbacks(int (*create)(struct interface *ifp),
- int (*up)(struct interface *ifp),
- int (*down)(struct interface *ifp),
- int (*destroy)(struct interface *ifp));
extern void if_new_via_zapi(struct interface *ifp);
extern void if_up_via_zapi(struct interface *ifp);
diff --git a/lib/prefix.h b/lib/prefix.h
index fc6e32dd54..14f2695933 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -286,23 +286,25 @@ struct prefix_sg {
struct in_addr grp;
};
+/* clang-format off */
union prefixptr {
- prefixtype(prefixptr, struct prefix, p)
- prefixtype(prefixptr, struct prefix_ipv4, p4)
- prefixtype(prefixptr, struct prefix_ipv6, p6)
- prefixtype(prefixptr, struct prefix_evpn, evp)
- prefixtype(prefixptr, struct prefix_fs, fs)
- prefixtype(prefixptr, struct prefix_rd, rd)
+ uniontype(prefixptr, struct prefix, p)
+ uniontype(prefixptr, struct prefix_ipv4, p4)
+ uniontype(prefixptr, struct prefix_ipv6, p6)
+ uniontype(prefixptr, struct prefix_evpn, evp)
+ uniontype(prefixptr, struct prefix_fs, fs)
+ uniontype(prefixptr, struct prefix_rd, rd)
} TRANSPARENT_UNION;
union prefixconstptr {
- prefixtype(prefixconstptr, const struct prefix, p)
- prefixtype(prefixconstptr, const struct prefix_ipv4, p4)
- prefixtype(prefixconstptr, const struct prefix_ipv6, p6)
- prefixtype(prefixconstptr, const struct prefix_evpn, evp)
- prefixtype(prefixconstptr, const struct prefix_fs, fs)
- prefixtype(prefixconstptr, const struct prefix_rd, rd)
+ uniontype(prefixconstptr, const struct prefix, p)
+ uniontype(prefixconstptr, const struct prefix_ipv4, p4)
+ uniontype(prefixconstptr, const struct prefix_ipv6, p6)
+ uniontype(prefixconstptr, const struct prefix_evpn, evp)
+ uniontype(prefixconstptr, const struct prefix_fs, fs)
+ uniontype(prefixconstptr, const struct prefix_rd, rd)
} TRANSPARENT_UNION;
+/* clang-format on */
#ifndef INET_ADDRSTRLEN
#define INET_ADDRSTRLEN 16
diff --git a/lib/sockunion.h b/lib/sockunion.h
index e507255999..675855e2b6 100644
--- a/lib/sockunion.h
+++ b/lib/sockunion.h
@@ -7,6 +7,8 @@
#ifndef _ZEBRA_SOCKUNION_H
#define _ZEBRA_SOCKUNION_H
+#include "compiler.h"
+
#include "privs.h"
#include "if.h"
#include <sys/un.h>
@@ -27,8 +29,40 @@ union sockunion {
struct sockaddr_mpls smpls;
struct sockaddr_rtlabel rtlabel;
#endif
+
+ /* sockaddr_storage is guaranteed to be larger than the others */
+ struct sockaddr_storage sa_storage;
};
+/* clang-format off */
+/* for functions that want to accept any sockaddr pointer without casts */
+union sockaddrptr {
+ uniontype(sockaddrptr, union sockunion, su)
+ uniontype(sockaddrptr, struct sockaddr, sa)
+ uniontype(sockaddrptr, struct sockaddr_in, sin)
+ uniontype(sockaddrptr, struct sockaddr_in6, sin6)
+ uniontype(sockaddrptr, struct sockaddr_un, sun)
+#ifdef __OpenBSD__
+ uniontype(sockaddrptr, struct sockaddr_mpls, smpls)
+ uniontype(sockaddrptr, struct sockaddr_rtlabel, rtlabel)
+#endif
+ uniontype(sockaddrptr, struct sockaddr_storage, sa_storage)
+} TRANSPARENT_UNION;
+
+union sockaddrconstptr {
+ uniontype(sockaddrconstptr, const union sockunion, su)
+ uniontype(sockaddrconstptr, const struct sockaddr, sa)
+ uniontype(sockaddrconstptr, const struct sockaddr_in, sin)
+ uniontype(sockaddrconstptr, const struct sockaddr_in6, sin6)
+ uniontype(sockaddrconstptr, const struct sockaddr_un, sun)
+#ifdef __OpenBSD__
+ uniontype(sockaddrconstptr, const struct sockaddr_mpls, smpls)
+ uniontype(sockaddrconstptr, const struct sockaddr_rtlabel, rtlabel)
+#endif
+ uniontype(sockaddrconstptr, const struct sockaddr_storage, sa_storage)
+} TRANSPARENT_UNION;
+/* clang-format on */
+
enum connect_result { connect_error, connect_success, connect_in_progress };
/* Default address family. */
diff --git a/lib/workqueue.c b/lib/workqueue.c
index 2281c4c369..d630af1d1d 100644
--- a/lib/workqueue.c
+++ b/lib/workqueue.c
@@ -42,6 +42,15 @@ static void work_queue_item_free(struct work_queue_item *item)
return;
}
+static inline void work_queue_item_dequeue(struct work_queue *wq,
+ struct work_queue_item *item)
+{
+ assert(wq->item_count > 0);
+
+ wq->item_count--;
+ STAILQ_REMOVE(&wq->items, item, work_queue_item, wq);
+}
+
static void work_queue_item_remove(struct work_queue *wq,
struct work_queue_item *item)
{
@@ -133,6 +142,13 @@ static int work_queue_schedule(struct work_queue *wq, unsigned int delay)
return 0;
}
+static inline void work_queue_item_enqueue(struct work_queue *wq,
+ struct work_queue_item *item)
+{
+ STAILQ_INSERT_TAIL(&wq->items, item, wq);
+ wq->item_count++;
+}
+
void work_queue_add(struct work_queue *wq, void *data)
{
struct work_queue_item *item;
@@ -265,8 +281,7 @@ void work_queue_run(struct event *thread)
do {
ret = wq->spec.workfunc(wq, item->data);
item->ran++;
- } while ((ret == WQ_RETRY_NOW)
- && (item->ran < wq->spec.max_retries));
+ } while (item->ran < wq->spec.max_retries);
switch (ret) {
case WQ_QUEUE_BLOCKED: {
@@ -276,9 +291,6 @@ void work_queue_run(struct event *thread)
item->ran--;
goto stats;
}
- case WQ_RETRY_LATER: {
- goto stats;
- }
case WQ_REQUEUE: {
item->ran--;
work_queue_item_requeue(wq, item);
@@ -296,11 +308,6 @@ void work_queue_run(struct event *thread)
titem = item;
break;
}
- case WQ_RETRY_NOW:
- /* a RETRY_NOW that gets here has exceeded max_tries, same
- * as ERROR
- */
- fallthrough;
case WQ_SUCCESS:
default: {
work_queue_item_remove(wq, item);
@@ -352,8 +359,7 @@ stats:
/* Is the queue done yet? If it is, call the completion callback. */
if (!work_queue_empty(wq)) {
- if (ret == WQ_RETRY_LATER ||
- ret == WQ_QUEUE_BLOCKED)
+ if (ret == WQ_QUEUE_BLOCKED)
work_queue_schedule(wq, wq->spec.retry);
else
work_queue_schedule(wq, 0);
diff --git a/lib/workqueue.h b/lib/workqueue.h
index 5d84739d5c..a495fe8615 100644
--- a/lib/workqueue.h
+++ b/lib/workqueue.h
@@ -26,9 +26,7 @@ DECLARE_MTYPE(WORK_QUEUE);
/* action value, for use by item processor and item error handlers */
typedef enum {
WQ_SUCCESS = 0,
- WQ_RETRY_NOW, /* retry immediately */
- WQ_RETRY_LATER, /* retry later, cease processing work queue */
- WQ_REQUEUE, /* requeue item, continue processing work queue */
+ WQ_REQUEUE, /* requeue item, continue processing work queue */
WQ_QUEUE_BLOCKED, /* Queue cant be processed at this time.
* Similar to WQ_RETRY_LATER, but doesn't penalise
* the particular item.. */
@@ -117,22 +115,6 @@ work_queue_last_item(struct work_queue *wq)
return STAILQ_LAST(&wq->items, work_queue_item, wq);
}
-static inline void work_queue_item_enqueue(struct work_queue *wq,
- struct work_queue_item *item)
-{
- STAILQ_INSERT_TAIL(&wq->items, item, wq);
- wq->item_count++;
-}
-
-static inline void work_queue_item_dequeue(struct work_queue *wq,
- struct work_queue_item *item)
-{
- assert(wq->item_count > 0);
-
- wq->item_count--;
- STAILQ_REMOVE(&wq->items, item, work_queue_item, wq);
-}
-
/* create a new work queue, of given name.
* user must fill in the spec of the returned work queue before adding
* anything to it
@@ -160,6 +142,7 @@ bool work_queue_is_scheduled(struct work_queue *wq);
/* Helpers, exported for thread.c and command.c */
extern void work_queue_run(struct event *thread);
+/* Function to initialize the workqueue cli */
extern void workqueue_cmd_init(void);
#ifdef __cplusplus
diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c
index e401f21ed4..73af78cbf0 100644
--- a/nhrpd/nhrp_main.c
+++ b/nhrpd/nhrp_main.c
@@ -155,8 +155,10 @@ int main(int argc, char **argv)
nhrp_vc_init();
nhrp_packet_init();
vici_init();
- if_zapi_callbacks(nhrp_ifp_create, nhrp_ifp_up,
- nhrp_ifp_down, nhrp_ifp_destroy);
+ hook_register_prio(if_real, 0, nhrp_ifp_create);
+ hook_register_prio(if_up, 0, nhrp_ifp_up);
+ hook_register_prio(if_down, 0, nhrp_ifp_down);
+ hook_register_prio(if_unreal, 0, nhrp_ifp_destroy);
nhrp_zebra_init();
nhrp_shortcut_init();
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 90185b09bc..a05ff1098c 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -2797,8 +2797,10 @@ void ospf6_interface_init(void)
{
/* Install interface node. */
if_cmd_init(config_write_interface);
- if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up, ospf6_ifp_down,
- ospf6_ifp_destroy);
+ hook_register_prio(if_real, 0, ospf6_ifp_create);
+ hook_register_prio(if_up, 0, ospf6_ifp_up);
+ hook_register_prio(if_down, 0, ospf6_ifp_down);
+ hook_register_prio(if_unreal, 0, ospf6_ifp_destroy);
install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c
index 938d373d8b..808eeb50fd 100644
--- a/ospfd/ospf_interface.c
+++ b/ospfd/ospf_interface.c
@@ -1562,8 +1562,10 @@ void ospf_reset_hello_timer(struct interface *ifp, struct in_addr addr,
void ospf_if_init(void)
{
- if_zapi_callbacks(ospf_ifp_create, ospf_ifp_up,
- ospf_ifp_down, ospf_ifp_destroy);
+ hook_register_prio(if_real, 0, ospf_ifp_create);
+ hook_register_prio(if_up, 0, ospf_ifp_up);
+ hook_register_prio(if_down, 0, ospf_ifp_down);
+ hook_register_prio(if_unreal, 0, ospf_ifp_destroy);
/* Initialize Zebra interface data structure. */
hook_register_prio(if_add, 0, ospf_if_new_hook);
diff --git a/pathd/path_pcep.h b/pathd/path_pcep.h
index 5c6a02372f..d6dbcb5c08 100644
--- a/pathd/path_pcep.h
+++ b/pathd/path_pcep.h
@@ -25,6 +25,7 @@ DECLARE_MTYPE(PCEP);
#define PCEP_DEBUG_MODE_PATH 0x02
#define PCEP_DEBUG_MODE_PCEP 0x04
#define PCEP_DEBUG_MODE_PCEPLIB 0x08
+#define PCEP_DEBUG_MODE_ALL 0x0F
#define PCEP_DEBUG(fmt, ...) \
do { \
if (DEBUG_FLAGS_CHECK(&pcep_g->dbg, PCEP_DEBUG_MODE_BASIC)) \
diff --git a/pathd/path_pcep_cli.c b/pathd/path_pcep_cli.c
index c46649b0db..ab61abc02d 100644
--- a/pathd/path_pcep_cli.c
+++ b/pathd/path_pcep_cli.c
@@ -458,28 +458,32 @@ static void pcep_cli_remove_pce_connection(struct pce_opts *pce_opts)
* VTY command implementations
*/
-static int path_pcep_cli_debug(struct vty *vty, const char *no_str,
- const char *basic_str, const char *path_str,
- const char *message_str, const char *pceplib_str)
+static int path_pcep_cli_debug(struct vty *vty, const char *debug_type, bool set)
{
uint32_t mode = DEBUG_NODE2MODE(vty->node);
- bool no = (no_str != NULL);
- DEBUG_MODE_SET(&pcep_g->dbg, mode, !no);
-
- if (basic_str != NULL) {
- DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_BASIC, !no);
- }
- if (path_str != NULL) {
- DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PATH, !no);
- }
- if (message_str != NULL) {
- DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PCEP, !no);
- }
- if (pceplib_str != NULL) {
- DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PCEPLIB, !no);
+ /* Global Set */
+ if (debug_type == NULL) {
+ DEBUG_MODE_SET(&pcep_g->dbg, mode, set);
+ DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_ALL, set);
+ return CMD_SUCCESS;
}
+ DEBUG_MODE_SET(&pcep_g->dbg, mode, true);
+
+ if (strcmp(debug_type, "basic") == 0)
+ DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_BASIC, set);
+ else if (strcmp(debug_type, "path") == 0)
+ DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PATH, set);
+ else if (strcmp(debug_type, "message") == 0)
+ DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PCEP, set);
+ else if (strcmp(debug_type, "pceplib") == 0)
+ DEBUG_FLAGS_SET(&pcep_g->dbg, PCEP_DEBUG_MODE_PCEPLIB, set);
+
+ /* Unset the pcep debug mode if there is no flag at least set*/
+ if (!DEBUG_FLAGS_CHECK(&pcep_g->dbg, PCEP_DEBUG_MODE_ALL))
+ DEBUG_MODE_SET(&pcep_g->dbg, mode, false);
+
return CMD_SUCCESS;
}
@@ -1788,7 +1792,7 @@ DEFPY(show_debugging_pathd_pcep,
DEFPY(pcep_cli_debug,
pcep_cli_debug_cmd,
- "[no] debug pathd pcep [basic]$basic_str [path]$path_str [message]$message_str [pceplib]$pceplib_str",
+ "[no] debug pathd pcep [<basic|path|message|pceplib>$debug_type]",
NO_STR DEBUG_STR
"pathd debugging\n"
"pcep module debugging\n"
@@ -1797,8 +1801,7 @@ DEFPY(pcep_cli_debug,
"pcep message debugging\n"
"pceplib debugging\n")
{
- return path_pcep_cli_debug(vty, no, basic_str, path_str, message_str,
- pceplib_str);
+ return path_pcep_cli_debug(vty, debug_type, !no);
}
DEFPY(pcep_cli_show_srte_pcep_counters,
diff --git a/pbrd/pbr_main.c b/pbrd/pbr_main.c
index c4708d3f08..6699079a68 100644
--- a/pbrd/pbr_main.c
+++ b/pbrd/pbr_main.c
@@ -158,8 +158,10 @@ int main(int argc, char **argv, char **envp)
access_list_init();
pbr_nht_init();
pbr_map_init();
- if_zapi_callbacks(pbr_ifp_create, pbr_ifp_up,
- pbr_ifp_down, pbr_ifp_destroy);
+ hook_register_prio(if_real, 0, pbr_ifp_create);
+ hook_register_prio(if_up, 0, pbr_ifp_up);
+ hook_register_prio(if_down, 0, pbr_ifp_down);
+ hook_register_prio(if_unreal, 0, pbr_ifp_destroy);
pbr_zebra_init();
pbr_vrf_init();
pbr_vty_init();
diff --git a/pimd/pim_addr.h b/pimd/pim_addr.h
index 94c63bbccc..ecba739a5a 100644
--- a/pimd/pim_addr.h
+++ b/pimd/pim_addr.h
@@ -33,13 +33,13 @@ typedef struct in_addr pim_addr;
#define PIM_ADDR_FUNCNAME(name) ipv4_##name
union pimprefixptr {
- prefixtype(pimprefixptr, struct prefix, p)
- prefixtype(pimprefixptr, struct prefix_ipv4, p4)
+ uniontype(pimprefixptr, struct prefix, p)
+ uniontype(pimprefixptr, struct prefix_ipv4, p4)
} TRANSPARENT_UNION;
union pimprefixconstptr {
- prefixtype(pimprefixconstptr, const struct prefix, p)
- prefixtype(pimprefixconstptr, const struct prefix_ipv4, p4)
+ uniontype(pimprefixconstptr, const struct prefix, p)
+ uniontype(pimprefixconstptr, const struct prefix_ipv4, p4)
} TRANSPARENT_UNION;
#else
@@ -63,13 +63,13 @@ typedef struct in6_addr pim_addr;
#define PIM_ADDR_FUNCNAME(name) ipv6_##name
union pimprefixptr {
- prefixtype(pimprefixptr, struct prefix, p)
- prefixtype(pimprefixptr, struct prefix_ipv6, p6)
+ uniontype(pimprefixptr, struct prefix, p)
+ uniontype(pimprefixptr, struct prefix_ipv6, p6)
} TRANSPARENT_UNION;
union pimprefixconstptr {
- prefixtype(pimprefixconstptr, const struct prefix, p)
- prefixtype(pimprefixconstptr, const struct prefix_ipv6, p6)
+ uniontype(pimprefixconstptr, const struct prefix, p)
+ uniontype(pimprefixconstptr, const struct prefix_ipv6, p6)
} TRANSPARENT_UNION;
#endif
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 5fa4715b05..e00a3c0f98 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -1771,8 +1771,10 @@ void pim_iface_init(void)
hook_register_prio(if_add, 0, pim_if_new_hook);
hook_register_prio(if_del, 0, pim_if_delete_hook);
- if_zapi_callbacks(pim_ifp_create, pim_ifp_up, pim_ifp_down,
- pim_ifp_destroy);
+ hook_register_prio(if_real, 0, pim_ifp_create);
+ hook_register_prio(if_up, 0, pim_ifp_up);
+ hook_register_prio(if_down, 0, pim_ifp_down);
+ hook_register_prio(if_unreal, 0, pim_ifp_destroy);
}
static void pim_if_membership_clear(struct interface *ifp)
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 505290ed31..93494549cc 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -1118,6 +1118,8 @@ void rip_if_init(void)
/* Install interface node. */
if_cmd_init_default();
- if_zapi_callbacks(rip_ifp_create, rip_ifp_up,
- rip_ifp_down, rip_ifp_destroy);
+ hook_register_prio(if_real, 0, rip_ifp_create);
+ hook_register_prio(if_up, 0, rip_ifp_up);
+ hook_register_prio(if_down, 0, rip_ifp_down);
+ hook_register_prio(if_unreal, 0, rip_ifp_destroy);
}
diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c
index 4cb4bb5ef3..aa470aa652 100644
--- a/ripngd/ripng_interface.c
+++ b/ripngd/ripng_interface.c
@@ -877,6 +877,8 @@ void ripng_if_init(void)
/* Install interface node. */
if_cmd_init_default();
- if_zapi_callbacks(ripng_ifp_create, ripng_ifp_up,
- ripng_ifp_down, ripng_ifp_destroy);
+ hook_register_prio(if_real, 0, ripng_ifp_create);
+ hook_register_prio(if_up, 0, ripng_ifp_up);
+ hook_register_prio(if_down, 0, ripng_ifp_down);
+ hook_register_prio(if_unreal, 0, ripng_ifp_destroy);
}
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index c095fec17b..30bf4f30e1 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -1077,8 +1077,10 @@ void sharp_zebra_init(void)
{
struct zclient_options opt = {.receive_notify = true};
- if_zapi_callbacks(sharp_ifp_create, sharp_ifp_up, sharp_ifp_down,
- sharp_ifp_destroy);
+ hook_register_prio(if_real, 0, sharp_ifp_create);
+ hook_register_prio(if_up, 0, sharp_ifp_up);
+ hook_register_prio(if_down, 0, sharp_ifp_down);
+ hook_register_prio(if_unreal, 0, sharp_ifp_destroy);
zclient = zclient_new(master, &opt, sharp_handlers,
array_size(sharp_handlers));
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index 6abbdadc08..7799cbdee3 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -542,8 +542,10 @@ void static_zebra_init(void)
{
struct zclient_options opt = { .receive_notify = true };
- if_zapi_callbacks(static_ifp_create, static_ifp_up,
- static_ifp_down, static_ifp_destroy);
+ hook_register_prio(if_real, 0, static_ifp_create);
+ hook_register_prio(if_up, 0, static_ifp_up);
+ hook_register_prio(if_down, 0, static_ifp_down);
+ hook_register_prio(if_unreal, 0, static_ifp_destroy);
zclient = zclient_new(master, &opt, static_handlers,
array_size(static_handlers));
diff --git a/tests/lib/test_heavy_wq.c b/tests/lib/test_heavy_wq.c
index 225573ae92..8c2765cfdf 100644
--- a/tests/lib/test_heavy_wq.c
+++ b/tests/lib/test_heavy_wq.c
@@ -76,12 +76,6 @@ static wq_item_status slow_func(struct work_queue *wq, void *data)
for (j = 0; j < 300; j++)
x += sin(x) * j;
- if ((hn->i % ITERS_LATER) == 0)
- return WQ_RETRY_LATER;
-
- if ((hn->i % ITERS_ERR) == 0)
- return WQ_RETRY_NOW;
-
if ((hn->i % ITERS_PRINT) == 0)
printf("%s did %d, x = %g\n", hn->str, hn->i, x);
diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c
index 6d753d2e47..10394752e0 100644
--- a/vrrpd/vrrp_zebra.c
+++ b/vrrpd/vrrp_zebra.c
@@ -183,8 +183,10 @@ static zclient_handler *const vrrp_handlers[] = {
void vrrp_zebra_init(void)
{
- if_zapi_callbacks(vrrp_ifp_create, vrrp_ifp_up,
- vrrp_ifp_down, vrrp_ifp_destroy);
+ hook_register_prio(if_real, 0, vrrp_ifp_create);
+ hook_register_prio(if_up, 0, vrrp_ifp_up);
+ hook_register_prio(if_down, 0, vrrp_ifp_down);
+ hook_register_prio(if_unreal, 0, vrrp_ifp_destroy);
/* Socket for receiving updates from Zebra daemon */
zclient = zclient_new(master, &zclient_options_default, vrrp_handlers,
diff --git a/zebra/interface.c b/zebra/interface.c
index 1afd9d5a7d..1283f15b05 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -5664,11 +5664,6 @@ void zebra_if_init(void)
/* Install configuration write function. */
if_cmd_init(if_config_write);
install_node(&link_params_node);
- /*
- * This is *intentionally* setting this to NULL, signaling
- * that interface creation for zebra acts differently
- */
- if_zapi_callbacks(NULL, NULL, NULL, NULL);
install_element(VIEW_NODE, &show_interface_cmd);
install_element(VIEW_NODE, &show_interface_vrf_all_cmd);
diff --git a/zebra/main.c b/zebra/main.c
index 1e833ce7f1..158d1b8c4c 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -59,8 +59,6 @@ int retain_mode = 0;
int graceful_restart;
-bool v6_rr_semantics = false;
-
/* Receive buffer size for kernel control sockets */
#define RCVBUFSIZE_MIN 4194304
#ifdef HAVE_NETLINK
@@ -385,7 +383,7 @@ int main(int argc, char **argv)
vrf_configure_backend(VRF_BACKEND_NETNS);
break;
case OPTION_V6_RR_SEMANTICS:
- v6_rr_semantics = true;
+ zrouter.v6_rr_semantics = true;
break;
case OPTION_ASIC_OFFLOAD:
if (!strcmp(optarg, "notify_on_offload"))
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 7d3a9617a4..1cfed6df4b 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -136,10 +136,6 @@ static void zebra_redistribute(struct zserv *client, int type,
if (!zebra_check_addr(&rn->p))
continue;
- if (type == ZEBRA_ROUTE_ADD && is_table_direct &&
- newre->vrf_id != VRF_DEFAULT)
- continue;
-
zsend_redistribute_route(ZEBRA_REDISTRIBUTE_ROUTE_ADD,
client, rn, newre, is_table_direct);
}
diff --git a/zebra/rib.h b/zebra/rib.h
index e70b5c1423..665f286f67 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -627,8 +627,6 @@ extern void zebra_vty_init(void);
extern pid_t pid;
-extern bool v6_rr_semantics;
-
extern uint32_t rt_table_main_id;
/* Name of hook calls */
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index ec35842b0a..58116c6563 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -2209,7 +2209,8 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx
req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
if (((cmd == RTM_NEWROUTE) &&
- ((p->family == AF_INET) || v6_rr_semantics)) ||
+ ((p->family == AF_INET) || kernel_nexthops_supported() ||
+ zrouter.v6_rr_semantics)) ||
force_rr)
req->n.nlmsg_flags |= NLM_F_REPLACE;
@@ -3095,8 +3096,8 @@ netlink_put_route_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx)
} else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_INSTALL) {
cmd = RTM_NEWROUTE;
} else if (dplane_ctx_get_op(ctx) == DPLANE_OP_ROUTE_UPDATE) {
-
- if (p->family == AF_INET || v6_rr_semantics) {
+ if (p->family == AF_INET || kernel_nexthops_supported() ||
+ zrouter.v6_rr_semantics) {
/* Single 'replace' operation */
/*
diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h
index b700851df5..a926369ef8 100644
--- a/zebra/zebra_router.h
+++ b/zebra/zebra_router.h
@@ -209,6 +209,8 @@ struct zebra_router {
bool notify_on_ack;
bool v6_with_v4_nexthop;
+ bool v6_rr_semantics;
+
/*
* If the asic is notifying us about successful nexthop
* allocation/control. Some developers have made their
diff --git a/zebra/zebra_script.c b/zebra/zebra_script.c
index 9f8490ac66..3ebc6d974b 100644
--- a/zebra/zebra_script.c
+++ b/zebra/zebra_script.c
@@ -396,6 +396,7 @@ void lua_pushzebra_dplane_ctx(lua_State *L, const struct zebra_dplane_ctx *ctx)
lua_setfield(L, -2, "mtu");
}
lua_setfield(L, -2, "gre");
+ break;
case DPLANE_OP_ADDR_INSTALL:
case DPLANE_OP_ADDR_UNINSTALL:
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index d36c2f81c7..8c97248737 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -4028,6 +4028,17 @@ static int config_write_protocol(struct vty *vty)
return 1;
}
+static inline bool zebra_vty_v6_rr_semantics_used(void)
+{
+ if (zebra_nhg_kernel_nexthops_enabled())
+ return true;
+
+ if (zrouter.v6_rr_semantics)
+ return true;
+
+ return false;
+}
+
DEFUN (show_zebra,
show_zebra_cmd,
"show zebra",
@@ -4047,7 +4058,9 @@ DEFUN (show_zebra,
ttable_add_row(table, "MPLS|%s", mpls_enabled ? "On" : "Off");
ttable_add_row(table, "EVPN|%s", is_evpn_enabled() ? "On" : "Off");
ttable_add_row(table, "Kernel socket buffer size|%d", rcvbufsize);
-
+ ttable_add_row(table, "v6 Route Replace Semantics|%s",
+ zebra_vty_v6_rr_semantics_used() ? "Replace"
+ : "Delete then Add");
#ifdef GNU_LINUX
if (!vrf_is_backend_netns())