Skip to content

Commit

Permalink
bgpd, zebra, tests: move plugin down to zebra
Browse files Browse the repository at this point in the history
Move plugin invocation lower in the demon stack.
This way, dscp tag is exposed for usage to the rest of demons.

Signed-off-by: Volodymyr Huti <[email protected]>
  • Loading branch information
Volodymyr Huti committed Feb 24, 2024
1 parent 1775066 commit 04962e7
Show file tree
Hide file tree
Showing 16 changed files with 77 additions and 62 deletions.
8 changes: 5 additions & 3 deletions bgpd/bgp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ static bool bgp_zebra_label_manager_connect(void);
/* hook to indicate vrf status change for SNMP */
DEFINE_HOOK(bgp_vrf_status_changed, (struct bgp *bgp, struct interface *ifp),
(bgp, ifp));
DEFINE_HOOK(bgp_qppb_mark_prefix,
(const struct prefix *p, uint8_t dscp, bool add), (p, dscp, add));

DEFINE_MTYPE_STATIC(BGPD, BGP_IF_INFO, "BGP interface context");

Expand Down Expand Up @@ -1645,6 +1643,11 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
api.metric = metric;

if (dscp) {
SET_FLAG(api.message, ZAPI_MESSAGE_DSCP);
api.dscp = dscp;
}

if (tag) {
SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
api.tag = tag;
Expand All @@ -1671,7 +1674,6 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
__func__, p, (recursion_flag ? "" : "NOT "));
}

hook_call(bgp_qppb_mark_prefix, p, dscp, is_add);
zclient_route_send(is_add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
zclient, &api);
}
Expand Down
2 changes: 0 additions & 2 deletions bgpd/bgpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -2733,8 +2733,6 @@ DECLARE_HOOK(bgp_rpki_prefix_status,
(struct peer * peer, struct attr *attr,
const struct prefix *prefix),
(peer, attr, prefix));
DECLARE_HOOK(bgp_qppb_mark_prefix,
(const struct prefix *p, uint8_t dscp, bool add), (p, dscp, add));

void peer_nsf_stop(struct peer *peer);

Expand Down
7 changes: 0 additions & 7 deletions bgpd/subdir.am
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ noinst_PROGRAMS += bgpd/bgp_btoa

vtysh_daemons += bgpd

if QPPB
module_LTLIBRARIES += bgpd/bgpd_qppb.la
endif
if SNMP
module_LTLIBRARIES += bgpd/bgpd_snmp.la
endif
Expand Down Expand Up @@ -209,10 +206,6 @@ bgpd_bgpd_bmp_la_SOURCES = bgpd/bgp_bmp.c
bgpd_bgpd_bmp_la_LIBADD = lib/libfrrcares.la
bgpd_bgpd_bmp_la_LDFLAGS = $(MODULE_LDFLAGS)

bgpd_bgpd_qppb_la_SOURCES = bgpd/bgp_qppb_private.c
bgpd_bgpd_qppb_la_LIBADD = lib/libfrrcares.la
bgpd_bgpd_qppb_la_LDFLAGS = $(MODULE_LDFLAGS) -lbpf

clippy_scan += \
bgpd/bgp_bmp.c \
bgpd/bgp_debug.c \
Expand Down
4 changes: 4 additions & 0 deletions lib/zclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -1336,6 +1336,8 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
stream_putc(s, api->distance);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
stream_putl(s, api->metric);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DSCP))
stream_putl(s, api->dscp);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
stream_putl(s, api->tag);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
Expand Down Expand Up @@ -1589,6 +1591,8 @@ int zapi_route_decode(struct stream *s, struct zapi_route *api)
STREAM_GETC(s, api->distance);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_METRIC))
STREAM_GETL(s, api->metric);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_DSCP))
STREAM_GETL(s, api->dscp);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_TAG))
STREAM_GETL(s, api->tag);
if (CHECK_FLAG(api->message, ZAPI_MESSAGE_MTU))
Expand Down
3 changes: 3 additions & 0 deletions lib/zclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ extern int zclient_bfd_session_update(ZAPI_CALLBACK_ARGS);
#define ZAPI_MESSAGE_TABLEID 0x0100
#define ZAPI_MESSAGE_SRTE 0x0200
#define ZAPI_MESSAGE_OPAQUE 0x0400
#define ZAPI_MESSAGE_DSCP 0x0800

