This commit is contained in:
Christian Hopps 2025-04-29 16:22:43 +00:00 committed by GitHub
commit 95173c30b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 5056 additions and 11 deletions

View file

@ -138,6 +138,9 @@ char const *const mgmt_daemons[] = {
#ifdef HAVE_STATICD
"staticd",
#endif
#ifdef HAVE_OSPFD
"ospfd",
#endif
};
uint mgmt_daemons_count = array_size(mgmt_daemons);

View file

@ -37,6 +37,9 @@
const char *mgmt_be_client_names[MGMTD_BE_CLIENT_ID_MAX + 1] = {
[MGMTD_BE_CLIENT_ID_TESTC] = "mgmtd-testc", /* always first */
[MGMTD_BE_CLIENT_ID_ZEBRA] = "zebra",
#ifdef HAVE_OSPFD
[MGMTD_BE_CLIENT_ID_OSPFD] = "ospfd",
#endif
#ifdef HAVE_RIPD
[MGMTD_BE_CLIENT_ID_RIPD] = "ripd",
#endif
@ -91,6 +94,14 @@ static const char *const mgmtd_testc_oper_xpaths[] = {
};
#endif
#if HAVE_OSPFD
static const char *const ospfd_oper_xpaths[] = {
"/frr-interface:lib/interface/state/frr-ospfd-lite:ospf/state/*",
"/frr-ospfd-lite:ospf/instance/state/*",
NULL,
};
#endif
#ifdef HAVE_RIPD
static const char *const ripd_config_xpaths[] = {
"/frr-filter:lib",
@ -174,6 +185,9 @@ static const char *const *be_client_oper_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {
[MGMTD_BE_CLIENT_ID_STATICD] = staticd_oper_xpaths,
#endif
[MGMTD_BE_CLIENT_ID_ZEBRA] = zebra_oper_xpaths,
#if HAVE_OSPFD
[MGMTD_BE_CLIENT_ID_OSPFD] = ospfd_oper_xpaths,
#endif
};
static const char *const *be_client_notif_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {

View file

@ -29,6 +29,9 @@
enum mgmt_be_client_id {
MGMTD_BE_CLIENT_ID_TESTC, /* always first */
MGMTD_BE_CLIENT_ID_ZEBRA,
#ifdef HAVE_OSPFD
MGMTD_BE_CLIENT_ID_OSPFD,
#endif
#ifdef HAVE_RIPD
MGMTD_BE_CLIENT_ID_RIPD,
#endif

View file

@ -15,6 +15,7 @@
#include "frr_pthread.h"
#include "mgmtd/mgmt.h"
#include "mgmtd/mgmt_ds.h"
#include "ospfd/ospf_nb.h"
#include "ripd/rip_nb.h"
#include "ripngd/ripng_nb.h"
#include "routing_nb.h"
@ -175,6 +176,7 @@ const struct frr_yang_module_info zebra_route_map_info = {
* List of YANG modules to be loaded in the process context of
* MGMTd.
*/
/* clang-format off */
static const struct frr_yang_module_info *const mgmt_yang_modules[] = {
&frr_filter_cli_info,
&frr_interface_cli_info,
@ -205,9 +207,11 @@ static const struct frr_yang_module_info *const mgmt_yang_modules[] = {
#ifdef HAVE_STATICD
&frr_staticd_cli_info,
#endif
#ifdef HAVE_OSPFD
&frr_ospfd_lite_cli_info
#endif
};
/* clang-format off */
FRR_DAEMON_INFO(mgmtd, MGMTD,
.vty_port = MGMTD_VTY_PORT,
.proghelp = "FRR Management Daemon.",

View file

@ -78,6 +78,15 @@ nodist_mgmtd_mgmtd_SOURCES += yang/frr-bfdd.yang.c
endif
endif
if OSPFD
nodist_mgmtd_mgmtd_SOURCES += \
yang/frr-ospfd-lite.yang.c \
# end
mgmtd_libmgmt_be_nb_la_SOURCES += \
ospfd/ospf_cli.c \
# end
endif
if RIPD
nodist_mgmtd_mgmtd_SOURCES += \
yang/frr-ripd.yang.c \

62
ospfd/ospf_cli.c Normal file
View file

@ -0,0 +1,62 @@
/*
* March 15 2025, Christian Hopps <chopps@labn.net>
*
* Copyright (c) 2025, LabN Consulting, L.L.C.
*
*/
#include <zebra.h>
#include "ospf_nb.h"
#include "ospfd/ospf_cli_clippy.c"
/*
* XXX Add YANG based CLI config writing functions here.
*/
#if 0
static void lib_interface_ospf_interface_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults)
{
/* TODO: this cli callback is optional; the cli output may not need to be done at each node. */
}
static void ospf_instance_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults)
{
/* TODO: this cli callback is optional; the cli output may not need to be done at each node. */
}
static void ospf_instance_areas_area_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults)
{
/* TODO: this cli callback is optional; the cli output may not need to be done at each node. */
}
#endif
/* clang-format off */
const struct frr_yang_module_info frr_ospfd_lite_cli_info = {
.name = "frr-ospfd-lite",
.ignore_cfg_cbs = true,
.nodes = {
#if 0
{
.xpath = "/frr-interface:lib/interface/frr-ospfd-lite:ospf-interface",
.cbs = {
.cli_show = lib_interface_ospf_interface_cli_write,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance",
.cbs = {
.cli_show = ospf_instance_cli_write,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/areas/area",
.cbs = {
.cli_show = ospf_instance_areas_area_cli_write,
}
},
#endif
{
.xpath = NULL,
},
}
};
/* clang-format on */

View file

@ -15,6 +15,7 @@
#include "stream.h"
#include "log.h"
#include "sockopt.h"
#include "mgmt_be_client.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@ -2112,4 +2113,7 @@ void ospf_debug_init(void)
install_element(CONFIG_NODE, &no_debug_ospf_instance_event_cmd);
install_element(CONFIG_NODE, &no_debug_ospf_instance_nssa_cmd);
install_element(CONFIG_NODE, &no_debug_ospf_cmd);
/* Init mgmtd backend client debug commands. */
mgmt_be_client_lib_vty_init();
}

View file

@ -29,6 +29,7 @@
#include "routemap.h"
#include "keychain.h"
#include "libagentx.h"
#include "mgmt_be_client.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h"
@ -46,6 +47,7 @@
#include "ospfd/ospf_ldp_sync.h"
#include "ospfd/ospf_routemap_nb.h"
#include "ospfd/ospf_apiserver.h"
#include "ospfd/ospf_nb.h"
#define OSPFD_STATE_NAME "%s/ospfd.json", frr_libstatedir
#define OSPFD_INST_STATE_NAME(i) "%s/ospfd-%d.json", frr_libstatedir, i
@ -92,6 +94,8 @@ const struct option longopts[] = {
/* Master of threads. */
struct event_loop *master;
struct mgmt_be_client *mgmt_be_client;
/* SIGHUP handler. */
static void sighup(void)
{
@ -103,6 +107,7 @@ static FRR_NORETURN void sigint(void)
{
zlog_notice("Terminating on signal");
bfd_protocol_integration_set_shutdown(true);
mgmt_be_client_destroy(mgmt_be_client);
ospf_terminate();
exit(0);
@ -134,13 +139,10 @@ struct frr_signal_t ospf_signals[] = {
};
static const struct frr_yang_module_info *const ospfd_yang_modules[] = {
&frr_filter_info,
&frr_interface_info,
&frr_route_map_info,
&frr_vrf_info,
&frr_ospf_route_map_info,
&ietf_key_chain_info,
&ietf_key_chain_deviation_info,
&frr_filter_info, &frr_interface_info,
&frr_route_map_info, &frr_vrf_info,
&frr_ospf_route_map_info, &frr_ospfd_lite_info,
&ietf_key_chain_info, &ietf_key_chain_deviation_info,
};
/* actual paths filled in main() */
@ -291,6 +293,8 @@ int main(int argc, char **argv)
ospf_vty_show_init();
ospf_vty_clear_init();
mgmt_be_client = mgmt_be_client_create("ospfd", NULL, 0, master);
/* OSPF BFD init */
ospf_bfd_init(master);

167
ospfd/ospf_nb.c Normal file
View file

@ -0,0 +1,167 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* June 21 2023, Christian Hopps <chopps@labn.net>
*
* Copyright (C) 2023 LabN Consulting, L.L.C.
*/
#include <zebra.h>
#include "ospfd/ospf_nb.h"
/* clang-format off */
const struct frr_yang_module_info frr_ospfd_lite_info = {
.name = "frr-ospfd-lite",
.nodes = {
{
.xpath = "/frr-interface:lib/interface/frr-ospfd-lite:ospf-interface",
.cbs = {
.create = lib_interface_ospf_interface_create,
.destroy = lib_interface_ospf_interface_destroy,
.get_next = lib_interface_ospf_interface_get_next,
.get_keys = lib_interface_ospf_interface_get_keys,
.lookup_entry = lib_interface_ospf_interface_lookup_entry,
}
},
{
.xpath = "/frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/state",
.cbs = {
.get_elem = lib_interface_ospf_interface_state_state_get_elem,
}
},
{
.xpath = "/frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/hello-timer",
.cbs = {
.get_elem = lib_interface_ospf_interface_state_hello_timer_get_elem,
}
},
{
.xpath = "/frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/neighbors/neighbor",
.cbs = {
.get_next = lib_interface_ospf_interface_state_neighbors_neighbor_get_next,
.get_keys = lib_interface_ospf_interface_state_neighbors_neighbor_get_keys,
.lookup_entry = lib_interface_ospf_interface_state_neighbors_neighbor_lookup_entry,
}
},
{
.xpath = "/frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/neighbors/neighbor/neighbor-router-id",
.cbs = {
.get_elem = lib_interface_ospf_interface_state_neighbors_neighbor_neighbor_router_id_get_elem,
}
},
{
.xpath = "/frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/neighbors/neighbor/address",
.cbs = {
.get_elem = lib_interface_ospf_interface_state_neighbors_neighbor_address_get_elem,
}
},
{
.xpath = "/frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/neighbors/neighbor/state",
.cbs = {
.get_elem = lib_interface_ospf_interface_state_neighbors_neighbor_state_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance",
.cbs = {
.create = ospf_instance_create,
.destroy = ospf_instance_destroy,
.get_next = ospf_instance_get_next,
.get_keys = ospf_instance_get_keys,
.lookup_entry = ospf_instance_lookup_entry,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/state/router-flags/router-flag",
.cbs = {
.get_elem = ospf_instance_state_router_flags_router_flag_get_elem,
.get_next = ospf_instance_state_router_flags_router_flag_get_next,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/state/statistics/originate-new-lsa-count",
.cbs = {
.get_elem = ospf_instance_state_statistics_originate_new_lsa_count_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/state/statistics/rx-new-lsas-count",
.cbs = {
.get_elem = ospf_instance_state_statistics_rx_new_lsas_count_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/state/statistics/spf/timestamp",
.cbs = {
.get_elem = ospf_instance_state_statistics_spf_timestamp_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/state/statistics/spf/duration",
.cbs = {
.get_elem = ospf_instance_state_statistics_spf_duration_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/areas/area",
.cbs = {
.create = ospf_instance_areas_area_create,
.destroy = ospf_instance_areas_area_destroy,
.get_next = ospf_instance_areas_area_get_next,
.get_keys = ospf_instance_areas_area_get_keys,
.lookup_entry = ospf_instance_areas_area_lookup_entry,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/areas/area/state/statistics/spf-runs-count",
.cbs = {
.get_elem = ospf_instance_areas_area_state_statistics_spf_runs_count_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/areas/area/state/statistics/abr-count",
.cbs = {
.get_elem = ospf_instance_areas_area_state_statistics_abr_count_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/areas/area/state/statistics/asbr-count",
.cbs = {
.get_elem = ospf_instance_areas_area_state_statistics_asbr_count_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/areas/area/state/statistics/area-scope-lsa-count",
.cbs = {
.get_elem = ospf_instance_areas_area_state_statistics_area_scope_lsa_count_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/areas/area/state/statistics/spf-timestamp",
.cbs = {
.get_elem = ospf_instance_areas_area_state_statistics_spf_timestamp_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/areas/area/state/statistics/active-interfaces",
.cbs = {
.get_elem = ospf_instance_areas_area_state_statistics_active_interfaces_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/areas/area/state/statistics/full-nbrs",
.cbs = {
.get_elem = ospf_instance_areas_area_state_statistics_full_nbrs_get_elem,
}
},
{
.xpath = "/frr-ospfd-lite:ospf/instance/areas/area/state/statistics/full-virtual",
.cbs = {
.get_elem = ospf_instance_areas_area_state_statistics_full_virtual_get_elem,
}
},
{
.xpath = NULL,
},
}
};

62
ospfd/ospf_nb.h Normal file
View file

@ -0,0 +1,62 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* June 21 2023, Christian Hopps <chopps@labn.net>
*
* Copyright (c) 2023, LabN Consulting, L.L.C.
*
*/
#ifndef _FRR_OSPF_NB_H_
#define _FRR_OSPF_NB_H_
#include "northbound.h"
extern const struct frr_yang_module_info frr_ospfd_lite_info;
extern const struct frr_yang_module_info frr_ospfd_lite_cli_info;
int lib_interface_ospf_interface_create(struct nb_cb_create_args *args);
int lib_interface_ospf_interface_destroy(struct nb_cb_destroy_args *args);
const void *lib_interface_ospf_interface_get_next(struct nb_cb_get_next_args *args);
int lib_interface_ospf_interface_get_keys(struct nb_cb_get_keys_args *args);
const void *lib_interface_ospf_interface_lookup_entry(struct nb_cb_lookup_entry_args *args);
struct yang_data *lib_interface_ospf_interface_state_state_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *lib_interface_ospf_interface_state_hello_timer_get_elem(struct nb_cb_get_elem_args *args);
const void *lib_interface_ospf_interface_state_neighbors_neighbor_get_next(struct nb_cb_get_next_args *args);
int lib_interface_ospf_interface_state_neighbors_neighbor_get_keys(struct nb_cb_get_keys_args *args);
const void *lib_interface_ospf_interface_state_neighbors_neighbor_lookup_entry(struct nb_cb_lookup_entry_args *args);
struct yang_data *lib_interface_ospf_interface_state_neighbors_neighbor_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *lib_interface_ospf_interface_state_neighbors_neighbor_neighbor_router_id_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *lib_interface_ospf_interface_state_neighbors_neighbor_address_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *lib_interface_ospf_interface_state_neighbors_neighbor_state_get_elem(struct nb_cb_get_elem_args *args);
int ospf_instance_create(struct nb_cb_create_args *args);
int ospf_instance_destroy(struct nb_cb_destroy_args *args);
const void *ospf_instance_get_next(struct nb_cb_get_next_args *args);
int ospf_instance_get_keys(struct nb_cb_get_keys_args *args);
const void *ospf_instance_lookup_entry(struct nb_cb_lookup_entry_args *args);
struct yang_data *ospf_instance_state_router_flags_router_flag_get_elem(struct nb_cb_get_elem_args *args);
const void *ospf_instance_state_router_flags_router_flag_get_next(struct nb_cb_get_next_args *args);
struct yang_data *ospf_instance_state_statistics_originate_new_lsa_count_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *ospf_instance_state_statistics_rx_new_lsas_count_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *ospf_instance_state_statistics_spf_timestamp_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *ospf_instance_state_statistics_spf_duration_get_elem(struct nb_cb_get_elem_args *args);
int ospf_instance_areas_area_create(struct nb_cb_create_args *args);
int ospf_instance_areas_area_destroy(struct nb_cb_destroy_args *args);
const void *ospf_instance_areas_area_get_next(struct nb_cb_get_next_args *args);
int ospf_instance_areas_area_get_keys(struct nb_cb_get_keys_args *args);
const void *ospf_instance_areas_area_lookup_entry(struct nb_cb_lookup_entry_args *args);
struct yang_data *ospf_instance_areas_area_state_statistics_spf_runs_count_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *ospf_instance_areas_area_state_statistics_abr_count_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *ospf_instance_areas_area_state_statistics_asbr_count_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *ospf_instance_areas_area_state_statistics_area_scope_lsa_count_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *ospf_instance_areas_area_state_statistics_spf_timestamp_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *ospf_instance_areas_area_state_statistics_active_interfaces_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *ospf_instance_areas_area_state_statistics_full_nbrs_get_elem(struct nb_cb_get_elem_args *args);
struct yang_data *ospf_instance_areas_area_state_statistics_full_virtual_get_elem(struct nb_cb_get_elem_args *args);
#ifdef __cplusplus
}
#endif
#endif

104
ospfd/ospf_nb_config.c Normal file
View file

@ -0,0 +1,104 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* June 21 2023, Christian Hopps <chopps@labn.net>
*
* Copyright (C) 2023 LabN Consulting, L.L.C.
*
*/
#include <zebra.h>
#include "ospfd/ospf_nb.h"
/*
* XPath: /frr-interface:lib/interface/frr-ospfd-lite:ospf-interface
*/
int lib_interface_ospf_interface_create(struct nb_cb_create_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}
return NB_OK;
}
int lib_interface_ospf_interface_destroy(struct nb_cb_destroy_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}
return NB_OK;
}
/*
* XPath: /frr-ospfd-lite:ospf/instance
*/
int ospf_instance_create(struct nb_cb_create_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}
return NB_OK;
}
int ospf_instance_destroy(struct nb_cb_destroy_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}
return NB_OK;
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/areas/area
*/
int ospf_instance_areas_area_create(struct nb_cb_create_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}
return NB_OK;
}
int ospf_instance_areas_area_destroy(struct nb_cb_destroy_args *args)
{
switch (args->event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}
return NB_OK;
}

455
ospfd/ospf_nb_state.c Normal file
View file

@ -0,0 +1,455 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* June 21 2023, Christian Hopps <chopps@labn.net>
*
* Copyright (C) 2023 LabN Consulting, L.L.C.
*/
#include <zebra.h>
#include "debug.h"
#include "northbound.h"
#include "table.h"
#include "ospfd/ospfd.h"
#include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h"
#include "ospfd/ospf_lsdb.h"
#include "ospfd/ospf_interface.h"
#include "ospfd/ospf_opaque.h"
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_nb.h"
#include "ospfd/ospf_vty.h"
#define RNPARENT(args) ((struct route_node *)((args)->parent_list_entry))
#define RNENTRY(args) ((struct route_node *)((args)->list_entry))
#define OIPARENT(args) ((struct ospf_interface *)RNPARENT(args)->info)
#define OIENTRY(args) ((struct ospf_interface *)RNENTRY(args)->info)
#define NBRENTRY(args) ((struct ospf_neighbor *)RNENTRY(args)->info)
/*
* XPath: /frr-interface:lib/interface/state/frr-ospfd-lite:ospf/state
*/
const void *
lib_interface_ospf_interface_get_next(struct nb_cb_get_next_args *args)
{
struct interface *ifp = (struct interface *)args->parent_list_entry;
struct route_node *rn = (struct route_node *)args->list_entry;
assert(ifp);
if (!rn)
rn = route_top(IF_OIFS(ifp));
else
rn = route_next(rn);
for (; rn && !rn->info; rn = route_next(rn))
;
return rn;
}
int lib_interface_ospf_interface_get_keys(struct nb_cb_get_keys_args *args)
{
struct ospf_interface *oi = OIENTRY(args);
args->keys->num = 1;
if (CHECK_FLAG(oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
args->keys->key[0][0] = 0;
else
snprintfrr(args->keys->key[0], sizeof(args->keys->key[0]),
"%pI4", &oi->address->u.prefix4);
return NB_OK;
}
const void *
lib_interface_ospf_interface_lookup_entry(struct nb_cb_lookup_entry_args *args)
{
struct interface *ifp = (struct interface *)args->parent_list_entry;
const char *key = args->keys->key[0];
struct ospf_interface *oi;
struct route_node *rn;
struct prefix_ipv4 p;
assert(ifp);
/* handle unnumbered case */
if (!key[0]) {
for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn)) {
oi = rn->info;
if (oi && CHECK_FLAG(oi->connected->flags,
ZEBRA_IFA_UNNUMBERED))
return rn;
}
return NULL;
}
if (!str2prefix_ipv4(key, &p)) {
DEBUGD(&nb_dbg_cbs_state, "invalid interface address key: %s",
key);
return NULL;
}
rn = route_node_match(IF_OIFS(ifp), &p);
if (!rn || !rn->info)
return NULL;
return rn;
}
/*
* XPath: /frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/state
*/
struct yang_data *lib_interface_ospf_interface_state_state_get_elem(
struct nb_cb_get_elem_args *args)
{
return yang_data_new_enum(args->xpath, OIENTRY(args)->state);
}
/*
* XPath:
* /frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/hello-timer
*/
struct yang_data *lib_interface_ospf_interface_state_hello_timer_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf_interface *oi = OIENTRY(args);
uint16_t secs;
/* TODO: update the model to support fast-hello */
secs = OSPF_IF_PARAM(oi, fast_hello) ? 1 : OSPF_IF_PARAM(oi, v_hello);
return yang_data_new_uint16(args->xpath, secs);
}
/*
* XPath:
* /frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/neighbors/neighbor
*/
const void *lib_interface_ospf_interface_state_neighbors_neighbor_get_next(
struct nb_cb_get_next_args *args)
{
struct route_node *rn = RNENTRY(args);
if (rn)
rn = route_next(rn);
else {
struct ospf_interface *oi = OIPARENT(args);
assert(oi);
rn = route_top(oi->nbrs);
}
for (; rn && !rn->info; rn = route_next(rn))
;
return rn;
}
int lib_interface_ospf_interface_state_neighbors_neighbor_get_keys(
struct nb_cb_get_keys_args *args)
{
struct ospf_neighbor *nbr = NBRENTRY(args);
args->keys->num = 1;
snprintfrr(args->keys->key[0], sizeof(args->keys->key[0]), "%pI4",
&nbr->router_id);
return NB_OK;
}
const void *lib_interface_ospf_interface_state_neighbors_neighbor_lookup_entry(
struct nb_cb_lookup_entry_args *args)
{
struct ospf_interface *oi = OIPARENT(args);
const char *key = args->keys->key[0];
struct route_node *rn;
struct prefix_ipv4 p;
if (!str2prefix_ipv4(key, &p) || p.prefixlen != IPV4_MAX_BITLEN) {
DEBUGD(&nb_dbg_cbs_state, "invalid neighbor router id key : %s",
key);
return NULL;
}
rn = route_node_match(oi->nbrs, &p);
if (!rn || !rn->info)
return NULL;
return rn;
}
struct yang_data *
lib_interface_ospf_interface_state_neighbors_neighbor_get_elem(
struct nb_cb_get_elem_args *args)
{
return yang_data_new_ipv4(args->xpath, &NBRENTRY(args)->router_id);
}
/*
* XPath:
* /frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/neighbors/neighbor/neighbor-router-id
*/
struct yang_data *
lib_interface_ospf_interface_state_neighbors_neighbor_neighbor_router_id_get_elem(
struct nb_cb_get_elem_args *args)
{
return yang_data_new_ipv4(args->xpath, &NBRENTRY(args)->router_id);
}
/*
* XPath:
* /frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/neighbors/neighbor/address
*/
struct yang_data *
lib_interface_ospf_interface_state_neighbors_neighbor_address_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf_neighbor *nbr = NBRENTRY(args);
if (CHECK_FLAG(nbr->oi->connected->flags, ZEBRA_IFA_UNNUMBERED))
return NULL;
return yang_data_new_ipv4(args->xpath, &nbr->address.u.prefix4);
}
/*
* XPath:
* /frr-interface:lib/interface/frr-ospfd-lite:ospf-interface/state/neighbors/neighbor/state
*/
struct yang_data *
lib_interface_ospf_interface_state_neighbors_neighbor_state_get_elem(
struct nb_cb_get_elem_args *args)
{
return yang_data_new_enum(args->xpath, NBRENTRY(args)->state);
}
#define LNPARENT(args) ((const struct listnode *)((args)->parent_list_entry))
#define LNENTRY(args) ((const struct listnode *)((args)->list_entry))
#define OPARENT(args) ((struct ospf *)listgetdata(LNPARENT(args)))
#define OENTRY(args) ((struct ospf *)listgetdata(LNENTRY(args)))
const void *ospf_instance_get_next(struct nb_cb_get_next_args *args)
{
const struct listnode *node = LNENTRY(args);
if (node == NULL)
return listhead(om->ospf);
else
return listnextnode(node);
}
int ospf_instance_get_keys(struct nb_cb_get_keys_args *args)
{
struct ospf *ospf = OENTRY(args);
args->keys->num = 1;
if (!ospf->name)
args->keys->key[0][0] = 0;
else
strlcpy(args->keys->key[0], ospf->name, sizeof(args->keys->key[0]));
return NB_OK;
}
const void *ospf_instance_lookup_entry(struct nb_cb_lookup_entry_args *args)
{
const char *vrf_name = args->keys->key[0];
const struct listnode *node;
struct ospf *ospf;
for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf))
if ((ospf->name == NULL && vrf_name[0]) ||
(ospf->name && vrf_name[0] && !strcmp(ospf->name, vrf_name)))
return node;
return NULL;
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/state/router-flags/router-flag
*/
struct yang_data *ospf_instance_state_router_flags_router_flag_get_elem(
struct nb_cb_get_elem_args *args)
{
/* TODO: implement me. */
return NULL;
}
const void *ospf_instance_state_router_flags_router_flag_get_next(
struct nb_cb_get_next_args *args)
{
/* TODO: implement me. */
return NULL;
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/state/statistics/originate-new-lsa-count
*/
struct yang_data *
ospf_instance_state_statistics_originate_new_lsa_count_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf *ospf = OENTRY(args);
return yang_data_new_uint32(args->xpath, ospf->lsa_originate_count);
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/state/statistics/rx-new-lsas-count
*/
struct yang_data *ospf_instance_state_statistics_rx_new_lsas_count_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf *ospf = OENTRY(args);
return yang_data_new_uint32(args->xpath, ospf->rx_lsa_count);
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/state/statistics/spf/timestamp
*/
struct yang_data *ospf_instance_state_statistics_spf_timestamp_get_elem(
struct nb_cb_get_elem_args *args)
{
/* TODO: implement me. */
return NULL;
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/state/statistics/spf/duration
*/
struct yang_data *ospf_instance_state_statistics_spf_duration_get_elem(
struct nb_cb_get_elem_args *args)
{
/* TODO: implement me. */
return NULL;
}
#define APARENT(args) ((struct ospf_area *)listgetdata(LNPARENT(args)))
#define AENTRY(args) ((struct ospf_area *)listgetdata(LNENTRY(args)))
const void *ospf_instance_areas_area_get_next(struct nb_cb_get_next_args *args)
{
struct ospf *ospf = OPARENT(args);
const struct listnode *node = LNENTRY(args);
if (node == NULL)
return listhead(ospf->areas);
else
return listnextnode(node);
}
int ospf_instance_areas_area_get_keys(struct nb_cb_get_keys_args *args)
{
struct ospf_area *area = AENTRY(args);
args->keys->num = 1;
snprintfrr(args->keys->key[0], sizeof(args->keys->key[0]), "%pI4",
&area->area_id);
return NB_OK;
}
const void *
ospf_instance_areas_area_lookup_entry(struct nb_cb_lookup_entry_args *args)
{
struct ospf *ospf = OPARENT(args);
const char *key = args->keys->key[0];
struct ospf_area *area;
struct listnode *node;
struct in_addr area_id;
int aid_fmt;
if (str2area_id(key, &area_id, &aid_fmt))
/* TODO: dbg log ? */
return NULL;
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area))
if (area->area_id.s_addr == area_id.s_addr)
return node;
return NULL;
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/areas/area/state/statistics/spf-runs-count
*/
struct yang_data *ospf_instance_areas_area_state_statistics_spf_runs_count_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf_area *area = AENTRY(args);
return yang_data_new_uint32(args->xpath, area->spf_calculation);
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/areas/area/state/statistics/abr-count
*/
struct yang_data *ospf_instance_areas_area_state_statistics_abr_count_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf_area *area = AENTRY(args);
return yang_data_new_uint32(args->xpath, area->abr_count);
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/areas/area/state/statistics/asbr-count
*/
struct yang_data *ospf_instance_areas_area_state_statistics_asbr_count_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf_area *area = AENTRY(args);
return yang_data_new_uint32(args->xpath, area->asbr_count);
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/areas/area/state/statistics/area-scope-lsa-count
*/
struct yang_data *ospf_instance_areas_area_state_statistics_area_scope_lsa_count_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf_area *area = AENTRY(args);
return yang_data_new_uint32(args->xpath, area->lsdb->total);
}
/*
* XPath:
* /frr-ospfd-lite:ospf/instance/areas/area/state/statistics/spf-timestamp
*/
struct yang_data *
ospf_instance_areas_area_state_statistics_spf_timestamp_get_elem(
struct nb_cb_get_elem_args *args)
{
/* TODO: implement me. */
return NULL;
}
/*
* XPath:
* /frr-ospfd-lite:ospf/instance/areas/area/state/statistics/active-interfaces
*/
struct yang_data *ospf_instance_areas_area_state_statistics_active_interfaces_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf_area *area = AENTRY(args);
return yang_data_new_uint32(args->xpath, area->act_ints);
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/areas/area/state/statistics/full-nbrs
*/
struct yang_data *ospf_instance_areas_area_state_statistics_full_nbrs_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf_area *area = AENTRY(args);
return yang_data_new_uint32(args->xpath, area->full_nbrs);
}
/*
* XPath: /frr-ospfd-lite:ospf/instance/areas/area/state/statistics/full-virtual
*/
struct yang_data *ospf_instance_areas_area_state_statistics_full_virtual_get_elem(
struct nb_cb_get_elem_args *args)
{
struct ospf_area *area = AENTRY(args);
return yang_data_new_uint32(args->xpath, area->full_vls);
}

View file

@ -38,6 +38,9 @@ ospfd_libfrrospf_a_SOURCES = \
ospfd/ospf_lsa.c \
ospfd/ospf_lsdb.c \
ospfd/ospf_memory.c \
ospfd/ospf_nb.c \
ospfd/ospf_nb_config.c \
ospfd/ospf_nb_state.c \
ospfd/ospf_neighbor.c \
ospfd/ospf_network.c \
ospfd/ospf_nsm.c \
@ -80,6 +83,7 @@ clippy_scan += \
ospfd/ospf_ldp_sync.c \
ospfd/ospf_dump.c \
ospfd/ospf_gr.c \
ospfd/ospf_cli.c \
# end
noinst_HEADERS += \
@ -94,6 +98,7 @@ noinst_HEADERS += \
ospfd/ospf_interface.h \
ospfd/ospf_ldp_sync.h \
ospfd/ospf_memory.h \
ospfd/ospf_nb.h \
ospfd/ospf_neighbor.h \
ospfd/ospf_network.h \
ospfd/ospf_packet.h \

View file

@ -0,0 +1,25 @@
log timestamp precision 6
log file frr.log
debug northbound notifications
debug northbound libyang
debug northbound events
debug northbound callbacks
debug mgmt backend datastore frontend transaction
debug mgmt client frontend
debug mgmt client backend
interface r1-eth0
ip address 10.0.1.1/24
ip ospf hello-interval 3
ip ospf dead-interval 10
ip ospf retransmit-interval 2
ip route 11.0.0.0/8 Null0
router ospf
ospf router-id 1.1.1.1
network 10.0.0.0/16 area 0.0.0.0
redistribute static

View file

@ -0,0 +1,17 @@
interface r2-eth0
ip address 10.0.1.2/24
ip ospf hello-interval 3
ip ospf dead-interval 10
ip ospf retransmit-interval 2
interface r2-eth1
ip address 10.0.2.2/24
ip ospf hello-interval 3
ip ospf dead-interval 10
ip ospf retransmit-interval 2
ip route 22.0.0.0/8 Null0
router ospf
ospf router-id 2.2.2.2
network 10.0.0.0/16 area 0.0.0.0
redistribute static

View file

@ -0,0 +1,12 @@
interface r3-eth0
ip address 10.0.2.3/24
ip ospf hello-interval 3
ip ospf dead-interval 10
ip ospf retransmit-interval 2
ip route 33.0.0.0/8 Null0
router ospf
ospf router-id 3.3.3.3
network 10.0.0.0/16 area 0.0.0.0
redistribute static

View file

@ -0,0 +1,74 @@
#!/usr/bin/env python
# -*- coding: utf-8 eval: (blacken-mode 1) -*-
# SPDX-License-Identifier: ISC
#
# <template>.py
# Part of NetDEF Topology Tests
#
# Copyright (c) 2017 by
# Network Device Education Foundation, Inc. ("NetDEF")
#
"""
<template>.py: Test <template>.
"""
import sys
import pytest
from lib.topogen import Topogen, TopoRouter
from lib.topolog import logger
pytestmark = [
pytest.mark.ospfd,
]
# New form of setup/teardown using pytest fixture
@pytest.fixture(scope="module")
def tgen(request):
"Setup/Teardown the environment and provide tgen argument to tests"
topodef = {
"s0": ("r1", "r2"),
"s1": ("r2", "r3"),
}
tgen = Topogen(topodef, request.module.__name__)
tgen.start_topology()
router_list = tgen.routers()
for rname, router in router_list.items():
router.load_frr_config("frr.conf")
tgen.start_router()
yield tgen
tgen.stop_topology()
# Fixture that executes before each test
@pytest.fixture(autouse=True)
def skip_on_failure(tgen):
if tgen.routers_have_failure():
pytest.skip("skipped because of previous test failure")
# ===================
# The tests functions
# ===================
def test_get_version(tgen):
"Test the logs the FRR version"
# tgen.gears["r1"].net.cmd_nostatus(
# "vtysh -c 'debug ospfd client frontend' " "-c 'debug ospfd client backend' "
# )
# stepf("about to get version")
r1 = tgen.gears["r1"]
version = r1.vtysh_cmd("show version")
logger.info("FRR version is: " + version)

View file

@ -90,8 +90,7 @@ extern struct event_loop *master;
#define VTYSH_NH_GROUP VTYSH_PBRD|VTYSH_SHARPD
#define VTYSH_SR VTYSH_ZEBRA|VTYSH_PATHD
#define VTYSH_DPDK VTYSH_ZEBRA
#define VTYSH_MGMT_BACKEND \
VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_STATICD | VTYSH_ZEBRA
#define VTYSH_MGMT_BACKEND VTYSH_OSPFD | VTYSH_RIPD | VTYSH_RIPNGD | VTYSH_STATICD | VTYSH_ZEBRA
#define VTYSH_MGMT_FRONTEND VTYSH_MGMTD
enum vtysh_write_integrated {

File diff suppressed because it is too large Load diff

1260
yang/frr-ospfd-lite.yang Normal file

File diff suppressed because it is too large Load diff

View file

@ -98,7 +98,8 @@ dist_yangmodels_DATA += yang/frr-bgp.yang
endif
if OSPFD
dist_yangmodels_DATA += yang/frr-ospfd.yang
dist_yangmodels_DATA += yang/frr-ospf-common-lite.yang
dist_yangmodels_DATA += yang/frr-ospfd-lite.yang
endif
if PATHD