forked from Mirror/frr
staticd: Add v4-via-v6 nexthop support
Routing v4 over an v6 nexthop is already well supported within zebra (and FRR). This adds support to staticd, allowing an IPv6 nexthop to be provided to ip route statements. For this the commands are extended and the address family is parsed from the parameter. When receiving nht updates from zebra, both AFIs are checked because prefixes could exist in both. Additionally when route_node is known, family of prefix is used instead of nexthop. Signed-off-by: Christopher Dziomba <christopher.dziomba@telekom.de>
This commit is contained in:
parent
ac56da1f50
commit
8fc41e81f0
|
@ -86,6 +86,7 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
|
||||||
uint8_t segs_stack_id = 0;
|
uint8_t segs_stack_id = 0;
|
||||||
char *orig_label = NULL, *orig_seg = NULL;
|
char *orig_label = NULL, *orig_seg = NULL;
|
||||||
const char *buf_gate_str;
|
const char *buf_gate_str;
|
||||||
|
struct ipaddr gate_ip;
|
||||||
uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
|
uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
|
||||||
route_tag_t tag = 0;
|
route_tag_t tag = 0;
|
||||||
uint32_t table_id = 0;
|
uint32_t table_id = 0;
|
||||||
|
@ -149,22 +150,27 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
|
||||||
|
|
||||||
if (src.prefixlen)
|
if (src.prefixlen)
|
||||||
prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix));
|
prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix));
|
||||||
if (args->gateway)
|
|
||||||
|
if (args->gateway) {
|
||||||
buf_gate_str = args->gateway;
|
buf_gate_str = args->gateway;
|
||||||
else
|
if (str2ipaddr(args->gateway, &gate_ip) != 0) {
|
||||||
|
vty_out(vty, "%% Invalid gateway address %s\n", args->gateway);
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
}
|
||||||
|
} 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;
|
||||||
else if (args->gateway && args->interface_name) {
|
else if (args->gateway && args->interface_name) {
|
||||||
if (args->afi == AFI_IP)
|
if (gate_ip.ipa_type == IPADDR_V4)
|
||||||
type = STATIC_IPV4_GATEWAY_IFNAME;
|
type = STATIC_IPV4_GATEWAY_IFNAME;
|
||||||
else
|
else
|
||||||
type = STATIC_IPV6_GATEWAY_IFNAME;
|
type = STATIC_IPV6_GATEWAY_IFNAME;
|
||||||
} else if (args->interface_name)
|
} else if (args->interface_name)
|
||||||
type = STATIC_IFNAME;
|
type = STATIC_IFNAME;
|
||||||
else {
|
else {
|
||||||
if (args->afi == AFI_IP)
|
if (gate_ip.ipa_type == IPADDR_V4)
|
||||||
type = STATIC_IPV4_GATEWAY;
|
type = STATIC_IPV4_GATEWAY;
|
||||||
else
|
else
|
||||||
type = STATIC_IPV6_GATEWAY;
|
type = STATIC_IPV6_GATEWAY;
|
||||||
|
@ -552,7 +558,7 @@ DEFPY_YANG(ip_route_address_interface,
|
||||||
ip_route_address_interface_cmd,
|
ip_route_address_interface_cmd,
|
||||||
"[no] ip route\
|
"[no] ip route\
|
||||||
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
||||||
A.B.C.D$gate \
|
<A.B.C.D|X:X::X:X>$gate \
|
||||||
<INTERFACE|Null0>$ifname \
|
<INTERFACE|Null0>$ifname \
|
||||||
[{ \
|
[{ \
|
||||||
tag (1-4294967295) \
|
tag (1-4294967295) \
|
||||||
|
@ -571,7 +577,8 @@ DEFPY_YANG(ip_route_address_interface,
|
||||||
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
||||||
"IP destination prefix\n"
|
"IP destination prefix\n"
|
||||||
"IP destination prefix mask\n"
|
"IP destination prefix mask\n"
|
||||||
"IP gateway address\n"
|
"IPv4 gateway address\n"
|
||||||
|
"IPv6 gateway address\n"
|
||||||
"IP gateway interface name\n"
|
"IP gateway interface name\n"
|
||||||
"Null interface\n"
|
"Null interface\n"
|
||||||
"Set tag for this route\n"
|
"Set tag for this route\n"
|
||||||
|
@ -624,7 +631,7 @@ DEFPY_YANG(ip_route_address_interface_vrf,
|
||||||
ip_route_address_interface_vrf_cmd,
|
ip_route_address_interface_vrf_cmd,
|
||||||
"[no] ip route\
|
"[no] ip route\
|
||||||
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
||||||
A.B.C.D$gate \
|
<A.B.C.D|X:X::X:X>$gate \
|
||||||
<INTERFACE|Null0>$ifname \
|
<INTERFACE|Null0>$ifname \
|
||||||
[{ \
|
[{ \
|
||||||
tag (1-4294967295) \
|
tag (1-4294967295) \
|
||||||
|
@ -642,7 +649,8 @@ DEFPY_YANG(ip_route_address_interface_vrf,
|
||||||
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
||||||
"IP destination prefix\n"
|
"IP destination prefix\n"
|
||||||
"IP destination prefix mask\n"
|
"IP destination prefix mask\n"
|
||||||
"IP gateway address\n"
|
"IPv4 gateway address\n"
|
||||||
|
"IPv6 gateway address\n"
|
||||||
"IP gateway interface name\n"
|
"IP gateway interface name\n"
|
||||||
"Null interface\n"
|
"Null interface\n"
|
||||||
"Set tag for this route\n"
|
"Set tag for this route\n"
|
||||||
|
@ -694,7 +702,7 @@ DEFPY_YANG(ip_route,
|
||||||
ip_route_cmd,
|
ip_route_cmd,
|
||||||
"[no] ip route\
|
"[no] ip route\
|
||||||
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
||||||
<A.B.C.D$gate|<INTERFACE|Null0>$ifname> \
|
<<A.B.C.D|X:X::X:X>$gate|<INTERFACE|Null0>$ifname> \
|
||||||
[{ \
|
[{ \
|
||||||
tag (1-4294967295) \
|
tag (1-4294967295) \
|
||||||
|(1-255)$distance \
|
|(1-255)$distance \
|
||||||
|
@ -711,7 +719,8 @@ DEFPY_YANG(ip_route,
|
||||||
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
||||||
"IP destination prefix\n"
|
"IP destination prefix\n"
|
||||||
"IP destination prefix mask\n"
|
"IP destination prefix mask\n"
|
||||||
"IP gateway address\n"
|
"IPv4 gateway address\n"
|
||||||
|
"IPv6 gateway address\n"
|
||||||
"IP gateway interface name\n"
|
"IP gateway interface name\n"
|
||||||
"Null interface\n"
|
"Null interface\n"
|
||||||
"Set tag for this route\n"
|
"Set tag for this route\n"
|
||||||
|
@ -762,7 +771,7 @@ DEFPY_YANG(ip_route_vrf,
|
||||||
ip_route_vrf_cmd,
|
ip_route_vrf_cmd,
|
||||||
"[no] ip route\
|
"[no] ip route\
|
||||||
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
||||||
<A.B.C.D$gate|<INTERFACE|Null0>$ifname> \
|
<<A.B.C.D|X:X::X:X>$gate|<INTERFACE|Null0>$ifname> \
|
||||||
[{ \
|
[{ \
|
||||||
tag (1-4294967295) \
|
tag (1-4294967295) \
|
||||||
|(1-255)$distance \
|
|(1-255)$distance \
|
||||||
|
@ -778,7 +787,8 @@ DEFPY_YANG(ip_route_vrf,
|
||||||
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
||||||
"IP destination prefix\n"
|
"IP destination prefix\n"
|
||||||
"IP destination prefix mask\n"
|
"IP destination prefix mask\n"
|
||||||
"IP gateway address\n"
|
"IPv4 gateway address\n"
|
||||||
|
"IPv6 gateway address\n"
|
||||||
"IP gateway interface name\n"
|
"IP gateway interface name\n"
|
||||||
"Null interface\n"
|
"Null interface\n"
|
||||||
"Set tag for this route\n"
|
"Set tag for this route\n"
|
||||||
|
|
|
@ -209,14 +209,10 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched,
|
||||||
struct zapi_route *nhr)
|
struct zapi_route *nhr)
|
||||||
{
|
{
|
||||||
struct static_nht_data *nhtd, lookup;
|
struct static_nht_data *nhtd, lookup;
|
||||||
afi_t afi = AFI_IP;
|
|
||||||
|
|
||||||
if (static_zclient->bfd_integration)
|
if (static_zclient->bfd_integration)
|
||||||
bfd_nht_update(matched, nhr);
|
bfd_nht_update(matched, nhr);
|
||||||
|
|
||||||
if (matched->family == AF_INET6)
|
|
||||||
afi = AFI_IP6;
|
|
||||||
|
|
||||||
if (nhr->type == ZEBRA_ROUTE_CONNECT) {
|
if (nhr->type == ZEBRA_ROUTE_CONNECT) {
|
||||||
if (static_nexthop_is_local(vrf->vrf_id, matched,
|
if (static_nexthop_is_local(vrf->vrf_id, matched,
|
||||||
nhr->prefix.family))
|
nhr->prefix.family))
|
||||||
|
@ -233,8 +229,12 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched,
|
||||||
if (nhtd) {
|
if (nhtd) {
|
||||||
nhtd->nh_num = nhr->nexthop_num;
|
nhtd->nh_num = nhr->nexthop_num;
|
||||||
|
|
||||||
static_nht_reset_start(matched, afi, nhr->safi, nhtd->nh_vrf_id);
|
/* The tracked nexthop might be used by IPv4 and IPv6 routes */
|
||||||
static_nht_update(NULL, NULL, matched, nhr->nexthop_num, afi, nhr->safi,
|
static_nht_reset_start(matched, AFI_IP, nhr->safi, nhtd->nh_vrf_id);
|
||||||
|
static_nht_update(NULL, NULL, matched, nhr->nexthop_num, AFI_IP, nhr->safi,
|
||||||
|
nhtd->nh_vrf_id);
|
||||||
|
static_nht_reset_start(matched, AFI_IP6, nhr->safi, nhtd->nh_vrf_id);
|
||||||
|
static_nht_update(NULL, NULL, matched, nhr->nexthop_num, AFI_IP6, nhr->safi,
|
||||||
nhtd->nh_vrf_id);
|
nhtd->nh_vrf_id);
|
||||||
} else
|
} else
|
||||||
zlog_err("No nhtd?");
|
zlog_err("No nhtd?");
|
||||||
|
@ -361,7 +361,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
|
||||||
if (reg) {
|
if (reg) {
|
||||||
if (nhtd->nh_num) {
|
if (nhtd->nh_num) {
|
||||||
/* refresh with existing data */
|
/* refresh with existing data */
|
||||||
afi_t afi = prefix_afi(&lookup.nh);
|
afi_t afi = prefix_afi(&rn->p);
|
||||||
|
|
||||||
if (nh->state == STATIC_NOT_INSTALLED ||
|
if (nh->state == STATIC_NOT_INSTALLED ||
|
||||||
nh->state == STATIC_SENT_TO_ZEBRA)
|
nh->state == STATIC_SENT_TO_ZEBRA)
|
||||||
|
|
Loading…
Reference in a new issue