Re: [RFCv2] Babel: add v4viav6 support

2022-04-01 Thread Andreas Rammhold
Toke Høiland-Jørgensen  writes:

> Andreas Rammhold  writes:
>
>> This implements [draft-ietf-babel-v4viav6] an IPv4 via IPv6 extension
>> to the Babel routing protocol that allows annoncing routes to an IPv4
>> prefix with an IPv6 next-hop, which makes it possible for IPv4 traffic
>> to flow through interfaces that have not been assigned an IPv4 address.
>>
>> The implementation is compatible with the current Babeld version (the
>> relevant changes can be seen in the [babeld PR]). I've verified this
>> with a few VMs in the following setup:
>>
>> Bird <- v4 only -> Bird <- v6 only -> Babeld <- v4 only -> Babeld
>>
>> Each routing daemon was running on their own VM and had L2 connectivity
>> to only its direct neighbors. At the nodes at the edges v4 networks have
>> been announced and full end-to-end communication was possible over the
>> mixed AF network. The v6 only link between Babel and Bird (at the
>> "center" of the above setup) did transport the v4 packets via the v6
>> link-local next hop addresses just as expected.
>>
>> Thanks to Toke Høiland-Jørgensen for early review on this work.
>>
>> [draft-ietf-babel-v4viav6]: 
>> https://datatracker.ietf.org/doc/draft-ietf-babel-v4viav6/
>> [babeld PR]: https://github.com/jech/babeld/pull/56
>
> Thank you for the respin! Code LGTM; only comment is that it would be
> nice if the documentation was changed to refer to the proper RFC number
> instead of draft-ieft-babel-v4viav6; but that can be fixed up when
> applying (after the number gets assigned hopefully soonish).

Agreed.

>
> Also, one small nit regarding the comment you left in:
>
>> +  /*
>> +   * When receiving requests, AEs 1 (IPv4) and 4 (v4-via-v6) MUST be
>> +   * treated in the same manner: the receiver processes the request as
>> +   * described in Section 3.8 of [RFC6126bis].  If an Update is sent, then
>> +   * it MAY be sent with AE 1 or 4, as described in Section 2.1 above,
>> +   * irrespective of which AE was used in the request.
>> +   */
>
> This is a bit long, especially when repeated in two places; also the ref
> to RFC6126bis is outdated. But maybe just shorten it to:
>
> /* RFC section 2.3: When receiving requests, AEs 1 (IPv4) and 4
>  * (v4-via-v6) MUST be treated in the same manner.
>  */

Agreed. 


@Maintainers: let me know if you want me to do these minor modifications
(once we have the required information) or if you are fine applying
those.



Regards,

Andi



[RFCv2] Babel: add v4viav6 support

2022-03-31 Thread Andreas Rammhold
This implements [draft-ietf-babel-v4viav6] an IPv4 via IPv6 extension
to the Babel routing protocol that allows annoncing routes to an IPv4
prefix with an IPv6 next-hop, which makes it possible for IPv4 traffic
to flow through interfaces that have not been assigned an IPv4 address.

The implementation is compatible with the current Babeld version (the
relevant changes can be seen in the [babeld PR]). I've verified this
with a few VMs in the following setup:

Bird <- v4 only -> Bird <- v6 only -> Babeld <- v4 only -> Babeld

Each routing daemon was running on their own VM and had L2 connectivity
to only its direct neighbors. At the nodes at the edges v4 networks have
been announced and full end-to-end communication was possible over the
mixed AF network. The v6 only link between Babel and Bird (at the
"center" of the above setup) did transport the v4 packets via the v6
link-local next hop addresses just as expected.

Thanks to Toke Høiland-Jørgensen for early review on this work.

[draft-ietf-babel-v4viav6]: 
https://datatracker.ietf.org/doc/draft-ietf-babel-v4viav6/
[babeld PR]: https://github.com/jech/babeld/pull/56
---

The draft has reached the "Proposed Standard" stage:
  
https://mailarchive.ietf.org/arch/msg/ietf-announce/oybMxQbud2RvpyBBn8hkMTKakm4/

The mentioned babeld PR has been merged and a new babel release has been
cut a few hours ago.

