]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: allow using rtt in route-map's set metric
authorTimo Teräs <timo.teras@iki.fi>
Wed, 29 Apr 2015 06:43:04 +0000 (09:43 +0300)
committervivek <vivek@cumulusnetworks.com>
Mon, 6 Jun 2016 15:25:42 +0000 (08:25 -0700)
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@iki.fi>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from commit ef757700d0fd51dc0b46df9d3631208919f9b779)

bgpd/bgp_packet.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c
bgpd/bgpd.h

index 6c1e9e2f960b1c9ac632a7c9632c6f13e229222c..bf8ba199e4afd2512f1967e34cf32598bd2e3ae5 100644 (file)
@@ -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"
 #include "queue.h"
@@ -2345,6 +2346,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:
index 7a7814d414b0a07b74d3c02042f4352a46e81ffd..d32c79d20487ee02b32eeb9354c6cbca2c52e1ee 100644 (file)
@@ -117,22 +117,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)
     {
@@ -152,8 +163,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;
 
@@ -168,16 +179,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;
 }
@@ -1244,7 +1266,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;
@@ -1277,7 +1299,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)
@@ -1316,7 +1338,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;
@@ -3640,6 +3662,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",
@@ -4625,6 +4656,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);
index 70d2c60010ca116272e3d85634ccb382d20fcd4e..5041e64eebd2a1a061e4e8217006a53a16496acd 100644 (file)
@@ -12030,6 +12030,11 @@ bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *js
         }
     }
 
+  /* 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 (use_json)
     {
index 1e7a00628fd11d8dc8099b1c647fd3e10112856d..b3e508634e7f3aad23586f3a5577df6d0c78b989 100644 (file)
@@ -569,6 +569,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 */