zebra: Notice when an interface is turned on w/ mpls and enable mpls subsystem

Currently when FRR starts up it queries the kernel to see if mpls is turned on.
If not FRR does not enable zebra's mpls subsection.  If at a later time mpls
is turned on, let's notice that an interface now is enabled for mpls( thus
implying that all the bits and bobs in the kernel are now setup properly ).

a) convert mpls_enabled to a bool
b) abstract a new function zebra_mpls_turned_on and call it
when FRR notices that an interface now has mpls enabled.
c) mpls_processq_init cannot fail, so actually notice that
and don't have special code to detect a failure.

New results:

sharpd@eva ~> vtysh -c "show zebra"
 OS                           Linux(5.10.0-12-amd64)
 ECMP Maximum                 128
 v4 Forwarding                On
 v6 Forwarding                On
 MPLS                         Off
 EVPN                         Off
 Kernel socket buffer size    90000000
 VRF                          l3mdev Available
 ASIC offload                 Unavailable
 RA                           Compiled in
 RFC 5549                     BGP is not using
 Kernel NHG                   Available
 v4 All LinkDown Routes       Off
 v4 Default LinkDown Routes   Off
 v6 All LinkDown Routes       Off
 v6 Default LinkDown Routes   Off
 v4 All MC Forwarding         On
 v4 Default MC Forwarding     Off
 v6 All MC Forwarding         On
 v6 Default MC Forwarding     Off

                            Route      Route      Neighbor   LSP        LSP
VRF                         Installs   Removals    Updates   Installs   Removals
default                           26          7          0          0          0
<turn on mpls_iptunnel and mpls_router modules in the kernel and then do this>:
sharpd@eva ~> sudo sysctl -w net.mpls.conf.enp39s0.input=1
[sudo] password for sharpd:
net.mpls.conf.enp39s0.input = 1
sharpd@eva ~> vtysh -c "show zebra"
 OS                           Linux(5.10.0-12-amd64)
 ECMP Maximum                 128
 v4 Forwarding                On
 v6 Forwarding                On
 MPLS                         On
 EVPN                         Off
 Kernel socket buffer size    90000000
 VRF                          l3mdev Available
 ASIC offload                 Unavailable
 RA                           Compiled in
 RFC 5549                     BGP is not using
 Kernel NHG                   Available
 v4 All LinkDown Routes       Off
 v4 Default LinkDown Routes   Off
 v6 All LinkDown Routes       Off
 v6 Default LinkDown Routes   Off
 v4 All MC Forwarding         On
 v4 Default MC Forwarding     Off
 v6 All MC Forwarding         On
 v6 Default MC Forwarding     Off

                            Route      Route      Neighbor   LSP        LSP
VRF                         Installs   Removals    Updates   Installs   Removals
default                           26          7          0          0          0
sharpd@eva ~>

I am doing this work because FRR keeps having operators not know about how
to properly use mpls.  Let's make FRR behave a bit better in this weird edge
case.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This commit is contained in:
Donald Sharp 2022-06-28 14:58:55 -04:00
parent e63831f133
commit c87f5c2392
3 changed files with 26 additions and 18 deletions

View File

@ -1453,9 +1453,10 @@ static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx,
/*
* mpls netconf data is neither v4 or v6 it's AF_MPLS!
*/
if (mpls == DPLANE_NETCONF_STATUS_ENABLED)
if (mpls == DPLANE_NETCONF_STATUS_ENABLED) {
zif->mpls = true;
else if (mpls == DPLANE_NETCONF_STATUS_DISABLED)
zebra_mpls_turned_on();
} else if (mpls == DPLANE_NETCONF_STATUS_DISABLED)
zif->mpls = false;
}

View File

@ -53,7 +53,7 @@ DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object");
DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object");
DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object");
int mpls_enabled;
bool mpls_enabled;
bool mpls_pw_reach_strict; /* Strict reachability checking */
/* static function declarations */
@ -1748,14 +1748,9 @@ static int lsp_cmp(const struct zebra_lsp *lsp1, const struct zebra_lsp *lsp2)
/*
* Initialize work queue for processing changed LSPs.
*/
static int mpls_processq_init(void)
static void mpls_processq_init(void)
{
zrouter.lsp_process_q = work_queue_new(zrouter.master, "LSP processing");
if (!zrouter.lsp_process_q) {
flog_err(EC_ZEBRA_WQ_NONEXISTENT,
"%s: could not initialise work queue!", __func__);
return -1;
}
zrouter.lsp_process_q->spec.workfunc = &lsp_process;
zrouter.lsp_process_q->spec.del_item_data = &lsp_processq_del;
@ -1763,8 +1758,6 @@ static int mpls_processq_init(void)
zrouter.lsp_process_q->spec.completion_func = &lsp_processq_complete;
zrouter.lsp_process_q->spec.max_retries = 0;
zrouter.lsp_process_q->spec.hold = 10;
return 0;
}
@ -4061,12 +4054,23 @@ void zebra_mpls_init_tables(struct zebra_vrf *zvrf)
zvrf->mpls_srgb.end_label = MPLS_DEFAULT_MAX_SRGB_LABEL;
}
void zebra_mpls_turned_on(void)
{
if (!mpls_enabled) {
mpls_processq_init();
mpls_enabled = true;
}
hook_register(zserv_client_close, zebra_mpls_cleanup_fecs_for_client);
hook_register(zserv_client_close, zebra_mpls_cleanup_zclient_labels);
}
/*
* Global MPLS initialization.
*/
void zebra_mpls_init(void)
{
mpls_enabled = 0;
mpls_enabled = false;
mpls_pw_reach_strict = false;
if (mpls_kernel_init() < 0) {
@ -4075,9 +4079,5 @@ void zebra_mpls_init(void)
return;
}
if (!mpls_processq_init())
mpls_enabled = 1;
hook_register(zserv_client_close, zebra_mpls_cleanup_fecs_for_client);
hook_register(zserv_client_close, zebra_mpls_cleanup_zclient_labels);
zebra_mpls_turned_on();
}

View File

@ -394,6 +394,13 @@ void zebra_mpls_close_tables(struct zebra_vrf *zvrf);
*/
void zebra_mpls_init_tables(struct zebra_vrf *zvrf);
/*
* If mpls is turned on *after* FRR is brought
* up let's actually notice this and turn on
* the relevant bits to make it work.
*/
void zebra_mpls_turned_on(void);
/*
* Global MPLS initialization.
*/
@ -569,7 +576,7 @@ static inline int mpls_should_lsps_be_processed(struct route_node *rn)
}
/* Global variables. */
extern int mpls_enabled;
extern bool mpls_enabled;
extern bool mpls_pw_reach_strict; /* Strict pseudowire reachability checking */
#ifdef __cplusplus