mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
Merge pull request #18654 from chdxD1/v4-via-v6-nexthop
Add v4-via-v6 nexthop support to staticd
This commit is contained in:
commit
417c82aadd
|
@ -46,8 +46,8 @@ a static prefix and gateway, with several possible forms.
|
|||
NETWORK is destination prefix with a valid v4 or v6 network based upon
|
||||
initial form of the command.
|
||||
|
||||
GATEWAY is the IP address to use as next-hop for the prefix. Currently, it must match
|
||||
the v4 or v6 route type specified at the start of the command.
|
||||
GATEWAY is the IP address to use as next-hop for the prefix. Routes of type v4 can use v4 and v6 next-hops,
|
||||
v6 routes only support v6 next-hops.
|
||||
|
||||
IFNAME is the name of the interface to use as next-hop. If only IFNAME is specified
|
||||
(without GATEWAY), a connected route will be created.
|
||||
|
|
|
@ -86,6 +86,7 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
|
|||
uint8_t segs_stack_id = 0;
|
||||
char *orig_label = NULL, *orig_seg = NULL;
|
||||
const char *buf_gate_str;
|
||||
struct ipaddr gate_ip;
|
||||
uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
|
||||
route_tag_t tag = 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)
|
||||
prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix));
|
||||
if (args->gateway)
|
||||
|
||||
if (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 = "";
|
||||
|
||||
if (args->gateway == NULL && args->interface_name == NULL)
|
||||
type = STATIC_BLACKHOLE;
|
||||
else if (args->gateway && args->interface_name) {
|
||||
if (args->afi == AFI_IP)
|
||||
if (gate_ip.ipa_type == IPADDR_V4)
|
||||
type = STATIC_IPV4_GATEWAY_IFNAME;
|
||||
else
|
||||
type = STATIC_IPV6_GATEWAY_IFNAME;
|
||||
} else if (args->interface_name)
|
||||
type = STATIC_IFNAME;
|
||||
else {
|
||||
if (args->afi == AFI_IP)
|
||||
if (gate_ip.ipa_type == IPADDR_V4)
|
||||
type = STATIC_IPV4_GATEWAY;
|
||||
else
|
||||
type = STATIC_IPV6_GATEWAY;
|
||||
|
@ -552,7 +558,7 @@ DEFPY_YANG(ip_route_address_interface,
|
|||
ip_route_address_interface_cmd,
|
||||
"[no] ip route\
|
||||
<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 \
|
||||
[{ \
|
||||
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\n"
|
||||
"IP destination prefix mask\n"
|
||||
"IP gateway address\n"
|
||||
"IPv4 gateway address\n"
|
||||
"IPv6 gateway address\n"
|
||||
"IP gateway interface name\n"
|
||||
"Null interface\n"
|
||||
"Set tag for this route\n"
|
||||
|
@ -624,7 +631,7 @@ DEFPY_YANG(ip_route_address_interface_vrf,
|
|||
ip_route_address_interface_vrf_cmd,
|
||||
"[no] ip route\
|
||||
<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 \
|
||||
[{ \
|
||||
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\n"
|
||||
"IP destination prefix mask\n"
|
||||
"IP gateway address\n"
|
||||
"IPv4 gateway address\n"
|
||||
"IPv6 gateway address\n"
|
||||
"IP gateway interface name\n"
|
||||
"Null interface\n"
|
||||
"Set tag for this route\n"
|
||||
|
@ -693,16 +701,16 @@ DEFPY_YANG(ip_route_address_interface_vrf,
|
|||
DEFPY_YANG(ip_route,
|
||||
ip_route_cmd,
|
||||
"[no] ip route\
|
||||
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
||||
<A.B.C.D$gate|<INTERFACE|Null0>$ifname> \
|
||||
[{ \
|
||||
tag (1-4294967295) \
|
||||
|(1-255)$distance \
|
||||
|vrf NAME \
|
||||
|label WORD \
|
||||
|table (1-4294967295) \
|
||||
|nexthop-vrf NAME \
|
||||
|color (1-4294967295) \
|
||||
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
||||
<<A.B.C.D|X:X::X:X>$gate|<INTERFACE|Null0>$ifname> \
|
||||
[{ \
|
||||
tag (1-4294967295) \
|
||||
|(1-255)$distance \
|
||||
|vrf NAME \
|
||||
|label WORD \
|
||||
|table (1-4294967295) \
|
||||
|nexthop-vrf NAME \
|
||||
|color (1-4294967295) \
|
||||
|bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \
|
||||
|segments WORD \
|
||||
}]",
|
||||
|
@ -711,7 +719,8 @@ DEFPY_YANG(ip_route,
|
|||
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
||||
"IP destination prefix\n"
|
||||
"IP destination prefix mask\n"
|
||||
"IP gateway address\n"
|
||||
"IPv4 gateway address\n"
|
||||
"IPv6 gateway address\n"
|
||||
"IP gateway interface name\n"
|
||||
"Null interface\n"
|
||||
"Set tag for this route\n"
|
||||
|
@ -761,15 +770,15 @@ DEFPY_YANG(ip_route,
|
|||
DEFPY_YANG(ip_route_vrf,
|
||||
ip_route_vrf_cmd,
|
||||
"[no] ip route\
|
||||
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
||||
<A.B.C.D$gate|<INTERFACE|Null0>$ifname> \
|
||||
[{ \
|
||||
tag (1-4294967295) \
|
||||
|(1-255)$distance \
|
||||
|label WORD \
|
||||
|table (1-4294967295) \
|
||||
|nexthop-vrf NAME \
|
||||
|color (1-4294967295) \
|
||||
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
|
||||
<<A.B.C.D|X:X::X:X>$gate|<INTERFACE|Null0>$ifname> \
|
||||
[{ \
|
||||
tag (1-4294967295) \
|
||||
|(1-255)$distance \
|
||||
|label WORD \
|
||||
|table (1-4294967295) \
|
||||
|nexthop-vrf NAME \
|
||||
|color (1-4294967295) \
|
||||
|bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \
|
||||
|segments WORD \
|
||||
}]",
|
||||
|
@ -778,7 +787,8 @@ DEFPY_YANG(ip_route_vrf,
|
|||
"IP destination prefix (e.g. 10.0.0.0/8)\n"
|
||||
"IP destination prefix\n"
|
||||
"IP destination prefix mask\n"
|
||||
"IP gateway address\n"
|
||||
"IPv4 gateway address\n"
|
||||
"IPv6 gateway address\n"
|
||||
"IP gateway interface name\n"
|
||||
"Null interface\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 static_nht_data *nhtd, lookup;
|
||||
afi_t afi = AFI_IP;
|
||||
|
||||
if (static_zclient->bfd_integration)
|
||||
bfd_nht_update(matched, nhr);
|
||||
|
||||
if (matched->family == AF_INET6)
|
||||
afi = AFI_IP6;
|
||||
|
||||
if (nhr->type == ZEBRA_ROUTE_CONNECT) {
|
||||
if (static_nexthop_is_local(vrf->vrf_id, matched,
|
||||
nhr->prefix.family))
|
||||
|
@ -233,8 +229,12 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched,
|
|||
if (nhtd) {
|
||||
nhtd->nh_num = nhr->nexthop_num;
|
||||
|
||||
static_nht_reset_start(matched, afi, nhr->safi, nhtd->nh_vrf_id);
|
||||
static_nht_update(NULL, NULL, matched, nhr->nexthop_num, afi, nhr->safi,
|
||||
/* The tracked nexthop might be used by IPv4 and IPv6 routes */
|
||||
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);
|
||||
} else
|
||||
zlog_err("No nhtd?");
|
||||
|
@ -361,7 +361,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
|
|||
if (reg) {
|
||||
if (nhtd->nh_num) {
|
||||
/* refresh with existing data */
|
||||
afi_t afi = prefix_afi(&lookup.nh);
|
||||
afi_t afi = prefix_afi(&rn->p);
|
||||
|
||||
if (nh->state == STATIC_NOT_INSTALLED ||
|
||||
nh->state == STATIC_SENT_TO_ZEBRA)
|
||||
|
|
|
@ -111,6 +111,7 @@ def do_config_inner(
|
|||
count,
|
||||
add=True,
|
||||
do_ipv6=False,
|
||||
do_ipv6_nexthop=False,
|
||||
do_sadr=False,
|
||||
via=None,
|
||||
vrf=None,
|
||||
|
@ -129,6 +130,8 @@ def do_config_inner(
|
|||
src_prefs = ["2001:db8:1111::/48", "2001:db8:2222::/48"]
|
||||
elif do_ipv6:
|
||||
super_prefs = ["2001::/48", "2002::/48"]
|
||||
elif do_ipv6_nexthop:
|
||||
super_prefs = ["11.0.0.0/8", "21.0.0.0/8"]
|
||||
else:
|
||||
super_prefs = ["10.0.0.0/8", "20.0.0.0/8"]
|
||||
|
||||
|
@ -142,11 +145,19 @@ def do_config_inner(
|
|||
matchvia = f"dev {via}"
|
||||
else:
|
||||
if vrf:
|
||||
via = "2102::2" if do_ipv6 else "102.0.0.2"
|
||||
matchvia = f"via {via} dev r1-eth1"
|
||||
via = "2102::2" if do_ipv6 or do_ipv6_nexthop else "102.0.0.2"
|
||||
matchvia = (
|
||||
f"via inet6 {via} dev r1-eth1"
|
||||
if not do_ipv6 and do_ipv6_nexthop
|
||||
else f"via {via} dev r1-eth1"
|
||||
)
|
||||
else:
|
||||
via = "2101::2" if do_ipv6 else "101.0.0.2"
|
||||
matchvia = f"via {via} dev r1-eth0"
|
||||
via = "2101::2" if do_ipv6 or do_ipv6_nexthop else "101.0.0.2"
|
||||
matchvia = (
|
||||
f"via inet6 {via} dev r1-eth0"
|
||||
if not do_ipv6 and do_ipv6_nexthop
|
||||
else f"via {via} dev r1-eth0"
|
||||
)
|
||||
|
||||
vrfdbg = " in vrf {}".format(vrf) if vrf else ""
|
||||
logger.debug("{} {} static {} routes{}".format(optype, count, iptype, vrfdbg))
|
||||
|
@ -201,6 +212,7 @@ def do_config_inner(
|
|||
|
||||
def do_config(*args, **kwargs):
|
||||
do_config_inner(*args, do_ipv6=False, do_sadr=False, **kwargs)
|
||||
do_config_inner(*args, do_ipv6=False, do_ipv6_nexthop=True, **kwargs)
|
||||
do_config_inner(*args, do_ipv6=True, do_sadr=False, **kwargs)
|
||||
do_config_inner(*args, do_ipv6=True, do_sadr=True, **kwargs)
|
||||
|
||||
|
|
Loading…
Reference in a new issue