staticd : Configuration northbound implementation

1. Modifies the data structs to make the distance, tag and table-id
   property of a route, i.e created a hireachical data struct to save
   route and nexthop information.
2. Backend northbound implementation

Signed-off-by: VishalDhingra <vdhingra@vmware.com>
This commit is contained in:
vdhingra 2020-04-24 05:38:43 -07:00
parent 7441ea1afd
commit 88fa5104a0
19 changed files with 2742 additions and 1139 deletions

View file

@ -1,3 +1,21 @@
/*
* 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 "northbound.h"
#include "libfrr.h" #include "libfrr.h"
#include "routing_nb.h" #include "routing_nb.h"

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); srcdest2str(dst_p, (const struct prefix_ipv6 *)src_p, buf, bsz);
return 2; 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)); return route_table_get_info(srcdest_rnode_table(rn));
} }
extern struct route_table *srcdest_srcnode_table(struct route_node *rn);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

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

View file

@ -25,4 +25,4 @@
DEFINE_MGROUP(STATIC, "staticd") 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_MGROUP(STATIC)
DECLARE_MTYPE(STATIC_ROUTE); DECLARE_MTYPE(STATIC_NEXTHOP);
DECLARE_MTYPE(STATIC_PATH);
#endif #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']" \
"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']" \
"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

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

View file

@ -32,256 +32,328 @@
#include "static_memory.h" #include "static_memory.h"
#include "static_zebra.h" #include "static_zebra.h"
/* Install static route into rib. */ DEFINE_MTYPE_STATIC(STATIC, STATIC_ROUTE, "Static Route Info");
static void static_install_route(struct route_node *rn, DEFINE_MTYPE(STATIC, STATIC_PATH, "Static Path");
struct static_route *si_changed, safi_t safi)
/* 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) frr_each(static_nexthop_list, &pn->nexthop_list, nh)
static_zebra_nht_register(rn, si, true); static_zebra_nht_register(rn, nh, true);
si = rn->info;
if (si)
static_zebra_route_add(rn, si_changed, si->vrf_id, safi, 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. */ /* Uninstall static path from RIB. */
static void static_uninstall_route(vrf_id_t vrf_id, safi_t safi, static void static_uninstall_path(struct route_node *rn, struct static_path *pn,
struct route_node *rn, safi_t safi, struct static_vrf *svrf)
struct static_route *si_changed)
{ {
if (static_nexthop_list_count(&pn->nexthop_list))
if (rn->info) static_zebra_route_add(rn, pn, safi, true);
static_zebra_route_add(rn, si_changed, vrf_id, safi, true);
else 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 route_node *static_add_route(afi_t afi, safi_t safi, struct prefix *p,
struct prefix_ipv6 *src_p, union g_addr *gate, struct prefix_ipv6 *src_p,
const char *ifname, enum static_blackhole_type bh_type, struct static_vrf *svrf)
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 *rn; struct route_node *rn;
struct static_route *si; struct static_route_info *si;
struct static_route *pp;
struct static_route *cp;
struct static_route *update = NULL;
struct route_table *stable = svrf->stable[afi][safi]; struct route_table *stable = svrf->stable[afi][safi];
struct interface *ifp;
if (!stable) if (!stable)
return -1; return NULL;
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;
/* Lookup static route prefix. */ /* Lookup static route prefix. */
rn = srcdest_rnode_get(stable, p, src_p); rn = srcdest_rnode_get(stable, p, src_p);
/* Do nothing if there is a same static route. */ si = XCALLOC(MTYPE_STATIC_ROUTE, sizeof(struct static_route_info));
for (si = rn->info; si; si = si->next) { static_route_info_init(si);
if (type == si->type
&& (!gate rn->info = si;
|| ((afi == AFI_IP
&& IPV4_ADDR_SAME(&gate->ipv4, &si->addr.ipv4)) /* Mark as having FRR configuration */
|| (afi == AFI_IP6 vrf_set_user_cfged(svrf->vrf);
&& IPV6_ADDR_SAME(gate, &si->addr.ipv6))))
&& (!strcmp(ifname ? ifname : "", si->ifname)) return rn;
&& nh_svrf->vrf->vrf_id == si->nh_vrf_id) { }
if ((distance == si->distance) && (tag == si->tag)
&& (table_id == si->table_id) /* To delete the srcnodes */
&& !memcmp(&si->snh_label, snh_label, static void static_del_src_route(struct route_node *rn, safi_t safi,
sizeof(struct static_nh_label)) struct static_vrf *svrf)
&& si->bh_type == bh_type && si->onlink == onlink) { {
route_unlock_node(rn); struct static_path *pn;
return 0; struct static_route_info *si;
}
update = 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. */ XFREE(MTYPE_STATIC_ROUTE, rn->info);
if (update) route_unlock_node(rn);
static_delete_route(afi, safi, type, p, src_p, gate, ifname, /* If no other FRR config for this VRF, mark accordingly. */
update->tag, update->distance, svrf, if (!static_vrf_has_config(svrf))
&update->snh_label, table_id); 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. */ /* 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; pn->distance = distance;
si->distance = distance; static_nexthop_list_init(&(pn->nexthop_list));
si->bh_type = bh_type;
si->tag = tag; si = rn->info;
si->vrf_id = svrf->vrf->vrf_id; static_path_list_add_head(&(si->path_list), pn);
si->nh_vrf_id = nh_svrf->vrf->vrf_id;
strlcpy(si->nh_vrfname, nh_svrf->vrf->name, sizeof(si->nh_vrfname)); return pn;
si->table_id = table_id; }
si->onlink = onlink;
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) if (ifname)
strlcpy(si->ifname, ifname, sizeof(si->ifname)); strlcpy(nh->ifname, ifname, sizeof(nh->ifname));
si->ifindex = IFINDEX_INTERNAL; nh->ifindex = IFINDEX_INTERNAL;
switch (type) { switch (type) {
case STATIC_IPV4_GATEWAY: case STATIC_IPV4_GATEWAY:
case STATIC_IPV4_GATEWAY_IFNAME: case STATIC_IPV4_GATEWAY_IFNAME:
si->addr.ipv4 = gate->ipv4; nh->addr.ipv4 = ipaddr->ipaddr_v4;
break; break;
case STATIC_IPV6_GATEWAY: case STATIC_IPV6_GATEWAY:
case STATIC_IPV6_GATEWAY_IFNAME: case STATIC_IPV6_GATEWAY_IFNAME:
si->addr.ipv6 = gate->ipv6; nh->addr.ipv6 = ipaddr->ipaddr_v6;
break; break;
case STATIC_IFNAME: default:
break; 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 * 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) { frr_each(static_nexthop_list, &pn->nexthop_list, cp) {
if (si->distance < cp->distance) if (nh->type == STATIC_IPV4_GATEWAY
break;
if (si->distance > cp->distance)
continue;
if (si->type == STATIC_IPV4_GATEWAY
&& cp->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)) < ntohl(cp->addr.ipv4.s_addr))
break; break;
if (ntohl(si->addr.ipv4.s_addr) if (ntohl(nh->addr.ipv4.s_addr)
> ntohl(cp->addr.ipv4.s_addr)) > ntohl(cp->addr.ipv4.s_addr))
continue; continue;
} }
} }
static_nexthop_list_add_after(&(pn->nexthop_list), cp, nh);
/* Make linked list. */ if (nh_svrf->vrf->vrf_id == VRF_UNKNOWN)
if (pp) return nh;
pp->next = si;
else
rn->info = si;
if (cp)
cp->prev = si;
si->prev = pp;
si->next = cp;
/* check whether interface exists in system & install if it does */ /* check whether interface exists in system & install if it does */
switch (si->type) { switch (nh->type) {
case STATIC_IPV4_GATEWAY: case STATIC_IPV4_GATEWAY:
case STATIC_IPV6_GATEWAY: case STATIC_IPV6_GATEWAY:
static_zebra_nht_register(rn, si, true);
break; break;
case STATIC_IPV4_GATEWAY_IFNAME: case STATIC_IPV4_GATEWAY_IFNAME:
case STATIC_IPV6_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) if (ifp && ifp->ifindex != IFINDEX_INTERNAL)
si->ifindex = ifp->ifindex; nh->ifindex = ifp->ifindex;
else else
zlog_warn("Static Route using %s interface not installed because the interface does not exist in specified vrf", zlog_warn(
ifname); "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; break;
case STATIC_BLACKHOLE: case STATIC_BLACKHOLE:
static_install_route(rn, si, safi);
break; break;
case STATIC_IFNAME: case STATIC_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) { if (ifp && ifp->ifindex != IFINDEX_INTERNAL) {
si->ifindex = ifp->ifindex; nh->ifindex = ifp->ifindex;
static_install_route(rn, si, safi);
} else } else
zlog_warn("Static Route using %s interface not installed because the interface does not exist in specified vrf", zlog_warn(
ifname); "Static Route using %s interface not installed because the interface does not exist in specified vrf",
ifname);
break; break;
} }
return 1; return nh;
} }
int static_delete_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p, void static_install_nexthop(struct route_node *rn, struct static_path *pn,
struct prefix_ipv6 *src_p, union g_addr *gate, struct static_nexthop *nh, safi_t safi,
const char *ifname, route_tag_t tag, uint8_t distance, struct static_vrf *svrf, const char *ifname,
struct static_vrf *svrf, static_types type, const char *nh_vrf)
struct static_nh_label *snh_label,
uint32_t table_id)
{ {
struct route_node *rn; struct static_vrf *nh_svrf;
struct static_route *si; struct interface *ifp;
struct route_table *stable;
/* Lookup table. */ nh_svrf = static_vty_get_unknown_vrf(nh_vrf);
stable = static_vrf_static_table(afi, safi, svrf);
if (!stable)
return -1;
/* Lookup static route prefix. */ if (!nh_svrf)
rn = srcdest_rnode_lookup(stable, p, src_p); return;
if (!rn)
return 0;
/* Find same static route is the tree */ if (nh_svrf->vrf->vrf_id == VRF_UNKNOWN)
for (si = rn->info; si; si = si->next) return;
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;
/* Can't find static route. */ /* check whether interface exists in system & install if it does */
if (!si) { switch (nh->type) {
route_unlock_node(rn); case STATIC_IPV4_GATEWAY:
return 0; 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. */ nh_svrf = static_vrf_lookup_by_name(nh->nh_vrfname);
if (si->prev)
si->prev->next = si->next;
else
rn->info = si->next;
if (si->next)
si->next->prev = si->prev;
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 * If we have other si nodes then route replace
* else delete the route * else delete the route
*/ */
static_uninstall_route(si->vrf_id, safi, rn, si); static_uninstall_path(rn, pn, safi, svrf);
route_unlock_node(rn);
EXIT:
route_unlock_node(rn);
/* Free static route configuration. */ /* Free static route configuration. */
XFREE(MTYPE_STATIC_ROUTE, si); XFREE(MTYPE_STATIC_NEXTHOP, nh);
route_unlock_node(rn);
return 1; return 1;
} }
@ -291,8 +363,10 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi,
{ {
struct route_table *stable; struct route_table *stable;
struct route_node *rn; struct route_node *rn;
struct static_route *si; struct static_nexthop *nh;
struct static_path *pn;
struct vrf *vrf; struct vrf *vrf;
struct static_route_info *si;
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
struct static_vrf *svrf; struct static_vrf *svrf;
@ -302,26 +376,34 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi,
stable = static_vrf_static_table(afi, safi, svrf); stable = static_vrf_static_table(afi, safi, svrf);
if (!stable) if (!stable)
continue; continue;
for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) { for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) {
for (si = rn->info; si; si = si->next) { si = static_route_info_from_rnode(rn);
if (!si->ifname[0]) if (!si)
continue; continue;
if (up) { frr_each(static_path_list, &si->path_list, pn) {
if (strcmp(si->ifname, ifp->name)) frr_each(static_nexthop_list,
&pn->nexthop_list, nh) {
if (!nh->ifname[0])
continue; continue;
if (si->nh_vrf_id != ifp->vrf_id) if (up) {
continue; if (strcmp(nh->ifname,
si->ifindex = ifp->ifindex; ifp->name))
} else { continue;
if (si->ifindex != ifp->ifindex) if (nh->nh_vrf_id
continue; != ifp->vrf_id)
if (si->nh_vrf_id != ifp->vrf_id) continue;
continue; nh->ifindex = ifp->ifindex;
si->ifindex = IFINDEX_INTERNAL; } else {
} if (nh->ifindex != ifp->ifindex)
continue;
if (nh->nh_vrf_id
!= ifp->vrf_id)
continue;
nh->ifindex = IFINDEX_INTERNAL;
}
static_install_route(rn, si, safi); static_install_path(rn, pn, safi, svrf);
}
} }
} }
} }
@ -343,26 +425,34 @@ static void static_fixup_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 route_node *rn;
struct static_route *si; struct static_nexthop *nh;
struct interface *ifp; struct interface *ifp;
struct static_path *pn;
struct static_route_info *si;
for (rn = route_top(stable); rn; rn = route_next(rn)) { for (rn = route_top(stable); rn; rn = route_next(rn)) {
for (si = rn->info; si; si = si->next) { si = static_route_info_from_rnode(rn);
if (strcmp(svrf->vrf->name, si->nh_vrfname) != 0) if (!si)
continue; continue;
frr_each(static_path_list, &si->path_list, pn) {
si->nh_vrf_id = svrf->vrf->vrf_id; frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
si->nh_registered = false; if (strcmp(svrf->vrf->name, nh->nh_vrfname)
if (si->ifindex) { != 0)
ifp = if_lookup_by_name(si->ifname,
si->nh_vrf_id);
if (ifp)
si->ifindex = ifp->ifindex;
else
continue; 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 +467,31 @@ static void static_fixup_vrf(struct static_vrf *svrf,
* safi -> the safi in question * safi -> the safi in question
*/ */
static void static_enable_vrf(struct static_vrf *svrf, static void static_enable_vrf(struct static_vrf *svrf,
struct route_table *stable, struct route_table *stable, afi_t afi,
afi_t afi, safi_t safi) safi_t safi)
{ {
struct route_node *rn; struct route_node *rn;
struct static_route *si; struct static_nexthop *nh;
struct interface *ifp; 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 (rn = route_top(stable); rn; rn = route_next(rn)) {
for (si = rn->info; si; si = si->next) { si = static_route_info_from_rnode(rn);
si->vrf_id = vrf->vrf_id; if (!si)
if (si->ifindex) { continue;
ifp = if_lookup_by_name(si->ifname, frr_each(static_path_list, &si->path_list, pn) {
si->nh_vrf_id); frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
if (ifp) if (nh->ifindex) {
si->ifindex = ifp->ifindex; ifp = if_lookup_by_name(nh->ifname,
else nh->nh_vrf_id);
continue; if (ifp)
nh->ifindex = ifp->ifindex;
else
continue;
}
static_install_path(rn, pn, safi, svrf);
} }
static_install_route(rn, si, safi);
} }
} }
} }
@ -452,14 +547,22 @@ static void static_cleanup_vrf(struct static_vrf *svrf,
afi_t afi, safi_t safi) afi_t afi, safi_t safi)
{ {
struct route_node *rn; 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 (rn = route_top(stable); rn; rn = route_next(rn)) {
for (si = rn->info; si; si = si->next) { si = static_route_info_from_rnode(rn);
if (strcmp(svrf->vrf->name, si->nh_vrfname) != 0) if (!si)
continue; 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 +579,23 @@ static void static_disable_vrf(struct route_table *stable,
afi_t afi, safi_t safi) afi_t afi, safi_t safi)
{ {
struct route_node *rn; 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)) info = route_table_get_info(stable);
for (si = rn->info; si; si = si->next)
static_uninstall_route(si->vrf_id, safi, rn, si); 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 +650,27 @@ static void static_fixup_intf_nh(struct route_table *stable,
afi_t afi, safi_t safi) afi_t afi, safi_t safi)
{ {
struct route_node *rn; 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 (rn = route_top(stable); rn; rn = route_next(rn)) {
for (si = rn->info; si; si = si->next) { si = static_route_info_from_rnode(rn);
if (si->nh_vrf_id != ifp->vrf_id) if (!si)
continue; 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) if (nh->ifindex != ifp->ifindex)
continue; continue;
static_install_route(rn, si, safi); static_install_path(rn, pn, safi, info->svrf);
}
} }
} }
} }
@ -589,3 +714,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_UNICAST);
static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_MULTICAST); 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__ #define __STATIC_ROUTES_H__
#include "lib/mpls.h" #include "lib/mpls.h"
#include "table.h"
/* Static route label information */ /* Static route label information */
struct static_nh_label { struct static_nh_label {
@ -35,13 +36,17 @@ enum static_blackhole_type {
STATIC_BLACKHOLE_REJECT STATIC_BLACKHOLE_REJECT
}; };
/*
* The order for below macros should be in sync with
* yang model typedef nexthop-type
*/
typedef enum { typedef enum {
STATIC_IFNAME, STATIC_IFNAME = 1,
STATIC_IPV4_GATEWAY, STATIC_IPV4_GATEWAY,
STATIC_IPV4_GATEWAY_IFNAME, STATIC_IPV4_GATEWAY_IFNAME,
STATIC_BLACKHOLE,
STATIC_IPV6_GATEWAY, STATIC_IPV6_GATEWAY,
STATIC_IPV6_GATEWAY_IFNAME, STATIC_IPV6_GATEWAY_IFNAME,
STATIC_BLACKHOLE,
} static_types; } static_types;
/* /*
@ -64,14 +69,37 @@ enum static_install_states {
STATIC_NOT_INSTALLED, 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. */ /* Static route information. */
struct static_route { struct static_nexthop {
/* For linked list. */ /* For linked list. */
struct static_route *prev; struct static_nexthop_list_item list;
struct static_route *next;
/* VRF identifier. */ /* VRF identifier. */
vrf_id_t vrf_id;
vrf_id_t nh_vrf_id; vrf_id_t nh_vrf_id;
char nh_vrfname[VRF_NAMSIZ + 1]; char nh_vrfname[VRF_NAMSIZ + 1];
@ -81,12 +109,6 @@ struct static_route {
*/ */
enum static_install_states state; enum static_install_states state;
/* Administrative distance. */
uint8_t distance;
/* Tag */
route_tag_t tag;
/* Flag for this static route's type. */ /* Flag for this static route's type. */
static_types type; static_types type;
@ -104,8 +126,6 @@ struct static_route {
/* Label information */ /* Label information */
struct static_nh_label snh_label; struct static_nh_label snh_label;
uint32_t table_id;
/* /*
* Whether to pretend the nexthop is directly attached to the specified * Whether to pretend the nexthop is directly attached to the specified
* link. Only meaningful when both a gateway address and interface name * link. Only meaningful when both a gateway address and interface name
@ -114,32 +134,64 @@ struct static_route {
bool onlink; 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 bool mpls_enabled;
extern struct zebra_privs_t static_privs; extern struct zebra_privs_t static_privs;
void static_fixup_vrf_ids(struct static_vrf *svrf); void static_fixup_vrf_ids(struct static_vrf *svrf);
extern int static_add_route(afi_t afi, safi_t safi, uint8_t type, extern struct static_nexthop *
struct prefix *p, struct prefix_ipv6 *src_p, static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi,
union g_addr *gate, const char *ifname, struct static_vrf *svrf, static_types type,
enum static_blackhole_type bh_type, route_tag_t tag, struct ipaddr *ipaddr, const char *ifname,
uint8_t distance, struct static_vrf *svrf, const char *nh_vrf);
struct static_vrf *nh_svrf, extern void static_install_nexthop(struct route_node *rn,
struct static_nh_label *snh_label, struct static_path *pn,
uint32_t table_id, bool onlink); 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, extern int static_delete_nexthop(struct route_node *rn, struct static_path *pn,
struct prefix *p, struct prefix_ipv6 *src_p, safi_t safi, struct static_vrf *svrf,
union g_addr *gate, const char *ifname, struct static_nexthop *nh);
route_tag_t tag, uint8_t distance,
struct static_vrf *svrf,
struct static_nh_label *snh_label,
uint32_t table_id);
extern void static_cleanup_vrf_ids(struct static_vrf *disable_svrf); extern void static_cleanup_vrf_ids(struct static_vrf *disable_svrf);
extern void static_install_intf_nh(struct interface *ifp); extern void static_install_intf_nh(struct interface *ifp);
extern void static_ifindex_update(struct interface *ifp, bool up); 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 #endif

View file

@ -30,26 +30,39 @@
#include "static_zebra.h" #include "static_zebra.h"
#include "static_vty.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, static void zebra_stable_node_cleanup(struct route_table *table,
struct route_node *node) 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) si = node->info;
for (si = node->info; si; si = next) {
next = si->next; if (si) {
XFREE(MTYPE_STATIC_ROUTE, 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) static struct static_vrf *static_vrf_alloc(void)
{ {
struct route_table *table; struct route_table *table;
struct static_vrf *svrf; struct static_vrf *svrf;
struct stable_info *info;
safi_t safi; safi_t safi;
afi_t afi; 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 (afi = AFI_IP; afi <= AFI_IP6; afi++) {
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
@ -57,6 +70,14 @@ static struct static_vrf *static_vrf_alloc(void)
table = srcdest_table_init(); table = srcdest_table_init();
else else
table = route_table_init(); 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; table->cleanup = zebra_stable_node_cleanup;
svrf->stable[afi][safi] = table; svrf->stable[afi][safi] = table;
} }
@ -81,12 +102,6 @@ static int static_vrf_enable(struct vrf *vrf)
static_fixup_vrf_ids(vrf->info); 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; return 0;
} }
@ -102,16 +117,19 @@ static int static_vrf_delete(struct vrf *vrf)
struct static_vrf *svrf; struct static_vrf *svrf;
safi_t safi; safi_t safi;
afi_t afi; afi_t afi;
void *info;
svrf = vrf->info; svrf = vrf->info;
for (afi = AFI_IP; afi <= AFI_IP6; afi++) { for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
table = svrf->stable[afi][safi]; table = svrf->stable[afi][safi];
info = route_table_get_info(table);
route_table_finish(table); route_table_finish(table);
XFREE(MTYPE_STATIC_RTABLE_INFO, info);
svrf->stable[afi][safi] = NULL; svrf->stable[afi][safi] = NULL;
} }
} }
XFREE(MTYPE_TMP, svrf); XFREE(MTYPE_STATIC_RTABLE_INFO, svrf);
return 0; return 0;
} }
@ -210,3 +228,25 @@ void static_vrf_terminate(void)
{ {
vrf_terminate(); 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 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_name(const char *vrf_name);
struct static_vrf *static_vrf_lookup_by_id(vrf_id_t vrf_id); 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 route_table *static_vrf_static_table(afi_t afi, safi_t safi,
struct static_vrf *svrf); struct static_vrf *svrf);
extern void static_vrf_terminate(void); extern void static_vrf_terminate(void);
struct static_vrf *static_vty_get_unknown_vrf(const char *vrf_name);
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -19,8 +19,6 @@
#ifndef __STATIC_VTY_H__ #ifndef __STATIC_VTY_H__
#define __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, int static_config(struct vty *vty, struct static_vrf *svrf,
afi_t afi, safi_t safi, const char *cmd); 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); struct static_vrf *svrf = static_vrf_lookup_by_id(ifp->vrf_id);
static_fixup_vrf_ids(svrf); static_fixup_vrf_ids(svrf);
static_config_install_delayed_routes(svrf);
} }
/* Install any static reliant on this interface coming up */ /* 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); XFREE(MTYPE_TMP, nhtd);
} }
void static_zebra_nht_register(struct route_node *rn, void static_zebra_nht_register(struct route_node *rn, struct static_nexthop *nh,
struct static_route *si, bool reg) bool reg)
{ {
struct static_nht_data *nhtd, lookup; struct static_nht_data *nhtd, lookup;
uint32_t cmd; uint32_t cmd;
@ -276,14 +275,14 @@ void static_zebra_nht_register(struct route_node *rn,
cmd = (reg) ? cmd = (reg) ?
ZEBRA_NEXTHOP_REGISTER : ZEBRA_NEXTHOP_UNREGISTER; ZEBRA_NEXTHOP_REGISTER : ZEBRA_NEXTHOP_UNREGISTER;
if (si->nh_registered && reg) if (nh->nh_registered && reg)
return; return;
if (!si->nh_registered && !reg) if (!nh->nh_registered && !reg)
return; return;
memset(&p, 0, sizeof(p)); memset(&p, 0, sizeof(p));
switch (si->type) { switch (nh->type) {
case STATIC_IFNAME: case STATIC_IFNAME:
case STATIC_BLACKHOLE: case STATIC_BLACKHOLE:
return; return;
@ -291,23 +290,23 @@ void static_zebra_nht_register(struct route_node *rn,
case STATIC_IPV4_GATEWAY_IFNAME: case STATIC_IPV4_GATEWAY_IFNAME:
p.family = AF_INET; p.family = AF_INET;
p.prefixlen = IPV4_MAX_BITLEN; p.prefixlen = IPV4_MAX_BITLEN;
p.u.prefix4 = si->addr.ipv4; p.u.prefix4 = nh->addr.ipv4;
afi = AFI_IP; afi = AFI_IP;
break; break;
case STATIC_IPV6_GATEWAY: case STATIC_IPV6_GATEWAY:
case STATIC_IPV6_GATEWAY_IFNAME: case STATIC_IPV6_GATEWAY_IFNAME:
p.family = AF_INET6; p.family = AF_INET6;
p.prefixlen = IPV6_MAX_BITLEN; p.prefixlen = IPV6_MAX_BITLEN;
p.u.prefix6 = si->addr.ipv6; p.u.prefix6 = nh->addr.ipv6;
afi = AFI_IP6; afi = AFI_IP6;
break; break;
} }
memset(&lookup, 0, sizeof(lookup)); memset(&lookup, 0, sizeof(lookup));
lookup.nh = &p; 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) { if (reg) {
nhtd = hash_get(static_nht_hash, &lookup, 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, zlog_debug("Registered nexthop(%pFX) for %pRN %d", &p,
rn, nhtd->nh_num); rn, nhtd->nh_num);
if (nhtd->refcount > 1 && nhtd->nh_num) { if (nhtd->refcount > 1 && nhtd->nh_num) {
static_nht_update(&rn->p, nhtd->nh, nhtd->nh_num, static_nht_update(&rn->p, nhtd->nh, nhtd->nh_num, afi,
afi, si->nh_vrf_id); nh->nh_vrf_id);
return; return;
} }
} else { } else {
@ -335,25 +334,72 @@ void static_zebra_nht_register(struct route_node *rn,
static_nht_hash_free(nhtd); 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__); 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, extern void static_zebra_route_add(struct route_node *rn,
struct static_route *si_changed, struct static_path *pn, safi_t safi,
vrf_id_t vrf_id, safi_t safi, bool install) bool install)
{ {
struct static_route *si = rn->info; struct static_nexthop *nh;
const struct prefix *p, *src_pp; const struct prefix *p, *src_pp;
struct zapi_nexthop *api_nh; struct zapi_nexthop *api_nh;
struct zapi_route api; struct zapi_route api;
uint32_t nh_num = 0; uint32_t nh_num = 0;
struct stable_info *info;
p = src_pp = NULL; p = src_pp = NULL;
srcdest_rnode_prefixes(rn, &p, &src_pp); srcdest_rnode_prefixes(rn, &p, &src_pp);
memset(&api, 0, sizeof(api)); 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.type = ZEBRA_ROUTE_STATIC;
api.safi = safi; api.safi = safi;
memcpy(&api.prefix, p, sizeof(api.prefix)); 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_RR_USE_DISTANCE);
SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION); SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
if (si_changed->distance) { if (pn->distance) {
SET_FLAG(api.message, ZAPI_MESSAGE_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); 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); 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]; api_nh = &api.nexthops[nh_num];
if (si->nh_vrf_id == VRF_UNKNOWN) if (nh->nh_vrf_id == VRF_UNKNOWN)
continue; continue;
if (si->distance != si_changed->distance) api_nh->vrf_id = nh->nh_vrf_id;
continue; if (nh->onlink)
if (si->table_id != si_changed->table_id)
continue;
api_nh->vrf_id = si->nh_vrf_id;
if (si->onlink)
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_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: case STATIC_IFNAME:
if (si->ifindex == IFINDEX_INTERNAL) if (nh->ifindex == IFINDEX_INTERNAL)
continue; continue;
api_nh->ifindex = si->ifindex; api_nh->ifindex = nh->ifindex;
api_nh->type = NEXTHOP_TYPE_IFINDEX; api_nh->type = NEXTHOP_TYPE_IFINDEX;
break; break;
case STATIC_IPV4_GATEWAY: case STATIC_IPV4_GATEWAY:
if (!si->nh_valid) if (!nh->nh_valid)
continue; continue;
api_nh->type = NEXTHOP_TYPE_IPV4; api_nh->type = NEXTHOP_TYPE_IPV4;
api_nh->gate = si->addr; api_nh->gate = nh->addr;
break; break;
case STATIC_IPV4_GATEWAY_IFNAME: case STATIC_IPV4_GATEWAY_IFNAME:
if (si->ifindex == IFINDEX_INTERNAL) if (nh->ifindex == IFINDEX_INTERNAL)
continue; continue;
api_nh->ifindex = si->ifindex; api_nh->ifindex = nh->ifindex;
api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
api_nh->gate = si->addr; api_nh->gate = nh->addr;
break; break;
case STATIC_IPV6_GATEWAY: case STATIC_IPV6_GATEWAY:
if (!si->nh_valid) if (!nh->nh_valid)
continue; continue;
api_nh->type = NEXTHOP_TYPE_IPV6; api_nh->type = NEXTHOP_TYPE_IPV6;
api_nh->gate = si->addr; api_nh->gate = nh->addr;
break; break;
case STATIC_IPV6_GATEWAY_IFNAME: case STATIC_IPV6_GATEWAY_IFNAME:
if (si->ifindex == IFINDEX_INTERNAL) if (nh->ifindex == IFINDEX_INTERNAL)
continue; continue;
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
api_nh->ifindex = si->ifindex; api_nh->ifindex = nh->ifindex;
api_nh->gate = si->addr; api_nh->gate = nh->addr;
break; break;
case STATIC_BLACKHOLE: case STATIC_BLACKHOLE:
api_nh->type = NEXTHOP_TYPE_BLACKHOLE; api_nh->type = NEXTHOP_TYPE_BLACKHOLE;
switch (si->bh_type) { switch (nh->bh_type) {
case STATIC_BLACKHOLE_DROP: case STATIC_BLACKHOLE_DROP:
case STATIC_BLACKHOLE_NULL: case STATIC_BLACKHOLE_NULL:
api_nh->bh_type = BLACKHOLE_NULL; api_nh->bh_type = BLACKHOLE_NULL;
@ -440,13 +480,13 @@ extern void static_zebra_route_add(struct route_node *rn,
break; break;
} }
if (si->snh_label.num_labels) { if (nh->snh_label.num_labels) {
int i; int i;
SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL); 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++) 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++; nh_num++;
} }

View file

@ -22,13 +22,15 @@
extern struct thread_master *master; extern struct thread_master *master;
extern void static_zebra_nht_register(struct route_node *rn, 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, extern void static_zebra_route_add(struct route_node *rn,
struct static_route *si_changed, struct static_path *pn, safi_t safi,
vrf_id_t vrf_id, safi_t safi, bool install); bool install);
extern void static_zebra_init(void); extern void static_zebra_init(void);
extern void static_zebra_vrf_register(struct vrf *vrf); extern void static_zebra_vrf_register(struct vrf *vrf);
extern void static_zebra_vrf_unregister(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 #endif

View file

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