summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
Diffstat (limited to 'zebra')
-rw-r--r--zebra/interface.c11
-rw-r--r--zebra/interface.h3
-rw-r--r--zebra/main.c11
-rw-r--r--zebra/rib.h7
-rw-r--r--zebra/rule_netlink.c4
-rw-r--r--zebra/zapi_msg.c16
-rw-r--r--zebra/zebra_dplane.c17
-rw-r--r--zebra/zebra_evpn_mh.c22
-rw-r--r--zebra/zebra_evpn_mh.h2
-rw-r--r--zebra/zebra_fpm.c13
-rw-r--r--zebra/zebra_fpm_netlink.c9
-rw-r--r--zebra/zebra_mlag.c2
-rw-r--r--zebra/zebra_ptm.c2
-rw-r--r--zebra/zebra_vxlan.c4
-rw-r--r--zebra/zserv.c16
15 files changed, 90 insertions, 49 deletions
diff --git a/zebra/interface.c b/zebra/interface.c
index 2585d0dc3..ba6a37653 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -135,6 +135,7 @@ static int if_zebra_new_hook(struct interface *ifp)
zebra_if->ifp = ifp;
zebra_if->multicast = IF_ZEBRA_DATA_UNSPEC;
+ zebra_if->mpls_config = IF_ZEBRA_DATA_UNSPEC;
zebra_if->shutdown = IF_ZEBRA_DATA_OFF;
zebra_if->link_nsid = NS_UNKNOWN;
@@ -267,6 +268,9 @@ struct interface *if_link_per_ns(struct zebra_ns *ns, struct interface *ifp)
/* Delete a VRF. This is called in vrf_terminate(). */
void if_unlink_per_ns(struct interface *ifp)
{
+ if (!ifp->node)
+ return;
+
ifp->node->info = NULL;
route_unlock_node(ifp->node);
ifp->node = NULL;
@@ -3010,10 +3014,10 @@ DEFPY (mpls,
if (no) {
dplane_intf_mpls_modify_state(ifp, false);
- if_data->mpls = IF_ZEBRA_DATA_UNSPEC;
+ if_data->mpls_config = IF_ZEBRA_DATA_UNSPEC;
} else {
dplane_intf_mpls_modify_state(ifp, true);
- if_data->mpls = IF_ZEBRA_DATA_ON;
+ if_data->mpls_config = IF_ZEBRA_DATA_ON;
}
return CMD_SUCCESS;
@@ -4853,7 +4857,8 @@ static int if_config_write(struct vty *vty)
IF_ZEBRA_DATA_ON
? ""
: "no ");
- if (if_data->mpls == IF_ZEBRA_DATA_ON)
+
+ if (if_data->mpls_config == IF_ZEBRA_DATA_ON)
vty_out(vty, " mpls enable\n");
}
diff --git a/zebra/interface.h b/zebra/interface.h
index 8cbdd349d..3b6799549 100644
--- a/zebra/interface.h
+++ b/zebra/interface.h
@@ -113,6 +113,9 @@ struct zebra_if {
/* MPLS status. */
bool mpls;
+ /* MPLS configuration */
+ uint8_t mpls_config;
+
/* Linkdown status */
bool linkdown, linkdownv6;
diff --git a/zebra/main.c b/zebra/main.c
index 81a306644..bd4623be5 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -206,12 +206,17 @@ void zebra_finalize(struct event *dummy)
vrf_terminate();
+ /*
+ * Stop dplane thread and finish any cleanup
+ * This is before the zebra_ns_early_shutdown call
+ * because sockets that the dplane depends on are closed
+ * in those functions
+ */
+ zebra_dplane_shutdown();
+
ns_walk_func(zebra_ns_early_shutdown, NULL, NULL);
zebra_ns_notify_close();
- /* Stop dplane thread and finish any cleanup */
- zebra_dplane_shutdown();
-
/* Final shutdown of ns resources */
ns_walk_func(zebra_ns_final_shutdown, NULL, NULL);
diff --git a/zebra/rib.h b/zebra/rib.h
index a56bb05d6..65cc1ffab 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -465,6 +465,13 @@ extern uint8_t route_distance(int type);
extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq,
bool rt_delete);
+/*
+ * rib_find_rn_from_ctx
+ *
+ * Returns a lock increased route_node for the appropriate
+ * table and prefix specified by the context. Developer
+ * should unlock the node when done.
+ */
extern struct route_node *
rib_find_rn_from_ctx(const struct zebra_dplane_ctx *ctx);
diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c
index c7832992e..518c948c9 100644
--- a/zebra/rule_netlink.c
+++ b/zebra/rule_netlink.c
@@ -116,9 +116,9 @@ static ssize_t netlink_rule_msg_encode(
return 0;
}
- /* dsfield, if specified */
+ /* dsfield, if specified; mask off the ECN bits */
if (filter_bm & PBR_FILTER_DSFIELD)
- req->frh.tos = dsfield;
+ req->frh.tos = dsfield & 0xfc;
/* protocol to match on */
if (filter_bm & PBR_FILTER_IP_PROTOCOL)
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index 4c6c336d4..4bc9f4acf 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -801,11 +801,17 @@ int zsend_route_notify_owner(const struct route_node *rn,
int zsend_route_notify_owner_ctx(const struct zebra_dplane_ctx *ctx,
enum zapi_route_notify_owner note)
{
- return (route_notify_internal(
- rib_find_rn_from_ctx(ctx), dplane_ctx_get_type(ctx),
- dplane_ctx_get_instance(ctx), dplane_ctx_get_vrf(ctx),
- dplane_ctx_get_table(ctx), note, dplane_ctx_get_afi(ctx),
- dplane_ctx_get_safi(ctx)));
+ int result;
+ struct route_node *rn = rib_find_rn_from_ctx(ctx);
+
+ result = route_notify_internal(
+ rn, dplane_ctx_get_type(ctx), dplane_ctx_get_instance(ctx),
+ dplane_ctx_get_vrf(ctx), dplane_ctx_get_table(ctx), note,
+ dplane_ctx_get_afi(ctx), dplane_ctx_get_safi(ctx));
+
+ route_unlock_node(rn);
+
+ return result;
}
static void zread_route_notify_request(ZAPI_HANDLER_ARGS)
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 3653f7152..f90f9191e 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -3799,8 +3799,7 @@ tc_qdisc_update_internal(enum dplane_op_e op,
} else {
atomic_fetch_add_explicit(&zdplane_info.dg_tcs_errors, 1,
memory_order_relaxed);
- if (ctx)
- dplane_ctx_free(&ctx);
+ dplane_ctx_free(&ctx);
}
return result;
@@ -3830,8 +3829,7 @@ tc_class_update_internal(enum dplane_op_e op, struct zebra_tc_class *class)
} else {
atomic_fetch_add_explicit(&zdplane_info.dg_tcs_errors, 1,
memory_order_relaxed);
- if (ctx)
- dplane_ctx_free(&ctx);
+ dplane_ctx_free(&ctx);
}
return result;
@@ -3861,8 +3859,7 @@ tc_filter_update_internal(enum dplane_op_e op, struct zebra_tc_filter *filter)
} else {
atomic_fetch_add_explicit(&zdplane_info.dg_tcs_errors, 1,
memory_order_relaxed);
- if (ctx)
- dplane_ctx_free(&ctx);
+ dplane_ctx_free(&ctx);
}
return result;
@@ -4230,8 +4227,7 @@ done:
else {
atomic_fetch_add_explicit(&zdplane_info.dg_lsp_errors, 1,
memory_order_relaxed);
- if (ctx)
- dplane_ctx_free(&ctx);
+ dplane_ctx_free(&ctx);
}
return result;
}
@@ -5550,7 +5546,7 @@ int dplane_provider_register(const char *name,
struct zebra_dplane_provider **prov_p)
{
int ret = 0;
- struct zebra_dplane_provider *p = NULL, *last;
+ struct zebra_dplane_provider *p = NULL, *last, *prev = NULL;
/* Validate */
if (fp == NULL) {
@@ -5593,10 +5589,11 @@ int dplane_provider_register(const char *name,
frr_each (dplane_prov_list, &zdplane_info.dg_providers, last) {
if (last->dp_priority > p->dp_priority)
break;
+ prev = last;
}
if (last)
- dplane_prov_list_add_after(&zdplane_info.dg_providers, last, p);
+ dplane_prov_list_add_after(&zdplane_info.dg_providers, prev, p);
else
dplane_prov_list_add_tail(&zdplane_info.dg_providers, p);
diff --git a/zebra/zebra_evpn_mh.c b/zebra/zebra_evpn_mh.c
index 49120c287..a5092c629 100644
--- a/zebra/zebra_evpn_mh.c
+++ b/zebra/zebra_evpn_mh.c
@@ -535,19 +535,26 @@ static bool zebra_evpn_acc_vl_cmp(const void *p1, const void *p2)
}
/* Lookup VLAN based broadcast domain */
-struct zebra_evpn_access_bd *zebra_evpn_acc_vl_find(vlanid_t vid,
- struct interface *br_if)
+struct zebra_evpn_access_bd *
+zebra_evpn_acc_vl_find_index(vlanid_t vid, ifindex_t bridge_ifindex)
{
struct zebra_evpn_access_bd *acc_bd;
struct zebra_evpn_access_bd tmp;
tmp.vid = vid;
- tmp.bridge_ifindex = br_if->ifindex;
+ tmp.bridge_ifindex = bridge_ifindex;
acc_bd = hash_lookup(zmh_info->evpn_vlan_table, &tmp);
return acc_bd;
}
+/* Lookup VLAN based broadcast domain */
+struct zebra_evpn_access_bd *zebra_evpn_acc_vl_find(vlanid_t vid,
+ struct interface *br_if)
+{
+ return zebra_evpn_acc_vl_find_index(vid, br_if->ifindex);
+}
+
/* A new broadcast domain can be created when a VLAN member or VLAN<=>VxLAN_IF
* mapping is added.
*/
@@ -842,9 +849,9 @@ void zebra_evpn_access_bd_bridge_cleanup(vlanid_t vid, struct interface *br_if,
void zebra_evpn_vxl_evpn_set(struct zebra_if *zif, struct zebra_evpn *zevpn,
bool set)
{
- struct interface *br_if;
struct zebra_vxlan_vni *vni;
struct zebra_evpn_access_bd *acc_bd;
+ ifindex_t br_ifindex;
if (!zif)
return;
@@ -854,11 +861,12 @@ void zebra_evpn_vxl_evpn_set(struct zebra_if *zif, struct zebra_evpn *zevpn,
if (!vni)
return;
- br_if = zif->brslave_info.br_if;
- if (!br_if)
+ /* Use the index as the pointer can be stale (deleted) */
+ br_ifindex = zif->brslave_info.bridge_ifindex;
+ if (!zif->brslave_info.br_if || br_ifindex == IFINDEX_INTERNAL)
return;
- acc_bd = zebra_evpn_acc_vl_find(vni->access_vlan, br_if);
+ acc_bd = zebra_evpn_acc_vl_find_index(vni->access_vlan, br_ifindex);
if (!acc_bd)
return;
diff --git a/zebra/zebra_evpn_mh.h b/zebra/zebra_evpn_mh.h
index 6dda30a57..59a41d060 100644
--- a/zebra/zebra_evpn_mh.h
+++ b/zebra/zebra_evpn_mh.h
@@ -344,6 +344,8 @@ extern void zebra_evpn_if_es_print(struct vty *vty, json_object *json,
struct zebra_if *zif);
extern struct zebra_evpn_access_bd *
zebra_evpn_acc_vl_find(vlanid_t vid, struct interface *br_if);
+struct zebra_evpn_access_bd *
+zebra_evpn_acc_vl_find_index(vlanid_t vid, ifindex_t bridge_ifindex);
extern void zebra_evpn_acc_vl_show_vid(struct vty *vty, bool uj, vlanid_t vid,
struct interface *br_if);
extern void zebra_evpn_es_cleanup(void);
diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c
index e379a5868..699f3ed11 100644
--- a/zebra/zebra_fpm.c
+++ b/zebra/zebra_fpm.c
@@ -497,6 +497,11 @@ static inline void zfpm_connect_off(void)
EVENT_OFF(zfpm_g->t_connect);
}
+static inline void zfpm_conn_down_off(void)
+{
+ EVENT_OFF(zfpm_g->t_conn_down);
+}
+
/*
* zfpm_conn_up_thread_cb
*
@@ -635,8 +640,6 @@ static void zfpm_conn_down_thread_cb(struct event *thread)
while ((mac = TAILQ_FIRST(&zfpm_g->mac_q)) != NULL)
zfpm_mac_info_del(mac);
- zfpm_g->t_conn_down = NULL;
-
iter = &zfpm_g->t_conn_down_state.iter;
while ((rnode = zfpm_rnodes_iter_next(iter))) {
@@ -667,7 +670,6 @@ static void zfpm_conn_down_thread_cb(struct event *thread)
zfpm_g->stats.t_conn_down_yields++;
zfpm_rnodes_iter_pause(iter);
- zfpm_g->t_conn_down = NULL;
event_add_timer_msec(zfpm_g->master, zfpm_conn_down_thread_cb,
NULL, 0, &zfpm_g->t_conn_down);
return;
@@ -712,7 +714,7 @@ static void zfpm_connection_down(const char *detail)
*/
assert(!zfpm_g->t_conn_down);
zfpm_rnodes_iter_init(&zfpm_g->t_conn_down_state.iter);
- zfpm_g->t_conn_down = NULL;
+ zfpm_conn_down_off();
event_add_timer_msec(zfpm_g->master, zfpm_conn_down_thread_cb, NULL, 0,
&zfpm_g->t_conn_down);
zfpm_g->stats.t_conn_down_starts++;
@@ -2042,10 +2044,13 @@ static int zfpm_fini(void)
zfpm_write_off();
zfpm_read_off();
zfpm_connect_off();
+ zfpm_conn_down_off();
zfpm_stop_stats_timer();
hook_unregister(rib_update, zfpm_trigger_update);
+ hook_unregister(zebra_rmac_update, zfpm_trigger_rmac_update);
+
return 0;
}
diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c
index 5adca14d7..ba34951e7 100644
--- a/zebra/zebra_fpm_netlink.c
+++ b/zebra/zebra_fpm_netlink.c
@@ -252,20 +252,15 @@ static int netlink_route_info_fill(struct netlink_route_info *ri, int cmd,
rib_dest_t *dest, struct route_entry *re)
{
struct nexthop *nexthop;
- struct rib_table_info *table_info =
- rib_table_info(rib_dest_table(dest));
- struct zebra_vrf *zvrf = table_info->zvrf;
memset(ri, 0, sizeof(*ri));
ri->prefix = rib_dest_prefix(dest);
ri->af = rib_dest_af(dest);
- if (zvrf && zvrf->zns)
- ri->nlmsg_pid = zvrf->zns->netlink_dplane_out.snl.nl_pid;
+ ri->nlmsg_pid = pid;
ri->nlmsg_type = cmd;
- ri->rtm_table = table_info->table_id;
ri->rtm_protocol = RTPROT_UNSPEC;
/*
@@ -280,6 +275,8 @@ static int netlink_route_info_fill(struct netlink_route_info *ri, int cmd,
return 0;
}
+ ri->rtm_table = re->table;
+
ri->rtm_protocol = netlink_proto_from_route_type(re->type);
ri->rtm_type = RTN_UNICAST;
ri->metric = &re->metric;
diff --git a/zebra/zebra_mlag.c b/zebra/zebra_mlag.c
index 6713dbc96..7715eab0a 100644
--- a/zebra/zebra_mlag.c
+++ b/zebra/zebra_mlag.c
@@ -338,8 +338,6 @@ static void zebra_mlag_post_data_from_main_thread(struct event *thread)
}
}
- stream_free(s);
- return;
stream_failure:
stream_free(s);
if (zebra_s)
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index fc3f0c96a..a678e7173 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -1185,7 +1185,7 @@ struct ptm_process {
TAILQ_HEAD(ppqueue, ptm_process) ppqueue;
DEFINE_MTYPE_STATIC(ZEBRA, ZEBRA_PTM_BFD_PROCESS,
- "PTM BFD process registration table.");
+ "PTM BFD process reg table");
/*
* Prototypes.
diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c
index 36290f99e..babd93ab2 100644
--- a/zebra/zebra_vxlan.c
+++ b/zebra/zebra_vxlan.c
@@ -5274,7 +5274,9 @@ int zebra_vxlan_vrf_delete(struct zebra_vrf *zvrf)
vni = zl3vni->vni;
zl3vni_del(zl3vni);
- zebra_vxlan_handle_vni_transition(zvrf, vni, 0);
+
+ if (!zrouter.in_shutdown)
+ zebra_vxlan_handle_vni_transition(zvrf, vni, 0);
return 0;
}
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 6abd49310..85e1edeca 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -181,9 +181,10 @@ void zserv_log_message(const char *errmsg, struct stream *msg,
*/
static void zserv_client_fail(struct zserv *client)
{
- flog_warn(EC_ZEBRA_CLIENT_IO_ERROR,
- "Client '%s' encountered an error and is shutting down.",
- zebra_route_string(client->proto));
+ flog_warn(
+ EC_ZEBRA_CLIENT_IO_ERROR,
+ "Client '%s' (session id %d) encountered an error and is shutting down.",
+ zebra_route_string(client->proto), client->session_id);
atomic_store_explicit(&client->pthread->running, false,
memory_order_relaxed);
@@ -507,8 +508,6 @@ static void zserv_process_messages(struct event *thread)
stream_fifo_push(cache, msg);
}
- msg = NULL;
-
/* Need to reschedule processing work if there are still
* packets in the fifo.
*/
@@ -588,6 +587,13 @@ static void zserv_client_free(struct zserv *client)
close(client->sock);
+ /* If this is a synchronous BGP Zebra client for label/table
+ * manager, then ignore it. It's not GR-aware, and causes GR to
+ * be skipped for the session_id == 0 (asynchronous).
+ */
+ if (client->proto == ZEBRA_ROUTE_BGP && client->session_id == 1)
+ return;
+
if (DYNAMIC_CLIENT_GR_DISABLED(client)) {
zebra_mpls_client_cleanup_vrf_label(client->proto);