summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas@opensourcerouting.org>2022-08-08 19:04:49 +0300
committerGitHub <noreply@github.com>2022-08-08 19:04:49 +0300
commit8d60d4da501d015ab645d8546c429990d7ecb033 (patch)
treebf80a5ff2108be24c72165478a1cddaacffa2a85
parente1b8fb026720bce43b57a57f6fcdcc744815c14f (diff)
parentcbc08d1fb9f511323363fd3578ed7b1a5f9a6859 (diff)
Merge pull request #11501 from donaldsharp/mpls_turns_on
Mpls turns on
-rw-r--r--doc/user/zebra.rst7
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/customize.py16
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r1/zebra.conf3
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r2/zebra.conf4
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r3/zebra.conf3
-rw-r--r--tests/topotests/bgp_l3vpn_to_bgp_direct/r4/zebra.conf3
-rw-r--r--zebra/if_socket.c11
-rw-r--r--zebra/interface.c88
-rw-r--r--zebra/interface.h12
-rw-r--r--zebra/kernel_netlink.c4
-rw-r--r--zebra/kernel_socket.c24
-rw-r--r--zebra/netconf_netlink.c53
-rw-r--r--zebra/netconf_netlink.h4
-rw-r--r--zebra/rt.h3
-rw-r--r--zebra/zebra_dplane.c50
-rw-r--r--zebra/zebra_dplane.h2
-rw-r--r--zebra/zebra_mpls.c30
-rw-r--r--zebra/zebra_mpls.h9
-rw-r--r--zebra/zebra_nhg.c3
19 files changed, 250 insertions, 79 deletions
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
@@ -395,6 +395,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.
*/
void zebra_mpls_init(void);
@@ -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);