Merge pull request #6296 from vishaldhingra/static

staticd: static route NB configuration code
This commit is contained in:
Quentin Young 2020-07-17 12:39:03 -04:00 committed by GitHub
commit d58258e909
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 3220 additions and 1255 deletions

40
lib/routing_nb.c Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2018 Vmware
* Vishal Dhingra
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "northbound.h"
#include "libfrr.h"
#include "routing_nb.h"
/* clang-format off */
const struct frr_yang_module_info frr_routing_info = {
.name = "frr-routing",
.nodes = {
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol",
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_destroy,
}
},
{
.xpath = NULL,
},
}
};

24
lib/routing_nb.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef _FRR_ROUTING_NB_H_
#define _FRR_ROUTING_NB_H_
extern const struct frr_yang_module_info frr_routing_info;
/* Mandatory callbacks. */
int routing_control_plane_protocols_control_plane_protocol_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_destroy(
struct nb_cb_destroy_args *args);
#define FRR_ROUTING_XPATH \
"/frr-routing:routing/control-plane-protocols/control-plane-protocol"
#define FRR_ROUTING_KEY_XPATH \
"/frr-routing:routing/control-plane-protocols/" \
"control-plane-protocol[type='%s'][name='%s'][vrf='%s']"
/*
* callbacks for routing to handle configuration events
* based on the control plane protocol
*/
DECLARE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args))
#endif /* _FRR_ROUTING_NB_H_ */

74
lib/routing_nb_config.c Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright (C) 2018 Vmware
* Vishal Dhingra
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "northbound.h"
#include "libfrr.h"
#include "vrf.h"
#include "lib_errors.h"
#include "routing_nb.h"
DEFINE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args))
/*
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol
*/
int routing_control_plane_protocols_control_plane_protocol_create(
struct nb_cb_create_args *args)
{
struct vrf *vrf;
const char *vrfname;
switch (args->event) {
case NB_EV_VALIDATE:
if (hook_call(routing_conf_event, args))
return NB_ERR_VALIDATION;
break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
vrfname = yang_dnode_get_string(args->dnode, "./vrf");
vrf = vrf_lookup_by_name(vrfname);
vrf = vrf ? vrf : vrf_get(VRF_UNKNOWN, vrfname);
if (!vrf) {
flog_warn(EC_LIB_NB_CB_CONFIG_APPLY,
"vrf creation %s failed", vrfname);
return NB_ERR;
}
nb_running_set_entry(args->dnode, vrf);
break;
};
return NB_OK;
}
int routing_control_plane_protocols_control_plane_protocol_destroy(
struct nb_cb_destroy_args *args)
{
struct vrf *vrf __attribute__((unused));
if (args->event != NB_EV_APPLY)
return NB_OK;
vrf = nb_running_unset_entry(args->dnode);
return NB_OK;
}

View File

@ -317,3 +317,13 @@ static ssize_t printfrr_rn(char *buf, size_t bsz, const char *fmt,
srcdest2str(dst_p, (const struct prefix_ipv6 *)src_p, buf, bsz);
return 2;
}
struct route_table *srcdest_srcnode_table(struct route_node *rn)
{
if (rnode_is_dstnode(rn)) {
struct srcdest_rnode *srn = srcdest_rnode_from_rnode(rn);
return srn->src_table;
}
return NULL;
}

View File

@ -100,6 +100,8 @@ static inline void *srcdest_rnode_table_info(struct route_node *rn)
return route_table_get_info(srcdest_rnode_table(rn));
}
extern struct route_table *srcdest_srcnode_table(struct route_node *rn);
#ifdef __cplusplus
}
#endif

View File

@ -108,6 +108,8 @@ lib_libfrr_la_SOURCES = \
lib/printf/printf-pos.c \
lib/printf/vfprintf.c \
lib/printf/glue.c \
lib/routing_nb.c \
lib/routing_nb_config.c \
# end
nodist_lib_libfrr_la_SOURCES = \
@ -117,6 +119,7 @@ nodist_lib_libfrr_la_SOURCES = \
yang/frr-route-types.yang.c \
yang/frr-vrf.yang.c \
yang/frr-routing.yang.c \
yang/frr-nexthop.yang.c \
yang/ietf/ietf-routing-types.yang.c \
yang/ietf/ietf-interfaces.yang.c \
yang/frr-module-translator.yang.c \
@ -266,6 +269,7 @@ pkginclude_HEADERS += \
lib/zlog.h \
lib/zlog_targets.h \
lib/pbr.h \
lib/routing_nb.h \
# end

View File

@ -749,3 +749,147 @@ void yang_terminate(void)
ly_ctx_destroy(ly_native_ctx, NULL);
}
const struct lyd_node *yang_dnode_get_parent(const struct lyd_node *dnode,
const char *name)
{
const struct lyd_node *orig_dnode = dnode;
while (orig_dnode) {
switch (orig_dnode->schema->nodetype) {
case LYS_LIST:
case LYS_CONTAINER:
if (!strcmp(orig_dnode->schema->name, name))
return orig_dnode;
break;
default:
break;
}
orig_dnode = orig_dnode->parent;
}
return NULL;
}
/* API to check if the given node is last node in the list */
static bool yang_is_last_list_dnode(const struct lyd_node *dnode)
{
return (((dnode->next == NULL)
|| (dnode->next
&& (strcmp(dnode->next->schema->name, dnode->schema->name)
!= 0)))
&& dnode->prev
&& ((dnode->prev == dnode)
|| (strcmp(dnode->prev->schema->name, dnode->schema->name)
!= 0)));
}
/* API to check if the given node is last node in the data tree level */
static bool yang_is_last_level_dnode(const struct lyd_node *dnode)
{
const struct lyd_node *parent;
const struct lys_node_list *snode;
const struct lyd_node *key_leaf;
uint8_t keys_size;
switch (dnode->schema->nodetype) {
case LYS_LIST:
assert(dnode->parent);
parent = dnode->parent;
snode = (struct lys_node_list *)parent->schema;
key_leaf = dnode->prev;
for (keys_size = 1; keys_size < snode->keys_size; keys_size++)
key_leaf = key_leaf->prev;
if (key_leaf->prev == dnode)
return true;
break;
case LYS_CONTAINER:
return true;
default:
break;
}
return false;
}
const struct lyd_node *
yang_get_subtree_with_no_sibling(const struct lyd_node *dnode)
{
bool parent = true;
const struct lyd_node *node;
const struct lys_node_container *snode;
node = dnode;
if (node->schema->nodetype != LYS_LIST)
return node;
while (parent) {
switch (node->schema->nodetype) {
case LYS_CONTAINER:
snode = (struct lys_node_container *)node->schema;
if ((!snode->presence)
&& yang_is_last_level_dnode(node)) {
if (node->parent
&& (node->parent->schema->module
== dnode->schema->module))
node = node->parent;
else
parent = false;
} else
parent = false;
break;
case LYS_LIST:
if (yang_is_last_list_dnode(node)
&& yang_is_last_level_dnode(node)) {
if (node->parent
&& (node->parent->schema->module
== dnode->schema->module))
node = node->parent;
else
parent = false;
} else
parent = false;
break;
default:
parent = false;
break;
}
}
return node;
}
uint32_t yang_get_list_pos(const struct lyd_node *node)
{
return lyd_list_pos(node);
}
uint32_t yang_get_list_elements_count(const struct lyd_node *node)
{
unsigned int count;
struct lys_node *schema;
if (!node
|| ((node->schema->nodetype != LYS_LIST)
&& (node->schema->nodetype != LYS_LEAFLIST))) {
return 0;
}
schema = node->schema;
count = 0;
do {
if (node->schema == schema)
++count;
node = node->next;
} while (node);
return count;
}
const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode)
{
if (dnode)
return dnode->child;
return NULL;
}

View File

@ -34,7 +34,7 @@ extern "C" {
#endif
/* Maximum XPath length. */
#define XPATH_MAXLEN 512
#define XPATH_MAXLEN 1024
/* Maximum list key length. */
#define LIST_MAXKEYS 8
@ -551,6 +551,57 @@ extern void yang_init(bool embedded_modules);
*/
extern void yang_terminate(void);
/*
* API to return the parent dnode having a given schema-node name
* Use case: One has to access the parent dnode's private pointer
* for a given child node.
* For that there is a need to find parent dnode first.
*
* dnode The starting node to work on
*
* name The name of container/list schema-node
*
* Returns The dnode matched with the given name
*/
extern const struct lyd_node *
yang_dnode_get_parent(const struct lyd_node *dnode, const char *name);
/*
* In some cases there is a need to auto delete the parent nodes
* if the given node is last in the list.
* It tries to delete all the parents in a given tree in a given module.
* The use case is with static routes and route maps
* example : ip route 1.1.1.1/32 ens33
* ip route 1.1.1.1/32 ens34
* After this no ip route 1.1.1.1/32 ens34 came, now staticd
* has to find out upto which level it has to delete the dnodes.
* For this case it has to send delete nexthop
* After this no ip route 1.1.1.1/32 ens33 came, now staticd has to
* clear nexthop, path and route nodes.
* The same scheme is required for routemaps also
* dnode The starting node to work on
*
* Returns The final parent node selected for deletion
*/
extern const struct lyd_node *
yang_get_subtree_with_no_sibling(const struct lyd_node *dnode);
/* To get the relative position of a node in list */
extern uint32_t yang_get_list_pos(const struct lyd_node *node);
/* To get the number of elements in a list
*
* dnode : The head of list
* Returns : The number of dnodes present in the list
*/
extern uint32_t yang_get_list_elements_count(const struct lyd_node *node);
/* To get the immediate child of a dnode */
const struct lyd_node *yang_dnode_get_child(const struct lyd_node *dnode);
#ifdef __cplusplus
}
#endif

