staticd: add ability to create onlink static route

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2018-10-16 20:49:32 +00:00
parent f3a1b29d41
commit 02dc8ba37e
4 changed files with 55 additions and 33 deletions

View File

@ -64,8 +64,8 @@ int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
const char *ifname, enum static_blackhole_type bh_type, const char *ifname, enum static_blackhole_type bh_type,
route_tag_t tag, uint8_t distance, struct static_vrf *svrf, route_tag_t tag, uint8_t distance, struct static_vrf *svrf,
struct static_vrf *nh_svrf, struct static_vrf *nh_svrf,
struct static_nh_label *snh_label, struct static_nh_label *snh_label, uint32_t table_id,
uint32_t table_id) bool onlink)
{ {
struct route_node *rn; struct route_node *rn;
struct static_route *si; struct static_route *si;
@ -104,7 +104,7 @@ int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
&& (table_id == si->table_id) && (table_id == si->table_id)
&& !memcmp(&si->snh_label, snh_label, && !memcmp(&si->snh_label, snh_label,
sizeof(struct static_nh_label)) sizeof(struct static_nh_label))
&& si->bh_type == bh_type) { && si->bh_type == bh_type && si->onlink == onlink) {
route_unlock_node(rn); route_unlock_node(rn);
return 0; return 0;
} }
@ -129,6 +129,7 @@ int static_add_route(afi_t afi, safi_t safi, uint8_t type, struct prefix *p,
si->nh_vrf_id = nh_svrf->vrf->vrf_id; si->nh_vrf_id = nh_svrf->vrf->vrf_id;
strcpy(si->nh_vrfname, nh_svrf->vrf->name); strcpy(si->nh_vrfname, nh_svrf->vrf->name);
si->table_id = table_id; si->table_id = table_id;
si->onlink = onlink;
if (ifname) if (ifname)
strlcpy(si->ifname, ifname, sizeof(si->ifname)); strlcpy(si->ifname, ifname, sizeof(si->ifname));

View File

@ -79,6 +79,13 @@ struct static_route {
struct static_nh_label snh_label; struct static_nh_label snh_label;
uint32_t table_id; 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
* are specified.
*/
bool onlink;
}; };
extern bool mpls_enabled; extern bool mpls_enabled;
@ -94,7 +101,7 @@ extern int static_add_route(afi_t afi, safi_t safi, uint8_t type,
uint8_t distance, struct static_vrf *svrf, uint8_t distance, struct static_vrf *svrf,
struct static_vrf *nh_svrf, struct static_vrf *nh_svrf,
struct static_nh_label *snh_label, struct static_nh_label *snh_label,
uint32_t table_id); uint32_t table_id, bool onlink);
extern int static_delete_route(afi_t afi, safi_t safi, uint8_t type, extern int static_delete_route(afi_t afi, safi_t safi, uint8_t type,
struct prefix *p, struct prefix_ipv6 *src_p, struct prefix *p, struct prefix_ipv6 *src_p,

View File

@ -79,6 +79,7 @@ struct static_hold_route {
char *distance_str; char *distance_str;
char *label_str; char *label_str;
char *table_str; char *table_str;
bool onlink;
/* processed & masked destination, used for config display */ /* processed & masked destination, used for config display */
struct prefix dest; struct prefix dest;
@ -273,7 +274,8 @@ static int static_route_leak(
afi_t afi, safi_t safi, const char *negate, const char *dest_str, afi_t afi, safi_t safi, const char *negate, const char *dest_str,
const char *mask_str, const char *src_str, const char *gate_str, const char *mask_str, const char *src_str, const char *gate_str,
const char *ifname, const char *flag_str, const char *tag_str, const char *ifname, const char *flag_str, const char *tag_str,
const char *distance_str, const char *label_str, const char *table_str) const char *distance_str, const char *label_str, const char *table_str,
bool onlink)
{ {
int ret; int ret;
uint8_t distance; uint8_t distance;
@ -509,7 +511,7 @@ static int static_route_leak(
if (!negate) { if (!negate) {
static_add_route(afi, safi, type, &p, src_p, gatep, ifname, static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
bh_type, tag, distance, svrf, nh_svrf, bh_type, tag, distance, svrf, nh_svrf,
&snh_label, table_id); &snh_label, table_id, onlink);
/* Mark as having FRR configuration */ /* Mark as having FRR configuration */
vrf_set_user_cfged(svrf->vrf); vrf_set_user_cfged(svrf->vrf);
} else { } else {
@ -550,10 +552,10 @@ static int static_route(struct vty *vty, afi_t afi, safi_t safi,
if (!svrf) if (!svrf)
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }
return static_route_leak( return static_route_leak(vty, svrf, svrf, afi, safi, negate, dest_str,
vty, svrf, svrf, afi, safi, negate, dest_str, mask_str, src_str, mask_str, src_str, gate_str, ifname, flag_str,
gate_str, ifname, flag_str, tag_str, distance_str, label_str, tag_str, distance_str, label_str, table_str,
table_str); false);
} }
void static_config_install_delayed_routes(struct static_vrf *svrf) void static_config_install_delayed_routes(struct static_vrf *svrf)
@ -578,7 +580,8 @@ void static_config_install_delayed_routes(struct static_vrf *svrf)
NULL, osvrf, nh_svrf, shr->afi, shr->safi, NULL, NULL, osvrf, nh_svrf, shr->afi, shr->safi, NULL,
shr->dest_str, shr->mask_str, shr->src_str, shr->dest_str, shr->mask_str, shr->src_str,
shr->gate_str, shr->ifname, shr->flag_str, shr->tag_str, shr->gate_str, shr->ifname, shr->flag_str, shr->tag_str,
shr->distance_str, shr->label_str, shr->table_str); shr->distance_str, shr->label_str, shr->table_str,
shr->onlink);
if (installed != CMD_SUCCESS) if (installed != CMD_SUCCESS)
zlog_debug( zlog_debug(
@ -817,9 +820,10 @@ DEFPY(ip_route_blackhole_vrf,
* valid. Add an assert to make it happy * valid. Add an assert to make it happy
*/ */
assert(prefix); assert(prefix);
return static_route_leak(vty, svrf, svrf, AFI_IP, SAFI_UNICAST, return static_route_leak(vty, svrf, svrf, AFI_IP, SAFI_UNICAST, no,
no, prefix, mask_str, NULL, NULL, NULL, prefix, mask_str, NULL, NULL, NULL, flag,
flag, tag_str, distance_str, label, table_str); tag_str, distance_str, label, table_str,
false);
} }
DEFPY(ip_route_address_interface, DEFPY(ip_route_address_interface,
@ -835,6 +839,7 @@ DEFPY(ip_route_address_interface,
|label WORD \ |label WORD \
|table (1-4294967295) \ |table (1-4294967295) \
|nexthop-vrf NAME \ |nexthop-vrf NAME \
|onlink$onlink \
}]", }]",
NO_STR IP_STR NO_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
@ -851,7 +856,8 @@ DEFPY(ip_route_address_interface,
MPLS_LABEL_HELPSTR MPLS_LABEL_HELPSTR
"Table to configure\n" "Table to configure\n"
"The table number to configure\n" "The table number to configure\n"
VRF_CMD_HELP_STR) VRF_CMD_HELP_STR
"Treat the nexthop as directly attached to the interface")
{ {
struct static_vrf *svrf; struct static_vrf *svrf;
struct static_vrf *nh_svrf; struct static_vrf *nh_svrf;
@ -884,10 +890,10 @@ DEFPY(ip_route_address_interface,
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }
return static_route_leak( return static_route_leak(vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no,
vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, prefix, mask_str, NULL, gate_str, ifname, flag,
NULL, gate_str, ifname, flag, tag_str, distance_str, label, tag_str, distance_str, label, table_str,
table_str); !!onlink);
} }
DEFPY(ip_route_address_interface_vrf, DEFPY(ip_route_address_interface_vrf,
@ -902,6 +908,7 @@ DEFPY(ip_route_address_interface_vrf,
|label WORD \ |label WORD \
|table (1-4294967295) \ |table (1-4294967295) \
|nexthop-vrf NAME \ |nexthop-vrf NAME \
|onlink$onlink \
}]", }]",
NO_STR IP_STR NO_STR IP_STR
"Establish static routes\n" "Establish static routes\n"
@ -917,7 +924,8 @@ DEFPY(ip_route_address_interface_vrf,
MPLS_LABEL_HELPSTR MPLS_LABEL_HELPSTR
"Table to configure\n" "Table to configure\n"
"The table number to configure\n" "The table number to configure\n"
VRF_CMD_HELP_STR) VRF_CMD_HELP_STR
"Treat the nexthop as directly attached to the interface")
{ {
VTY_DECLVAR_CONTEXT(vrf, vrf); VTY_DECLVAR_CONTEXT(vrf, vrf);
const char *flag = NULL; const char *flag = NULL;
@ -945,10 +953,10 @@ DEFPY(ip_route_address_interface_vrf,
return CMD_WARNING_CONFIG_FAILED; return CMD_WARNING_CONFIG_FAILED;
} }
return static_route_leak( return static_route_leak(vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no,
vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, prefix, mask_str, NULL, gate_str, ifname, flag,
NULL, gate_str, ifname, flag, tag_str, distance_str, label, tag_str, distance_str, label, table_str,
table_str); !!onlink);
} }
DEFPY(ip_route, DEFPY(ip_route,
@ -1014,7 +1022,7 @@ DEFPY(ip_route,
return static_route_leak( return static_route_leak(
vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
NULL, gate_str, ifname, flag, tag_str, distance_str, label, NULL, gate_str, ifname, flag, tag_str, distance_str, label,
table_str); table_str, false);
} }
DEFPY(ip_route_vrf, DEFPY(ip_route_vrf,
@ -1073,7 +1081,7 @@ DEFPY(ip_route_vrf,
return static_route_leak( return static_route_leak(
vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str, vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
NULL, gate_str, ifname, flag, tag_str, distance_str, label, NULL, gate_str, ifname, flag, tag_str, distance_str, label,
table_str); table_str, false);
} }
DEFPY(ipv6_route_blackhole, DEFPY(ipv6_route_blackhole,
@ -1159,7 +1167,7 @@ DEFPY(ipv6_route_blackhole_vrf,
return static_route_leak( return static_route_leak(
vty, svrf, svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, vty, svrf, svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
from_str, NULL, NULL, flag, tag_str, distance_str, label, from_str, NULL, NULL, flag, tag_str, distance_str, label,
table_str); table_str, false);
} }
DEFPY(ipv6_route_address_interface, DEFPY(ipv6_route_address_interface,
@ -1174,6 +1182,7 @@ DEFPY(ipv6_route_address_interface,
|label WORD \ |label WORD \
|table (1-4294967295) \ |table (1-4294967295) \
|nexthop-vrf NAME \ |nexthop-vrf NAME \
|onlink$onlink \
}]", }]",
NO_STR NO_STR
IPV6_STR IPV6_STR
@ -1190,7 +1199,8 @@ DEFPY(ipv6_route_address_interface,
MPLS_LABEL_HELPSTR MPLS_LABEL_HELPSTR
"Table to configure\n" "Table to configure\n"
"The table number to configure\n" "The table number to configure\n"
VRF_CMD_HELP_STR) VRF_CMD_HELP_STR
"Treat the nexthop as directly attached to the interface")
{ {
struct static_vrf *svrf; struct static_vrf *svrf;
struct static_vrf *nh_svrf; struct static_vrf *nh_svrf;
@ -1220,7 +1230,7 @@ DEFPY(ipv6_route_address_interface,
return static_route_leak( return static_route_leak(
vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
from_str, gate_str, ifname, NULL, tag_str, distance_str, label, from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
table_str); table_str, !!onlink);
} }
DEFPY(ipv6_route_address_interface_vrf, DEFPY(ipv6_route_address_interface_vrf,
@ -1234,6 +1244,7 @@ DEFPY(ipv6_route_address_interface_vrf,
|label WORD \ |label WORD \
|table (1-4294967295) \ |table (1-4294967295) \
|nexthop-vrf NAME \ |nexthop-vrf NAME \
|onlink$onlink \
}]", }]",
NO_STR NO_STR
IPV6_STR IPV6_STR
@ -1249,7 +1260,8 @@ DEFPY(ipv6_route_address_interface_vrf,
MPLS_LABEL_HELPSTR MPLS_LABEL_HELPSTR
"Table to configure\n" "Table to configure\n"
"The table number to configure\n" "The table number to configure\n"
VRF_CMD_HELP_STR) VRF_CMD_HELP_STR
"Treat the nexthop as directly attached to the interface")
{ {
VTY_DECLVAR_CONTEXT(vrf, vrf); VTY_DECLVAR_CONTEXT(vrf, vrf);
struct static_vrf *svrf = vrf->info; struct static_vrf *svrf = vrf->info;
@ -1274,7 +1286,7 @@ DEFPY(ipv6_route_address_interface_vrf,
return static_route_leak( return static_route_leak(
vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
from_str, gate_str, ifname, NULL, tag_str, distance_str, label, from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
table_str); table_str, !!onlink);
} }
DEFPY(ipv6_route, DEFPY(ipv6_route,
@ -1334,7 +1346,7 @@ DEFPY(ipv6_route,
return static_route_leak( return static_route_leak(
vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
from_str, gate_str, ifname, NULL, tag_str, distance_str, label, from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
table_str); table_str, false);
} }
DEFPY(ipv6_route_vrf, DEFPY(ipv6_route_vrf,
@ -1387,7 +1399,7 @@ DEFPY(ipv6_route_vrf,
return static_route_leak( return static_route_leak(
vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL, vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
from_str, gate_str, ifname, NULL, tag_str, distance_str, label, from_str, gate_str, ifname, NULL, tag_str, distance_str, label,
table_str); table_str, false);
} }
DEFUN_NOSH (show_debugging_staticd, DEFUN_NOSH (show_debugging_staticd,

View File

@ -364,6 +364,8 @@ extern void static_zebra_route_add(struct route_node *rn,
memcpy(&api.src_prefix, src_pp, sizeof(api.src_prefix)); memcpy(&api.src_prefix, src_pp, sizeof(api.src_prefix));
} }
SET_FLAG(api.flags, ZEBRA_FLAG_RR_USE_DISTANCE); SET_FLAG(api.flags, ZEBRA_FLAG_RR_USE_DISTANCE);
if (si_changed->onlink)
SET_FLAG(api.flags, ZEBRA_FLAG_ONLINK);
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
if (si_changed->distance) { if (si_changed->distance) {
SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);