I've addressed the feedback gathered in 2020 when I posted this for the
first time. On the topic of "feature detection" I didn't invest any more
time. It seems like the conclusion was that the adminitrator has to
ensure that the host system provides the required capabilities. If it
doesn't then we don't try to disable features.

I've rebased this onto Bird 2.0.9 and rerun my test suite. Everything
looks fine.

 doc/bird.sgml |   6 +++
 proto/babel/babel.c   |  26 --
 proto/babel/babel.h   |   3 ++
 proto/babel/config.Y  |   5 +-
 proto/babel/packets.c | 114 ++
 5 files changed, 116 insertions(+), 38 deletions(-)

diff --git a/doc/bird.sgml b/doc/bird.sgml
index 1d5ae056..14758627 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -1892,6 +1892,7 @@ protocol babel [] {
algorithm ( hmac sha1 | hmac sha256 | hmac sha384 |
hmac sha512 | blake2s128 | blake2s256 | blake2b256 | blake2b512 );
};
+   ipv4 via ipv6 ;
};
 }
 
@@ -2000,6 +2001,11 @@ protocol babel [] {
   protocol will only accept HMAC-based algorithms or one of the Blake
   algorithms, and the length of the supplied password string must match the
   key size used by the selected algorithm.
+
+  ipv4 via ipv6 
+  If enabled, Bird will accept and emit IPv4-via-IPv6 routes when IPv4
+  addresses are absent from the interface as described in 
draft-ietf-babel-v4viav6.
+  Default: yes.
 
 
 Attributes
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 174fc9e2..cba407e3 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -965,8 +965,17 @@ babel_send_update_(struct babel_iface *ifa, btime changed, 
struct fib *rtable)
 msg.update.router_id = e->router_id;
 net_copy(&msg.update.net, e->n.addr);
 
-msg.update.next_hop = ((e->n.addr->type == NET_IP4) ?
-  ifa->next_hop_ip4 : ifa->next_hop_ip6);
+if (e->n.addr->type == NET_IP4) {
+  /* Always prefer v4 nexthop if set */
+  if(!ipa_zero(ifa->next_hop_ip4))
+msg.update.next_hop = ifa->next_hop_ip4;
+
+  /* Only send v4-via-v6 if enabled */
+  else if (ifa->cf->ip4_via_ip6)
+msg.update.next_hop = ifa->next_hop_ip6;
+} else {
+  msg.update.next_hop = ifa->next_hop_ip6;
+}
 
 /* Do not send route if next hop is unknown, e.g. no configured IPv4 
address */
 if (ipa_zero(msg.update.next_hop))
@@ -1261,6 +1270,12 @@ babel_handle_update(union babel_msg *m, struct 
babel_iface *ifa)
 return;
   }
 
+  /* Reject IPv4 via IPv6 routes if disabled */
+  if (!ifa->cf->ip4_via_ip6 && msg->net.type == NET_IP4 && 
ipa_is_ip6(msg->next_hop)) {
+DBG("Babel: Ignoring disabled IPv4 via IPv6 route.\n");
+return;
+  }
+
   /* Regular update */
   e = babel_get_entry(p, &msg->net);
   r = babel_get_route(p, e, nbr); /* the route entry indexed by neighbour */
@@ -1666,7 +1681,7 @@ babel_iface_update_addr4(struct babel_iface *ifa)
   ip_addr addr4 = ifa->iface->addr4 ? ifa->iface->addr4->ip : IPA_NONE;
   ifa->next_hop_ip4 = ipa_nonzero(ifa->cf->next_hop_ip4) ? 
ifa->cf->next_hop_ip4 : addr4;
 
-  if (ipa_zero(ifa->next_hop_ip4) && p->ip4_channel)
+  if (ipa_zero(ifa->next_hop_ip4) && p->ip4_channel && !ifa->cf->ip4_via_ip6)
 log(L_WARN "%s: Missing IPv4 next hop address for %s", p->p.name, 
ifa->ifname);
 
   if (ifa->up)
@@ -2049,8 +2064,8 @@ babel_show_interfaces(struct proto *P, const char *iff)
   }
 
   cli_msg(-1023, "%s:", p->p.name);
-  cli_msg(-1023, "%-10s %-6s %-5s %7s %6s %7s %-15s %s",
- "Interf