View File

@ -1191,3 +1191,38 @@ const char *yang_nexthop_type2str(uint32_t ntype)
break;
}
}
const char *yang_afi_safi_value2identity(afi_t afi, safi_t safi)
{
if (afi == AFI_IP && safi == SAFI_UNICAST)
return "frr-routing:ipv4-unicast";
if (afi == AFI_IP6 && safi == SAFI_UNICAST)
return "frr-routing:ipv6-unicast";
if (afi == AFI_IP && safi == SAFI_MULTICAST)
return "frr-routing:ipv4-multicast";
if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
return "frr-routing:ipv6-multicast";
return NULL;
}
void yang_afi_safi_identity2value(const char *key, afi_t *afi, safi_t *safi)
{
if (strmatch(key, "frr-routing:ipv4-unicast")) {
*afi = AFI_IP;
*safi = SAFI_UNICAST;
} else if (strmatch(key, "frr-routing:ipv6-unicast")) {
*afi = AFI_IP6;
*safi = SAFI_UNICAST;
} else if (strmatch(key, "frr-routing:ipv4-multicast")) {
*afi = AFI_IP;
*safi = SAFI_MULTICAST;
} else if (strmatch(key, "frr-routing:ipv6-multicast")) {
*afi = AFI_IP6;
*safi = SAFI_MULTICAST;
} else {
*afi = AFI_UNSPEC;
*safi = SAFI_UNSPEC;
}
}

View File

@ -191,6 +191,9 @@ extern struct yang_data *yang_data_new_date_and_time(const char *xpath,
/* nexthop enum2str */
extern const char *yang_nexthop_type2str(uint32_t ntype);
const char *yang_afi_safi_value2identity(afi_t afi, safi_t safi);
void yang_afi_safi_identity2value(const char *key, afi_t *afi, safi_t *safi);
#ifdef __cplusplus
}
#endif

View File

