diff --git a/isisd/isis_affinitymap.c b/isisd/isis_affinitymap.c index 41bad0a7d934..c0a018137f86 100644 --- a/isisd/isis_affinitymap.c +++ b/isisd/isis_affinitymap.c @@ -40,7 +40,8 @@ static bool isis_affinity_map_check_use(const char *affmap_name) return false; } -static void isis_affinity_map_update(const char *affmap_name, uint16_t old_pos, +static void isis_affinity_map_update(const struct lyd_node *dnode, + const char *affmap_name, uint16_t old_pos, uint16_t new_pos) { struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT); @@ -88,8 +89,6 @@ static void isis_affinity_map_update(const char *affmap_name, uint16_t old_pos, void isis_affinity_map_init(void) { - affinity_map_init(); - affinity_map_set_check_use_hook(isis_affinity_map_check_use); affinity_map_set_update_hook(isis_affinity_map_update); } diff --git a/lib/affinitymap.c b/lib/affinitymap.c index 17e1b2cc0169..6342c9b4598b 100644 --- a/lib/affinitymap.c +++ b/lib/affinitymap.c @@ -128,15 +128,18 @@ bool affinity_map_check_use_hook(const char *affmap_name) return false; } -bool affinity_map_check_update_hook(const char *affmap_name, uint16_t new_pos) +bool affinity_map_check_update_hook(const struct lyd_node *dnode, + const char *affmap_name, uint16_t new_pos) { if (affinity_map_master.check_update_hook) - return (*affinity_map_master.check_update_hook)(affmap_name, + return (*affinity_map_master.check_update_hook)(dnode, + affmap_name, new_pos); return true; } -void affinity_map_update_hook(const char *affmap_name, uint16_t new_pos) +void affinity_map_update_hook(const struct lyd_node *dnode, + const char *affmap_name, uint16_t new_pos) { struct affinity_map *map; @@ -149,8 +152,8 @@ void affinity_map_update_hook(const char *affmap_name, uint16_t new_pos) /* Affinity-map creation */ return; - (*affinity_map_master.update_hook)(affmap_name, map->bit_position, - new_pos); + (*affinity_map_master.update_hook)(dnode, affmap_name, + map->bit_position, new_pos); } @@ -159,13 +162,15 @@ void affinity_map_set_check_use_hook(bool (*func)(const char *affmap_name)) affinity_map_master.check_use_hook = func; } -void affinity_map_set_check_update_hook(bool (*func)(const char *affmap_name, +void affinity_map_set_check_update_hook(bool (*func)(const struct lyd_node *dnode, + const char *affmap_name, uint16_t new_pos)) { affinity_map_master.check_update_hook = func; } -void affinity_map_set_update_hook(void (*func)(const char *affmap_name, +void affinity_map_set_update_hook(void (*func)(const struct lyd_node *dnode, + const char *affmap_name, uint16_t old_pos, uint16_t new_pos)) { diff --git a/lib/affinitymap.h b/lib/affinitymap.h index 19edf5a269ea..34316873ef9d 100644 --- a/lib/affinitymap.h +++ b/lib/affinitymap.h @@ -51,8 +51,10 @@ struct affinity_maps { struct list *maps; bool (*check_use_hook)(const char *affmap_name); - bool (*check_update_hook)(const char *affmap_name, uint16_t new_pos); - void (*update_hook)(const char *affmap_name, uint16_t old_pos, + bool (*check_update_hook)(const struct lyd_node *dnode, + const char *affmap_name, uint16_t new_pos); + void (*update_hook)(const struct lyd_node *dnode, + const char *affmap_name, uint16_t old_pos, uint16_t new_pos); QOBJ_FIELDS; @@ -60,6 +62,7 @@ struct affinity_maps { DECLARE_QOBJ_TYPE(affinity_maps); extern const struct frr_yang_module_info frr_affinity_map_info; +extern const struct frr_yang_module_info frr_affinity_map_cli_info; void affinity_map_set(const char *name, int pos); void affinity_map_unset(const char *name); @@ -67,13 +70,17 @@ struct affinity_map *affinity_map_get(const char *name); char *affinity_map_name_get(const int pos); bool affinity_map_check_use_hook(const char *affmap_name); -bool affinity_map_check_update_hook(const char *affmap_name, uint16_t new_pos); -void affinity_map_update_hook(const char *affmap_name, uint16_t new_pos); +bool affinity_map_check_update_hook(const struct lyd_node *dnode, + const char *affmap_name, uint16_t new_pos); +void affinity_map_update_hook(const struct lyd_node *dnode, + const char *affmap_name, uint16_t new_pos); void affinity_map_set_check_use_hook(bool (*func)(const char *affmap_name)); -void affinity_map_set_check_update_hook(bool (*func)(const char *affmap_name, +void affinity_map_set_check_update_hook(bool (*func)(const struct lyd_node *dnode, + const char *affmap_name, uint16_t new_pos)); -void affinity_map_set_update_hook(void (*func)(const char *affmap_name, +void affinity_map_set_update_hook(void (*func)(const struct lyd_node *dnode, + const char *affmap_name, uint16_t old_pos, uint16_t new_pos)); diff --git a/lib/affinitymap_cli.c b/lib/affinitymap_cli.c index d417ae195156..51665b452e21 100644 --- a/lib/affinitymap_cli.c +++ b/lib/affinitymap_cli.c @@ -30,13 +30,19 @@ #include "lib/affinitymap.h" #include "lib/affinitymap_cli_clippy.c" -/* Route map node structure. */ -static int affinity_map_config_write(struct vty *vty); -static struct cmd_node affinitymap_node = { - .name = "affinity-map", - .node = AFFMAP_NODE, - .prompt = "", - .config_write = affinity_map_config_write, +/* clang-format off */ +const struct frr_yang_module_info frr_affinity_map_cli_info = { + .name = "frr-affinity-map", + .ignore_cfg_cbs = true, + .nodes = { + { + .xpath = "/frr-affinity-map:lib/affinity-maps/affinity-map", + .cbs.cli_show = cli_show_affinity_map, + }, + { + .xpath = NULL, + }, + } }; /* max value is EXT_ADMIN_GROUP_MAX_POSITIONS - 1 */ @@ -75,20 +81,6 @@ DEFPY_YANG_NOSH(no_affinity_map, no_affinity_map_cmd, return nb_cli_apply_changes(vty, NULL); } -static int affinity_map_config_write(struct vty *vty) -{ - const struct lyd_node *dnode; - int written = 0; - - dnode = yang_dnode_get(running_config->dnode, "/frr-affinity-map:lib"); - if (dnode) { - nb_cli_show_dnode_cmds(vty, dnode, false); - written = 1; - } - - return written; -} - void cli_show_affinity_map(struct vty *vty, const struct lyd_node *dnode, bool show_defaults __attribute__((__unused__))) { @@ -101,7 +93,6 @@ void cli_show_affinity_map(struct vty *vty, const struct lyd_node *dnode, void affinity_map_init(void) { /* CLI commands. */ - install_node(&affinitymap_node); install_element(CONFIG_NODE, &affinity_map_cmd); install_element(CONFIG_NODE, &no_affinity_map_cmd); } diff --git a/lib/affinitymap_northbound.c b/lib/affinitymap_northbound.c index 331075f5c111..3cc55a49a860 100644 --- a/lib/affinitymap_northbound.c +++ b/lib/affinitymap_northbound.c @@ -67,26 +67,19 @@ static int lib_affinity_map_destroy(struct nb_cb_destroy_args *args) */ static int lib_affinity_map_value_modify(struct nb_cb_modify_args *args) { + const struct lyd_node *dnode = args->dnode; const char *name; - char *map_name; uint16_t pos; - name = yang_dnode_get_string( - (const struct lyd_node *)args->dnode->parent, "./name"); + name = yang_dnode_get_string((const struct lyd_node *)dnode->parent, + "./name"); - pos = yang_dnode_get_uint16( - (const struct lyd_node *)args->dnode->parent, "./value"); + pos = yang_dnode_get_uint16((const struct lyd_node *)dnode->parent, + "./value"); switch (args->event) { case NB_EV_VALIDATE: - map_name = affinity_map_name_get(pos); - if (map_name && - strncmp(map_name, name, AFFINITY_NAME_SIZE) != 0) { - snprintf(args->errmsg, args->errmsg_len, - "bit-position is used by %s.", map_name); - return NB_ERR_VALIDATION; - } - if (!affinity_map_check_update_hook(name, pos)) { + if (!affinity_map_check_update_hook(dnode, name, pos)) { snprintf( args->errmsg, args->errmsg_len, "affinity-map new bit-position > 31 but is used with standard admin-groups"); @@ -97,7 +90,7 @@ static int lib_affinity_map_value_modify(struct nb_cb_modify_args *args) case NB_EV_ABORT: break; case NB_EV_APPLY: - affinity_map_update_hook(name, pos); + affinity_map_update_hook(dnode, name, pos); affinity_map_set(name, pos); break; } @@ -119,7 +112,6 @@ const struct frr_yang_module_info frr_affinity_map_info = { .cbs = { .create = lib_affinity_map_create, .destroy = lib_affinity_map_destroy, - .cli_show = cli_show_affinity_map, } }, { diff --git a/lib/subdir.am b/lib/subdir.am index 4f203c0c842f..7afa199c52ee 100644 --- a/lib/subdir.am +++ b/lib/subdir.am @@ -9,7 +9,6 @@ lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(UST lib_libfrr_la_SOURCES = \ lib/admin_group.c \ lib/affinitymap.c \ - lib/affinitymap_cli.c \ lib/affinitymap_northbound.c \ lib/agg_table.c \ lib/atomlist.c \ diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c index 2be70901a840..934390082561 100644 --- a/mgmtd/mgmt_be_adapter.c +++ b/mgmtd/mgmt_be_adapter.c @@ -58,6 +58,15 @@ struct mgmt_be_xpath_map { * Each client gets their own map, but also union all the strings into the * above map as well. */ + + +static const char *const zebra_config_xpaths[] = { + "/frr-affinity-map:lib/affinity-maps/affinity-map", + "/frr-interface:lib", + "/frr-vrf:lib", + NULL, +}; + #if HAVE_STATICD static const char *const staticd_config_xpaths[] = { "/frr-vrf:lib", @@ -68,6 +77,7 @@ static const char *const staticd_config_xpaths[] = { #endif static const char *const *be_client_config_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { + [MGMTD_BE_CLIENT_ID_ZEBRA] = zebra_config_xpaths, #ifdef HAVE_STATICD [MGMTD_BE_CLIENT_ID_STATICD] = staticd_config_xpaths, #endif diff --git a/mgmtd/mgmt_main.c b/mgmtd/mgmt_main.c index 743091e5c47b..5f75881980ed 100644 --- a/mgmtd/mgmt_main.c +++ b/mgmtd/mgmt_main.c @@ -8,6 +8,7 @@ #include #include "lib/version.h" +#include "affinitymap.h" #include "routemap.h" #include "filter.h" #include "libfrr.h" @@ -141,11 +142,14 @@ static struct frr_signal_t mgmt_signals[] = { extern const struct frr_yang_module_info frr_staticd_info; #endif - /* * These are stub info structs that are used to load the modules used by backend * clients into mgmtd. The modules are used by libyang in order to support * parsing binary data returns from the backend. + * + * These are only needed if `cli_show` commands are not defined for the module. + * When `cli_show` callbacks are defined then the non-stub frr_yang_module_info + * that contains pointers to them should be included here instead. */ const struct frr_yang_module_info zebra_info = { .name = "frr-zebra", @@ -153,12 +157,6 @@ const struct frr_yang_module_info zebra_info = { .nodes = { { .xpath = NULL } }, }; -const struct frr_yang_module_info affinity_map_info = { - .name = "frr-affinity-map", - .ignore_cfg_cbs = true, - .nodes = { { .xpath = NULL } }, -}; - const struct frr_yang_module_info zebra_route_map_info = { .name = "frr-zebra-route-map", .ignore_cfg_cbs = true, @@ -170,6 +168,7 @@ const struct frr_yang_module_info zebra_route_map_info = { * MGMTd. */ static const struct frr_yang_module_info *const mgmt_yang_modules[] = { + &frr_affinity_map_cli_info, &frr_filter_info, &frr_interface_info, &frr_route_map_info, @@ -181,7 +180,6 @@ static const struct frr_yang_module_info *const mgmt_yang_modules[] = { */ &zebra_info, - &affinity_map_info, &zebra_route_map_info, #ifdef HAVE_STATICD @@ -253,9 +251,6 @@ int main(int argc, char **argv) /* VRF commands initialization. */ vrf_cmd_init(NULL); - /* Interface commands initialization. */ - if_cmd_init(NULL); - /* MGMTD related initialization. */ mgmt_init(); diff --git a/mgmtd/mgmt_vty.c b/mgmtd/mgmt_vty.c index f4b24acf3ace..17b9b1bcb9a4 100644 --- a/mgmtd/mgmt_vty.c +++ b/mgmtd/mgmt_vty.c @@ -8,6 +8,7 @@ #include +#include "affinitymap.h" #include "command.h" #include "json.h" #include "network.h" @@ -566,6 +567,8 @@ void mgmt_vty_init(void) * backend components that are moved to new MGMTD infra * here one by one. */ + affinity_map_init(); + if_cmd_init(NULL); #if HAVE_STATICD extern void static_vty_init(void); static_vty_init(); diff --git a/mgmtd/subdir.am b/mgmtd/subdir.am index 89a6596f49f2..77826b729e33 100644 --- a/mgmtd/subdir.am +++ b/mgmtd/subdir.am @@ -61,3 +61,8 @@ nodist_mgmtd_mgmtd_SOURCES += \ # end nodist_mgmtd_libmgmt_be_nb_la_SOURCES += staticd/static_vty.c endif + +# Unconditionally YANG support + +nodist_mgmtd_mgmtd_SOURCES += yang/frr-affinity-map.yang.c +mgmtd_libmgmtd_a_SOURCES += lib/affinitymap_cli.c diff --git a/tests/topotests/example_munet/test_munet.py b/tests/topotests/example_munet/test_munet.py index 0d9599fa541d..31dd5c81606d 100644 --- a/tests/topotests/example_munet/test_munet.py +++ b/tests/topotests/example_munet/test_munet.py @@ -5,6 +5,24 @@ # # Copyright (c) 2023, LabN Consulting, L.L.C. # +import pytest +from munet.base import get_event_loop + +pytestmark = [pytest.mark.asyncio] + + +@pytest.fixture(scope="function") +def event_loop(): + """Create an instance of the default event loop for the session.""" + loop = get_event_loop() + try: + # logging.info("event_loop_fixture: yielding with new event loop watcher") + yield loop + finally: + loop.close() + + async def test_native_test(unet): - o = unet.hosts["r1"].cmd_nostatus("ip addr") + # o = unet.hosts["r1"].cmd_nostatus("ip addr") + o = "Hello World" print(o) diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 11751d027e89..a71985c0bd1c 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -50,7 +50,7 @@ extern struct event_loop *master; VTYSH_SHARPD | VTYSH_PBRD | VTYSH_STATICD | VTYSH_BFDD | \ VTYSH_FABRICD | VTYSH_VRRPD | VTYSH_PATHD | VTYSH_MGMTD #define VTYSH_ACL VTYSH_BFDD|VTYSH_BABELD|VTYSH_BGPD|VTYSH_EIGRPD|VTYSH_ISISD|VTYSH_FABRICD|VTYSH_LDPD|VTYSH_NHRPD|VTYSH_OSPF6D|VTYSH_OSPFD|VTYSH_PBRD|VTYSH_PIMD|VTYSH_PIM6D|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_VRRPD|VTYSH_ZEBRA -#define VTYSH_AFFMAP VTYSH_ZEBRA | VTYSH_ISISD +#define VTYSH_AFFMAP VTYSH_MGMTD #define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD|VTYSH_EIGRPD|VTYSH_FABRICD #define VTYSH_INTERFACE_SUBSET \ VTYSH_ZEBRA | VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_OSPFD | VTYSH_OSPF6D | \ diff --git a/yang/frr-affinity-map.yang b/yang/frr-affinity-map.yang index c4377e62467f..66ba26deecd2 100644 --- a/yang/frr-affinity-map.yang +++ b/yang/frr-affinity-map.yang @@ -3,18 +3,6 @@ module frr-affinity-map { namespace "http://frrouting.org/yang/affinity-map"; prefix frr-affinity-map; - import ietf-inet-types { - prefix inet; - } - - import frr-filter { - prefix filter; - } - - import frr-interface { - prefix frr-interface; - } - organization "FRRouting"; contact @@ -51,14 +39,17 @@ module frr-affinity-map { revision 2022-11-03 { description "Initial revision"; + reference "FRRouting"; } container lib { + description "Root node of affinitymap module."; container affinity-maps { description "Affinity Mapping Table"; list affinity-map { key "name"; + unique "value"; description "Affinity Mapping configuration"; leaf name { diff --git a/zebra/zebra_affinitymap.c b/zebra/zebra_affinitymap.c index ae0f9a8a354d..e80cfb8cba7e 100644 --- a/zebra/zebra_affinitymap.c +++ b/zebra/zebra_affinitymap.c @@ -50,7 +50,8 @@ static bool zebra_affinity_map_check_use(const char *affmap_name) return false; } -static bool zebra_affinity_map_check_update(const char *affmap_name, +static bool zebra_affinity_map_check_update(const struct lyd_node *dnode, + const char *affmap_name, uint16_t new_pos) { char xpath[XPATH_MAXLEN]; @@ -69,25 +70,26 @@ static bool zebra_affinity_map_check_update(const char *affmap_name, snprintf(xpath, sizeof(xpath), "/frr-interface:lib/interface[name='%s']", ifp->name); - if (!yang_dnode_exists(running_config->dnode, xpath)) + if (!yang_dnode_exists(dnode, xpath)) continue; snprintf( xpath, sizeof(xpath), "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities[affinity='%s']", ifp->name, affmap_name); - if (!yang_dnode_exists(running_config->dnode, xpath)) + if (!yang_dnode_exists(dnode, xpath)) continue; - if (yang_dnode_get_enum( - running_config->dnode, - "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinity-mode", - ifp->name) == AFFINITY_MODE_STANDARD) + if (yang_dnode_get_enum(dnode, + "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinity-mode", + ifp->name) == + AFFINITY_MODE_STANDARD) return false; } } return true; } -static void zebra_affinity_map_update(const char *affmap_name, uint16_t old_pos, +static void zebra_affinity_map_update(const struct lyd_node *dnode, + const char *affmap_name, uint16_t old_pos, uint16_t new_pos) { struct if_link_params *iflp; @@ -101,16 +103,16 @@ static void zebra_affinity_map_update(const char *affmap_name, uint16_t old_pos, snprintf(xpath, sizeof(xpath), "/frr-interface:lib/interface[name='%s']", ifp->name); - if (!yang_dnode_exists(running_config->dnode, xpath)) + if (!yang_dnode_exists(dnode, xpath)) continue; snprintf( xpath, sizeof(xpath), "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinities[affinity='%s']", ifp->name, affmap_name); - if (!yang_dnode_exists(running_config->dnode, xpath)) + if (!yang_dnode_exists(dnode, xpath)) continue; aff_mode = yang_dnode_get_enum( - running_config->dnode, + dnode, "/frr-interface:lib/interface[name='%s']/frr-zebra:zebra/link-params/affinity-mode", ifp->name); iflp = if_link_params_get(ifp); @@ -136,8 +138,6 @@ static void zebra_affinity_map_update(const char *affmap_name, uint16_t old_pos, void zebra_affinity_map_init(void) { - affinity_map_init(); - affinity_map_set_check_use_hook(zebra_affinity_map_check_use); affinity_map_set_check_update_hook(zebra_affinity_map_check_update); affinity_map_set_update_hook(zebra_affinity_map_update);