diff --git a/doc/user/zebra.rst b/doc/user/zebra.rst index d96df0ce52..05990e2523 100644 --- a/doc/user/zebra.rst +++ b/doc/user/zebra.rst @@ -155,6 +155,13 @@ Standard Commands Set description for the interface. +.. clicmd:: mpls enable + + Enable or disable mpls kernel processing on the interface, for linux. Interfaces + configured with mpls will not automatically turn on if mpls kernel modules do not + happen to be loaded. This command will fail on 3.X linux kernels and does not + work on non-linux systems at all. + .. clicmd:: multicast diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/customize.py b/tests/topotests/bgp_l3vpn_to_bgp_direct/customize.py index 36bfdfe068..c0a5c7ad9c 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/customize.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/customize.py @@ -137,22 +137,6 @@ def ltemplatePreRouterStartHook(): if tgen.hasmpls != True: logger.info("MPLS not available, skipping setup") return False - # configure r2 mpls interfaces - intfs = ["lo", "r2-eth0", "r2-eth1", "r2-eth2"] - for intf in intfs: - cc.doCmd(tgen, "r2", "echo 1 > /proc/sys/net/mpls/conf/{}/input".format(intf)) - # configure MPLS - rtrs = ["r1", "r3", "r4"] - cmds = ["echo 1 > /proc/sys/net/mpls/conf/lo/input"] - for rtr in rtrs: - router = tgen.gears[rtr] - for cmd in cmds: - cc.doCmd(tgen, rtr, cmd) - intfs = ["lo", rtr + "-eth0", rtr + "-eth4"] - for intf in intfs: - cc.doCmd( - tgen, rtr, "echo 1 > /proc/sys/net/mpls/conf/{}/input".format(intf) - ) logger.info("setup mpls input") return True diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/zebra.conf index 18f61e0c54..767e17e62c 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r1/zebra.conf @@ -3,15 +3,18 @@ log file zebra.log hostname r1 ! interface lo + mpls ip address 1.1.1.1/32 ! interface r1-eth0 description to sw0 + mpls ip address 10.0.1.1/24 no link-detect ! interface r1-eth4 description to ce1 + mpls ip address 192.168.1.1/24 no link-detect ! diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/zebra.conf index dd1dbac32b..829ac969e3 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r2/zebra.conf @@ -3,20 +3,24 @@ log file zebra.log hostname r2 ! interface lo + mpls ip address 2.2.2.2/32 ! interface r2-eth0 description to sw0 + mpls ip address 10.0.1.2/24 no link-detect ! interface r2-eth1 description to sw1 + mpls ip address 10.0.2.2/24 no link-detect ! interface r2-eth2 description to sw2 + mpls ip address 10.0.3.2/24 no link-detect ! diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/zebra.conf index 9dbc290243..916dabf37d 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r3/zebra.conf @@ -3,10 +3,12 @@ log file zebra.log hostname r3 ! interface lo + mpls ip address 3.3.3.3/32 ! interface r3-eth0 description to sw1 + mpls ip address 10.0.2.3/24 no link-detect ! @@ -17,6 +19,7 @@ interface r3-eth1 ! interface r3-eth4 description to ce2 + mpls ip address 192.168.1.1/24 no link-detect ! diff --git a/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/zebra.conf index 415f03df51..e08ac86aec 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_direct/r4/zebra.conf @@ -3,15 +3,18 @@ log file zebra.log hostname r4 ! interface lo + mpls ip address 4.4.4.4/32 ! interface r4-eth0 description to sw1 + mpls ip address 10.0.2.4/24 no link-detect ! interface r4-eth4 description to ce3 + mpls ip address 192.168.1.1/24 no link-detect ! diff --git a/zebra/if_socket.c b/zebra/if_socket.c index 309d5a3f3e..da9fadf7c7 100644 --- a/zebra/if_socket.c +++ b/zebra/if_socket.c @@ -38,4 +38,15 @@ enum zebra_dplane_result kernel_intf_update(struct zebra_dplane_ctx *ctx) return ZEBRA_DPLANE_REQUEST_FAILURE; } +enum zebra_dplane_result +kernel_intf_netconf_update(struct zebra_dplane_ctx *ctx) +{ + const char *ifname = dplane_ctx_get_ifname(ctx); + enum dplane_netconf_status_e mpls_on = dplane_ctx_get_netconf_mpls(ctx); + + zlog_warn("%s: Unable to set kernel mpls state for interface %s(%d)", + __func__, ifname, mpls_on); + + return ZEBRA_DPLANE_REQUEST_SUCCESS; +} #endif diff --git a/zebra/interface.c b/zebra/interface.c index de7db2d48f..b7a984e44d 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -147,8 +147,8 @@ static int if_zebra_new_hook(struct interface *ifp) zebra_if = XCALLOC(MTYPE_ZINFO, sizeof(struct zebra_if)); zebra_if->ifp = ifp; - zebra_if->multicast = IF_ZEBRA_MULTICAST_UNSPEC; - zebra_if->shutdown = IF_ZEBRA_SHUTDOWN_OFF; + zebra_if->multicast = IF_ZEBRA_DATA_UNSPEC; + zebra_if->shutdown = IF_ZEBRA_DATA_OFF; zebra_if_nhg_dependents_init(zebra_if); @@ -583,9 +583,9 @@ void if_add_update(struct interface *ifp) if_data = ifp->info; assert(if_data); - if (if_data->multicast == IF_ZEBRA_MULTICAST_ON) + if (if_data->multicast == IF_ZEBRA_DATA_ON) if_set_flags(ifp, IFF_MULTICAST); - else if (if_data->multicast == IF_ZEBRA_MULTICAST_OFF) + else if (if_data->multicast == IF_ZEBRA_DATA_OFF) if_unset_flags(ifp, IFF_MULTICAST); zebra_ptm_if_set_ptm_state(ifp, if_data); @@ -595,7 +595,7 @@ void if_add_update(struct interface *ifp) if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { SET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE); - if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON) { + if (if_data->shutdown == IF_ZEBRA_DATA_ON) { if (IS_ZEBRA_DEBUG_KERNEL) { zlog_debug( "interface %s vrf %s(%u) index %d is shutdown. Won't wake it up.", @@ -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; } @@ -2908,7 +2909,7 @@ int if_multicast_set(struct interface *ifp) if_refresh(ifp); } if_data = ifp->info; - if_data->multicast = IF_ZEBRA_MULTICAST_ON; + if_data->multicast = IF_ZEBRA_DATA_ON; return 0; } @@ -2931,7 +2932,28 @@ DEFUN (multicast, if_refresh(ifp); } if_data = ifp->info; - if_data->multicast = IF_ZEBRA_MULTICAST_ON; + if_data->multicast = IF_ZEBRA_DATA_ON; + + return CMD_SUCCESS; +} + +DEFPY (mpls, + mpls_cmd, + "[no] mpls enable", + NO_STR + MPLS_STR + "Set mpls to be on for the interface\n") +{ + VTY_DECLVAR_CONTEXT(interface, ifp); + struct zebra_if *if_data = ifp->info; + + if (no) { + dplane_intf_mpls_modify_state(ifp, false); + if_data->mpls = IF_ZEBRA_DATA_UNSPEC; + } else { + dplane_intf_mpls_modify_state(ifp, true); + if_data->mpls = IF_ZEBRA_DATA_ON; + } return CMD_SUCCESS; } @@ -2949,7 +2971,7 @@ int if_multicast_unset(struct interface *ifp) if_refresh(ifp); } if_data = ifp->info; - if_data->multicast = IF_ZEBRA_MULTICAST_OFF; + if_data->multicast = IF_ZEBRA_DATA_OFF; return 0; } @@ -2973,7 +2995,7 @@ DEFUN (no_multicast, if_refresh(ifp); } if_data = ifp->info; - if_data->multicast = IF_ZEBRA_MULTICAST_OFF; + if_data->multicast = IF_ZEBRA_DATA_OFF; return CMD_SUCCESS; } @@ -3039,7 +3061,7 @@ int if_shutdown(struct interface *ifp) if_refresh(ifp); } if_data = ifp->info; - if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON; + if_data->shutdown = IF_ZEBRA_DATA_ON; return 0; } @@ -3064,7 +3086,7 @@ DEFUN (shutdown_if, if_refresh(ifp); } if_data = ifp->info; - if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON; + if_data->shutdown = IF_ZEBRA_DATA_ON; return CMD_SUCCESS; } @@ -3088,7 +3110,7 @@ int if_no_shutdown(struct interface *ifp) } if_data = ifp->info; - if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF; + if_data->shutdown = IF_ZEBRA_DATA_OFF; return 0; } @@ -3119,7 +3141,7 @@ DEFUN (no_shutdown_if, } if_data = ifp->info; - if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF; + if_data->shutdown = IF_ZEBRA_DATA_OFF; return CMD_SUCCESS; } @@ -3906,9 +3928,9 @@ int if_ip_address_install(struct interface *ifp, struct prefix *prefix, SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); /* In case of this route need to install kernel. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) - && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) - && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) { + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) && + CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && + !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) { /* Some system need to up the interface to set IP address. */ if (!if_is_up(ifp)) { if_set_flags(ifp, IFF_UP | IFF_RUNNING); @@ -4001,9 +4023,9 @@ static int ip_address_install(struct vty *vty, struct interface *ifp, SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); /* In case of this route need to install kernel. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) - && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) - && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) { + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) && + CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && + !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) { /* Some system need to up the interface to set IP address. */ if (!if_is_up(ifp)) { if_set_flags(ifp, IFF_UP | IFF_RUNNING); @@ -4264,9 +4286,9 @@ int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix, SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); /* In case of this route need to install kernel. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) - && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) - && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) { + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) && + CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && + !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) { /* Some system need to up the interface to set IP address. */ if (!if_is_up(ifp)) { if_set_flags(ifp, IFF_UP | IFF_RUNNING); @@ -4337,9 +4359,9 @@ static int ipv6_address_install(struct vty *vty, struct interface *ifp, SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED); /* In case of this route need to install kernel. */ - if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) - && CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) - && !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) { + if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED) && + CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE) && + !(if_data && if_data->shutdown == IF_ZEBRA_DATA_ON)) { /* Some system need to up the interface to set IP address. */ if (!if_is_up(ifp)) { if_set_flags(ifp, IFF_UP | IFF_RUNNING); @@ -4524,7 +4546,7 @@ static int if_config_write(struct vty *vty) if_vty_config_start(vty, ifp); if (if_data) { - if (if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON) + if (if_data->shutdown == IF_ZEBRA_DATA_ON) vty_out(vty, " shutdown\n"); zebra_ptm_if_write(vty, if_data); @@ -4574,13 +4596,14 @@ static int if_config_write(struct vty *vty) } if (if_data) { - if (if_data->multicast - != IF_ZEBRA_MULTICAST_UNSPEC) + if (if_data->multicast != IF_ZEBRA_DATA_UNSPEC) vty_out(vty, " %smulticast\n", - if_data->multicast - == IF_ZEBRA_MULTICAST_ON + if_data->multicast == + IF_ZEBRA_DATA_ON ? "" : "no "); + if (if_data->mpls == IF_ZEBRA_DATA_ON) + vty_out(vty, " mpls\n"); } hook_call(zebra_if_config_wr, vty, ifp); @@ -4617,6 +4640,7 @@ void zebra_if_init(void) install_element(ENABLE_NODE, &show_interface_desc_vrf_all_cmd); install_element(INTERFACE_NODE, &multicast_cmd); install_element(INTERFACE_NODE, &no_multicast_cmd); + install_element(INTERFACE_NODE, &mpls_cmd); install_element(INTERFACE_NODE, &linkdetect_cmd); install_element(INTERFACE_NODE, &no_linkdetect_cmd); install_element(INTERFACE_NODE, &shutdown_if_cmd); diff --git a/zebra/interface.h b/zebra/interface.h index f3f41b90c5..801078e83d 100644 --- a/zebra/interface.h +++ b/zebra/interface.h @@ -36,14 +36,10 @@ extern "C" { #endif -/* For interface multicast configuration. */ -#define IF_ZEBRA_MULTICAST_UNSPEC 0 -#define IF_ZEBRA_MULTICAST_ON 1 -#define IF_ZEBRA_MULTICAST_OFF 2 - -/* For interface shutdown configuration. */ -#define IF_ZEBRA_SHUTDOWN_OFF 0 -#define IF_ZEBRA_SHUTDOWN_ON 1 +/* For interface configuration. */ +#define IF_ZEBRA_DATA_UNSPEC 0 +#define IF_ZEBRA_DATA_ON 1 +#define IF_ZEBRA_DATA_OFF 2 #define IF_VLAN_BITMAP_MAX 4096 diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c index 5c8aca9691..396ccb34bd 100644 --- a/zebra/kernel_netlink.c +++ b/zebra/kernel_netlink.c @@ -1613,10 +1613,12 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth, case DPLANE_OP_INTF_ADDR_ADD: case DPLANE_OP_INTF_ADDR_DEL: - case DPLANE_OP_INTF_NETCONFIG: case DPLANE_OP_NONE: return FRR_NETLINK_ERROR; + case DPLANE_OP_INTF_NETCONFIG: + return netlink_put_intf_netconfig(bth, ctx); + case DPLANE_OP_INTF_INSTALL: case DPLANE_OP_INTF_UPDATE: case DPLANE_OP_INTF_DELETE: diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 2741a23242..076e9c4dfa 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1529,7 +1529,7 @@ void kernel_update_multi(struct dplane_ctx_q *ctx_list) { struct zebra_dplane_ctx *ctx; struct dplane_ctx_q handled_list; - enum zebra_dplane_result res; + enum zebra_dplane_result res = ZEBRA_DPLANE_REQUEST_SUCCESS; TAILQ_INIT(&handled_list); @@ -1611,9 +1611,27 @@ void kernel_update_multi(struct dplane_ctx_q *ctx_list) res = ZEBRA_DPLANE_REQUEST_SUCCESS; break; - default: - res = ZEBRA_DPLANE_REQUEST_FAILURE; + case DPLANE_OP_INTF_NETCONFIG: + res = kernel_intf_netconf_update(ctx); break; + + case DPLANE_OP_NONE: + case DPLANE_OP_BR_PORT_UPDATE: + case DPLANE_OP_IPTABLE_ADD: + case DPLANE_OP_IPTABLE_DELETE: + case DPLANE_OP_IPSET_ADD: + case DPLANE_OP_IPSET_DELETE: + case DPLANE_OP_IPSET_ENTRY_ADD: + case DPLANE_OP_IPSET_ENTRY_DELETE: + case DPLANE_OP_NEIGH_IP_INSTALL: + case DPLANE_OP_NEIGH_IP_DELETE: + case DPLANE_OP_NEIGH_TABLE_UPDATE: + case DPLANE_OP_GRE_SET: + case DPLANE_OP_INTF_ADDR_ADD: + case DPLANE_OP_INTF_ADDR_DEL: + zlog_err("Unhandled dplane data for %s", + dplane_op2str(dplane_ctx_get_op(ctx))); + res = ZEBRA_DPLANE_REQUEST_FAILURE; } skip_one: diff --git a/zebra/netconf_netlink.c b/zebra/netconf_netlink.c index f9cb37a3cf..56f56bfe66 100644 --- a/zebra/netconf_netlink.c +++ b/zebra/netconf_netlink.c @@ -29,6 +29,7 @@ #include "linux/netconf.h" +#include "lib/lib_errors.h" #include "zebra/zebra_ns.h" #include "zebra/zebra_dplane.h" #include "zebra/kernel_netlink.h" @@ -185,4 +186,56 @@ int netlink_request_netconf(int sockfd) return netlink_request(nls, &req); } +extern struct zebra_privs_t zserv_privs; +/* + * Currently netconf has no ability to set from netlink. + * So we've received a request to do this work in the data plane. + * as such we need to set the value via the /proc system + */ +enum netlink_msg_status netlink_put_intf_netconfig(struct nl_batch *bth, + struct zebra_dplane_ctx *ctx) +{ + const char *ifname = dplane_ctx_get_ifname(ctx); + enum dplane_netconf_status_e mpls_on = dplane_ctx_get_netconf_mpls(ctx); + char set[64]; + char mpls_proc[PATH_MAX]; + int fd, ret = FRR_NETLINK_ERROR; + + snprintf(mpls_proc, sizeof(mpls_proc), + "/proc/sys/net/mpls/conf/%s/input", ifname); + + if (mpls_on == DPLANE_NETCONF_STATUS_ENABLED) + snprintf(set, sizeof(set), "1\n"); + else if (mpls_on == DPLANE_NETCONF_STATUS_DISABLED) + snprintf(set, sizeof(set), "0\n"); + else { + flog_err_sys( + EC_LIB_DEVELOPMENT, + "%s: Expected interface %s to be set to ENABLED or DISABLED was %d", + __func__, ifname, mpls_on); + return ret; + } + + frr_with_privs (&zserv_privs) { + fd = open(mpls_proc, O_WRONLY); + if (fd < 0) { + flog_err_sys( + EC_LIB_SOCKET, + "%s: Unable to open %s for writing: %s(%d)", + __func__, mpls_proc, safe_strerror(errno), + errno); + return ret; + } + if (write(fd, set, 2) == 2) + ret = FRR_NETLINK_SUCCESS; + else + flog_err_sys(EC_LIB_SOCKET, + "%s: Unsuccessful write to %s: %s(%d)", + __func__, mpls_proc, safe_strerror(errno), + errno); + close(fd); + } + return ret; +} + #endif /* HAVE_NETLINK */ diff --git a/zebra/netconf_netlink.h b/zebra/netconf_netlink.h index 3f2e7af768..1b3450bcb5 100644 --- a/zebra/netconf_netlink.h +++ b/zebra/netconf_netlink.h @@ -38,6 +38,10 @@ extern int netlink_netconf_change(struct nlmsghdr *h, ns_id_t ns_id, /* Request info from the host OS. */ int netlink_request_netconf(int sockfd); +struct nl_batch; + +extern enum netlink_msg_status +netlink_put_intf_netconfig(struct nl_batch *bth, struct zebra_dplane_ctx *ctx); #ifdef __cplusplus } diff --git a/zebra/rt.h b/zebra/rt.h index 4952c3eb1a..0a86a2897c 100644 --- a/zebra/rt.h +++ b/zebra/rt.h @@ -69,6 +69,9 @@ kernel_pbr_rule_update(struct zebra_dplane_ctx *ctx); extern enum zebra_dplane_result kernel_intf_update(struct zebra_dplane_ctx *ctx); +extern enum zebra_dplane_result +kernel_intf_netconf_update(struct zebra_dplane_ctx *ctx); + #endif /* !HAVE_NETLINK */ extern int kernel_neigh_update(int cmd, int ifindex, void *addr, char *lla, diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c index a4330a3200..4c7838198e 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c @@ -509,6 +509,8 @@ static struct zebra_dplane_globals { _Atomic uint32_t dg_intf_addrs_in; _Atomic uint32_t dg_intf_addr_errors; + _Atomic uint32_t dg_intf_changes; + _Atomic uint32_t dg_intf_changes_errors; _Atomic uint32_t dg_macs_in; _Atomic uint32_t dg_mac_errors; @@ -3913,6 +3915,47 @@ dplane_br_port_update(const struct interface *ifp, bool non_df, return result; } +enum zebra_dplane_result +dplane_intf_mpls_modify_state(const struct interface *ifp, bool set) +{ + enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE; + struct zebra_dplane_ctx *ctx; + struct zebra_ns *zns; + int ret = EINVAL; + + ctx = dplane_ctx_alloc(); + ctx->zd_op = DPLANE_OP_INTF_NETCONFIG; + ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS; + ctx->zd_vrf_id = ifp->vrf->vrf_id; + strlcpy(ctx->zd_ifname, ifp->name, sizeof(ctx->zd_ifname)); + + zns = zebra_ns_lookup(ifp->vrf->vrf_id); + dplane_ctx_ns_init(ctx, zns, false); + + ctx->zd_ifindex = ifp->ifindex; + if (set) + dplane_ctx_set_netconf_mpls(ctx, DPLANE_NETCONF_STATUS_ENABLED); + else + dplane_ctx_set_netconf_mpls(ctx, + DPLANE_NETCONF_STATUS_DISABLED); + /* Increment counter */ + atomic_fetch_add_explicit(&zdplane_info.dg_intf_changes, 1, + memory_order_relaxed); + + ret = dplane_update_enqueue(ctx); + + if (ret == AOK) + result = ZEBRA_DPLANE_REQUEST_QUEUED; + else { + /* Error counter */ + atomic_fetch_add_explicit(&zdplane_info.dg_intf_changes_errors, + 1, memory_order_relaxed); + dplane_ctx_free(&ctx); + } + + return result; +} + /* * Enqueue interface address add for the dataplane. */ @@ -4900,6 +4943,13 @@ int dplane_show_helper(struct vty *vty, bool detailed) vty_out(vty, "Intf addr updates: %"PRIu64"\n", incoming); vty_out(vty, "Intf addr errors: %"PRIu64"\n", errs); + incoming = atomic_load_explicit(&zdplane_info.dg_intf_changes, + memory_order_relaxed); + errs = atomic_load_explicit(&zdplane_info.dg_intf_changes_errors, + memory_order_relaxed); + vty_out(vty, "Intf change updates: %" PRIu64 "\n", incoming); + vty_out(vty, "Intf change errors: %" PRIu64 "\n", errs); + incoming = atomic_load_explicit(&zdplane_info.dg_macs_in, memory_order_relaxed); errs = atomic_load_explicit(&zdplane_info.dg_mac_errors, diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h index d940bd9568..c96ea40094 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h @@ -690,6 +690,8 @@ enum zebra_dplane_result dplane_lsp_notif_update(struct zebra_lsp *lsp, enum zebra_dplane_result dplane_pw_install(struct zebra_pw *pw); enum zebra_dplane_result dplane_pw_uninstall(struct zebra_pw *pw); +enum zebra_dplane_result +dplane_intf_mpls_modify_state(const struct interface *ifp, const bool set); /* * Enqueue interface address changes for the dataplane. */ diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index caac3e3230..ade381e27f 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -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(); } diff --git a/zebra/zebra_mpls.h b/zebra/zebra_mpls.h index a8c4e1a60c..a7a955a80b 100644 --- a/zebra/zebra_mpls.h +++ b/zebra/zebra_mpls.h @@ -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 diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 660ac1f102..c5b533fc22 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1613,9 +1613,6 @@ void zebra_nhg_free(struct nhg_hash_entry *nhe) THREAD_OFF(nhe->timer); - if (nhe->refcnt) - zlog_debug("nhe_id=%pNG hash refcnt=%d", nhe, nhe->refcnt); - zebra_nhg_free_members(nhe); XFREE(MTYPE_NHG, nhe);