Re: Babel and Unnumbered interfaces

2024-03-30 Thread Pim van Pelt via Bird-users

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 [] {
 		check link ;
 		next hop ipv4 ;
 		next hop ipv6 ;
-		extended next hop ;
+		extended next hop |always;
 		rtt cost ;
 		rtt min ;
 		rtt max ;
@@ -2338,7 +2338,11 @@ protocol babel [] {
   extended next hop 
   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
-  . Default: yes.
+  . The order of preference when selecting a nexthop is: if
+  this option is set to rtt cost 
   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		0x
 
+#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  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; }


Re: Babel and Unnumbered interfaces

2024-03-30 Thread Juliusz Chroboczek
> I don't think it's a violation of the Babel protocol to use IPv6 next hops 
> when
> an IPv4 address is present.

Yes, it's legal, but discouraged.  Please see RFC 9229 Section 2.1:

   If the outgoing interface has been assigned an IPv4 address, then, in
   the interest of maximising compatibility with existing routers, the
   sender SHOULD prefer an ordinary IPv4 announcement; even in that
   case, however, it MAY send a v4-via-v6 announcement.

-- Juliusz


Babel and Unnumbered interfaces

2024-03-30 Thread Pim van Pelt via Bird-users

Hoi folks,

By means of context, I am working on allowing VPP and Bird2/Babel to 
program the routing table with IPv6 nexthops for IPv4 destinations.


I finished a few small code changes in VPP to allow transit-net-less 
transport of IPv4 and IPv6 in VPP and wrote about it on 
https://ipng.ch/s/articles/2024/03/06/vpp-babel-1.html 
. Considering 
this dataplane has some different idioms than Linux, it took a bit of 
work. I thought you might find this VPP + Bird2 + Babel story from the 
field interesting. I wanted to ask you to read the article, and in 
particular the /Additional thoughts/ section at the bottom, as it tries 
to ask for opinions on a somewhat complex topic of unnumbered 
point-to-point interfaces in VPP.


On the VPP side, I have a small change 
(https://gerrit.fd.io/r/c/vpp/+/40482) that builds support for 
point-to-point over Ethernet. With this approach, VPP will copy the IPv4 
and IPv6 address over from a loopback interface to the ethernet transit 
networks.


In the article above, I mentioned in /Approach 3/,

   One option is to ask Babel to use |extended next hop| even when IPv4
   is available, which would be a change to Bird (and possibly a
   violation of the Babel specification, I should read up on that).


I don't think it's a violation of the Babel protocol to use IPv6 next 
hops when an IPv4 address is present. However, I noticed that in 
proto/babel/babel.c function babel_send_update_() the protocol /always/ 
prefers IPv4 when it's set.


My question: would it be feasible to extend the configuration syntax of 
/extended next hop/ to also allow keyword /always/, in which case the 
IPv6 nexthop is preferred even if an IPv4 address is present? The logic 
in proto/babel/babel.c 1039-1950 seems straight-forward to adapt to this 
case, in a non-intrusive way.


I can attempt a patch if the Bird (and Babel) community believes this is 
a useful behavior.


groet,
Pim

--
Pim van Pelt
PBVP1-RIPE -https://ipng.ch/