Resend of the patch in 
http://trubka.network.cz/pipermail/bird-users/2023-June/017058.html

ETX link quality estimation algorithm is useful for link types other than 
wireless,
especially when using babel with tunnels where packet losses do occur.
---
 doc/bird.sgml        | 10 ++++++++++
 proto/babel/babel.c  |  8 +++-----
 proto/babel/babel.h  |  8 ++++++++
 proto/babel/config.Y |  8 +++++++-
 4 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/doc/bird.sgml b/doc/bird.sgml
index f2063325..1a9bab87 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -2209,6 +2209,7 @@ protocol babel [<name>] {
                rx buffer <number>;
                tx length <number>;
                check link <switch>;
+               link quality <none|etx>;
                next hop ipv4 <address>;
                next hop ipv6 <address>;
                extended next hop <switch>;
@@ -2312,6 +2313,15 @@ protocol babel [<name>] {
       hardware drivers or platforms do not implement this feature. Default:
       yes.
 
+      <tag><label id="babel-link-quality">link quality none|etx </tag>
+      This option specifies the link quality estimation algorithm for computing
+      costs based on Hello history: none or etx. The none (k-out-of-j) 
algorithm
+      is suitable for wired links that are either up, in which case they only
+      occasionally drop a packet, or down, in which case they drop all packets.
+      The Expected Transmission Cost algorithm, or etx, is suitable for 
wireless
+      links that exhibit continuous variation of the link quality. Default: 
etx for
+      wireless interfaces, none otherwise.
+
       <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.
diff --git a/proto/babel/babel.c b/proto/babel/babel.c
index 4187d258..f865c089 100644
--- a/proto/babel/babel.c
+++ b/proto/babel/babel.c
@@ -593,10 +593,9 @@ babel_update_cost(struct babel_neighbor *nbr)
   if (!rcv || !nbr->ifa->up)
     goto done;
 
-  switch (cf->type)
+  switch (cf->link_quality)
   {
-  case BABEL_IFACE_TYPE_WIRED:
-  case BABEL_IFACE_TYPE_TUNNEL:
+  case BABEL_IFACE_LINK_QUALITY_NONE:
     /* k-out-of-j selection - Appendix 2.1 in the RFC. */
 
     /* Link is bad if less than cf->limit/16 of expected hellos were received 
*/
@@ -606,8 +605,7 @@ babel_update_cost(struct babel_neighbor *nbr)
     rxcost =  cf->rxcost;
     txcost = nbr->txcost;
     break;
-
-  case BABEL_IFACE_TYPE_WIRELESS:
+  case BABEL_IFACE_LINK_QUALITY_ETX:
     /*
      * ETX - Appendix 2.2 in the RFC.
      *
diff --git a/proto/babel/babel.h b/proto/babel/babel.h
index edde4cab..6a2968f1 100644
--- a/proto/babel/babel.h
+++ b/proto/babel/babel.h
@@ -118,6 +118,13 @@ enum babel_iface_type {
   BABEL_IFACE_TYPE_MAX
 };
 
+enum babel_iface_link_quality {
+  BABEL_IFACE_LINK_QUALITY_UNDEF       = 0,
+  BABEL_IFACE_LINK_QUALITY_NONE        = 1,
+  BABEL_IFACE_LINK_QUALITY_ETX         = 2,
+  BABEL_IFACE_LINK_QUALITY_MAX
+};
+
 enum babel_ae_type {
   BABEL_AE_WILDCARD            = 0,
   BABEL_AE_IP4                 = 1,
@@ -145,6 +152,7 @@ struct babel_iface_config {
   u8 type;
   u8 limit;                            /* Minimum number of Hellos to keep 
link up */
   u8 check_link;
+  u8 link_quality;
   uint port;
   uint hello_interval;                 /* Hello interval, in us */
   uint ihu_interval;                   /* IHU interval, in us */
diff --git a/proto/babel/config.Y b/proto/babel/config.Y
index b8af0267..285a3f33 100644
--- a/proto/babel/config.Y
+++ b/proto/babel/config.Y
@@ -26,7 +26,7 @@ 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)
+       EXTENDED, TUNNEL, RTT, MIN, MAX, DECAY, SEND, TIMESTAMPS, QUALITY, ETX)
 
 CF_GRAMMAR
 
@@ -84,6 +84,8 @@ babel_iface_finish:
       BABEL_IFACE->hello_interval = BABEL_HELLO_INTERVAL_WIRELESS;
     if (!BABEL_IFACE->rxcost)
       BABEL_IFACE->rxcost = BABEL_RXCOST_WIRELESS;
+    if (!BABEL_IFACE->link_quality)
+      BABEL_IFACE->link_quality = BABEL_IFACE_LINK_QUALITY_ETX;
   }
   else
   {
@@ -93,6 +95,8 @@ babel_iface_finish:
       BABEL_IFACE->rxcost = BABEL_RXCOST_WIRED;
     if (BABEL_IFACE->type == BABEL_IFACE_TYPE_TUNNEL && !BABEL_IFACE->rtt_cost)
       BABEL_IFACE->rtt_cost = BABEL_RXCOST_RTT;
+    if (!BABEL_IFACE->link_quality)
+      BABEL_IFACE->link_quality = BABEL_IFACE_LINK_QUALITY_NONE;
   }
 
   if (BABEL_IFACE->rtt_cost && !BABEL_IFACE->rtt_send)
@@ -156,6 +160,8 @@ babel_iface_item:
  | TX tos { BABEL_IFACE->tx_tos = $2; }
  | TX PRIORITY expr { BABEL_IFACE->tx_priority = $3; }
  | CHECK LINK bool { BABEL_IFACE->check_link = $3; }
+ | LINK QUALITY NONE { BABEL_IFACE->link_quality = 
BABEL_IFACE_LINK_QUALITY_NONE; }
+ | LINK QUALITY ETX { BABEL_IFACE->link_quality = 
BABEL_IFACE_LINK_QUALITY_ETX; }
  | 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; }
-- 
2.42.0

Reply via email to