Skip to content

Commit

Permalink
ldpd, lib, zebra, topotests: add MPLS interface config from LDP
Browse files Browse the repository at this point in the history
When LDP is enabled per interface, MPLS is not turned on on each
of those interfaces.

Fix this by letting LDP configure the interface if the 'mpls auto'
mode is configured.

Create an IMSG to send interface config request from ldpe thread
to main thread of ldp.
Create a ZAPI message to set MPLS from ldp to zebra.
Update the MPLS setting.
Add a test that ensures that LDP properly configures the interface.

Signed-off-by: Philippe Guibert <[email protected]>
  • Loading branch information
pguibert6WIND committed May 17, 2024
1 parent 14711ad commit dbf2252
Show file tree
Hide file tree
Showing 17 changed files with 162 additions and 3 deletions.
18 changes: 18 additions & 0 deletions ldpd/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

#include <zebra.h>
#include "privs.h"

#include "ldpd.h"
#include "ldpe.h"
Expand All @@ -16,6 +17,8 @@

#include "sockopt.h"

extern struct zebra_privs_t ldpe_privs;

static __inline int iface_compare(const struct iface *, const struct iface *);
static struct if_addr *if_addr_new(struct kaddr *);
static struct if_addr *if_addr_lookup(struct if_addr_head *, struct kaddr *);
Expand Down Expand Up @@ -93,6 +96,20 @@ ldpe_if_init(struct iface *iface)
ldp_sync_fsm_init(iface, LDP_SYNC_STA_NOT_ACH);
}

/* proc sys net mpls conf <name> input set to 1 or 0
* should be used from ldpe only
*/
void ldpe_interface_set_mpls(struct iface *iface, bool val)
{
struct ldp_igp_configure_if_mpls config;

config.ifindex = iface->ifindex;
config.enabled = val;

ldpe_imsg_compose_parent(IMSG_LDP_CONFIGURE_IF_MPLS, getpid(), &config,
sizeof(config));
}

void
ldpe_if_exit(struct iface *iface)
{
Expand Down Expand Up @@ -277,6 +294,7 @@ if_start(struct iface *iface, int af)

log_debug("%s: %s address-family %s", __func__, iface->name, af_name(af));

ldpe_interface_set_mpls(iface, true);
ia = iface_af_get(iface, af);

gettimeofday(&now, NULL);
Expand Down
9 changes: 9 additions & 0 deletions ldpd/ldp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ ldp_sync_zebra_send_state_update(struct ldp_igp_sync_if_state *state)
return 0;
}

int ldp_sync_zebra_send_configure_if_mpls(struct ldp_igp_configure_if_mpls *config)
{
if (zebra_send_interface_mpls_set(zclient, VRF_DEFAULT, config->ifindex,
config->enabled) <= 0)
return -1;

return zclient_send_message(zclient);
}

