Hoi,
On 3/30/24 19:24, Juliusz Chroboczek wrote:
Yes, it's legal, but discouraged. Please see RFC 9229 Section 2.1:
Thanks Juliusz, for confirming and for making the allowance in the RFC
in the first place.
Attached is a patch that optionally allows extended next hop to be set
for IPv4 routes. Please take a look.
groet,
Pim
--
Pim van Pelt
PBVP1-RIPE -https://ipng.ch/
diff --git a/doc/bird.sgml b/doc/bird.sgml
index d0bfabdb..35c36484 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -2224,7 +2224,7 @@ protocol babel [<name>] {
check link <switch>;
next hop ipv4 <address>;
next hop ipv6 <address>;
- extended next hop <switch>;
+ extended next hop <switch>|always;
rtt cost <number>;
rtt min <time>;
rtt max <time>;
@@ -2338,7 +2338,11 @@ protocol babel [<name>] {
<tag><label id="babel-extended-next-hop">extended next hop <m/switch/</tag>
If enabled, BIRD will accept and emit IPv4 routes with an IPv6 next
hop when IPv4 addresses are absent from the interface as described in
- <rfc id="9229">. Default: yes.
+ <rfc id="9229">. The order of preference when selecting a nexthop is: if
+ this option is set to <cf/always/, IPv6 nexthop is always used; otherwise,
+ if an IPv4 address is present on the interface, then IPv4 is used; otherwise,
+ if this option is set to yes, then IPv6 is used. Default: yes.
+
<tag><label id="babel-rtt-cost">rtt cost <m/number/</tag>
The RTT-based cost that will be applied to all routes from each neighbour
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 4187d258..846baf7a 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -1038,12 +1038,16 @@ babel_send_update_(struct babel_iface *ifa, btime changed, struct fib *rtable)
if (e->n.addr->type == NET_IP4)
{
- /* Always prefer IPv4 nexthop if set */
- if (ipa_nonzero(ifa->next_hop_ip4))
+ /* Order of preference:
+ * 1) IPv6 iff extended next hop always; is set
+ * 2) IPv4 if there's an IPv4 address on the interface
+ * 3) IPv6 if extended next hop on; is set
+ */
+ if (ifa->cf->ext_next_hop == BABEL_EXTNH_ALWAYS)
+ msg.update.next_hop = ifa->next_hop_ip6;
+ else if (ipa_nonzero(ifa->next_hop_ip4))
msg.update.next_hop = ifa->next_hop_ip4;
-
- /* Only send IPv6 nexthop if enabled */
- else if (ifa->cf->ext_next_hop)
+ else if (ifa->cf->ext_next_hop == BABEL_EXTNH_ON)
msg.update.next_hop = ifa->next_hop_ip6;
}
else
diff --git a/proto/babel/babel.h b/proto/babel/babel.h
index edde4cab..0582a3fc 100644
--- a/proto/babel/babel.h
+++ b/proto/babel/babel.h
@@ -35,6 +35,9 @@
#define BABEL_PORT 6696
#define BABEL_INFINITY 0xFFFF
+#define BABEL_EXTNH_ON 1
+#define BABEL_EXTNH_ALWAYS 2
+
#define BABEL_HELLO_INTERVAL_WIRED (4 S_) /* Default hello intervals in seconds */
#define BABEL_HELLO_INTERVAL_WIRELESS (4 S_)
diff --git a/proto/babel/config.Y b/proto/babel/config.Y
index d412a54b..a1d4c017 100644
--- a/proto/babel/config.Y
+++ b/proto/babel/config.Y
@@ -24,9 +24,11 @@ CF_DECLS
CF_KEYWORDS(BABEL, INTERFACE, METRIC, RXCOST, HELLO, UPDATE, INTERVAL, PORT,
TYPE, WIRED, WIRELESS, RX, TX, BUFFER, PRIORITY, LENGTH, CHECK, LINK,
- NEXT, HOP, IPV4, IPV6, BABEL_METRIC, SHOW, INTERFACES, NEIGHBORS,
+ NEXT, HOP, ALWAYS, IPV4, IPV6, BABEL_METRIC, SHOW, INTERFACES, NEIGHBORS,
ENTRIES, RANDOMIZE, ROUTER, ID, AUTHENTICATION, NONE, MAC, PERMISSIVE,
- EXTENDED, TUNNEL, RTT, MIN, MAX, DECAY, SEND, TIMESTAMPS, COST, DELAY)
+ EXTENDED, TUNNEL, RTT, MIN, MAX, DECAY, SEND, TIMESTAMPS)
+
+%type <i> babel_extnh
CF_GRAMMAR
@@ -142,6 +144,10 @@ babel_iface_finish:
};
+babel_extnh:
+ bool { $$ = $1; }
+ | ALWAYS { $$ = BABEL_EXTNH_ALWAYS; }
+
babel_iface_item:
| PORT expr { BABEL_IFACE->port = $2; if (($2<1) || ($2>65535)) cf_error("Invalid port number"); }
| RXCOST expr { BABEL_IFACE->rxcost = $2; if (($2<1) || ($2>65535)) cf_error("Invalid rxcost"); }
@@ -158,7 +164,7 @@ babel_iface_item:
| CHECK LINK bool { BABEL_IFACE->check_link = $3; }
| NEXT HOP IPV4 ipa { BABEL_IFACE->next_hop_ip4 = $4; if (!ipa_is_ip4($4)) cf_error("Must be an IPv4 address"); }
| NEXT HOP IPV6 ipa { BABEL_IFACE->next_hop_ip6 = $4; if (!ipa_is_ip6($4)) cf_error("Must be an IPv6 address"); }
- | EXTENDED NEXT HOP bool { BABEL_IFACE->ext_next_hop = $4; }
+ | EXTENDED NEXT HOP babel_extnh { BABEL_IFACE->ext_next_hop = $4; }
| AUTHENTICATION NONE { BABEL_IFACE->auth_type = BABEL_AUTH_NONE; }
| AUTHENTICATION MAC { BABEL_IFACE->auth_type = BABEL_AUTH_MAC; BABEL_IFACE->auth_permissive = 0; }
| AUTHENTICATION MAC PERMISSIVE { BABEL_IFACE->auth_type = BABEL_AUTH_MAC; BABEL_IFACE->auth_permissive = 1; }