]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Babel: Add option 'next hop prefer' to control next hops of IPv4 routes
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 27 Mar 2025 01:50:35 +0000 (02:50 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 27 Mar 2025 01:50:35 +0000 (02:50 +0100)
By default, the Babel protocol will advertise IPv4 routes with an IPv6
next hop address only on interfaces which do not have an IPv4 address.

Add option 'next hop prefer' to control whether IPv4 routes should use
IPv4 or IPv6 next hop when both are available.

Based on the patch from Chris Webb, thanks!

.gitlab-ci.yml
doc/bird.sgml
proto/babel/babel.c
proto/babel/babel.h
proto/babel/config.Y

index 7634f46a5c860eeab80e3cf5357387f216aa2a5c..fd7582770a2ef1de661a92e59c8a5f188fa3836e 100644 (file)
@@ -490,11 +490,6 @@ test-bgp-rs-multitab:
   variables:
     TEST_NAME: cf-bgp-rs-multitab
 
-test-bgp-rs-singletab:
-  <<: *test-base
-  variables:
-    TEST_NAME: cf-bgp-rs-singletab
-
 test-ebgp-loop:
   <<: *test-base
   variables:
index 6515bdf3648b6488599af74e4fddedee3e7b80de..1a94739023b2244df538ff8289947ae12ddb0f98 100644 (file)
@@ -2312,7 +2312,7 @@ protocol babel [<name>] {
        ipv6 [sadr] { <channel config> };
        randomize router id <switch>;
        interface <interface pattern> {
-               type <wired|wireless|tunnel>;
+               type wired|wireless|tunnel;
                rxcost <number>;
                limit <number>;
                hello interval <time>;
@@ -2325,6 +2325,7 @@ protocol babel [<name>] {
                check link <switch>;
                next hop ipv4 <address>;
                next hop ipv6 <address>;
+               next hop prefer native|ipv6;
                extended next hop <switch>;
                rtt cost <number>;
                rtt min <time>;
@@ -2427,19 +2428,28 @@ protocol babel [<name>] {
       yes.
 
       <tag><label id="babel-next-hop-ipv4">next hop ipv4 <m/address/</tag>
-      Set the next hop address advertised for IPv4 routes advertised on this
-      interface. Default: the preferred IPv4 address of the interface.
+      Set the IPv4 next hop address advertised for (IPv4) routes advertised on
+      this interface. Default: the preferred IPv4 address of the interface.
 
       <tag><label id="babel-next-hop-ipv6">next hop ipv6 <m/address/</tag>
-      Set the next hop address advertised for IPv6 routes advertised on this
+      Set the IPv6 next hop address advertised for routes advertised on this
       interface. If not set, the same link-local address that is used as the
       source for Babel packets will be used. In normal operation, it should not
       be necessary to set this option.
 
+      <tag><label id="babel-next-hop-prefer">next hop prefer native|ipv6</tag>
+      By default, BIRD prefers to advertise IPv4 routes with an IPv4 next hop
+      address, using an IPv6 next hop address only when IPv4 addresses are
+      absent from the interface. When set to <cf/ipv6/, BIRD will advertise IPv4
+      routes with an IPv6 next hop address even when IPv4 addresses are present
+      on the interface (assuming the option <ref id="babel-extended-next-hop"
+      name="extended next hop"> is enabled). Default: native.
+
       <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.
+      Specify whether BIRD should allow IPv4 routes with an IPv6 next hop, as
+      described in <rfc id="9229">. Note that when both IPv4 and IPv6 next hops
+      are available, the option <ref id="babel-next-hop-prefer"
+      name="next hop prefer"> controls which one is advertised. 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
index b5cbb63f8591846225646953a86fb801e221601a..cc9bc7647eed114b438eb836a9cd7ceac00ea0e5 100644 (file)
@@ -1038,13 +1038,18 @@ 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))
+      /* Use IPv4 nexthop if available and preferred */
+      if (ipa_nonzero(ifa->next_hop_ip4) &&
+         (ifa->cf->next_hop_prefer == BABEL_NHP_NATIVE))
         msg.update.next_hop = ifa->next_hop_ip4;
 
       /* Only send IPv6 nexthop if enabled */
       else if (ifa->cf->ext_next_hop)
         msg.update.next_hop = ifa->next_hop_ip6;
+
+      /* Fallback (prefer IPv6 but !ext_next_hop) */
+      else
+       msg.update.next_hop = ifa->next_hop_ip4;
     }
     else
       msg.update.next_hop = ifa->next_hop_ip6;
index edde4cabe6b13a00be914fbf349de955f34bdb60..7e070f2dbb5f08ffecdec57329de3da9c1fae315 100644 (file)
@@ -118,6 +118,11 @@ enum babel_iface_type {
   BABEL_IFACE_TYPE_MAX
 };
 
+enum babel_next_hop_prefer {
+  BABEL_NHP_NATIVE             = 0,
+  BABEL_NHP_IP6                        = 1,
+};
+
 enum babel_ae_type {
   BABEL_AE_WILDCARD            = 0,
   BABEL_AE_IP4                 = 1,
@@ -163,6 +168,7 @@ struct babel_iface_config {
 
   ip_addr next_hop_ip4;
   ip_addr next_hop_ip6;
+  u8 next_hop_prefer;                  /* Prefer native or IPv6 nexthop */
   u8 ext_next_hop;                     /* Enable IPv4 via IPv6 */
 
   u8 auth_type;                                /* Authentication type (BABEL_AUTH_*) */
index d412a54b575feca507438e9807739052a92f1daa..de628f7aaa9915669ec891e2ed8ff46b3c79bee4 100644 (file)
@@ -26,7 +26,8 @@ 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,
        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, COST, DELAY,
+       PREFER, NATIVE)
 
 CF_GRAMMAR
 
@@ -158,6 +159,8 @@ 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"); }
+ | NEXT HOP PREFER NATIVE { BABEL_IFACE->next_hop_prefer = BABEL_NHP_NATIVE; }
+ | NEXT HOP PREFER IPV6 { BABEL_IFACE->next_hop_prefer = BABEL_NHP_IP6; }
  | EXTENDED NEXT HOP bool { 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; }