[quagga-dev 12200] [PATCH 6/7] bgpd: allow using rtt in route-map's set metric

Timo Teräs timo.teras at iki.fi
Wed Apr 29 07:43:04 BST 2015


Useful when the BGP neighbors are over tunnels that have large
differences in geographic distances and RTTs. Especially useful
for DMVPN setups to allow preferring closes hub.

The parameter is added as new alias command as otherwise it seems
the command parser is not able to match it properly (it seems
merging is done for the various 'set metric' route-map objects in
different routing engines). For same reason also they are listed
as three separate options: optional +/- seems not possibly easily.

Related research papers:
http://www.pps.univ-paris-diderot.fr/~jch/research/delay-based.pdf
http://arxiv.org/pdf/1309.0632.pdf

Paper on similar extension to Babel:
http://www.pps.univ-paris-diderot.fr/~jch/research/rapport-jonglez-2013.pdf

Signed-off-by: Timo Teräs <timo.teras at iki.fi>
---
 bgpd/bgp_packet.c   |  2 ++
 bgpd/bgp_routemap.c | 56 +++++++++++++++++++++++++++++++++++++++++------------
 bgpd/bgp_vty.c      |  5 +++++
 bgpd/bgpd.h         |  1 +
 4 files changed, 52 insertions(+), 12 deletions(-)

diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 14fd6e5..8e53445 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -28,6 +28,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "log.h"
 #include "memory.h"
 #include "sockunion.h"		/* for inet_ntop () */
+#include "sockopt.h"
 #include "linklist.h"
 #include "plist.h"
 
@@ -2592,6 +2593,7 @@ bgp_read (struct thread *thread)
     {
     case BGP_MSG_OPEN:
       peer->open_in++;
+      peer->rtt = sockopt_tcp_rtt(peer->fd);
       bgp_open_receive (peer, size); /* XXX return value ignored! */
       break;
     case BGP_MSG_UPDATE:
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 4a0dac7..5467cfd 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -110,22 +110,33 @@ o Local extensions
 struct rmap_value
 {
   u_int8_t action;
+  u_int8_t variable;
   u_int32_t value;
 };
 
 static int
 route_value_match (struct rmap_value *rv, u_int32_t value)
 {
-  if (value == rv->value)
+  if (rv->variable == 0 && value == rv->value)
     return RMAP_MATCH;
 
   return RMAP_NOMATCH;
 }
 
 static u_int32_t
-route_value_adjust (struct rmap_value *rv, u_int32_t current)
+route_value_adjust (struct rmap_value *rv, u_int32_t current, struct peer *peer)
 {
-  u_int32_t value = rv->value;
+  u_int32_t value;
+
+  switch (rv->variable)
+    {
+    case 1:
+      value = peer->rtt;
+      break;
+    default:
+      value = rv->value;
+      break;
+    }
 
   switch (rv->action)
     {
@@ -145,8 +156,8 @@ route_value_adjust (struct rmap_value *rv, u_int32_t current)
 static void *
 route_value_compile (const char *arg)
 {
-  u_int8_t action = RMAP_VALUE_SET;
-  unsigned long larg;
+  u_int8_t action = RMAP_VALUE_SET, var = 0;
+  unsigned long larg = 0;
   char *endptr = NULL;
   struct rmap_value *rv;
 
@@ -161,16 +172,27 @@ route_value_compile (const char *arg)
       arg++;
     }
 
-  errno = 0;
-  larg = strtoul (arg, &endptr, 10);
-  if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
-    return NULL;
+  if (all_digit(arg))
+    {
+      errno = 0;
+      larg = strtoul (arg, &endptr, 10);
+      if (*arg == 0 || *endptr != 0 || errno || larg > UINT32_MAX)
+        return NULL;
+    }
+  else
+    {
+      if (strcmp(arg, "rtt") == 0)
+        var = 1;
+      else
+        return NULL;
+    }
 
   rv = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof(struct rmap_value));
   if (!rv)
     return NULL;
 
   rv->action = action;
+  rv->variable = var;
   rv->value = larg;
   return rv;
 }
@@ -1050,7 +1072,7 @@ route_set_local_pref (void *rule, struct prefix *prefix,
 	locpref = bgp_info->attr->local_pref;
 
       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
-      bgp_info->attr->local_pref = route_value_adjust(rv, locpref);
+      bgp_info->attr->local_pref = route_value_adjust(rv, locpref, bgp_info->peer);
     }
 
   return RMAP_OKAY;
@@ -1083,7 +1105,7 @@ route_set_weight (void *rule, struct prefix *prefix, route_map_object_t type,
       bgp_info = object;
     
       /* Set weight value. */ 
-      weight = route_value_adjust(rv, 0);
+      weight = route_value_adjust(rv, 0, bgp_info->peer);
       if (weight)
         (bgp_attr_extra_get (bgp_info->attr))->weight = weight;
       else if (bgp_info->attr->extra)
@@ -1122,7 +1144,7 @@ route_set_metric (void *rule, struct prefix *prefix,
       if (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
 	med = bgp_info->attr->med;
 
-      bgp_info->attr->med = route_value_adjust(rv, med);
+      bgp_info->attr->med = route_value_adjust(rv, med, bgp_info->peer);
       bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
     }
   return RMAP_OKAY;
@@ -2974,6 +2996,15 @@ ALIAS (set_metric,
        "Metric value for destination routing protocol\n"
        "Add or subtract metric\n")
 
+ALIAS (set_metric,
+       set_metric_rtt_cmd,
+       "set metric (rtt|+rtt|-rtt)",
+       SET_STR
+       "Metric value for destination routing protocol\n"
+       "Assign round trip time\n"
+       "Add round trip time\n"
+       "Subtract round trip time\n")
+
 DEFUN (no_set_metric,
        no_set_metric_cmd,
        "no set metric",
@@ -3937,6 +3968,7 @@ bgp_route_map_init (void)
   install_element (RMAP_NODE, &no_set_weight_val_cmd);
   install_element (RMAP_NODE, &set_metric_cmd);
   install_element (RMAP_NODE, &set_metric_addsub_cmd);
+  install_element (RMAP_NODE, &set_metric_rtt_cmd);
   install_element (RMAP_NODE, &no_set_metric_cmd);
   install_element (RMAP_NODE, &no_set_metric_val_cmd);
   install_element (RMAP_NODE, &set_aspath_prepend_cmd);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 00d766d..6233163 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -7906,6 +7906,11 @@ bgp_show_peer (struct vty *vty, struct peer *p)
 #endif /* HAVE_IPV6 */
     }
 
+  /* TCP metrics. */
+  if (p->status == Established && p->rtt)
+    vty_out (vty, "Estimated round trip time: %d ms%s",
+	     p->rtt, VTY_NEWLINE);
+
   /* Timer information. */
   if (p->t_start)
     vty_out (vty, "Next start timer due in %ld seconds%s",
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 40c381c..58d1eca 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -331,6 +331,7 @@ struct peer
   /* Peer information */
   int fd;			/* File descriptor */
   int ttl;			/* TTL of TCP connection to the peer. */
+  int rtt;			/* Estimated round-trip-time from TCP_INFO */
   int gtsm_hops;		/* minimum hopcount to peer */
   char *desc;			/* Description of the peer. */
   unsigned short port;          /* Destination port for peer */
-- 
2.3.6





More information about the Quagga-dev mailing list