@ -31,12 +31,14 @@
#include "vrf.h"
#include "nexthop.h"
#include "filter.h"
#include "routing_nb.h"
#include "static_vrf.h"
#include "static_vty.h"
#include "static_routes.h"
#include "static_zebra.h"
#include "static_debug.h"
#include "static_nb.h"
char backup_config_file[256];
@ -63,10 +65,12 @@ struct option longopts[] = { { 0 } };
/* Master of threads. */
struct thread_master *master;
static struct frr_daemon_info staticd_di;
/* SIGHUP handler. */
static void sighup(void)
{
zlog_info("SIGHUP received");
vty_read_config(NULL, staticd_di.config_file, config_default);
}
/* SIGINT / SIGTERM handler. */
@ -108,7 +112,10 @@ struct quagga_signal_t static_signals[] = {
static const struct frr_yang_module_info *const staticd_yang_modules[] = {
&frr_filter_info,
&frr_interface_info,
&frr_vrf_info,
&frr_routing_info,
&frr_staticd_info,
};
#define STATIC_VTY_PORT 2616
@ -155,6 +162,9 @@ int main(int argc, char **argv, char **envp)
static_zebra_init();
static_vty_init();
hook_register(routing_conf_event,
routing_control_plane_protocols_name_validate);
snprintf(backup_config_file, sizeof(backup_config_file),
"%s/zebra.conf", frr_sysconfdir);
staticd_di.backup_config_file = backup_config_file;

View File

@ -25,4 +25,4 @@
DEFINE_MGROUP(STATIC, "staticd")
DEFINE_MTYPE(STATIC, STATIC_ROUTE, "Static Route");
DEFINE_MTYPE(STATIC, STATIC_NEXTHOP, "Static Nexthop");

View File

@ -23,6 +23,7 @@
DECLARE_MGROUP(STATIC)
DECLARE_MTYPE(STATIC_ROUTE);
DECLARE_MTYPE(STATIC_NEXTHOP);
DECLARE_MTYPE(STATIC_PATH);
#endif

188
staticd/static_nb.c Normal file
View File

@ -0,0 +1,188 @@
/*
* Copyright (C) 2018 Vmware
* Vishal Dhingra
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "northbound.h"
#include "libfrr.h"
#include "static_nb.h"
/* clang-format off */
const struct frr_yang_module_info frr_staticd_info = {
.name = "frr-staticd",
.nodes = {
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list",
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list",
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/tag",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_tag_modify,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/table-id",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_table_id_modify,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop",
.cbs = {
.apply_finish = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_apply_finish,
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_destroy,
.pre_validate = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_pre_validate,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/bh-type",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/onlink",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry",
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/label",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/ttl",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/traffic-class",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list",
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list",
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/tag",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_tag_modify,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/table-id",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_table_id_modify,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop",
.cbs = {
.apply_finish = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_apply_finish,
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_destroy,
.pre_validate = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_pre_validate,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/bh-type",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/onlink",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry",
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/label",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/ttl",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy,
}
},
{
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list/src-list/path-list/frr-nexthops/nexthop/mpls-label-stack/entry/traffic-class",
.cbs = {
.modify = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy,
}
},
{
.xpath = NULL,
},
}
};

166
staticd/static_nb.h Normal file
View File

@ -0,0 +1,166 @@
/*
* Copyright (C) 2018 Vmware
* Vishal Dhingra
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
* You should have received a copy of the GNU General Public License along
* with this program; see the file COPYING; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _FRR_STATIC_NB_H_
#define _FRR_STATIC_NB_H_
extern const struct frr_yang_module_info frr_staticd_info;
/* Mandatory callbacks. */
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_tag_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_table_id_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_bh_type_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_onlink_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_tag_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_table_id_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_bh_type_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_onlink_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_create(
struct nb_cb_create_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_label_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_ttl_destroy(
struct nb_cb_destroy_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_modify(
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_mpls_label_stack_entry_traffic_class_destroy(
struct nb_cb_destroy_args *args);
/* Optional 'apply_finish' callbacks. */
void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_apply_finish(
struct nb_cb_apply_finish_args *args);
void routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_apply_finish(
struct nb_cb_apply_finish_args *args);
/* Optional 'pre_validate' callbacks. */
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_pre_validate(
struct nb_cb_pre_validate_args *args);
/*
* Callback registered with routing_nb lib to validate only
* one instance of staticd is allowed
*/
int routing_control_plane_protocols_name_validate(
struct nb_cb_create_args *args);
/* xpath macros */
/* route-list */
#define FRR_STATIC_ROUTE_INFO_KEY_XPATH \
"/frr-routing:routing/control-plane-protocols/" \
"control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \
"frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \
"path-list[distance='%u']"
#define FRR_STATIC_ROUTE_PATH_TAG_XPATH "/tag"
#define FRR_STATIC_ROUTE_PATH_TABLEID_XPATH "/table-id"
/* route-list/frr-nexthops */
#define FRR_STATIC_ROUTE_NH_KEY_XPATH \
"/frr-nexthops/" \
"nexthop[nh-type='%s'][vrf='%s'][gateway='%s'][interface='%s']"
#define FRR_STATIC_ROUTE_NH_ONLINK_XPATH "/onlink"
#define FRR_STATIC_ROUTE_NH_BH_XPATH "/bh-type"
#define FRR_STATIC_ROUTE_NH_LABEL_XPATH "/mpls-label-stack"
#define FRR_STATIC_ROUTE_NHLB_KEY_XPATH "/entry[id='%u']/label"
/* route-list/srclist */
#define FRR_S_ROUTE_SRC_INFO_KEY_XPATH \
"/frr-routing:routing/control-plane-protocols/" \
"control-plane-protocol[type='%s'][name='%s'][vrf='%s']/" \
"frr-staticd:staticd/route-list[prefix='%s'][afi-safi='%s']/" \
"src-list[src-prefix='%s']/path-list[distance='%u']"
/* route-list/frr-nexthops */
#define FRR_DEL_S_ROUTE_NH_KEY_XPATH \
FRR_STATIC_ROUTE_INFO_KEY_XPATH \
FRR_STATIC_ROUTE_NH_KEY_XPATH
/* route-list/src/src-list/frr-nexthops*/
#define FRR_DEL_S_ROUTE_SRC_NH_KEY_XPATH \
FRR_S_ROUTE_SRC_INFO_KEY_XPATH \
FRR_STATIC_ROUTE_NH_KEY_XPATH
#endif

1241
staticd/static_nb_config.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -30,33 +30,33 @@
#include "static_zebra.h"
#include "static_nht.h"
static void static_nht_update_rn(struct route_node *rn,
struct prefix *nhp, uint32_t nh_num,
vrf_id_t nh_vrf_id, struct vrf *vrf,
safi_t safi)
static void static_nht_update_path(struct route_node *rn,
struct static_path *pn, struct prefix *nhp,
uint32_t nh_num, vrf_id_t nh_vrf_id,
struct vrf *vrf, safi_t safi)
{
struct static_route *si;
struct static_nexthop *nh;
for (si = rn->info; si; si = si->next) {
if (si->nh_vrf_id != nh_vrf_id)
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
if (nh->nh_vrf_id != nh_vrf_id)
continue;
if (si->type != STATIC_IPV4_GATEWAY
&& si->type != STATIC_IPV4_GATEWAY_IFNAME
&& si->type != STATIC_IPV6_GATEWAY
&& si->type != STATIC_IPV6_GATEWAY_IFNAME)
if (nh->type != STATIC_IPV4_GATEWAY
&& nh->type != STATIC_IPV4_GATEWAY_IFNAME
&& nh->type != STATIC_IPV6_GATEWAY
&& nh->type != STATIC_IPV6_GATEWAY_IFNAME)
continue;
if (nhp->family == AF_INET
&& nhp->u.prefix4.s_addr == si->addr.ipv4.s_addr)
si->nh_valid = !!nh_num;
&& nhp->u.prefix4.s_addr == nh->addr.ipv4.s_addr)
nh->nh_valid = !!nh_num;
if (nhp->family == AF_INET6
&& memcmp(&nhp->u.prefix6, &si->addr.ipv6, 16) == 0)
si->nh_valid = !!nh_num;
&& memcmp(&nhp->u.prefix6, &nh->addr.ipv6, 16) == 0)
nh->nh_valid = !!nh_num;
if (si->state == STATIC_START)
static_zebra_route_add(rn, si, vrf->vrf_id, safi, true);
if (nh->state == STATIC_START)
static_zebra_route_add(rn, pn, safi, true);
}
}
@ -67,6 +67,8 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp,
struct route_table *stable;
struct static_vrf *svrf;
struct route_node *rn;
struct static_path *pn;
struct static_route_info *si;
svrf = vrf->info;
if (!svrf)
@ -78,17 +80,26 @@ static void static_nht_update_safi(struct prefix *sp, struct prefix *nhp,
if (sp) {
rn = srcdest_rnode_lookup(stable, sp, NULL);
if (rn) {
static_nht_update_rn(rn, nhp, nh_num, nh_vrf_id,
vrf, safi);
if (rn && rn->info) {
si = static_route_info_from_rnode(rn);
frr_each(static_path_list, &si->path_list, pn) {
static_nht_update_path(rn, pn, nhp, nh_num,
nh_vrf_id, vrf, safi);
}
route_unlock_node(rn);
}
return;
}
for (rn = route_top(stable); rn; rn = route_next(rn))
static_nht_update_rn(rn, nhp, nh_num, nh_vrf_id, vrf, safi);
for (rn = route_top(stable); rn; rn = route_next(rn)) {
si = static_route_info_from_rnode(rn);
if (!si)
continue;
frr_each(static_path_list, &si->path_list, pn) {
static_nht_update_path(rn, pn, nhp, nh_num, nh_vrf_id,
vrf, safi);
}
}
}
void static_nht_update(struct prefix *sp, struct prefix *nhp,
@ -111,8 +122,10 @@ static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi,
{
struct static_vrf *svrf;
struct route_table *stable;
struct static_route *si;
struct static_nexthop *nh;
struct static_path *pn;
struct route_node *rn;
struct static_route_info *si;
svrf = vrf->info;
if (!svrf)
@ -123,25 +136,33 @@ static void static_nht_reset_start_safi(struct prefix *nhp, afi_t afi,
return;
for (rn = route_top(stable); rn; rn = route_next(rn)) {
for (si = rn->info; si; si = si->next) {
if (si->nh_vrf_id != nh_vrf_id)
continue;
si = static_route_info_from_rnode(rn);
if (!si)
continue;
frr_each(static_path_list, &si->path_list, pn) {
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
if (nh->nh_vrf_id != nh_vrf_id)
continue;
if (nhp->family == AF_INET
&& nhp->u.prefix4.s_addr != si->addr.ipv4.s_addr)
continue;
if (nhp->family == AF_INET
&& nhp->u.prefix4.s_addr
!= nh->addr.ipv4.s_addr)
continue;
if (nhp->family == AF_INET6
&& memcmp(&nhp->u.prefix6, &si->addr.ipv6, 16) != 0)
continue;
if (nhp->family == AF_INET6
&& memcmp(&nhp->u.prefix6, &nh->addr.ipv6,
16)
!= 0)
continue;
/*
* We've been told that a nexthop we depend
* on has changed in some manner, so reset
* the state machine to allow us to start
* over.
*/
si->state = STATIC_START;
/*
* We've been told that a nexthop we
* depend on has changed in some manner,
* so reset the state machine to allow
* us to start over.
*/
nh->state = STATIC_START;
}
}
}
}
@ -164,8 +185,10 @@ static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi,
{
struct static_vrf *svrf;
struct route_table *stable;
struct static_route *si;
struct route_node *rn;
struct static_nexthop *nh;
struct static_path *pn;
struct static_route_info *si;
svrf = vrf->info;
if (!svrf)
@ -178,9 +201,14 @@ static void static_nht_mark_state_safi(struct prefix *sp, afi_t afi,
rn = srcdest_rnode_lookup(stable, sp, NULL);
if (!rn)
return;
for (si = rn->info; si; si = si->next)
si->state = state;
si = rn->info;
if (si) {
frr_each(static_path_list, &si->path_list, pn) {
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
nh->state = state;
}
}
}
route_unlock_node(rn);
}

View File

@ -32,267 +32,366 @@
#include "static_memory.h"
#include "static_zebra.h"
/* Install static route into rib. */
static void static_install_route(struct route_node *rn,
struct static_route *si_changed, safi_t safi)
DEFINE_MTYPE_STATIC(STATIC, STATIC_ROUTE, "Static Route Info");
DEFINE_MTYPE(STATIC, STATIC_PATH, "Static Path");
/* Install static path into rib. */
void static_install_path(struct route_node *rn, struct static_path *pn,
safi_t safi, struct static_vrf *svrf)
{
struct static_route *si;
struct static_nexthop *nh;
for (si = rn->info; si; si = si->next)
static_zebra_nht_register(rn, si, true);
si = rn->info;
if (si)
static_zebra_route_add(rn, si_changed, si->vrf_id, safi, true);
frr_each(static_nexthop_list, &pn->nexthop_list, nh)
static_zebra_nht_register(rn, nh, true);
if (static_nexthop_list_count(&pn->nexthop_list) && svrf && svrf->vrf)
static_zebra_route_add(rn, pn, safi, true);
}
/* Uninstall static route from RIB. */
static void static_uninstall_route(vrf_id_t vrf_id, safi_t safi,
struct route_node *rn,
struct static_route *si_changed)
/* Uninstall static path from RIB. */
static void static_uninstall_path(struct route_node *rn, struct static_path *pn,
safi_t safi, struct static_vrf *svrf)
{
if (rn->info)
static_zebra_route_add(rn, si_changed, vrf_id, safi, true);
if (static_nexthop_list_count(&pn->nexthop_list))
static_zebra_route_add(rn, pn, safi, true);
else
static_zebra_route_add(rn, si_changed, vrf_id, safi, false);
static_zebra_route_add(rn, pn, safi, false);
}
int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
struct prefix_ipv6 *src_p, union g_addr *gate,
const char *ifname, enum static_blackhole_type bh_type,
route_tag_t tag, uint8_t distance, struct static_vrf *svrf,
struct static_vrf *nh_svrf,
struct static_nh_label *snh_label, uint32_t table_id,
bool onlink)
struct route_node *static_add_route(afi_t afi, safi_t safi, struct prefix *p,
struct prefix_ipv6 *src_p,
struct static_vrf *svrf)
{
struct route_node *rn;
struct static_route *si;
struct static_route *pp;
struct static_route *cp;
struct static_route *update = NULL;
struct static_route_info *si;
struct route_table *stable = svrf->stable[afi][safi];
struct interface *ifp;
if (!stable)
return -1;
if (!gate && (type == STATIC_IPV4_GATEWAY
|| type == STATIC_IPV4_GATEWAY_IFNAME
|| type == STATIC_IPV6_GATEWAY
|| type == STATIC_IPV6_GATEWAY_IFNAME))
return -1;
if (!ifname
&& (type == STATIC_IFNAME || type == STATIC_IPV4_GATEWAY_IFNAME
|| type == STATIC_IPV6_GATEWAY_IFNAME))
return -1;
return NULL;
/* Lookup static route prefix. */
rn = srcdest_rnode_get(stable, p, src_p);
/* Do nothing if there is a same static route. */
for (si = rn->info; si; si = si->next) {
if (type == si->type
&& (!gate
|| ((afi == AFI_IP
&& IPV4_ADDR_SAME(&gate->ipv4, &si->addr.ipv4))
|| (afi == AFI_IP6
&& IPV6_ADDR_SAME(gate, &si->addr.ipv6))))
&& (!strcmp(ifname ? ifname : "", si->ifname))
&& nh_svrf->vrf->vrf_id == si->nh_vrf_id) {
if ((distance == si->distance) && (tag == si->tag)
&& (table_id == si->table_id)
&& !memcmp(&si->snh_label, snh_label,
sizeof(struct static_nh_label))
&& si->bh_type == bh_type && si->onlink == onlink) {
route_unlock_node(rn);
return 0;
}
update = si;
}
si = XCALLOC(MTYPE_STATIC_ROUTE, sizeof(struct static_route_info));
static_route_info_init(si);
rn->info = si;
/* Mark as having FRR configuration */
vrf_set_user_cfged(svrf->vrf);
return rn;
}
/* To delete the srcnodes */
static void static_del_src_route(struct route_node *rn, safi_t safi,
struct static_vrf *svrf)
{
struct static_path *pn;
struct static_route_info *si;
si = rn->info;
frr_each_safe(static_path_list, &si->path_list, pn) {
static_del_path(rn, pn, safi, svrf);
}
/* Distance or tag or label changed, delete existing first. */
if (update)
static_delete_route(afi, safi, type, p, src_p, gate, ifname,
update->tag, update->distance, svrf,
&update->snh_label, table_id);
XFREE(MTYPE_STATIC_ROUTE, rn->info);
route_unlock_node(rn);
/* If no other FRR config for this VRF, mark accordingly. */
if (!static_vrf_has_config(svrf))
vrf_reset_user_cfged(svrf->vrf);
}
void static_del_route(struct route_node *rn, safi_t safi,
struct static_vrf *svrf)
{
struct static_path *pn;
struct static_route_info *si;
struct route_table *src_table;
struct route_node *src_node;
si = rn->info;
frr_each_safe(static_path_list, &si->path_list, pn) {
static_del_path(rn, pn, safi, svrf);
}
/* clean up for dst table */
src_table = srcdest_srcnode_table(rn);
if (src_table) {
/* This means the route_node is part of the top hierarchy
* and refers to a destination prefix.
*/
for (src_node = route_top(src_table); src_node;
src_node = route_next(src_node)) {
static_del_src_route(src_node, safi, svrf);
}
}
XFREE(MTYPE_STATIC_ROUTE, rn->info);
route_unlock_node(rn);
/* If no other FRR config for this VRF, mark accordingly. */
if (!static_vrf_has_config(svrf))
vrf_reset_user_cfged(svrf->vrf);
}
bool static_add_nexthop_validate(struct static_vrf *svrf, static_types type,
struct ipaddr *ipaddr)
{
switch (type) {
case STATIC_IPV4_GATEWAY:
case STATIC_IPV4_GATEWAY_IFNAME:
if (if_lookup_exact_address(&ipaddr->ipaddr_v4, AF_INET,
svrf->vrf->vrf_id))
return false;
break;
case STATIC_IPV6_GATEWAY:
case STATIC_IPV6_GATEWAY_IFNAME:
if (if_lookup_exact_address(&ipaddr->ipaddr_v6, AF_INET6,
svrf->vrf->vrf_id))
return false;
break;
default:
break;
}
return true;
}
struct static_path *static_add_path(struct route_node *rn, uint8_t distance)
{
struct static_path *pn;
struct static_route_info *si;
route_lock_node(rn);
/* Make new static route structure. */
si = XCALLOC(MTYPE_STATIC_ROUTE, sizeof(struct static_route));
pn = XCALLOC(MTYPE_STATIC_PATH, sizeof(struct static_path));
si->type = type;
si->distance = distance;
si->bh_type = bh_type;
si->tag = tag;
si->vrf_id = svrf->vrf->vrf_id;
si->nh_vrf_id = nh_svrf->vrf->vrf_id;
strlcpy(si->nh_vrfname, nh_svrf->vrf->name, sizeof(si->nh_vrfname));
si->table_id = table_id;
si->onlink = onlink;
pn->distance = distance;
static_nexthop_list_init(&(pn->nexthop_list));
si = rn->info;
static_path_list_add_head(&(si->path_list), pn);
return pn;
}
void static_del_path(struct route_node *rn, struct static_path *pn, safi_t safi,
struct static_vrf *svrf)
{
struct static_route_info *si;
struct static_nexthop *nh;
si = rn->info;
static_path_list_del(&si->path_list, pn);
frr_each_safe(static_nexthop_list, &pn->nexthop_list, nh) {
static_delete_nexthop(rn, pn, safi, svrf, nh);
}
route_unlock_node(rn);
XFREE(MTYPE_STATIC_PATH, pn);
}
struct static_nexthop *
static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi,
struct static_vrf *svrf, static_types type,
struct ipaddr *ipaddr, const char *ifname,
const char *nh_vrf)
{
struct static_nexthop *nh;
struct static_vrf *nh_svrf;
struct interface *ifp;
struct static_nexthop *cp;
route_lock_node(rn);
nh_svrf = static_vty_get_unknown_vrf(nh_vrf);
if (!nh_svrf)
return NULL;
/* Make new static route structure. */
nh = XCALLOC(MTYPE_STATIC_NEXTHOP, sizeof(struct static_nexthop));
nh->type = type;
nh->nh_vrf_id = nh_svrf->vrf->vrf_id;
strlcpy(nh->nh_vrfname, nh_svrf->vrf->name, sizeof(nh->nh_vrfname));
if (ifname)
strlcpy(si->ifname, ifname, sizeof(si->ifname));
si->ifindex = IFINDEX_INTERNAL;
strlcpy(nh->ifname, ifname, sizeof(nh->ifname));
nh->ifindex = IFINDEX_INTERNAL;
switch (type) {
case STATIC_IPV4_GATEWAY:
case STATIC_IPV4_GATEWAY_IFNAME:
si->addr.ipv4 = gate->ipv4;
nh->addr.ipv4 = ipaddr->ipaddr_v4;
break;
case STATIC_IPV6_GATEWAY:
case STATIC_IPV6_GATEWAY_IFNAME:
si->addr.ipv6 = gate->ipv6;
nh->addr.ipv6 = ipaddr->ipaddr_v6;
break;
case STATIC_IFNAME:
default:
break;
}
/* Save labels, if any. */
memcpy(&si->snh_label, snh_label, sizeof(struct static_nh_label));
/*
* Add new static route information to the tree with sort by
* distance value and gateway address.
* gateway address.
*/
for (pp = NULL, cp = rn->info; cp; pp = cp, cp = cp->next) {
if (si->distance < cp->distance)
break;
if (si->distance > cp->distance)
continue;
if (si->type == STATIC_IPV4_GATEWAY
frr_each(static_nexthop_list, &pn->nexthop_list, cp) {
if (nh->type == STATIC_IPV4_GATEWAY
&& cp->type == STATIC_IPV4_GATEWAY) {
if (ntohl(si->addr.ipv4.s_addr)
if (ntohl(nh->addr.ipv4.s_addr)
< ntohl(cp->addr.ipv4.s_addr))
break;
if (ntohl(si->addr.ipv4.s_addr)
if (ntohl(nh->addr.ipv4.s_addr)
> ntohl(cp->addr.ipv4.s_addr))
continue;
}
}
static_nexthop_list_add_after(&(pn->nexthop_list), cp, nh);
/* Make linked list. */
if (pp)
pp->next = si;
else
rn->info = si;
if (cp)
cp->prev = si;
si->prev = pp;
si->next = cp;
if (nh_svrf->vrf->vrf_id == VRF_UNKNOWN)
return nh;
/* check whether interface exists in system & install if it does */
switch (si->type) {
switch (nh->type) {
case STATIC_IPV4_GATEWAY:
case STATIC_IPV6_GATEWAY:
static_zebra_nht_register(rn, si, true);
break;
case STATIC_IPV4_GATEWAY_IFNAME:
case STATIC_IPV6_GATEWAY_IFNAME:
ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id);
ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id);
if (ifp && ifp->ifindex != IFINDEX_INTERNAL)
si->ifindex = ifp->ifindex;
nh->ifindex = ifp->ifindex;
else
zlog_warn("Static Route using %s interface not installed because the interface does not exist in specified vrf",
ifname);
zlog_warn(
"Static Route using %s interface not installed because the interface does not exist in specified vrf",
ifname);
static_zebra_nht_register(rn, si, true);
break;
case STATIC_BLACKHOLE:
static_install_route(rn, si, safi);
break;
case STATIC_IFNAME:
ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id);
if (ifp && ifp->ifindex != IFINDEX_INTERNAL) {
si->ifindex = ifp->ifindex;
static_install_route(rn, si, safi);
nh->ifindex = ifp->ifindex;
} else
zlog_warn("Static Route using %s interface not installed because the interface does not exist in specified vrf",
ifname);
zlog_warn(
"Static Route using %s interface not installed because the interface does not exist in specified vrf",
ifname);
break;
}
return 1;
return nh;
}
int static_delete_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
struct prefix_ipv6 *src_p, union g_addr *gate,
const char *ifname, route_tag_t tag, uint8_t distance,
struct static_vrf *svrf,
struct static_nh_label *snh_label,
uint32_t table_id)
void static_install_nexthop(struct route_node *rn, struct static_path *pn,
struct static_nexthop *nh, safi_t safi,
struct static_vrf *svrf, const char *ifname,
static_types type, const char *nh_vrf)
{
struct route_node *rn;
struct static_route *si;
struct route_table *stable;
struct static_vrf *nh_svrf;
struct interface *ifp;
/* Lookup table. */
stable = static_vrf_static_table(afi, safi, svrf);
if (!stable)
return -1;
nh_svrf = static_vty_get_unknown_vrf(nh_vrf);
/* Lookup static route prefix. */
rn = srcdest_rnode_lookup(stable, p, src_p);
if (!rn)
return 0;
if (!nh_svrf)
return;
/* Find same static route is the tree */
for (si = rn->info; si; si = si->next)
if (type == si->type
&& (!gate
|| ((afi == AFI_IP
&& IPV4_ADDR_SAME(&gate->ipv4, &si->addr.ipv4))
|| (afi == AFI_IP6
&& IPV6_ADDR_SAME(gate, &si->addr.ipv6))))
&& (!strcmp(ifname ? ifname : "", si->ifname))
&& (!tag || (tag == si->tag))
&& (table_id == si->table_id)
&& (!snh_label->num_labels
|| !memcmp(&si->snh_label, snh_label,
sizeof(struct static_nh_label))))
break;
if (nh_svrf->vrf->vrf_id == VRF_UNKNOWN)
return;
/* Can't find static route. */
if (!si) {
route_unlock_node(rn);
return 0;
/* check whether interface exists in system & install if it does */
switch (nh->type) {
case STATIC_IPV4_GATEWAY:
case STATIC_IPV6_GATEWAY:
if (!static_zebra_nh_update(rn, nh))
static_zebra_nht_register(rn, nh, true);
break;
case STATIC_IPV4_GATEWAY_IFNAME:
case STATIC_IPV6_GATEWAY_IFNAME:
if (!static_zebra_nh_update(rn, nh))
static_zebra_nht_register(rn, nh, true);
break;
case STATIC_BLACKHOLE:
static_install_path(rn, pn, safi, svrf);
break;
case STATIC_IFNAME:
ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id);
if (ifp && ifp->ifindex != IFINDEX_INTERNAL)
static_install_path(rn, pn, safi, svrf);
break;
}
}
static_zebra_nht_register(rn, si, false);
int static_delete_nexthop(struct route_node *rn, struct static_path *pn,
safi_t safi, struct static_vrf *svrf,
struct static_nexthop *nh)
{
struct static_vrf *nh_svrf;
/* Unlink static route from linked list. */
if (si->prev)
si->prev->next = si->next;
else
rn->info = si->next;
if (si->next)
si->next->prev = si->prev;
nh_svrf = static_vrf_lookup_by_name(nh->nh_vrfname);
static_nexthop_list_del(&(pn->nexthop_list), nh);
if (nh_svrf->vrf->vrf_id == VRF_UNKNOWN)
goto EXIT;
static_zebra_nht_register(rn, nh, false);
/*
* If we have other si nodes then route replace
* else delete the route
*/
static_uninstall_route(si->vrf_id, safi, rn, si);
route_unlock_node(rn);
static_uninstall_path(rn, pn, safi, svrf);
EXIT:
route_unlock_node(rn);
/* Free static route configuration. */
XFREE(MTYPE_STATIC_ROUTE, si);
route_unlock_node(rn);
XFREE(MTYPE_STATIC_NEXTHOP, nh);
return 1;
}
static void static_ifindex_update_nh(struct interface *ifp, bool up,
struct route_node *rn,
struct static_path *pn,
struct static_nexthop *nh,
struct static_vrf *svrf, safi_t safi)
{
if (!nh->ifname[0])
return;
if (up) {
if (strcmp(nh->ifname, ifp->name))
return;
if (nh->nh_vrf_id != ifp->vrf_id)
return;
nh->ifindex = ifp->ifindex;
} else {
if (nh->ifindex != ifp->ifindex)
return;
if (nh->nh_vrf_id != ifp->vrf_id)
return;
nh->ifindex = IFINDEX_INTERNAL;
}
static_install_path(rn, pn, safi, svrf);
}
static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi,
safi_t safi)
{
struct route_table *stable;
struct route_node *rn;
struct static_route *si;
struct static_nexthop *nh;
struct static_path *pn;
struct vrf *vrf;
struct static_route_info *si;
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
struct static_vrf *svrf;
@ -302,26 +401,17 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi,
stable = static_vrf_static_table(afi, safi, svrf);
if (!stable)
continue;
for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) {
for (si = rn->info; si; si = si->next) {
if (!si->ifname[0])
continue;
if (up) {
if (strcmp(si->ifname, ifp->name))
continue;
if (si->nh_vrf_id != ifp->vrf_id)
continue;
si->ifindex = ifp->ifindex;
} else {
if (si->ifindex != ifp->ifindex)
continue;
if (si->nh_vrf_id != ifp->vrf_id)
continue;
si->ifindex = IFINDEX_INTERNAL;
si = static_route_info_from_rnode(rn);
if (!si)
continue;
frr_each(static_path_list, &si->path_list, pn) {
frr_each(static_nexthop_list,
&pn->nexthop_list, nh) {
static_ifindex_update_nh(ifp, up, rn,
pn, nh, svrf,
safi);
}
static_install_route(rn, si, safi);
}
}
}
@ -343,26 +433,34 @@ static void static_fixup_vrf(struct static_vrf *svrf,
struct route_table *stable, afi_t afi, safi_t safi)
{
struct route_node *rn;
struct static_route *si;
struct static_nexthop *nh;
struct interface *ifp;
struct static_path *pn;
struct static_route_info *si;
for (rn = route_top(stable); rn; rn = route_next(rn)) {
for (si = rn->info; si; si = si->next) {
if (strcmp(svrf->vrf->name, si->nh_vrfname) != 0)
continue;
si->nh_vrf_id = svrf->vrf->vrf_id;
si->nh_registered = false;
if (si->ifindex) {
ifp = if_lookup_by_name(si->ifname,
si->nh_vrf_id);
if (ifp)
si->ifindex = ifp->ifindex;
else
si = static_route_info_from_rnode(rn);
if (!si)
continue;
frr_each(static_path_list, &si->path_list, pn) {
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
if (strcmp(svrf->vrf->name, nh->nh_vrfname)
!= 0)
continue;
}
static_install_route(rn, si, safi);
nh->nh_vrf_id = svrf->vrf->vrf_id;
nh->nh_registered = false;
if (nh->ifindex) {
ifp = if_lookup_by_name(nh->ifname,
nh->nh_vrf_id);
if (ifp)
nh->ifindex = ifp->ifindex;
else
continue;
}
static_install_path(rn, pn, safi, svrf);
}
}
}
}
@ -377,26 +475,31 @@ static void static_fixup_vrf(struct static_vrf *svrf,
* safi -> the safi in question
*/
static void static_enable_vrf(struct static_vrf *svrf,
struct route_table *stable,
afi_t afi, safi_t safi)
struct route_table *stable, afi_t afi,
safi_t safi)
{
struct route_node *rn;
struct static_route *si;
struct static_nexthop *nh;
struct interface *ifp;
struct vrf *vrf = svrf->vrf;
struct static_path *pn;
struct static_route_info *si;
for (rn = route_top(stable); rn; rn = route_next(rn)) {
for (si = rn->info; si; si = si->next) {
si->vrf_id = vrf->vrf_id;
if (si->ifindex) {
ifp = if_lookup_by_name(si->ifname,
si->nh_vrf_id);
if (ifp)
si->ifindex = ifp->ifindex;
else
continue;
si = static_route_info_from_rnode(rn);
if (!si)
continue;
frr_each(static_path_list, &si->path_list, pn) {
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
if (nh->ifindex) {
ifp = if_lookup_by_name(nh->ifname,
nh->nh_vrf_id);
if (ifp)
nh->ifindex = ifp->ifindex;
else
continue;
}
static_install_path(rn, pn, safi, svrf);
}
static_install_route(rn, si, safi);
}
}
}
@ -452,14 +555,22 @@ static void static_cleanup_vrf(struct static_vrf *svrf,
afi_t afi, safi_t safi)
{
struct route_node *rn;
struct static_route *si;
struct static_nexthop *nh;
struct static_path *pn;
struct static_route_info *si;
for (rn = route_top(stable); rn; rn = route_next(rn)) {
for (si = rn->info; si; si = si->next) {
if (strcmp(svrf->vrf->name, si->nh_vrfname) != 0)
continue;
si = static_route_info_from_rnode(rn);
if (!si)
continue;
frr_each(static_path_list, &si->path_list, pn) {
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
if (strcmp(svrf->vrf->name, nh->nh_vrfname)
!= 0)
continue;
static_uninstall_route(si->vrf_id, safi, rn, si);
static_uninstall_path(rn, pn, safi, svrf);
}
}
}
}
@ -476,11 +587,23 @@ static void static_disable_vrf(struct route_table *stable,
afi_t afi, safi_t safi)
{
struct route_node *rn;
struct static_route *si;
struct static_nexthop *nh;
struct static_path *pn;
struct stable_info *info;
struct static_route_info *si;
for (rn = route_top(stable); rn; rn = route_next(rn))
for (si = rn->info; si; si = si->next)
static_uninstall_route(si->vrf_id, safi, rn, si);
info = route_table_get_info(stable);
for (rn = route_top(stable); rn; rn = route_next(rn)) {
si = static_route_info_from_rnode(rn);
if (!si)
continue;
frr_each(static_path_list, &si->path_list, pn) {
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
static_uninstall_path(rn, pn, safi, info->svrf);
}
}
}
}
/*
@ -535,17 +658,27 @@ static void static_fixup_intf_nh(struct route_table *stable,
afi_t afi, safi_t safi)
{
struct route_node *rn;
struct static_route *si;
struct stable_info *info;
struct static_nexthop *nh;
struct static_path *pn;
struct static_route_info *si;
info = route_table_get_info(stable);
for (rn = route_top(stable); rn; rn = route_next(rn)) {
for (si = rn->info; si; si = si->next) {
if (si->nh_vrf_id != ifp->vrf_id)
continue;
si = static_route_info_from_rnode(rn);
if (!si)
continue;
frr_each(static_path_list, &si->path_list, pn) {
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
if (nh->nh_vrf_id != ifp->vrf_id)
continue;
if (si->ifindex != ifp->ifindex)
continue;
if (nh->ifindex != ifp->ifindex)
continue;
static_install_route(rn, si, safi);
static_install_path(rn, pn, safi, info->svrf);
}
}
}
}
@ -589,3 +722,40 @@ void static_ifindex_update(struct interface *ifp, bool up)
static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_UNICAST);
static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_MULTICAST);
}
void static_get_nh_type(static_types stype, char *type, size_t size)
{
switch (stype) {
case STATIC_IFNAME:
strlcpy(type, "ifindex", size);
break;
case STATIC_IPV4_GATEWAY:
strlcpy(type, "ip4", size);
break;
case STATIC_IPV4_GATEWAY_IFNAME:
strlcpy(type, "ip4-ifindex", size);
break;
case STATIC_BLACKHOLE:
strlcpy(type, "blackhole", size);
break;
case STATIC_IPV6_GATEWAY:
strlcpy(type, "ip6", size);
break;
case STATIC_IPV6_GATEWAY_IFNAME:
strlcpy(type, "ip6-ifindex", size);
break;
};
}
struct stable_info *static_get_stable_info(struct route_node *rn)
{
struct route_table *table;
table = srcdest_rnode_table(rn);
return table->info;
}
void static_route_info_init(struct static_route_info *si)
{
static_path_list_init(&(si->path_list));
}

View File

@ -21,6 +21,7 @@
#define __STATIC_ROUTES_H__
#include "lib/mpls.h"
#include "table.h"
/* Static route label information */
struct static_nh_label {
@ -35,13 +36,17 @@ enum static_blackhole_type {
STATIC_BLACKHOLE_REJECT
};
/*
* The order for below macros should be in sync with
* yang model typedef nexthop-type
*/
typedef enum {
STATIC_IFNAME,
STATIC_IFNAME = 1,
STATIC_IPV4_GATEWAY,
STATIC_IPV4_GATEWAY_IFNAME,
STATIC_BLACKHOLE,
STATIC_IPV6_GATEWAY,
STATIC_IPV6_GATEWAY_IFNAME,
STATIC_BLACKHOLE,
} static_types;
/*
@ -64,14 +69,37 @@ enum static_install_states {
STATIC_NOT_INSTALLED,
};
PREDECL_DLIST(static_path_list);
PREDECL_DLIST(static_nexthop_list);
/* Static route information */
struct static_route_info {
/* path list */
struct static_path_list_head path_list;
};
/* Static path information */
struct static_path {
/* Linkage for static path lists */
struct static_path_list_item list;
/* Administrative distance. */
uint8_t distance;
/* Tag */
route_tag_t tag;
/* Table-id */
uint32_t table_id;
/* Nexthop list */
struct static_nexthop_list_head nexthop_list;
};
DECLARE_DLIST(static_path_list, struct static_path, list);
/* Static route information. */
struct static_route {
struct static_nexthop {
/* For linked list. */
struct static_route *prev;
struct static_route *next;
struct static_nexthop_list_item list;
/* VRF identifier. */
vrf_id_t vrf_id;
vrf_id_t nh_vrf_id;
char nh_vrfname[VRF_NAMSIZ + 1];
@ -81,12 +109,6 @@ struct static_route {
*/
enum static_install_states state;
/* Administrative distance. */
uint8_t distance;
/* Tag */
route_tag_t tag;
/* Flag for this static route's type. */
static_types type;
@ -104,8 +126,6 @@ struct static_route {
/* Label information */
struct static_nh_label snh_label;
uint32_t table_id;
/*
* Whether to pretend the nexthop is directly attached to the specified
* link. Only meaningful when both a gateway address and interface name
@ -114,32 +134,64 @@ struct static_route {
bool onlink;
};
DECLARE_DLIST(static_nexthop_list, struct static_nexthop, list);
/*
* rib_dest_from_rnode
*/
static inline struct static_route_info *
static_route_info_from_rnode(struct route_node *rn)
{
return (struct static_route_info *)(rn->info);
}
extern bool mpls_enabled;
extern struct zebra_privs_t static_privs;
void static_fixup_vrf_ids(struct static_vrf *svrf);
extern int static_add_route(afi_t afi, safi_t safi, uint8_t type,
struct prefix *p, struct prefix_ipv6 *src_p,
union g_addr *gate, const char *ifname,
enum static_blackhole_type bh_type, route_tag_t tag,
uint8_t distance, struct static_vrf *svrf,
struct static_vrf *nh_svrf,
struct static_nh_label *snh_label,
uint32_t table_id, bool onlink);
extern struct static_nexthop *
static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi,
struct static_vrf *svrf, static_types type,
struct ipaddr *ipaddr, const char *ifname,
const char *nh_vrf);
extern void static_install_nexthop(struct route_node *rn,
struct static_path *pn,
struct static_nexthop *nh, safi_t safi,
struct static_vrf *svrf, const char *ifname,
static_types type, const char *nh_vrf);
extern int static_delete_route(afi_t afi, safi_t safi, uint8_t type,
struct prefix *p, struct prefix_ipv6 *src_p,
union g_addr *gate, const char *ifname,
route_tag_t tag, uint8_t distance,
struct static_vrf *svrf,
struct static_nh_label *snh_label,
uint32_t table_id);
extern int static_delete_nexthop(struct route_node *rn, struct static_path *pn,
safi_t safi, struct static_vrf *svrf,
struct static_nexthop *nh);
extern void static_cleanup_vrf_ids(struct static_vrf *disable_svrf);
extern void static_install_intf_nh(struct interface *ifp);
extern void static_ifindex_update(struct interface *ifp, bool up);
extern void static_install_path(struct route_node *rn, struct static_path *pn,
safi_t safi, struct static_vrf *svrf);
extern struct route_node *static_add_route(afi_t afi, safi_t safi,
struct prefix *p,
struct prefix_ipv6 *src_p,
struct static_vrf *svrf);
extern void static_del_route(struct route_node *rn, safi_t safi,
struct static_vrf *svrf);
extern struct static_path *static_add_path(struct route_node *rn,
uint8_t distance);
extern void static_del_path(struct route_node *rn, struct static_path *pn,
safi_t safi, struct static_vrf *svrf);
extern void static_get_nh_type(static_types stype, char *type, size_t size);
extern bool static_add_nexthop_validate(struct static_vrf *svrf,
static_types type,
struct ipaddr *ipaddr);
extern struct stable_info *static_get_stable_info(struct route_node *rn);
extern void static_route_info_init(struct static_route_info *si);
#endif

View File

@ -30,26 +30,39 @@
#include "static_zebra.h"
#include "static_vty.h"
DEFINE_MTYPE_STATIC(STATIC, STATIC_RTABLE_INFO, "Static Route Table Info");
static void zebra_stable_node_cleanup(struct route_table *table,
struct route_node *node)
{
struct static_route *si, *next;
struct static_nexthop *nh;
struct static_path *pn;
struct static_route_info *si;
if (node->info)
for (si = node->info; si; si = next) {
next = si->next;
XFREE(MTYPE_STATIC_ROUTE, si);
si = node->info;
if (si) {
frr_each_safe(static_path_list, &si->path_list, pn) {
frr_each_safe(static_nexthop_list, &pn->nexthop_list,
nh) {
static_nexthop_list_del(&pn->nexthop_list, nh);
XFREE(MTYPE_STATIC_NEXTHOP, nh);
}
static_path_list_del(&si->path_list, pn);
XFREE(MTYPE_STATIC_PATH, pn);
}
}
}
static struct static_vrf *static_vrf_alloc(void)
{
struct route_table *table;
struct static_vrf *svrf;
struct stable_info *info;
safi_t safi;
afi_t afi;
svrf = XCALLOC(MTYPE_TMP, sizeof(struct static_vrf));
svrf = XCALLOC(MTYPE_STATIC_RTABLE_INFO, sizeof(struct static_vrf));
for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
@ -57,6 +70,14 @@ static struct static_vrf *static_vrf_alloc(void)
table = srcdest_table_init();
else
table = route_table_init();
info = XCALLOC(MTYPE_STATIC_RTABLE_INFO,
sizeof(struct stable_info));
info->svrf = svrf;
info->afi = afi;
info->safi = safi;
route_table_set_info(table, info);
table->cleanup = zebra_stable_node_cleanup;
svrf->stable[afi][safi] = table;
}
@ -81,12 +102,6 @@ static int static_vrf_enable(struct vrf *vrf)
static_fixup_vrf_ids(vrf->info);
/*
* We may have static routes that are now possible to
* insert into the appropriate tables
*/
static_config_install_delayed_routes(vrf->info);
return 0;
}
@ -102,16 +117,19 @@ static int static_vrf_delete(struct vrf *vrf)
struct static_vrf *svrf;
safi_t safi;
afi_t afi;
void *info;
svrf = vrf->info;
for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
table = svrf->stable[afi][safi];
info = route_table_get_info(table);
route_table_finish(table);
XFREE(MTYPE_STATIC_RTABLE_INFO, info);
svrf->stable[afi][safi] = NULL;
}
}
XFREE(MTYPE_TMP, svrf);
XFREE(MTYPE_STATIC_RTABLE_INFO, svrf);
return 0;
}
@ -210,3 +228,25 @@ void static_vrf_terminate(void)
{
vrf_terminate();
}
struct static_vrf *static_vty_get_unknown_vrf(const char *vrf_name)
{
struct static_vrf *svrf;
struct vrf *vrf;
svrf = static_vrf_lookup_by_name(vrf_name);
if (svrf)
return svrf;
vrf = vrf_get(VRF_UNKNOWN, vrf_name);
if (!vrf)
return NULL;
svrf = vrf->info;
if (!svrf)
return NULL;
/* Mark as having FRR configuration */
vrf_set_user_cfged(vrf);
return svrf;
}

View File

@ -26,6 +26,14 @@ struct static_vrf {
struct route_table *stable[AFI_MAX][SAFI_MAX];
};
struct stable_info {
struct static_vrf *svrf;
afi_t afi;
safi_t safi;
};
#define GET_STABLE_VRF_ID(info) info->svrf->vrf->vrf_id
struct static_vrf *static_vrf_lookup_by_name(const char *vrf_name);
struct static_vrf *static_vrf_lookup_by_id(vrf_id_t vrf_id);
@ -36,4 +44,6 @@ void static_vrf_init(void);
struct route_table *static_vrf_static_table(afi_t afi, safi_t safi,
struct static_vrf *svrf);
extern void static_vrf_terminate(void);
struct static_vrf *static_vty_get_unknown_vrf(const char *vrf_name);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -19,8 +19,6 @@
#ifndef __STATIC_VTY_H__
#define __STATIC_VTY_H__
void static_config_install_delayed_routes(struct static_vrf *svrf);
int static_config(struct vty *vty, struct static_vrf *svrf,
afi_t afi, safi_t safi, const char *cmd);

View File

@ -89,7 +89,6 @@ static int static_ifp_up(struct interface *ifp)
struct static_vrf *svrf = static_vrf_lookup_by_id(ifp->vrf_id);
static_fixup_vrf_ids(svrf);
static_config_install_delayed_routes(svrf);
}
/* Install any static reliant on this interface coming up */
@ -265,8 +264,8 @@ static void static_nht_hash_free(void *data)
XFREE(MTYPE_TMP, nhtd);
}
void static_zebra_nht_register(struct route_node *rn,
struct static_route *si, bool reg)
void static_zebra_nht_register(struct route_node *rn, struct static_nexthop *nh,
bool reg)
{
struct static_nht_data *nhtd, lookup;
uint32_t cmd;
@ -276,14 +275,14 @@ void static_zebra_nht_register(struct route_node *rn,
cmd = (reg) ?
ZEBRA_NEXTHOP_REGISTER : ZEBRA_NEXTHOP_UNREGISTER;
if (si->nh_registered && reg)
if (nh->nh_registered && reg)
return;
if (!si->nh_registered && !reg)
if (!nh->nh_registered && !reg)
return;
memset(&p, 0, sizeof(p));
switch (si->type) {
switch (nh->type) {
case STATIC_IFNAME:
case STATIC_BLACKHOLE:
return;
@ -291,23 +290,23 @@ void static_zebra_nht_register(struct route_node *rn,
case STATIC_IPV4_GATEWAY_IFNAME:
p.family = AF_INET;
p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = si->addr.ipv4;
p.u.prefix4 = nh->addr.ipv4;
afi = AFI_IP;
break;
case STATIC_IPV6_GATEWAY:
case STATIC_IPV6_GATEWAY_IFNAME:
p.family = AF_INET6;
p.prefixlen = IPV6_MAX_BITLEN;
p.u.prefix6 = si->addr.ipv6;
p.u.prefix6 = nh->addr.ipv6;
afi = AFI_IP6;
break;
}
memset(&lookup, 0, sizeof(lookup));
lookup.nh = &p;
lookup.nh_vrf_id = si->nh_vrf_id;
lookup.nh_vrf_id = nh->nh_vrf_id;
si->nh_registered = reg;
nh->nh_registered = reg;
if (reg) {
nhtd = hash_get(static_nht_hash, &lookup,
@ -318,8 +317,8 @@ void static_zebra_nht_register(struct route_node *rn,
zlog_debug("Registered nexthop(%pFX) for %pRN %d", &p,
rn, nhtd->nh_num);
if (nhtd->refcount > 1 && nhtd->nh_num) {
static_nht_update(&rn->p, nhtd->nh, nhtd->nh_num,
afi, si->nh_vrf_id);
static_nht_update(&rn->p, nhtd->nh, nhtd->nh_num, afi,
nh->nh_vrf_id);
return;
}
} else {
@ -335,25 +334,72 @@ void static_zebra_nht_register(struct route_node *rn,
static_nht_hash_free(nhtd);
}
if (zclient_send_rnh(zclient, cmd, &p, false, si->nh_vrf_id) < 0)
if (zclient_send_rnh(zclient, cmd, &p, false, nh->nh_vrf_id) < 0)
zlog_warn("%s: Failure to send nexthop to zebra", __func__);
}
/*
* When nexthop gets updated via configuration then use the
* already registered NH and resend the route to zebra
*/
int static_zebra_nh_update(struct route_node *rn, struct static_nexthop *nh)
{
struct static_nht_data *nhtd, lookup = {};
struct prefix p = {};
afi_t afi = AFI_IP;
if (!nh->nh_registered)
return 0;
switch (nh->type) {
case STATIC_IFNAME:
case STATIC_BLACKHOLE:
return 0;
case STATIC_IPV4_GATEWAY:
case STATIC_IPV4_GATEWAY_IFNAME:
p.family = AF_INET;
p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = nh->addr.ipv4;
afi = AFI_IP;
break;
case STATIC_IPV6_GATEWAY:
case STATIC_IPV6_GATEWAY_IFNAME:
p.family = AF_INET6;
p.prefixlen = IPV6_MAX_BITLEN;
p.u.prefix6 = nh->addr.ipv6;
afi = AFI_IP6;
break;
}
lookup.nh = &p;
lookup.nh_vrf_id = nh->nh_vrf_id;
nhtd = hash_lookup(static_nht_hash, &lookup);
if (nhtd && nhtd->nh_num) {
nh->state = STATIC_START;
static_nht_update(&rn->p, nhtd->nh, nhtd->nh_num, afi,
nh->nh_vrf_id);
return 1;
}
return 0;
}
extern void static_zebra_route_add(struct route_node *rn,
struct static_route *si_changed,
vrf_id_t vrf_id, safi_t safi, bool install)
struct static_path *pn, safi_t safi,
bool install)
{
struct static_route *si = rn->info;
struct static_nexthop *nh;
const struct prefix *p, *src_pp;
struct zapi_nexthop *api_nh;
struct zapi_route api;
uint32_t nh_num = 0;
struct stable_info *info;
p = src_pp = NULL;
srcdest_rnode_prefixes(rn, &p, &src_pp);
memset(&api, 0, sizeof(api));
api.vrf_id = vrf_id;
info = static_get_stable_info(rn);
api.vrf_id = GET_STABLE_VRF_ID(info);
api.type = ZEBRA_ROUTE_STATIC;
api.safi = safi;
memcpy(&api.prefix, p, sizeof(api.prefix));
@ -365,71 +411,65 @@ extern void static_zebra_route_add(struct route_node *rn,
SET_FLAG(api.flags, ZEBRA_FLAG_RR_USE_DISTANCE);
SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
if (si_changed->distance) {
if (pn->distance) {
SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
api.distance = si_changed->distance;
api.distance = pn->distance;
}
if (si_changed->tag) {
if (pn->tag) {
SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
api.tag = si_changed->tag;
api.tag = pn->tag;
}
if (si_changed->table_id != 0) {
if (pn->table_id != 0) {
SET_FLAG(api.message, ZAPI_MESSAGE_TABLEID);
api.tableid = si_changed->table_id;
api.tableid = pn->table_id;
}
for (/*loaded above*/; si; si = si->next) {
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
api_nh = &api.nexthops[nh_num];
if (si->nh_vrf_id == VRF_UNKNOWN)
if (nh->nh_vrf_id == VRF_UNKNOWN)
continue;
if (si->distance != si_changed->distance)
continue;
if (si->table_id != si_changed->table_id)
continue;
api_nh->vrf_id = si->nh_vrf_id;
if (si->onlink)
api_nh->vrf_id = nh->nh_vrf_id;
if (nh->onlink)
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
si->state = STATIC_SENT_TO_ZEBRA;
nh->state = STATIC_SENT_TO_ZEBRA;
switch (si->type) {
switch (nh->type) {
case STATIC_IFNAME:
if (si->ifindex == IFINDEX_INTERNAL)
if (nh->ifindex == IFINDEX_INTERNAL)
continue;
api_nh->ifindex = si->ifindex;
api_nh->ifindex = nh->ifindex;
api_nh->type = NEXTHOP_TYPE_IFINDEX;
break;
case STATIC_IPV4_GATEWAY:
if (!si->nh_valid)
if (!nh->nh_valid)
continue;
api_nh->type = NEXTHOP_TYPE_IPV4;
api_nh->gate = si->addr;
api_nh->gate = nh->addr;
break;
case STATIC_IPV4_GATEWAY_IFNAME:
if (si->ifindex == IFINDEX_INTERNAL)
if (nh->ifindex == IFINDEX_INTERNAL)
continue;
api_nh->ifindex = si->ifindex;
api_nh->ifindex = nh->ifindex;
api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
api_nh->gate = si->addr;
api_nh->gate = nh->addr;
break;
case STATIC_IPV6_GATEWAY:
if (!si->nh_valid)
if (!nh->nh_valid)
continue;
api_nh->type = NEXTHOP_TYPE_IPV6;
api_nh->gate = si->addr;
api_nh->gate = nh->addr;
break;
case STATIC_IPV6_GATEWAY_IFNAME:
if (si->ifindex == IFINDEX_INTERNAL)
if (nh->ifindex == IFINDEX_INTERNAL)
continue;
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
api_nh->ifindex = si->ifindex;
api_nh->gate = si->addr;
api_nh->ifindex = nh->ifindex;
api_nh->gate = nh->addr;
break;
case STATIC_BLACKHOLE:
api_nh->type = NEXTHOP_TYPE_BLACKHOLE;
switch (si->bh_type) {
switch (nh->bh_type) {
case STATIC_BLACKHOLE_DROP:
case STATIC_BLACKHOLE_NULL:
api_nh->bh_type = BLACKHOLE_NULL;
@ -440,13 +480,13 @@ extern void static_zebra_route_add(struct route_node *rn,
break;
}
if (si->snh_label.num_labels) {
if (nh->snh_label.num_labels) {
int i;
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
api_nh->label_num = si->snh_label.num_labels;
api_nh->label_num = nh->snh_label.num_labels;
for (i = 0; i < api_nh->label_num; i++)
api_nh->labels[i] = si->snh_label.label[i];
api_nh->labels[i] = nh->snh_label.label[i];
}
nh_num++;
}

View File

@ -22,13 +22,15 @@
extern struct thread_master *master;
extern void static_zebra_nht_register(struct route_node *rn,
struct static_route *si, bool reg);
struct static_nexthop *nh, bool reg);
extern void static_zebra_route_add(struct route_node *rn,
struct static_route *si_changed,
vrf_id_t vrf_id, safi_t safi, bool install);
struct static_path *pn, safi_t safi,
bool install);
extern void static_zebra_init(void);
extern void static_zebra_vrf_register(struct vrf *vrf);
extern void static_zebra_vrf_unregister(struct vrf *vrf);
extern int static_zebra_nh_update(struct route_node *rn,
struct static_nexthop *nh);
#endif

View File

@ -18,6 +18,8 @@ staticd_libstatic_a_SOURCES = \
staticd/static_zebra.c \
staticd/static_vrf.c \
staticd/static_vty.c \
staticd/static_nb.c \
staticd/static_nb_config.c \
# end
noinst_HEADERS += \
@ -28,6 +30,7 @@ noinst_HEADERS += \
staticd/static_routes.h \
staticd/static_vty.h \
staticd/static_vrf.h \
staticd/static_nb.h \
# end
clippy_scan += \
@ -36,3 +39,7 @@ clippy_scan += \
staticd_staticd_SOURCES = staticd/static_main.c
staticd_staticd_LDADD = staticd/libstatic.a lib/libfrr.la $(LIBCAP)
nodist_staticd_staticd_SOURCES = \
yang/frr-staticd.yang.c \
# end

View File

@ -156,7 +156,7 @@ module frr-nexthop {
}
leaf vrf {
type frr-vrf:vrf-ref;
type string;
description
"The nexthop vrf name, if different from the route.";
}
@ -167,7 +167,7 @@ module frr-nexthop {
}
leaf interface {
type frr-interface:interface-ref;
type string;
description
"The nexthop egress interface.";
}
@ -236,7 +236,8 @@ module frr-nexthop {
grouping nexthop-grouping {
list nexthop {
key "nh-type gateway interface";
key "nh-type vrf gateway interface";
min-elements 1;
description
"A list of nexthop objects.";
uses frr-nexthop-attributes;

View File

@ -72,6 +72,35 @@ module frr-routing {
"This identity represents an IPv6 address family.";
}
identity afi-safi-type {
description
"Base identity type (AFI,SAFI) tuples for RIB";
}
identity ipv4-unicast {
base afi-safi-type;
description
"This identity represents the IPv4 unicast address family.";
}
identity ipv6-unicast {
base afi-safi-type;
description
"This identity represents the IPv6 unicast address family.";
}
identity ipv4-multicast {
base afi-safi-type;
description
"This identity represents the IPv4 multicast address family.";
}
identity ipv6-multicast {
base afi-safi-type;
description
"This identity represents the IPv6 multicast address family.";
}
identity control-plane-protocol {
description
"Base identity from which control-plane protocol identities are
@ -150,7 +179,7 @@ module frr-routing {
instance.";
}
leaf vrf {
type frr-vrf:vrf-ref;
type string;
description
"vrf for control-plane protocol";
}

View File

@ -1,11 +1,10 @@
module frr-staticd {
yang-version "1.1";
yang-version 1.1;
namespace "http://frrouting.org/yang/staticd";
prefix frr-staticd;
import frr-routing {
prefix "frr-rt";
prefix frr-rt;
}
import frr-nexthop {
@ -18,11 +17,9 @@ module frr-staticd {
organization
"FRRouting";
contact
"FRR Users List: <mailto:frog@lists.frrouting.org>
FRR Development List: <mailto:dev@lists.frrouting.org>";
description
"This module defines a model for managing FRR staticd information.
This YANG module augments the ietf-routing with additional
@ -58,52 +55,77 @@ module frr-staticd {
"Initial revision.";
}
identity static {
identity staticd {
base frr-rt:routing-protocol;
description
"'Static' routing pseudo-protocol.";
"'Staticd' routing pseudo-protocol.";
}
augment "/frr-rt:routing/frr-rt:control-plane-protocols/"
+ "frr-rt:control-plane-protocol" {
container staticd {
when "../frr-rt:type = 'frr-staticd:static'" {
grouping staticd-prefix-attributes {
list path-list {
key "distance";
leaf distance {
type frr-rt:administrative-distance;
description
"This container is only valid for the 'static' routing
"Admin distance associated with this route.";
}
leaf tag {
type uint32;
default "0";
description
"Route tag";
}
leaf table-id {
type uint32;
default "0";
description
"Table-id";
}
uses frr-nexthop:frr-nexthop;
}
}
augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol" {
container staticd {
when "../frr-rt:type = 'frr-staticd:staticd'" {
description
"This container is only valid for the 'staticd' routing
protocol.";
}
description
"Support for a 'static' pseudo-protocol instance
consists of a list of routes.";
list prefix-list {
key "destination-prefix";
"Support for a 'staticd' pseudo-protocol instance
consists of a list of routes.";
list route-list {
key "prefix afi-safi";
description
"List of static IP routes.";
leaf destination-prefix {
type inet:ip-address;
"List of staticd IP routes.";
leaf prefix {
type inet:ip-prefix;
description
"IP destination prefix.";
"IP prefix.";
}
leaf distance {
type frr-rt:administrative-distance;
description
"Admin distance associated with this route.";
}
leaf tag {
type uint32 {
range "1..4294967295";
leaf afi-safi {
type identityref {
base frr-rt:afi-safi-type;
}
description
"Route tag";
"AFI-SAFI type.";
}
container frr-staticd-next-hop {
description
"Augment static route configuration 'nexthop-list'.";
uses frr-nexthop:frr-nexthop;
uses staticd-prefix-attributes;
list src-list {
key "src-prefix";
leaf src-prefix {
type inet:ipv6-prefix;
description
"IPv6 source prefix";
}
uses staticd-prefix-attributes;
}
}
}

View File

@ -77,35 +77,6 @@ module frr-zebra {
"Initial revision.";
}
identity afi-safi-type {
description
"Base identity type (AFI,SAFI) tuples for RIB";
}
identity ipv4-unicast {
base afi-safi-type;
description
"This identity represents the IPv4 unicast address family.";
}
identity ipv6-unicast {
base afi-safi-type;
description
"This identity represents the IPv6 unicast address family.";
}
identity ipv4-multicast {
base afi-safi-type;
description
"This identity represents the IPv4 multicast address family.";
}
identity ipv6-multicast {
base afi-safi-type;
description
"This identity represents the IPv6 multicast address family.";
}
typedef unix-timestamp {
type uint32;
units "seconds";
@ -634,7 +605,7 @@ module frr-zebra {
key "afi-safi-name table-id";
leaf afi-safi-name {
type identityref {
base afi-safi-type;
base frr-rt:afi-safi-type;
}
description
"AFI, SAFI name.";

View File

@ -35,6 +35,7 @@
#include "vrf.h"
#include "libfrr.h"
#include "routemap.h"
#include "routing_nb.h"
#include "zebra/zebra_router.h"
#include "zebra/zebra_errors.h"
@ -258,6 +259,7 @@ static const struct frr_yang_module_info *const zebra_yang_modules[] = {
&frr_route_map_info,
&frr_zebra_info,
&frr_vrf_info,
&frr_routing_info,
};
FRR_DAEMON_INFO(

View File

@ -22,40 +22,6 @@
#include "libfrr.h"
#include "zebra_nb.h"
const char *zebra_afi_safi_value2identity(afi_t afi, safi_t safi)
{
if (afi == AFI_IP && safi == SAFI_UNICAST)
return "ipv4-unicast";
if (afi == AFI_IP6 && safi == SAFI_UNICAST)
return "ipv6-unicast";
if (afi == AFI_IP && safi == SAFI_MULTICAST)
return "ipv4-multicast";
if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
return "ipv6-multicast";
return " ";
}
void zebra_afi_safi_identity2value(const char *key, afi_t *afi, safi_t *safi)
{
if (strmatch(key, "frr-zebra:ipv4-unicast")) {
*afi = AFI_IP;
*safi = SAFI_UNICAST;
} else if (strmatch(key, "frr-zebra:ipv6-unicast")) {
*afi = AFI_IP6;
*safi = SAFI_UNICAST;
} else if (strmatch(key, "frr-zebra:ipv4-multicast")) {
*afi = AFI_IP;
*safi = SAFI_MULTICAST;
} else if (strmatch(key, "frr-zebra:ipv6-multicast")) {
*afi = AFI_IP6;
*safi = SAFI_MULTICAST;
} else {
*afi = AFI_UNSPEC;
*safi = SAFI_UNSPEC;
}
}
/* clang-format off */
const struct frr_yang_module_info frr_zebra_info = {
.name = "frr-zebra",

View File

@ -26,10 +26,6 @@ extern "C" {
extern const struct frr_yang_module_info frr_zebra_info;
/* helper functions */
const char *zebra_afi_safi_value2identity(afi_t afi, safi_t safi);
void zebra_afi_safi_identity2value(const char *key, afi_t *afi, safi_t *safi);
/* prototypes */
int get_route_information_rpc(struct nb_cb_rpc_args *args);
int get_v6_mroute_info_rpc(struct nb_cb_rpc_args *args);

View File

@ -1242,7 +1242,7 @@ int lib_vrf_zebra_ribs_rib_create(struct nb_cb_create_args *args)
table_id = zvrf->table_id;
afi_safi_name = yang_dnode_get_string(args->dnode, "./afi-safi-name");
zebra_afi_safi_identity2value(afi_safi_name, &afi, &safi);
yang_afi_safi_identity2value(afi_safi_name, &afi, &safi);
zrt = zebra_router_find_zrt(zvrf, table_id, afi, safi);

View File

@ -185,9 +185,8 @@ int lib_vrf_zebra_ribs_rib_get_keys(struct nb_cb_get_keys_args *args)
args->keys->num = 2;
snprintfrr(args->keys->key[0], sizeof(args->keys->key[0]), "%s:%s",
"frr-zebra",
zebra_afi_safi_value2identity(zrt->afi, zrt->safi));
snprintfrr(args->keys->key[0], sizeof(args->keys->key[0]), "%s",
yang_afi_safi_value2identity(zrt->afi, zrt->safi));
snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), "%u",
zrt->tableid);
@ -205,7 +204,7 @@ lib_vrf_zebra_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args)
zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id);
zebra_afi_safi_identity2value(args->keys->key[0], &afi, &safi);
yang_afi_safi_identity2value(args->keys->key[0], &afi, &safi);
table_id = yang_str2uint32(args->keys->key[1]);
/* table_id 0 assume vrf's table_id. */
if (!table_id)