summaryrefslogtreecommitdiffstats
path: root/staticd/static_nb_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'staticd/static_nb_config.c')
-rw-r--r--staticd/static_nb_config.c131
1 files changed, 81 insertions, 50 deletions
diff --git a/staticd/static_nb_config.c b/staticd/static_nb_config.c
index ede2e38..7de5f04 100644
--- a/staticd/static_nb_config.c
+++ b/staticd/static_nb_config.c
@@ -18,6 +18,7 @@
#include "static_vrf.h"
#include "static_routes.h"
#include "static_nb.h"
+#include "static_zebra.h"
static int static_path_list_create(struct nb_cb_create_args *args)
@@ -33,8 +34,8 @@ static int static_path_list_create(struct nb_cb_create_args *args)
case NB_EV_VALIDATE:
vrf_dnode = yang_dnode_get_parent(args->dnode,
"control-plane-protocol");
- vrf = yang_dnode_get_string(vrf_dnode, "./vrf");
- table_id = yang_dnode_get_uint32(args->dnode, "./table-id");
+ vrf = yang_dnode_get_string(vrf_dnode, "vrf");
+ table_id = yang_dnode_get_uint32(args->dnode, "table-id");
/*
* TableId is not applicable for VRF. Consider the case of
@@ -55,8 +56,8 @@ static int static_path_list_create(struct nb_cb_create_args *args)
break;
case NB_EV_APPLY:
rn = nb_running_get_entry(args->dnode, NULL, true);
- distance = yang_dnode_get_uint8(args->dnode, "./distance");
- table_id = yang_dnode_get_uint32(args->dnode, "./table-id");
+ distance = yang_dnode_get_uint8(args->dnode, "distance");
+ table_id = yang_dnode_get_uint32(args->dnode, "table-id");
pn = static_add_path(rn, table_id, distance);
nb_running_set_entry(args->dnode, pn);
}
@@ -111,7 +112,7 @@ static int nexthop_iter_cb(const struct lyd_node *dnode, void *arg)
struct nexthop_iter *iter = arg;
enum static_nh_type nh_type;
- nh_type = yang_dnode_get_enum(dnode, "./nh-type");
+ nh_type = yang_dnode_get_enum(dnode, "nh-type");
if (nh_type == STATIC_BLACKHOLE)
iter->blackhole = true;
@@ -134,9 +135,8 @@ static bool static_nexthop_create(struct nb_cb_create_args *args)
switch (args->event) {
case NB_EV_VALIDATE:
- ifname = yang_dnode_get_string(args->dnode, "./interface");
- nh_type = yang_dnode_get_enum(args->dnode, "./nh-type");
- if (ifname != NULL && nh_type != STATIC_BLACKHOLE) {
+ ifname = yang_dnode_get_string(args->dnode, "interface");
+ if (ifname != NULL) {
if (strcasecmp(ifname, "Null0") == 0
|| strcasecmp(ifname, "reject") == 0
|| strcasecmp(ifname, "blackhole") == 0) {
@@ -170,12 +170,15 @@ static bool static_nexthop_create(struct nb_cb_create_args *args)
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
- yang_dnode_get_ip(&ipaddr, args->dnode, "./gateway");
- nh_type = yang_dnode_get_enum(args->dnode, "./nh-type");
- ifname = yang_dnode_get_string(args->dnode, "./interface");
- nh_vrf = yang_dnode_get_string(args->dnode, "./vrf");
+ yang_dnode_get_ip(&ipaddr, args->dnode, "gateway");
+ nh_type = yang_dnode_get_enum(args->dnode, "nh-type");
+ ifname = yang_dnode_get_string(args->dnode, "interface");
+ nh_vrf = yang_dnode_get_string(args->dnode, "vrf");
pn = nb_running_get_entry(args->dnode, NULL, true);
+ if (strmatch(ifname, "(null)"))
+ ifname = "";
+
if (!static_add_nexthop_validate(nh_vrf, nh_type, &ipaddr))
flog_warn(
EC_LIB_NB_CB_CONFIG_VALIDATE,
@@ -464,33 +467,10 @@ static int static_nexthop_bh_type_modify(struct nb_cb_modify_args *args)
{
struct static_nexthop *nh;
enum static_nh_type nh_type;
- const char *nh_ifname;
- const char *nh_vrf;
switch (args->event) {
case NB_EV_VALIDATE:
nh_type = yang_dnode_get_enum(args->dnode, "../nh-type");
- nh_ifname = yang_dnode_get_string(args->dnode, "../interface");
- nh_vrf = yang_dnode_get_string(args->dnode, "../vrf");
- if (nh_ifname && nh_vrf) {
- struct vrf *vrf = vrf_lookup_by_name(nh_vrf);
-
- if (!vrf) {
- snprintf(args->errmsg, args->errmsg_len,
- "nexthop vrf %s not found", nh_vrf);
- return NB_ERR_VALIDATION;
- }
-
- struct interface *ifp = if_lookup_by_name(nh_ifname,
- vrf->vrf_id);
-
- if (ifp && (!strmatch(nh_ifname, "blackhole") ||
- !strmatch(nh_ifname, "reject"))) {
- snprintf(args->errmsg, args->errmsg_len,
- "nexthop interface name must be (reject, blackhole)");
- return NB_ERR_VALIDATION;
- }
- }
if (nh_type != STATIC_BLACKHOLE) {
snprintf(args->errmsg, args->errmsg_len,
"nexthop type is not the blackhole type");
@@ -535,7 +515,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_pa
const struct lyd_node *mls_dnode;
uint32_t count;
- mls_dnode = yang_dnode_get(args->dnode, "./mpls-label-stack");
+ mls_dnode = yang_dnode_get(args->dnode, "mpls-label-stack");
count = yang_get_list_elements_count(lyd_child(mls_dnode));
if (count > MPLS_MAX_LABELS) {
@@ -552,7 +532,7 @@ int routing_control_plane_protocols_name_validate(
{
const char *name;
- name = yang_dnode_get_string(args->dnode, "./name");
+ name = yang_dnode_get_string(args->dnode, "name");
if (!strmatch(name, "staticd")) {
snprintf(args->errmsg, args->errmsg_len,
"static routing supports only one instance with name staticd");
@@ -560,6 +540,48 @@ int routing_control_plane_protocols_name_validate(
}
return NB_OK;
}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol
+ */
+int routing_control_plane_protocols_staticd_create(struct nb_cb_create_args *args)
+{
+ struct static_vrf *svrf;
+ const char *vrf;
+
+ vrf = yang_dnode_get_string(args->dnode, "vrf");
+ svrf = static_vrf_alloc(vrf);
+ nb_running_set_entry(args->dnode, svrf);
+
+ return NB_OK;
+}
+
+int routing_control_plane_protocols_staticd_destroy(
+ struct nb_cb_destroy_args *args)
+{
+ struct static_vrf *svrf;
+ struct route_table *stable;
+ struct route_node *rn;
+ afi_t afi;
+ safi_t safi;
+
+ svrf = nb_running_unset_entry(args->dnode);
+
+ FOREACH_AFI_SAFI (afi, safi) {
+ stable = svrf->stable[afi][safi];
+ if (!stable)
+ continue;
+
+ for (rn = route_top(stable); rn; rn = route_next(rn))
+ static_del_route(rn);
+ }
+
+ static_vrf_free(svrf);
+
+ return NB_OK;
+}
+
/*
* XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list
@@ -567,8 +589,7 @@ int routing_control_plane_protocols_name_validate(
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
struct nb_cb_create_args *args)
{
- struct vrf *vrf;
- struct static_vrf *s_vrf;
+ struct static_vrf *svrf;
struct route_node *rn;
const struct lyd_node *vrf_dnode;
struct prefix prefix;
@@ -579,15 +600,15 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_cr
switch (args->event) {
case NB_EV_VALIDATE:
- yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
- afi_safi = yang_dnode_get_string(args->dnode, "./afi-safi");
+ yang_dnode_get_prefix(&prefix, args->dnode, "prefix");
+ afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
yang_afi_safi_identity2value(afi_safi, &afi, &safi);
prefix_afi = family2afi(prefix.family);
if (afi != prefix_afi) {
flog_warn(
EC_LIB_NB_CB_CONFIG_VALIDATE,
"route node %s creation failed",
- yang_dnode_get_string(args->dnode, "./prefix"));
+ yang_dnode_get_string(args->dnode, "prefix"));
return NB_ERR_VALIDATION;
}
break;
@@ -597,19 +618,18 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_cr
case NB_EV_APPLY:
vrf_dnode = yang_dnode_get_parent(args->dnode,
"control-plane-protocol");
- vrf = nb_running_get_entry(vrf_dnode, NULL, true);
- s_vrf = vrf->info;
+ svrf = nb_running_get_entry(vrf_dnode, NULL, true);
- yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
- afi_safi = yang_dnode_get_string(args->dnode, "./afi-safi");
+ yang_dnode_get_prefix(&prefix, args->dnode, "prefix");
+ afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
yang_afi_safi_identity2value(afi_safi, &afi, &safi);
- rn = static_add_route(afi, safi, &prefix, NULL, s_vrf);
- if (vrf->vrf_id == VRF_UNKNOWN)
+ rn = static_add_route(afi, safi, &prefix, NULL, svrf);
+ if (!svrf->vrf || svrf->vrf->vrf_id == VRF_UNKNOWN)
snprintf(
args->errmsg, args->errmsg_len,
"Static Route to %s not installed currently because dependent config not fully available",
- yang_dnode_get_string(args->dnode, "./prefix"));
+ yang_dnode_get_string(args->dnode, "prefix"));
nb_running_set_entry(args->dnode, rn);
break;
}
@@ -960,6 +980,17 @@ int route_next_hop_bfd_source_destroy(struct nb_cb_destroy_args *args)
sn = nb_running_get_entry(args->dnode, NULL, true);
static_next_hop_bfd_auto_source(sn);
+
+ /* NHT information are needed by BFD to automatically find the source
+ *
+ * Force zebra to resend the information to BFD by unregistering and
+ * registering again NHT. The (...)/frr-nexthops/nexthop northbound
+ * apply_finish function will trigger a call to static_install_nexthop()
+ * that does a call to static_zebra_nht_register(nh, true);
+ * static_zebra_nht_register(sn, false);
+ */
+ static_zebra_nht_register(sn, false);
+
return NB_OK;
}
@@ -1036,7 +1067,7 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_sr
rn = nb_running_get_entry(args->dnode, NULL, true);
info = route_table_get_info(rn->table);
s_vrf = info->svrf;
- yang_dnode_get_ipv6p(&src_prefix, args->dnode, "./src-prefix");
+ yang_dnode_get_ipv6p(&src_prefix, args->dnode, "src-prefix");
afi = family2afi(src_prefix.family);
src_rn =
static_add_route(afi, safi, &rn->p, &src_prefix, s_vrf);