mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
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:
parent
7441ea1afd
commit
88fa5104a0
|
@ -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 "libfrr.h"
|
||||
#include "routing_nb.h"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -25,4 +25,4 @@
|
|||
|
||||
DEFINE_MGROUP(STATIC, "staticd")
|
||||
|
||||
DEFINE_MTYPE(STATIC, STATIC_ROUTE, "Static Route");
|
||||
DEFINE_MTYPE(STATIC, STATIC_NEXTHOP, "Static Nexthop");
|
||||
|
|
|
@ -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
188
staticd/static_nb.c
Normal 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
166
staticd/static_nb.h
Normal 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
1234
staticd/static_nb_config.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -32,256 +32,328 @@
|
|||
#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;
|
||||
}
|
||||
|
@ -291,8 +363,10 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi,
|
|||
{
|
||||
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 +376,34 @@ 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))
|
||||
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->ifname[0])
|
||||
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;
|
||||
}
|
||||
if (up) {
|
||||
if (strcmp(nh->ifname,
|
||||
ifp->name))
|
||||
continue;
|
||||
if (nh->nh_vrf_id
|
||||
!= ifp->vrf_id)
|
||||
continue;
|
||||
nh->ifindex = ifp->ifindex;
|
||||
} 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_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 +467,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 +547,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 +579,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 +650,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 +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_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));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
1165
staticd/static_vty.c
1165
staticd/static_vty.c
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue