mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-29 07:59:35 +00:00
Merge pull request #15279 from idryzhov/staticd-fixes
several fixes for staticd configuration
This commit is contained in:
commit
22b79197bb
@ -29,6 +29,8 @@ int routing_control_plane_protocols_control_plane_protocol_destroy(
|
|||||||
* based on the control plane protocol
|
* based on the control plane protocol
|
||||||
*/
|
*/
|
||||||
DECLARE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args));
|
DECLARE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args));
|
||||||
|
DECLARE_HOOK(routing_create, (struct nb_cb_create_args *args), (args));
|
||||||
|
DECLARE_KOOH(routing_destroy, (struct nb_cb_destroy_args *args), (args));
|
||||||
|
|
||||||
void routing_control_plane_protocols_register_vrf_dependency(void);
|
void routing_control_plane_protocols_register_vrf_dependency(void);
|
||||||
|
|
||||||
|
@ -14,6 +14,8 @@
|
|||||||
|
|
||||||
|
|
||||||
DEFINE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args));
|
DEFINE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args));
|
||||||
|
DEFINE_HOOK(routing_create, (struct nb_cb_create_args *args), (args));
|
||||||
|
DEFINE_KOOH(routing_destroy, (struct nb_cb_destroy_args *args), (args));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol
|
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol
|
||||||
@ -49,6 +51,7 @@ int routing_control_plane_protocols_control_plane_protocol_create(
|
|||||||
assert(vrf);
|
assert(vrf);
|
||||||
nb_running_set_entry(args->dnode, vrf);
|
nb_running_set_entry(args->dnode, vrf);
|
||||||
}
|
}
|
||||||
|
hook_call(routing_create, args);
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,6 +64,8 @@ int routing_control_plane_protocols_control_plane_protocol_destroy(
|
|||||||
if (args->event != NB_EV_APPLY)
|
if (args->event != NB_EV_APPLY)
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
|
|
||||||
|
hook_call(routing_destroy, args);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If dependency on VRF module is registered, then VRF
|
* If dependency on VRF module is registered, then VRF
|
||||||
* pointer was stored and must be cleared.
|
* pointer was stored and must be cleared.
|
||||||
|
@ -263,14 +263,13 @@ static void static_bfd_show_path_json(struct vty *vty, struct json_object *jo,
|
|||||||
static void static_bfd_show_json(struct vty *vty)
|
static void static_bfd_show_json(struct vty *vty)
|
||||||
{
|
{
|
||||||
struct json_object *jo, *jo_path, *jo_afi_safi;
|
struct json_object *jo, *jo_path, *jo_afi_safi;
|
||||||
struct vrf *vrf;
|
struct static_vrf *svrf;
|
||||||
|
|
||||||
jo = json_object_new_object();
|
jo = json_object_new_object();
|
||||||
jo_path = json_object_new_object();
|
jo_path = json_object_new_object();
|
||||||
|
|
||||||
json_object_object_add(jo, "path-list", jo_path);
|
json_object_object_add(jo, "path-list", jo_path);
|
||||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
RB_FOREACH (svrf, svrf_name_head, &svrfs) {
|
||||||
const struct static_vrf *svrf = vrf->info;
|
|
||||||
struct route_table *rt;
|
struct route_table *rt;
|
||||||
|
|
||||||
jo_afi_safi = json_object_new_array();
|
jo_afi_safi = json_object_new_array();
|
||||||
@ -346,7 +345,7 @@ static void static_bfd_show_path(struct vty *vty, struct route_table *rt)
|
|||||||
|
|
||||||
void static_bfd_show(struct vty *vty, bool json)
|
void static_bfd_show(struct vty *vty, bool json)
|
||||||
{
|
{
|
||||||
struct vrf *vrf;
|
struct static_vrf *svrf;
|
||||||
|
|
||||||
if (json) {
|
if (json) {
|
||||||
static_bfd_show_json(vty);
|
static_bfd_show_json(vty);
|
||||||
@ -355,21 +354,20 @@ void static_bfd_show(struct vty *vty, bool json)
|
|||||||
|
|
||||||
vty_out(vty, "Showing BFD monitored static routes:\n");
|
vty_out(vty, "Showing BFD monitored static routes:\n");
|
||||||
vty_out(vty, "\n Next hops:\n");
|
vty_out(vty, "\n Next hops:\n");
|
||||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
RB_FOREACH (svrf, svrf_name_head, &svrfs) {
|
||||||
const struct static_vrf *svrf = vrf->info;
|
|
||||||
struct route_table *rt;
|
struct route_table *rt;
|
||||||
|
|
||||||
vty_out(vty, " VRF %s IPv4 Unicast:\n", vrf->name);
|
vty_out(vty, " VRF %s IPv4 Unicast:\n", svrf->name);
|
||||||
rt = svrf->stable[AFI_IP][SAFI_UNICAST];
|
rt = svrf->stable[AFI_IP][SAFI_UNICAST];
|
||||||
if (rt)
|
if (rt)
|
||||||
static_bfd_show_path(vty, rt);
|
static_bfd_show_path(vty, rt);
|
||||||
|
|
||||||
vty_out(vty, "\n VRF %s IPv4 Multicast:\n", vrf->name);
|
vty_out(vty, "\n VRF %s IPv4 Multicast:\n", svrf->name);
|
||||||
rt = svrf->stable[AFI_IP][SAFI_MULTICAST];
|
rt = svrf->stable[AFI_IP][SAFI_MULTICAST];
|
||||||
if (rt)
|
if (rt)
|
||||||
static_bfd_show_path(vty, rt);
|
static_bfd_show_path(vty, rt);
|
||||||
|
|
||||||
vty_out(vty, "\n VRF %s IPv6 Unicast:\n", vrf->name);
|
vty_out(vty, "\n VRF %s IPv6 Unicast:\n", svrf->name);
|
||||||
rt = svrf->stable[AFI_IP6][SAFI_UNICAST];
|
rt = svrf->stable[AFI_IP6][SAFI_UNICAST];
|
||||||
if (rt)
|
if (rt)
|
||||||
static_bfd_show_path(vty, rt);
|
static_bfd_show_path(vty, rt);
|
||||||
|
@ -168,8 +168,10 @@ int main(int argc, char **argv, char **envp)
|
|||||||
|
|
||||||
hook_register(routing_conf_event,
|
hook_register(routing_conf_event,
|
||||||
routing_control_plane_protocols_name_validate);
|
routing_control_plane_protocols_name_validate);
|
||||||
|
hook_register(routing_create,
|
||||||
routing_control_plane_protocols_register_vrf_dependency();
|
routing_control_plane_protocols_staticd_create);
|
||||||
|
hook_register(routing_destroy,
|
||||||
|
routing_control_plane_protocols_staticd_destroy);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We set FRR_NO_SPLIT_CONFIG flag to avoid reading our config, but we
|
* We set FRR_NO_SPLIT_CONFIG flag to avoid reading our config, but we
|
||||||
|
@ -13,6 +13,11 @@ extern "C" {
|
|||||||
extern const struct frr_yang_module_info frr_staticd_info;
|
extern const struct frr_yang_module_info frr_staticd_info;
|
||||||
extern const struct frr_yang_module_info frr_staticd_cli_info;
|
extern const struct frr_yang_module_info frr_staticd_cli_info;
|
||||||
|
|
||||||
|
int routing_control_plane_protocols_staticd_create(
|
||||||
|
struct nb_cb_create_args *args);
|
||||||
|
int routing_control_plane_protocols_staticd_destroy(
|
||||||
|
struct nb_cb_destroy_args *args);
|
||||||
|
|
||||||
/* Mandatory callbacks. */
|
/* Mandatory callbacks. */
|
||||||
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
|
||||||
struct nb_cb_create_args *args);
|
struct nb_cb_create_args *args);
|
||||||
|
@ -136,8 +136,7 @@ static bool static_nexthop_create(struct nb_cb_create_args *args)
|
|||||||
switch (args->event) {
|
switch (args->event) {
|
||||||
case NB_EV_VALIDATE:
|
case NB_EV_VALIDATE:
|
||||||
ifname = yang_dnode_get_string(args->dnode, "interface");
|
ifname = yang_dnode_get_string(args->dnode, "interface");
|
||||||
nh_type = yang_dnode_get_enum(args->dnode, "nh-type");
|
if (ifname != NULL) {
|
||||||
if (ifname != NULL && nh_type != STATIC_BLACKHOLE) {
|
|
||||||
if (strcasecmp(ifname, "Null0") == 0
|
if (strcasecmp(ifname, "Null0") == 0
|
||||||
|| strcasecmp(ifname, "reject") == 0
|
|| strcasecmp(ifname, "reject") == 0
|
||||||
|| strcasecmp(ifname, "blackhole") == 0) {
|
|| strcasecmp(ifname, "blackhole") == 0) {
|
||||||
@ -177,6 +176,9 @@ static bool static_nexthop_create(struct nb_cb_create_args *args)
|
|||||||
nh_vrf = yang_dnode_get_string(args->dnode, "vrf");
|
nh_vrf = yang_dnode_get_string(args->dnode, "vrf");
|
||||||
pn = nb_running_get_entry(args->dnode, NULL, true);
|
pn = nb_running_get_entry(args->dnode, NULL, true);
|
||||||
|
|
||||||
|
if (strmatch(ifname, "(null)"))
|
||||||
|
ifname = "";
|
||||||
|
|
||||||
if (!static_add_nexthop_validate(nh_vrf, nh_type, &ipaddr))
|
if (!static_add_nexthop_validate(nh_vrf, nh_type, &ipaddr))
|
||||||
flog_warn(
|
flog_warn(
|
||||||
EC_LIB_NB_CB_CONFIG_VALIDATE,
|
EC_LIB_NB_CB_CONFIG_VALIDATE,
|
||||||
@ -465,33 +467,10 @@ static int static_nexthop_bh_type_modify(struct nb_cb_modify_args *args)
|
|||||||
{
|
{
|
||||||
struct static_nexthop *nh;
|
struct static_nexthop *nh;
|
||||||
enum static_nh_type nh_type;
|
enum static_nh_type nh_type;
|
||||||
const char *nh_ifname;
|
|
||||||
const char *nh_vrf;
|
|
||||||
|
|
||||||
switch (args->event) {
|
switch (args->event) {
|
||||||
case NB_EV_VALIDATE:
|
case NB_EV_VALIDATE:
|
||||||
nh_type = yang_dnode_get_enum(args->dnode, "../nh-type");
|
nh_type = yang_dnode_get_enum(args->dnode, "../nh-type");
|
||||||
nh_ifname = yang_dnode_get_string(args->dnode, "../interface");
|
|
||||||
nh_vrf = yang_dnode_get_string(args->dnode, "../vrf");
|
|
||||||
if (nh_ifname && nh_vrf) {
|
|
||||||
struct vrf *vrf = vrf_lookup_by_name(nh_vrf);
|
|
||||||
|
|
||||||
if (!vrf) {
|
|
||||||
snprintf(args->errmsg, args->errmsg_len,
|
|
||||||
"nexthop vrf %s not found", nh_vrf);
|
|
||||||
return NB_ERR_VALIDATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct interface *ifp = if_lookup_by_name(nh_ifname,
|
|
||||||
vrf->vrf_id);
|
|
||||||
|
|
||||||
if (ifp && (!strmatch(nh_ifname, "blackhole") ||
|
|
||||||
!strmatch(nh_ifname, "reject"))) {
|
|
||||||
snprintf(args->errmsg, args->errmsg_len,
|
|
||||||
"nexthop interface name must be (reject, blackhole)");
|
|
||||||
return NB_ERR_VALIDATION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (nh_type != STATIC_BLACKHOLE) {
|
if (nh_type != STATIC_BLACKHOLE) {
|
||||||
snprintf(args->errmsg, args->errmsg_len,
|
snprintf(args->errmsg, args->errmsg_len,
|
||||||
"nexthop type is not the blackhole type");
|
"nexthop type is not the blackhole type");
|
||||||
@ -561,6 +540,48 @@ int routing_control_plane_protocols_name_validate(
|
|||||||
}
|
}
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* XPath:
|
||||||
|
* /frr-routing:routing/control-plane-protocols/control-plane-protocol
|
||||||
|
*/
|
||||||
|
int routing_control_plane_protocols_staticd_create(struct nb_cb_create_args *args)
|
||||||
|
{
|
||||||
|
struct static_vrf *svrf;
|
||||||
|
const char *vrf;
|
||||||
|
|
||||||
|
vrf = yang_dnode_get_string(args->dnode, "vrf");
|
||||||
|
svrf = static_vrf_alloc(vrf);
|
||||||
|
nb_running_set_entry(args->dnode, svrf);
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int routing_control_plane_protocols_staticd_destroy(
|
||||||
|
struct nb_cb_destroy_args *args)
|
||||||
|
{
|
||||||
|
struct static_vrf *svrf;
|
||||||
|
struct route_table *stable;
|
||||||
|
struct route_node *rn;
|
||||||
|
afi_t afi;
|
||||||
|
safi_t safi;
|
||||||
|
|
||||||
|
svrf = nb_running_unset_entry(args->dnode);
|
||||||
|
|
||||||
|
FOREACH_AFI_SAFI (afi, safi) {
|
||||||
|
stable = svrf->stable[afi][safi];
|
||||||
|
if (!stable)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (rn = route_top(stable); rn; rn = route_next(rn))
|
||||||
|
static_del_route(rn);
|
||||||
|
}
|
||||||
|
|
||||||
|
static_vrf_free(svrf);
|
||||||
|
|
||||||
|
return NB_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XPath:
|
* XPath:
|
||||||
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list
|
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list
|
||||||
@ -568,8 +589,7 @@ int routing_control_plane_protocols_name_validate(
|
|||||||
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
|
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
|
||||||
struct nb_cb_create_args *args)
|
struct nb_cb_create_args *args)
|
||||||
{
|
{
|
||||||
struct vrf *vrf;
|
struct static_vrf *svrf;
|
||||||
struct static_vrf *s_vrf;
|
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
const struct lyd_node *vrf_dnode;
|
const struct lyd_node *vrf_dnode;
|
||||||
struct prefix prefix;
|
struct prefix prefix;
|
||||||
@ -598,15 +618,14 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_cr
|
|||||||
case NB_EV_APPLY:
|
case NB_EV_APPLY:
|
||||||
vrf_dnode = yang_dnode_get_parent(args->dnode,
|
vrf_dnode = yang_dnode_get_parent(args->dnode,
|
||||||
"control-plane-protocol");
|
"control-plane-protocol");
|
||||||
vrf = nb_running_get_entry(vrf_dnode, NULL, true);
|
svrf = nb_running_get_entry(vrf_dnode, NULL, true);
|
||||||
s_vrf = vrf->info;
|
|
||||||
|
|
||||||
yang_dnode_get_prefix(&prefix, args->dnode, "prefix");
|
yang_dnode_get_prefix(&prefix, args->dnode, "prefix");
|
||||||
afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
|
afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
|
||||||
yang_afi_safi_identity2value(afi_safi, &afi, &safi);
|
yang_afi_safi_identity2value(afi_safi, &afi, &safi);
|
||||||
|
|
||||||
rn = static_add_route(afi, safi, &prefix, NULL, s_vrf);
|
rn = static_add_route(afi, safi, &prefix, NULL, svrf);
|
||||||
if (vrf->vrf_id == VRF_UNKNOWN)
|
if (!svrf->vrf || svrf->vrf->vrf_id == VRF_UNKNOWN)
|
||||||
snprintf(
|
snprintf(
|
||||||
args->errmsg, args->errmsg_len,
|
args->errmsg, args->errmsg_len,
|
||||||
"Static Route to %s not installed currently because dependent config not fully available",
|
"Static Route to %s not installed currently because dependent config not fully available",
|
||||||
|
@ -245,21 +245,20 @@ void static_del_path(struct static_path *pn)
|
|||||||
XFREE(MTYPE_STATIC_PATH, pn);
|
XFREE(MTYPE_STATIC_PATH, pn);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct static_nexthop *static_add_nexthop(struct static_path *pn,
|
struct static_nexthop *
|
||||||
enum static_nh_type type,
|
static_add_nexthop(struct static_path *pn, enum static_nh_type type,
|
||||||
struct ipaddr *ipaddr,
|
struct ipaddr *ipaddr, const char *ifname,
|
||||||
const char *ifname,
|
const char *nh_vrfname, uint32_t color)
|
||||||
const char *nh_vrf, uint32_t color)
|
|
||||||
{
|
{
|
||||||
struct route_node *rn = pn->rn;
|
struct route_node *rn = pn->rn;
|
||||||
struct static_nexthop *nh;
|
struct static_nexthop *nh;
|
||||||
struct static_vrf *nh_svrf;
|
struct vrf *nh_vrf;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
struct static_nexthop *cp;
|
struct static_nexthop *cp;
|
||||||
|
|
||||||
route_lock_node(rn);
|
route_lock_node(rn);
|
||||||
|
|
||||||
nh_svrf = static_vrf_lookup_by_name(nh_vrf);
|
nh_vrf = vrf_lookup_by_name(nh_vrfname);
|
||||||
|
|
||||||
/* Make new static route structure. */
|
/* Make new static route structure. */
|
||||||
nh = XCALLOC(MTYPE_STATIC_NEXTHOP, sizeof(struct static_nexthop));
|
nh = XCALLOC(MTYPE_STATIC_NEXTHOP, sizeof(struct static_nexthop));
|
||||||
@ -274,8 +273,8 @@ struct static_nexthop *static_add_nexthop(struct static_path *pn,
|
|||||||
if (nh->type == STATIC_BLACKHOLE)
|
if (nh->type == STATIC_BLACKHOLE)
|
||||||
nh->bh_type = STATIC_BLACKHOLE_NULL;
|
nh->bh_type = STATIC_BLACKHOLE_NULL;
|
||||||
|
|
||||||
nh->nh_vrf_id = nh_svrf ? nh_svrf->vrf->vrf_id : VRF_UNKNOWN;
|
nh->nh_vrf_id = nh_vrf ? nh_vrf->vrf_id : VRF_UNKNOWN;
|
||||||
strlcpy(nh->nh_vrfname, nh_vrf, sizeof(nh->nh_vrfname));
|
strlcpy(nh->nh_vrfname, nh_vrfname, sizeof(nh->nh_vrfname));
|
||||||
|
|
||||||
if (ifname)
|
if (ifname)
|
||||||
strlcpy(nh->ifname, ifname, sizeof(nh->ifname));
|
strlcpy(nh->ifname, ifname, sizeof(nh->ifname));
|
||||||
@ -437,14 +436,10 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi,
|
|||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
struct static_nexthop *nh;
|
struct static_nexthop *nh;
|
||||||
struct static_path *pn;
|
struct static_path *pn;
|
||||||
struct vrf *vrf;
|
struct static_vrf *svrf;
|
||||||
struct static_route_info *si;
|
struct static_route_info *si;
|
||||||
|
|
||||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
RB_FOREACH (svrf, svrf_name_head, &svrfs) {
|
||||||
struct static_vrf *svrf;
|
|
||||||
|
|
||||||
svrf = vrf->info;
|
|
||||||
|
|
||||||
stable = static_vrf_static_table(afi, safi, svrf);
|
stable = static_vrf_static_table(afi, safi, svrf);
|
||||||
if (!stable)
|
if (!stable)
|
||||||
continue;
|
continue;
|
||||||
@ -476,8 +471,8 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi,
|
|||||||
* afi -> The afi to look at
|
* afi -> The afi to look at
|
||||||
* safi -> the safi to look at
|
* safi -> the safi to look at
|
||||||
*/
|
*/
|
||||||
static void static_fixup_vrf(struct static_vrf *svrf,
|
static void static_fixup_vrf(struct vrf *vrf, struct route_table *stable,
|
||||||
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_nexthop *nh;
|
struct static_nexthop *nh;
|
||||||
@ -491,13 +486,12 @@ static void static_fixup_vrf(struct static_vrf *svrf,
|
|||||||
continue;
|
continue;
|
||||||
frr_each(static_path_list, &si->path_list, pn) {
|
frr_each(static_path_list, &si->path_list, pn) {
|
||||||
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
||||||
if (strcmp(svrf->vrf->name, nh->nh_vrfname)
|
if (strcmp(vrf->name, nh->nh_vrfname) != 0)
|
||||||
!= 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
nh->nh_vrf_id = svrf->vrf->vrf_id;
|
nh->nh_vrf_id = vrf->vrf_id;
|
||||||
nh->nh_registered = false;
|
nh->nh_registered = false;
|
||||||
if (nh->ifindex) {
|
if (nh->ifname[0]) {
|
||||||
ifp = if_lookup_by_name(nh->ifname,
|
ifp = if_lookup_by_name(nh->ifname,
|
||||||
nh->nh_vrf_id);
|
nh->nh_vrf_id);
|
||||||
if (ifp)
|
if (ifp)
|
||||||
@ -521,9 +515,7 @@ static void static_fixup_vrf(struct static_vrf *svrf,
|
|||||||
* afi -> the afi in question
|
* afi -> the afi in question
|
||||||
* 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 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_nexthop *nh;
|
struct static_nexthop *nh;
|
||||||
@ -537,7 +529,9 @@ static void static_enable_vrf(struct static_vrf *svrf,
|
|||||||
continue;
|
continue;
|
||||||
frr_each(static_path_list, &si->path_list, pn) {
|
frr_each(static_path_list, &si->path_list, pn) {
|
||||||
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
||||||
if (nh->ifindex) {
|
if (nh->nh_vrf_id == VRF_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
if (nh->ifname[0]) {
|
||||||
ifp = if_lookup_by_name(nh->ifname,
|
ifp = if_lookup_by_name(nh->ifname,
|
||||||
nh->nh_vrf_id);
|
nh->nh_vrf_id);
|
||||||
if (ifp)
|
if (ifp)
|
||||||
@ -545,8 +539,7 @@ static void static_enable_vrf(struct static_vrf *svrf,
|
|||||||
else
|
else
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (nh->nh_vrf_id == VRF_UNKNOWN)
|
|
||||||
continue;
|
|
||||||
static_install_path(pn);
|
static_install_path(pn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -560,27 +553,26 @@ static void static_enable_vrf(struct static_vrf *svrf,
|
|||||||
*
|
*
|
||||||
* enable_svrf -> the vrf being enabled
|
* enable_svrf -> the vrf being enabled
|
||||||
*/
|
*/
|
||||||
void static_fixup_vrf_ids(struct static_vrf *enable_svrf)
|
void static_fixup_vrf_ids(struct vrf *vrf)
|
||||||
{
|
{
|
||||||
struct route_table *stable;
|
struct route_table *stable;
|
||||||
struct vrf *vrf;
|
struct static_vrf *svrf, *enable_svrf;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
|
|
||||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
enable_svrf = vrf->info;
|
||||||
struct static_vrf *svrf;
|
|
||||||
|
|
||||||
svrf = vrf->info;
|
RB_FOREACH (svrf, svrf_name_head, &svrfs) {
|
||||||
/* Install any static routes configured for this VRF. */
|
/* Install any static routes configured for this VRF. */
|
||||||
FOREACH_AFI_SAFI (afi, safi) {
|
FOREACH_AFI_SAFI (afi, safi) {
|
||||||
stable = svrf->stable[afi][safi];
|
stable = svrf->stable[afi][safi];
|
||||||
if (!stable)
|
if (!stable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
static_fixup_vrf(enable_svrf, stable, afi, safi);
|
static_fixup_vrf(vrf, stable, afi, safi);
|
||||||
|
|
||||||
if (enable_svrf == svrf)
|
if (enable_svrf == svrf)
|
||||||
static_enable_vrf(svrf, stable, afi, safi);
|
static_enable_vrf(stable, afi, safi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -595,8 +587,7 @@ void static_fixup_vrf_ids(struct static_vrf *enable_svrf)
|
|||||||
* afi -> the afi in question
|
* afi -> the afi in question
|
||||||
* safi -> the safi in question
|
* safi -> the safi in question
|
||||||
*/
|
*/
|
||||||
static void static_cleanup_vrf(struct static_vrf *svrf,
|
static void static_cleanup_vrf(struct vrf *vrf, struct route_table *stable,
|
||||||
struct route_table *stable,
|
|
||||||
afi_t afi, safi_t safi)
|
afi_t afi, safi_t safi)
|
||||||
{
|
{
|
||||||
struct route_node *rn;
|
struct route_node *rn;
|
||||||
@ -610,11 +601,13 @@ static void static_cleanup_vrf(struct static_vrf *svrf,
|
|||||||
continue;
|
continue;
|
||||||
frr_each(static_path_list, &si->path_list, pn) {
|
frr_each(static_path_list, &si->path_list, pn) {
|
||||||
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
||||||
if (strcmp(svrf->vrf->name, nh->nh_vrfname)
|
if (strcmp(vrf->name, nh->nh_vrfname) != 0)
|
||||||
!= 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
static_uninstall_path(pn);
|
static_uninstall_path(pn);
|
||||||
|
|
||||||
|
nh->nh_vrf_id = VRF_UNKNOWN;
|
||||||
|
nh->ifindex = IFINDEX_INTERNAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -642,6 +635,9 @@ static void static_disable_vrf(struct route_table *stable,
|
|||||||
continue;
|
continue;
|
||||||
frr_each(static_path_list, &si->path_list, pn) {
|
frr_each(static_path_list, &si->path_list, pn) {
|
||||||
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
|
||||||
|
if (nh->nh_vrf_id == VRF_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
static_uninstall_path(pn);
|
static_uninstall_path(pn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -656,26 +652,23 @@ static void static_disable_vrf(struct route_table *stable,
|
|||||||
*
|
*
|
||||||
* disable_svrf - The vrf being disabled
|
* disable_svrf - The vrf being disabled
|
||||||
*/
|
*/
|
||||||
void static_cleanup_vrf_ids(struct static_vrf *disable_svrf)
|
void static_cleanup_vrf_ids(struct vrf *vrf)
|
||||||
{
|
{
|
||||||
struct vrf *vrf;
|
struct route_table *stable;
|
||||||
|
struct static_vrf *svrf, *disable_svrf;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
|
|
||||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
disable_svrf = vrf->info;
|
||||||
struct static_vrf *svrf;
|
|
||||||
|
|
||||||
svrf = vrf->info;
|
|
||||||
|
|
||||||
|
RB_FOREACH (svrf, svrf_name_head, &svrfs) {
|
||||||
/* Uninstall any static routes configured for this VRF. */
|
/* Uninstall any static routes configured for this VRF. */
|
||||||
FOREACH_AFI_SAFI (afi, safi) {
|
FOREACH_AFI_SAFI (afi, safi) {
|
||||||
struct route_table *stable;
|
|
||||||
|
|
||||||
stable = svrf->stable[afi][safi];
|
stable = svrf->stable[afi][safi];
|
||||||
if (!stable)
|
if (!stable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
static_cleanup_vrf(disable_svrf, stable, afi, safi);
|
static_cleanup_vrf(vrf, stable, afi, safi);
|
||||||
|
|
||||||
if (disable_svrf == svrf)
|
if (disable_svrf == svrf)
|
||||||
static_disable_vrf(stable, afi, safi);
|
static_disable_vrf(stable, afi, safi);
|
||||||
@ -683,71 +676,6 @@ void static_cleanup_vrf_ids(struct static_vrf *disable_svrf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function enables static routes when an interface it relies
|
|
||||||
* on in a different vrf is coming up.
|
|
||||||
*
|
|
||||||
* stable -> The stable we are looking at.
|
|
||||||
* ifp -> interface coming up
|
|
||||||
* afi -> the afi in question
|
|
||||||
* safi -> the safi in question
|
|
||||||
*/
|
|
||||||
static void static_fixup_intf_nh(struct route_table *stable,
|
|
||||||
struct interface *ifp,
|
|
||||||
afi_t afi, safi_t safi)
|
|
||||||
{
|
|
||||||
struct route_node *rn;
|
|
||||||
struct static_nexthop *nh;
|
|
||||||
struct static_path *pn;
|
|
||||||
struct static_route_info *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) {
|
|
||||||
if (nh->nh_vrf_id != ifp->vrf->vrf_id)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (nh->ifindex != ifp->ifindex)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
static_install_path(pn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This function enables static routes that rely on an interface in
|
|
||||||
* a different vrf when that interface comes up.
|
|
||||||
*/
|
|
||||||
void static_install_intf_nh(struct interface *ifp)
|
|
||||||
{
|
|
||||||
struct route_table *stable;
|
|
||||||
struct vrf *vrf;
|
|
||||||
afi_t afi;
|
|
||||||
safi_t safi;
|
|
||||||
|
|
||||||
RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
|
|
||||||
struct static_vrf *svrf = vrf->info;
|
|
||||||
|
|
||||||
/* Not needed if same vrf since happens naturally */
|
|
||||||
if (vrf->vrf_id == ifp->vrf->vrf_id)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Install any static routes configured for this interface. */
|
|
||||||
FOREACH_AFI_SAFI (afi, safi) {
|
|
||||||
stable = svrf->stable[afi][safi];
|
|
||||||
if (!stable)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
static_fixup_intf_nh(stable, ifp, afi, safi);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* called from if_{add,delete}_update, i.e. when ifindex becomes [in]valid */
|
/* called from if_{add,delete}_update, i.e. when ifindex becomes [in]valid */
|
||||||
void static_ifindex_update(struct interface *ifp, bool up)
|
void static_ifindex_update(struct interface *ifp, bool up)
|
||||||
{
|
{
|
||||||
|
@ -199,7 +199,8 @@ extern uint32_t zebra_ecmp_count;
|
|||||||
|
|
||||||
extern struct zebra_privs_t static_privs;
|
extern struct zebra_privs_t static_privs;
|
||||||
|
|
||||||
void static_fixup_vrf_ids(struct static_vrf *svrf);
|
extern void static_fixup_vrf_ids(struct vrf *vrf);
|
||||||
|
extern void static_cleanup_vrf_ids(struct vrf *vrf);
|
||||||
|
|
||||||
extern struct static_nexthop *
|
extern struct static_nexthop *
|
||||||
static_add_nexthop(struct static_path *pn, enum static_nh_type type,
|
static_add_nexthop(struct static_path *pn, enum static_nh_type type,
|
||||||
@ -209,10 +210,6 @@ extern void static_install_nexthop(struct static_nexthop *nh);
|
|||||||
|
|
||||||
extern void static_delete_nexthop(struct static_nexthop *nh);
|
extern void static_delete_nexthop(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_ifindex_update(struct interface *ifp, bool up);
|
||||||
|
|
||||||
extern void static_install_path(struct static_path *pn);
|
extern void static_install_path(struct static_path *pn);
|
||||||
|
@ -18,16 +18,37 @@
|
|||||||
|
|
||||||
DEFINE_MTYPE_STATIC(STATIC, STATIC_RTABLE_INFO, "Static Route Table Info");
|
DEFINE_MTYPE_STATIC(STATIC, STATIC_RTABLE_INFO, "Static Route Table Info");
|
||||||
|
|
||||||
static struct static_vrf *static_vrf_alloc(void)
|
static int svrf_name_compare(const struct static_vrf *a,
|
||||||
|
const struct static_vrf *b)
|
||||||
|
{
|
||||||
|
return strcmp(a->name, b->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
RB_GENERATE(svrf_name_head, static_vrf, entry, svrf_name_compare);
|
||||||
|
|
||||||
|
struct svrf_name_head svrfs = RB_INITIALIZER(&svrfs);
|
||||||
|
|
||||||
|
static struct static_vrf *static_vrf_lookup_by_name(const char *name)
|
||||||
|
{
|
||||||
|
struct static_vrf svrf;
|
||||||
|
|
||||||
|
strlcpy(svrf.name, name, sizeof(svrf.name));
|
||||||
|
return RB_FIND(svrf_name_head, &svrfs, &svrf);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct static_vrf *static_vrf_alloc(const char *name)
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct static_vrf *svrf;
|
struct static_vrf *svrf;
|
||||||
struct stable_info *info;
|
struct stable_info *info;
|
||||||
|
struct vrf *vrf;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
|
|
||||||
svrf = XCALLOC(MTYPE_STATIC_RTABLE_INFO, sizeof(struct static_vrf));
|
svrf = XCALLOC(MTYPE_STATIC_RTABLE_INFO, sizeof(struct static_vrf));
|
||||||
|
|
||||||
|
strlcpy(svrf->name, name, sizeof(svrf->name));
|
||||||
|
|
||||||
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++) {
|
||||||
if (afi == AFI_IP6)
|
if (afi == AFI_IP6)
|
||||||
@ -46,44 +67,34 @@ static struct static_vrf *static_vrf_alloc(void)
|
|||||||
svrf->stable[afi][safi] = table;
|
svrf->stable[afi][safi] = table;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RB_INSERT(svrf_name_head, &svrfs, svrf);
|
||||||
|
|
||||||
|
vrf = vrf_lookup_by_name(name);
|
||||||
|
if (vrf) {
|
||||||
|
svrf->vrf = vrf;
|
||||||
|
vrf->info = svrf;
|
||||||
|
}
|
||||||
|
|
||||||
return svrf;
|
return svrf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int static_vrf_new(struct vrf *vrf)
|
void static_vrf_free(struct static_vrf *svrf)
|
||||||
{
|
|
||||||
struct static_vrf *svrf;
|
|
||||||
|
|
||||||
svrf = static_vrf_alloc();
|
|
||||||
vrf->info = svrf;
|
|
||||||
svrf->vrf = vrf;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int static_vrf_enable(struct vrf *vrf)
|
|
||||||
{
|
|
||||||
static_zebra_vrf_register(vrf);
|
|
||||||
|
|
||||||
static_fixup_vrf_ids(vrf->info);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int static_vrf_disable(struct vrf *vrf)
|
|
||||||
{
|
|
||||||
static_zebra_vrf_unregister(vrf);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int static_vrf_delete(struct vrf *vrf)
|
|
||||||
{
|
{
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
struct static_vrf *svrf;
|
struct vrf *vrf;
|
||||||
safi_t safi;
|
safi_t safi;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
void *info;
|
void *info;
|
||||||
|
|
||||||
svrf = vrf->info;
|
vrf = svrf->vrf;
|
||||||
|
if (vrf) {
|
||||||
|
vrf->info = NULL;
|
||||||
|
svrf->vrf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RB_REMOVE(svrf_name_head, &svrfs, svrf);
|
||||||
|
|
||||||
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];
|
||||||
@ -93,7 +104,47 @@ static int static_vrf_delete(struct vrf *vrf)
|
|||||||
svrf->stable[afi][safi] = NULL;
|
svrf->stable[afi][safi] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XFREE(MTYPE_STATIC_RTABLE_INFO, svrf);
|
XFREE(MTYPE_STATIC_RTABLE_INFO, svrf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int static_vrf_new(struct vrf *vrf)
|
||||||
|
{
|
||||||
|
struct static_vrf *svrf;
|
||||||
|
|
||||||
|
svrf = static_vrf_lookup_by_name(vrf->name);
|
||||||
|
if (svrf) {
|
||||||
|
vrf->info = svrf;
|
||||||
|
svrf->vrf = vrf;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int static_vrf_enable(struct vrf *vrf)
|
||||||
|
{
|
||||||
|
static_zebra_vrf_register(vrf);
|
||||||
|
static_fixup_vrf_ids(vrf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int static_vrf_disable(struct vrf *vrf)
|
||||||
|
{
|
||||||
|
static_cleanup_vrf_ids(vrf);
|
||||||
|
static_zebra_vrf_unregister(vrf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int static_vrf_delete(struct vrf *vrf)
|
||||||
|
{
|
||||||
|
struct static_vrf *svrf;
|
||||||
|
|
||||||
|
svrf = vrf->info;
|
||||||
|
if (svrf) {
|
||||||
|
svrf->vrf = NULL;
|
||||||
|
vrf->info = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,20 +161,6 @@ struct route_table *static_vrf_static_table(afi_t afi, safi_t safi,
|
|||||||
return svrf->stable[afi][safi];
|
return svrf->stable[afi][safi];
|
||||||
}
|
}
|
||||||
|
|
||||||
struct static_vrf *static_vrf_lookup_by_name(const char *name)
|
|
||||||
{
|
|
||||||
struct vrf *vrf;
|
|
||||||
|
|
||||||
if (!name)
|
|
||||||
name = VRF_DEFAULT_NAME;
|
|
||||||
|
|
||||||
vrf = vrf_lookup_by_name(name);
|
|
||||||
if (vrf)
|
|
||||||
return ((struct static_vrf *)vrf->info);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void static_vrf_init(void)
|
void static_vrf_init(void)
|
||||||
{
|
{
|
||||||
vrf_init(static_vrf_new, static_vrf_enable, static_vrf_disable,
|
vrf_init(static_vrf_new, static_vrf_enable, static_vrf_disable,
|
||||||
@ -134,5 +171,10 @@ void static_vrf_init(void)
|
|||||||
|
|
||||||
void static_vrf_terminate(void)
|
void static_vrf_terminate(void)
|
||||||
{
|
{
|
||||||
|
struct static_vrf *svrf, *svrf_next;
|
||||||
|
|
||||||
|
RB_FOREACH_SAFE (svrf, svrf_name_head, &svrfs, svrf_next)
|
||||||
|
static_vrf_free(svrf);
|
||||||
|
|
||||||
vrf_terminate();
|
vrf_terminate();
|
||||||
}
|
}
|
||||||
|
@ -7,15 +7,27 @@
|
|||||||
#ifndef __STATIC_VRF_H__
|
#ifndef __STATIC_VRF_H__
|
||||||
#define __STATIC_VRF_H__
|
#define __STATIC_VRF_H__
|
||||||
|
|
||||||
|
#include "openbsd-tree.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct static_vrf {
|
struct static_vrf {
|
||||||
|
RB_ENTRY(static_vrf) entry;
|
||||||
|
|
||||||
|
char name[VRF_NAMSIZ + 1];
|
||||||
struct vrf *vrf;
|
struct vrf *vrf;
|
||||||
|
|
||||||
struct route_table *stable[AFI_MAX][SAFI_MAX];
|
struct route_table *stable[AFI_MAX][SAFI_MAX];
|
||||||
};
|
};
|
||||||
|
RB_HEAD(svrf_name_head, static_vrf);
|
||||||
|
RB_PROTOTYPE(svrf_name_head, static_vrf, entry, svrf_name_compare)
|
||||||
|
|
||||||
|
extern struct svrf_name_head svrfs;
|
||||||
|
|
||||||
|
struct static_vrf *static_vrf_alloc(const char *name);
|
||||||
|
void static_vrf_free(struct static_vrf *svrf);
|
||||||
|
|
||||||
struct stable_info {
|
struct stable_info {
|
||||||
struct static_vrf *svrf;
|
struct static_vrf *svrf;
|
||||||
@ -25,8 +37,6 @@ struct stable_info {
|
|||||||
|
|
||||||
#define GET_STABLE_VRF_ID(info) info->svrf->vrf->vrf_id
|
#define GET_STABLE_VRF_ID(info) info->svrf->vrf->vrf_id
|
||||||
|
|
||||||
struct static_vrf *static_vrf_lookup_by_name(const char *vrf_name);
|
|
||||||
|
|
||||||
void static_vrf_init(void);
|
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,
|
||||||
|
@ -60,8 +60,6 @@ struct static_route_args {
|
|||||||
bool bfd_multi_hop;
|
bool bfd_multi_hop;
|
||||||
const char *bfd_source;
|
const char *bfd_source;
|
||||||
const char *bfd_profile;
|
const char *bfd_profile;
|
||||||
|
|
||||||
const char *input;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
|
static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
|
||||||
@ -153,20 +151,9 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
|
|||||||
else
|
else
|
||||||
buf_gate_str = "";
|
buf_gate_str = "";
|
||||||
|
|
||||||
if (args->gateway == NULL && args->interface_name == NULL) {
|
if (args->gateway == NULL && args->interface_name == NULL)
|
||||||
type = STATIC_BLACKHOLE;
|
type = STATIC_BLACKHOLE;
|
||||||
/* If this is blackhole/reject flagged route, then
|
else if (args->gateway && args->interface_name) {
|
||||||
* specify interface_name with the value of what was really
|
|
||||||
* entered.
|
|
||||||
* interface_name will be validated later in NB functions
|
|
||||||
* to check if we don't create blackhole/reject routes that
|
|
||||||
* match the real interface names.
|
|
||||||
* E.g.: `ip route 10.0.0.1/32 bla` will create a blackhole
|
|
||||||
* route despite the real interface named `bla` exists.
|
|
||||||
*/
|
|
||||||
if (args->input)
|
|
||||||
args->interface_name = args->input;
|
|
||||||
} else if (args->gateway && args->interface_name) {
|
|
||||||
if (args->afi == AFI_IP)
|
if (args->afi == AFI_IP)
|
||||||
type = STATIC_IPV4_GATEWAY_IFNAME;
|
type = STATIC_IPV4_GATEWAY_IFNAME;
|
||||||
else
|
else
|
||||||
@ -553,8 +540,6 @@ DEFPY_YANG(ip_route_blackhole,
|
|||||||
"Table to configure\n"
|
"Table to configure\n"
|
||||||
"The table number to configure\n")
|
"The table number to configure\n")
|
||||||
{
|
{
|
||||||
int idx_flag = 0;
|
|
||||||
|
|
||||||
struct static_route_args args = {
|
struct static_route_args args = {
|
||||||
.delete = !!no,
|
.delete = !!no,
|
||||||
.afi = AFI_IP,
|
.afi = AFI_IP,
|
||||||
@ -569,9 +554,6 @@ DEFPY_YANG(ip_route_blackhole,
|
|||||||
.vrf = vrf,
|
.vrf = vrf,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (flag && argv_find(argv, argc, flag, &idx_flag))
|
|
||||||
args.input = argv[idx_flag]->arg;
|
|
||||||
|
|
||||||
return static_route_nb_run(vty, &args);
|
return static_route_nb_run(vty, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,8 +582,6 @@ DEFPY_YANG(ip_route_blackhole_vrf,
|
|||||||
"Table to configure\n"
|
"Table to configure\n"
|
||||||
"The table number to configure\n")
|
"The table number to configure\n")
|
||||||
{
|
{
|
||||||
int idx_flag = 0;
|
|
||||||
|
|
||||||
struct static_route_args args = {
|
struct static_route_args args = {
|
||||||
.delete = !!no,
|
.delete = !!no,
|
||||||
.afi = AFI_IP,
|
.afi = AFI_IP,
|
||||||
@ -623,9 +603,6 @@ DEFPY_YANG(ip_route_blackhole_vrf,
|
|||||||
*/
|
*/
|
||||||
assert(args.prefix);
|
assert(args.prefix);
|
||||||
|
|
||||||
if (flag && argv_find(argv, argc, flag, &idx_flag))
|
|
||||||
args.input = argv[idx_flag]->arg;
|
|
||||||
|
|
||||||
return static_route_nb_run(vty, &args);
|
return static_route_nb_run(vty, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,8 +893,6 @@ DEFPY_YANG(ipv6_route_blackhole,
|
|||||||
"Table to configure\n"
|
"Table to configure\n"
|
||||||
"The table number to configure\n")
|
"The table number to configure\n")
|
||||||
{
|
{
|
||||||
int idx_flag = 0;
|
|
||||||
|
|
||||||
struct static_route_args args = {
|
struct static_route_args args = {
|
||||||
.delete = !!no,
|
.delete = !!no,
|
||||||
.afi = AFI_IP6,
|
.afi = AFI_IP6,
|
||||||
@ -932,9 +907,6 @@ DEFPY_YANG(ipv6_route_blackhole,
|
|||||||
.vrf = vrf,
|
.vrf = vrf,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (flag && argv_find(argv, argc, flag, &idx_flag))
|
|
||||||
args.input = argv[idx_flag]->arg;
|
|
||||||
|
|
||||||
return static_route_nb_run(vty, &args);
|
return static_route_nb_run(vty, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -963,8 +935,6 @@ DEFPY_YANG(ipv6_route_blackhole_vrf,
|
|||||||
"Table to configure\n"
|
"Table to configure\n"
|
||||||
"The table number to configure\n")
|
"The table number to configure\n")
|
||||||
{
|
{
|
||||||
int idx_flag = 0;
|
|
||||||
|
|
||||||
struct static_route_args args = {
|
struct static_route_args args = {
|
||||||
.delete = !!no,
|
.delete = !!no,
|
||||||
.afi = AFI_IP6,
|
.afi = AFI_IP6,
|
||||||
@ -986,9 +956,6 @@ DEFPY_YANG(ipv6_route_blackhole_vrf,
|
|||||||
*/
|
*/
|
||||||
assert(args.prefix);
|
assert(args.prefix);
|
||||||
|
|
||||||
if (flag && argv_find(argv, argc, flag, &idx_flag))
|
|
||||||
args.input = argv[idx_flag]->arg;
|
|
||||||
|
|
||||||
return static_route_nb_run(vty, &args);
|
return static_route_nb_run(vty, &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,8 +111,6 @@ static int interface_address_delete(ZAPI_CALLBACK_ARGS)
|
|||||||
|
|
||||||
static int static_ifp_up(struct interface *ifp)
|
static int static_ifp_up(struct interface *ifp)
|
||||||
{
|
{
|
||||||
/* Install any static reliant on this interface coming up */
|
|
||||||
static_install_intf_nh(ifp);
|
|
||||||
static_ifindex_update(ifp, true);
|
static_ifindex_update(ifp, true);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -169,7 +167,7 @@ static void zebra_connected(struct zclient *zclient)
|
|||||||
zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST, zclient, true);
|
zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST, zclient, true);
|
||||||
zclient_send_reg_requests(zclient, VRF_DEFAULT);
|
zclient_send_reg_requests(zclient, VRF_DEFAULT);
|
||||||
|
|
||||||
static_fixup_vrf_ids(vrf_info_lookup(VRF_DEFAULT));
|
static_fixup_vrf_ids(vrf_lookup_by_id(VRF_DEFAULT));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* API to check whether the configured nexthop address is
|
/* API to check whether the configured nexthop address is
|
||||||
@ -388,6 +386,9 @@ extern void static_zebra_route_add(struct static_path *pn, bool install)
|
|||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
uint32_t nh_num = 0;
|
uint32_t nh_num = 0;
|
||||||
|
|
||||||
|
if (!si->svrf->vrf)
|
||||||
|
return;
|
||||||
|
|
||||||
p = src_pp = NULL;
|
p = src_pp = NULL;
|
||||||
srcdest_rnode_prefixes(rn, &p, &src_pp);
|
srcdest_rnode_prefixes(rn, &p, &src_pp);
|
||||||
|
|
||||||
|
@ -119,8 +119,10 @@ static void static_startup(void)
|
|||||||
|
|
||||||
hook_register(routing_conf_event,
|
hook_register(routing_conf_event,
|
||||||
routing_control_plane_protocols_name_validate);
|
routing_control_plane_protocols_name_validate);
|
||||||
|
hook_register(routing_create,
|
||||||
routing_control_plane_protocols_register_vrf_dependency();
|
routing_control_plane_protocols_staticd_create);
|
||||||
|
hook_register(routing_destroy,
|
||||||
|
routing_control_plane_protocols_staticd_destroy);
|
||||||
|
|
||||||
// Add a route
|
// Add a route
|
||||||
vty = vty_new();
|
vty = vty_new();
|
||||||
|
Loading…
Reference in New Issue
Block a user