#define ZSERV_VERSION 6
/* Zserv protocol message header */
Expand Down Expand Up @@ -591,6 +592,8 @@ struct zapi_route {

uint32_t metric;

uint32_t dscp;

route_tag_t tag;

uint32_t mtu;
Expand Down
9 changes: 1 addition & 8 deletions tests/topotests/bgp_qppb_flow/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def load_qppb_plugin(tgen, rnode, mode=XdpMode.SKB, debug_on=DEV_DEBUG):
"""
debug_flags = DEBUG_BPF | DEBUG_PREPROCESSOR | DEBUG_SOURCE | DEBUG_BTF
debug = debug_flags if debug_on else 0
src_file = CWD + "/bgp_xdp_qppb.c"
src_file = CWD + "/zebra_xdp_qppb.c"
bpf_flags = [
'-DMODE_STR="{}"'.format(mode),
"-D{}".format(mode.value),
Expand All @@ -110,13 +110,6 @@ def load_qppb_plugin(tgen, rnode, mode=XdpMode.SKB, debug_on=DEV_DEBUG):
except Exception as e:
pytest.skip("Failed to configure XDP environment -- \n" + str(e))

qppb_module = "-M vyos_qppb"
logger.info(
"Restart {}, XDP hooks loading...\nPlugin :: {}".format(rnode.name, qppb_module)
)
kill_router_daemons(tgen, rnode.name, ["bgpd"])
start_router_daemons(tgen, rnode.name, ["bgpd"], {"bgpd": qppb_module})


def tc_bpf_filter(rnode, ifid):
"Attach tc bpf filter, depends on pyroute2 package"
Expand Down
1 change: 0 additions & 1 deletion tests/topotests/bgp_qppb_flow/bgp_xdp_qppb.c

This file was deleted.

41 changes: 21 additions & 20 deletions tests/topotests/bgp_qppb_flow/test_bgp_qppb.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,27 @@ def setup_module(mod):
global topo
topo = tgen.json_topo

r1 = tgen.gears["r1"]
r4 = tgen.gears["r4"]
# Initializing BPF objects
# -----------------------------------------------------------------------
# NOTE: we need to switch mnt namespace to instantiate BPF mappings
# XXX: python3.12 introduces os.setns, for now use libc directly
ns = "/proc/%d/ns/mnt" % r1.net.pid
nsfd = os.open(ns, os.O_RDONLY)

libc = ctypes.CDLL("libc.so.6", use_errno=True)
libc.setns(nsfd, 0)

tgen.qppb_nodes.append("r1")
r1.cmd_raises(
"""
mkdir -p /sys/fs/bpf
mount -t bpf bpf /sys/fs/bpf
"""
)
load_qppb_plugin(tgen, r1)

start_topology(tgen)
build_config_from_json(tgen, topo)
if tgen.routers_have_failure():
Expand All @@ -173,9 +194,6 @@ def setup_module(mod):

# Extra setup steps
# -----------------------------------------------------------------------
r4 = tgen.gears["r4"]
r1 = tgen.gears["r1"]

debug_rmap_dict = {"r1": {"raw_config": ["end", "debug route-map"]}}
debug_config_dict = {
"r1": {"debug": {"log_file": "debug.log", "enable": ["bgpd", "zebra"]}}
Expand All @@ -196,23 +214,6 @@ def setup_module(mod):
lo_ip_add = "ip address add dev lo 10.6{0}.0.1/32"
[r4.cmd_raises(lo_ip_add.format(n)) for n in range(1, 7)]

# Initializing BPF objects
# -----------------------------------------------------------------------
# NOTE: we need to switch mnt namespace to instantiate BPF mappings
# XXX: python3.12 introduces os.setns, for now use libc directly
ns = "/proc/%d/ns/mnt" % r1.net.pid
nsfd = os.open(ns, os.O_RDONLY)

libc = ctypes.CDLL("libc.so.6", use_errno=True)
libc.setns(nsfd, 0)

r1.cmd_raises(
"""
mkdir -p /sys/fs/bpf
mount -t bpf bpf /sys/fs/bpf
"""
)
load_qppb_plugin(tgen, r1)


# Test Cases
Expand Down
1 change: 1 addition & 0 deletions tests/topotests/bgp_qppb_flow/zebra_xdp_qppb.c
1 change: 1 addition & 0 deletions tests/topotests/lib/topogen.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ def __init__(self, topodef, modname="unnamed"):
self.peern = 1
self.cfg_gen = 0
self.exabgp_cmd = None
self.qppb_nodes = []
self._init_topo(topodef)

logger.info("loading topology: {}".format(self.modname))
Expand Down
13 changes: 5 additions & 8 deletions tests/topotests/lib/topotest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2203,19 +2203,16 @@ def emacs_gdb_ready():
while "mgmtd" in daemons_list:
daemons_list.remove("mgmtd")

# XXX: handle plugins properly - per daemon
bgpd_plugins = plugins.get("bgpd") if plugins else None
if "bgpd" in daemons_list and bgpd_plugins:
start_daemon("bgpd", bgpd_plugins)
while "bgpd" in daemons_list:
daemons_list.remove("bgpd")

# Start Zebra after mgmtd
zebra_plugins = ""
if self.name in tgen.qppb_nodes:
zebra_plugins = "-M zebra_qppb"
if "zebra" in daemons_list:
start_daemon("zebra", "-s 90000000")
start_daemon("zebra", "-s 90000000 " + zebra_plugins)
while "zebra" in daemons_list:
daemons_list.remove("zebra")


# Start staticd next if required
if "staticd" in daemons_list:
start_daemon("staticd")
Expand Down
3 changes: 3 additions & 0 deletions zebra/rib.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ struct route_entry {
/* Metric */
uint32_t metric;

/* DSCP */
uint32_t dscp;

/* MTU */
uint32_t mtu;
uint32_t nexthop_mtu;
Expand Down
7 changes: 7 additions & 0 deletions zebra/subdir.am
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ endif
if LINUX
module_LTLIBRARIES += zebra/zebra_cumulus_mlag.la
endif
if QPPB
module_LTLIBRARIES += zebra/zebra_qppb.la
endif

# Dataplane sample plugin
if DEV_BUILD
Expand Down Expand Up @@ -197,6 +200,10 @@ noinst_HEADERS += \
zebra/dpdk/zebra_dplane_dpdk_private.h \
# end

zebra_zebra_qppb_la_SOURCES = zebra/zebra_qppb_private.c
zebra_zebra_qppb_la_LIBADD = lib/libfrrcares.la
zebra_zebra_qppb_la_LDFLAGS = $(MODULE_LDFLAGS) -lbpf

zebra_zebra_irdp_la_SOURCES = \
zebra/irdp_interface.c \
zebra/irdp_main.c \
Expand Down
12 changes: 12 additions & 0 deletions zebra/zapi_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@

DEFINE_MTYPE_STATIC(ZEBRA, RE_OPAQUE, "Route Opaque Data");

DEFINE_HOOK(zebra_qppb_mark_prefix,
(const struct prefix *p, uint8_t dscp, bool add), (p, dscp, add));


static int zapi_nhg_decode(struct stream *s, int cmd, struct zapi_nhg *api_nhg);

/* Encoding helpers -------------------------------------------------------- */
Expand Down Expand Up @@ -604,6 +608,10 @@ int zsend_redistribute_route(int cmd, struct zserv *client,
api.distance = re->distance;
SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
api.metric = re->metric;
if (re->dscp) {
SET_FLAG(api.message, ZAPI_MESSAGE_DSCP);
api.dscp = re->dscp;
}
if (re->tag) {
SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
api.tag = re->tag;
Expand Down Expand Up @@ -2182,6 +2190,8 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
XFREE(MTYPE_RE, re);
}

hook_call(zebra_qppb_mark_prefix, &api.prefix, api.dscp, true);

/* At this point, these allocations are not needed: 're' has been
* retained or freed, and if 're' still exists, it is using
* a reference to a shared group object.
Expand Down Expand Up @@ -2248,6 +2258,8 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
api.flags, &api.prefix, src_p, NULL, 0, table_id, api.metric,
api.distance, false);

hook_call(zebra_qppb_mark_prefix, &api.prefix, api.dscp, false);

/* Stats */
switch (api.prefix.family) {
case AF_INET:
Expand Down
27 changes: 14 additions & 13 deletions bgpd/bgp_qppb_private.c → zebra/zebra_qppb_private.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* BGP QPPB support
* zebra QPPB support
* Copyright (C) 2023 VyOS Inc.
* Volodymyr Huti
*/

#include <zebra.h>
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
#include "bgpd/bgpd.h"
#include "log.h"
#include "prefix.h"
#include "privs.h"
Expand All @@ -24,7 +23,9 @@
*/
#define BPF_LPM_KEY_SIZE (sizeof(struct bpf_lpm_trie_key) + sizeof(__u32))

extern struct zebra_privs_t bgpd_privs;
DECLARE_HOOK(zebra_qppb_mark_prefix,
(const struct prefix *p, uint8_t dscp, bool add), (p, dscp, add));
extern struct zebra_privs_t zserv_privs;
static int dscp_map_fd;

static int open_bpf_map_file(const char *pin_dir, const char *mapname)
Expand All @@ -45,26 +46,26 @@ static int open_bpf_map_file(const char *pin_dir, const char *mapname)
return fd;
}

static void bgp_qppb_map_init(void)
static void zebra_qppb_map_init(void)
{
const char *pin_dir = THIS_MODULE->load_args ?: BPF_PIN_DIR;

dscp_map_fd = open_bpf_map_file(pin_dir, BPF_DSCP_MAP);
}

static int bgp_qppb_mark_prefix(const struct prefix *p, uint8_t dscp, bool add)
static int zebra_qppb_mark_prefix(const struct prefix *p, uint8_t dscp, bool add)
{
struct bpf_lpm_trie_key *key_ipv4;
int err = 0;

if (dscp_map_fd < 0)
if (dscp_map_fd < 0 || !dscp)
return err;

key_ipv4 = alloca(BPF_LPM_KEY_SIZE);
key_ipv4->prefixlen = p->prefixlen;
memcpy(key_ipv4->data, &p->u.prefix4, sizeof(struct in_addr));

frr_with_privs (&bgpd_privs) {
frr_with_privs (&zserv_privs) {
err = add ? bpf_map_update_elem(dscp_map_fd, key_ipv4, &dscp, 0)
: bpf_map_delete_elem(dscp_map_fd, key_ipv4);
}
Expand All @@ -73,13 +74,13 @@ static int bgp_qppb_mark_prefix(const struct prefix *p, uint8_t dscp, bool add)
return err;
}

static int bgp_qppb_module_init(void)
static int zebra_qppb_module_init(void)
{
bgp_qppb_map_init();
hook_register(bgp_qppb_mark_prefix, bgp_qppb_mark_prefix);
zebra_qppb_map_init();
hook_register(zebra_qppb_mark_prefix, zebra_qppb_mark_prefix);
return 0;
}

FRR_MODULE_SETUP(.name = "bgp_vyos_qppb", .version = "0.0.1",
.description = "bgp QPPB implementation for VyOS",
.init = bgp_qppb_module_init);
FRR_MODULE_SETUP(.name = "zebra_vyos_qppb", .version = "0.0.1",
.description = "zebra QPPB plugin for VyOS",
.init = zebra_qppb_module_init);
File renamed without changes.

0 comments on commit 04962e7

Please sign in to comment.