static int
ldp_sync_zebra_send_announce(void)
{
Expand Down
10 changes: 10 additions & 0 deletions ldpd/ldpd.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,15 @@ static void main_dispatch_ldpe(struct event *thread)

ldp_sync_zebra_send_state_update((struct ldp_igp_sync_if_state *)imsg.data);
break;
case IMSG_LDP_CONFIGURE_IF_MPLS:
if (imsg.hdr.len !=
IMSG_HEADER_SIZE +
sizeof(struct ldp_igp_configure_if_mpls))
fatalx("IMSG_LDP_CONFIGURE_IF_MPLS imsg with wrong len");

ldp_sync_zebra_send_configure_if_mpls(
(struct ldp_igp_configure_if_mpls *)imsg.data);
break;
default:
log_debug("%s: error handling imsg %d", __func__,
imsg.hdr.type);
Expand Down Expand Up @@ -1524,6 +1533,7 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf)
if (if_lookup_name(xconf, iface->name) == NULL) {
switch (ldpd_process) {
case PROC_LDP_ENGINE:
ldpe_interface_set_mpls(iface, false);
ldpe_if_exit(iface);
break;
case PROC_LDE_ENGINE:
Expand Down
2 changes: 2 additions & 0 deletions ldpd/ldpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ enum imsg_type {
IMSG_RLFA_UNREG_ALL,
IMSG_RLFA_LABELS,
IMSG_AGENTX_ENABLED,
IMSG_LDP_CONFIGURE_IF_MPLS,
};

struct ldpd_init {
Expand Down Expand Up @@ -890,6 +891,7 @@ extern char ctl_sock_path[MAXPATHLEN];
void ldp_zebra_init(struct event_loop *m);
void ldp_zebra_destroy(void);
int ldp_sync_zebra_send_state_update(struct ldp_igp_sync_if_state *);
int ldp_sync_zebra_send_configure_if_mpls(struct ldp_igp_configure_if_mpls *);
int ldp_zebra_send_rlfa_labels(struct zapi_rlfa_response *
rlfa_labels);

Expand Down
1 change: 1 addition & 0 deletions ldpd/ldpe.h
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ void ldpe_l2vpn_init(struct l2vpn *);
void ldpe_l2vpn_exit(struct l2vpn *);
void ldpe_l2vpn_pw_init(struct l2vpn_pw *);
void ldpe_l2vpn_pw_exit(struct l2vpn_pw *);
extern void ldpe_interface_set_mpls(struct iface *iface, bool val);

DECLARE_HOOK(ldp_nbr_state_change, (struct nbr * nbr, int old_state),
(nbr, old_state));
Expand Down
5 changes: 5 additions & 0 deletions lib/ldp_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ struct ldp_igp_sync_if_state {
bool sync_start;
};

struct ldp_igp_configure_if_mpls {
ifindex_t ifindex;
bool enabled;
};

struct ldp_igp_sync_if_state_req {
int proto;
ifindex_t ifindex;
Expand Down
45 changes: 45 additions & 0 deletions lib/zclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -2867,6 +2867,51 @@ size_t zebra_interface_link_params_write(struct stream *s,
return w;
}

int zebra_send_interface_mpls_set(struct zclient *zclient, vrf_id_t vrf_id,
ifindex_t ifindex, bool set)
{
struct stream *s;

if (!zclient->obuf)
return 0;

s = zclient->obuf;
stream_reset(s);

zclient_create_header(s, ZEBRA_INTERFACE_MPLS_SET, VRF_DEFAULT);

stream_putl(s, ifindex);
stream_putc(s, set);

stream_putw_at(s, 0, stream_get_endp(s));

return zclient_send_message(zclient);
}

struct interface *zebra_interface_mpls_set_read(struct stream *s,
vrf_id_t vrf_id,
bool *value_to_set)
{
ifindex_t ifindex;
struct interface *ifp = NULL;

STREAM_GETL(s, ifindex);

ifp = if_lookup_by_index(ifindex, vrf_id);

if (ifp == NULL) {
flog_err(EC_LIB_ZAPI_ENCODE,
"%s: unknown ifindex %u, shouldn't happen", __func__,
ifindex);
return NULL;
}
if (value_to_set)
STREAM_GETC(s, *value_to_set);

stream_failure:
return ifp;
}

/*
* format of message for address addition is:
* 0
Expand Down
7 changes: 7 additions & 0 deletions lib/zclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ typedef enum {
ZEBRA_INTERFACE_DISABLE_RADV,
ZEBRA_NEXTHOP_LOOKUP_MRIB,
ZEBRA_INTERFACE_LINK_PARAMS,
ZEBRA_INTERFACE_MPLS_SET,
ZEBRA_MPLS_LABELS_ADD,
ZEBRA_MPLS_LABELS_DELETE,
ZEBRA_MPLS_LABELS_REPLACE,
Expand Down Expand Up @@ -1055,6 +1056,12 @@ extern struct interface *zebra_interface_link_params_read(struct stream *s,
bool *changed);
extern size_t zebra_interface_link_params_write(struct stream *,
struct interface *);
extern int zebra_send_interface_mpls_set(struct zclient *zclient,
vrf_id_t vrf_id, ifindex_t ifindex,
bool set);
extern struct interface *zebra_interface_mpls_set_read(struct stream *s,
vrf_id_t vrf_id,
bool *value_to_set);
extern enum zclient_send_status
zclient_send_get_label_chunk(struct zclient *zclient, uint8_t keep,
uint32_t chunk_size, uint32_t base);
Expand Down
1 change: 1 addition & 0 deletions tests/topotests/ldp_topo1/r1/zebra.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface r1-eth0
description to sw0
ip address 10.0.1.1/24
no link-detect
mpls auto
!
ip forwarding
!
Expand Down
3 changes: 3 additions & 0 deletions tests/topotests/ldp_topo1/r2/zebra.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,19 @@ interface r2-eth0
description to sw0
ip address 10.0.1.2/24
no link-detect
mpls auto
!
interface r2-eth1
description to sw1
ip address 10.0.2.2/24
no link-detect
mpls auto
!
interface r2-eth2
description to sw2
ip address 10.0.3.2/24
no link-detect
mpls auto
!
ip forwarding
!
Expand Down
2 changes: 2 additions & 0 deletions tests/topotests/ldp_topo1/r3/zebra.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ interface r3-eth0
description to sw1
ip address 10.0.2.3/24
no link-detect
mpls auto
!
interface r3-eth1
description to sw2
ip address 10.0.3.3/24
no link-detect
mpls auto
!
ip forwarding
!
Expand Down
1 change: 1 addition & 0 deletions tests/topotests/ldp_topo1/r4/zebra.conf
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface r4-eth0
description to sw1
ip address 10.0.2.4/24
no link-detect
mpls auto
!
ip forwarding
!
Expand Down
34 changes: 32 additions & 2 deletions tests/topotests/ldp_topo1/test_ldp_topo1.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@


def build_topo(tgen):

# Setup Routers
for i in range(1, 5):
tgen.add_router("r%s" % i)
Expand Down Expand Up @@ -134,6 +133,7 @@ def setup_module(module):
tgen.start_topology()

net = tgen.net
os.environ["TOPOTESTS_MPLS_AUTO"] = "1"

# Starting Routers
for i in range(1, 5):
Expand Down Expand Up @@ -781,6 +781,37 @@ def test_linux_mpls_routes():
assert fatal_error == "", fatal_error


def _check_mpls_interface_set(rname, ifname, value):
tgen = get_topogen()
val = (
tgen.net[rname]
.cmd_raises("sysctl -n " + "net.mpls.conf." + ifname + ".input")
.strip()
)
assert (
val == value
), f"{rname}, interface {ifname} has MPLS flag set to {val}, unexpected"


def test_linux_mpls_interface_settings():
global fatal_error

# Skip if previous fatal error condition is raised
if fatal_error != "":
pytest.skip(fatal_error)

# Verify Linux Kernel MPLS settings
print("\n\n** Verifying Linux MPLS interface settings")
print("******************************************\n")
_check_mpls_interface_set("r1", "r1-eth0", "1")
_check_mpls_interface_set("r2", "r2-eth0", "1")
_check_mpls_interface_set("r2", "r2-eth1", "1")
_check_mpls_interface_set("r2", "r2-eth2", "1")
_check_mpls_interface_set("r3", "r3-eth0", "1")
_check_mpls_interface_set("r3", "r3-eth1", "1")
_check_mpls_interface_set("r4", "r4-eth0", "1")


def test_shutdown_check_stderr():
global fatal_error
net = get_topogen().net
Expand Down Expand Up @@ -837,7 +868,6 @@ def test_shutdown_check_memleak():


if __name__ == "__main__":

# To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
# retval = pytest.main(["-s", "--tb=no"])
retval = pytest.main(["-s"])
Expand Down
6 changes: 5 additions & 1 deletion tests/topotests/lib/topogen.py
Original file line number Diff line number Diff line change
Expand Up @@ -907,9 +907,13 @@ def start(self):
daemon=daemon,
)

if nrouter.daemons["ldpd"] == 1 and not os.environ.get("TOPOTESTS_MPLS_AUTO"):
need_mpls_for_ldp = True
else:
need_mpls_for_ldp = False
if result != "":
self.tgen.set_error(result)
elif nrouter.daemons["ldpd"] == 1 or nrouter.daemons["pathd"] == 1:
elif need_mpls_for_ldp or nrouter.daemons["pathd"] == 1:
# Enable MPLS processing on all interfaces.
for interface in self.links:
topotest.sysctl_assure(
Expand Down
17 changes: 17 additions & 0 deletions zebra/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -3974,6 +3974,23 @@ void mpls_auto_interface_data_off(struct interface *ifp)
mpls_auto_interface_data_internal(ifp, false);
}

void zebra_interface_mpls_set(ZAPI_HANDLER_ARGS)
{
struct interface *ifp;
bool mpls = false;
struct stream *s;

s = msg;
ifp = zebra_interface_mpls_set_read(s, zvrf->vrf->vrf_id, &mpls);
if (!ifp)
return;

if (mpls)
mpls_auto_interface_data_on(ifp);
else
mpls_auto_interface_data_off(ifp);
}

/* Allocate and initialize interface vector. */
void zebra_if_init(void)
{
Expand Down
3 changes: 3 additions & 0 deletions zebra/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "zebra/zebra_nhg_private.h"
#include "zebra/zebra_router.h"
#include "zebra/rtadv.h"
#include "zebra/zserv.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -354,6 +355,8 @@ extern const char *zebra_protodown_rc_str(uint32_t protodown_rc, char *pd_buf,
uint32_t pd_buf_len);
extern void mpls_auto_interface_data_off(struct interface *ifp);
extern void mpls_auto_interface_data_on(struct interface *ifp);
extern void zebra_interface_mpls_set(struct zserv *client, struct zmsghdr *hdr,
struct stream *msg, struct zebra_vrf *zvrf);
void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx);

#ifdef HAVE_PROC_NET_DEV
Expand Down
1 change: 1 addition & 0 deletions zebra/zapi_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -3908,6 +3908,7 @@ void (*const zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
[ZEBRA_BFD_CLIENT_REGISTER] = zebra_ptm_bfd_client_register,
[ZEBRA_INTERFACE_ENABLE_RADV] = zebra_interface_radv_enable,
[ZEBRA_INTERFACE_DISABLE_RADV] = zebra_interface_radv_disable,
[ZEBRA_INTERFACE_MPLS_SET] = zebra_interface_mpls_set,
[ZEBRA_SR_POLICY_SET] = zread_sr_policy_set,
[ZEBRA_SR_POLICY_DELETE] = zread_sr_policy_delete,
[ZEBRA_MPLS_LABELS_ADD] = zread_mpls_labels_add,
Expand Down

0 comments on commit dbf2252

Please sign in to comment.