From baa376fc1ccc3879fb602d4f5c248f4ebb315d11 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timo=20Ter=C3=A4s?= Date: Wed, 29 Apr 2015 09:43:04 +0300 Subject: [PATCH] bgpd: allow using rtt in route-map's set metric MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Signed-off-by: David Lamparter (cherry picked from commit ef757700d0fd51dc0b46df9d3631208919f9b779) --- 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 6c1e9e2f9..bf8ba199e 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" #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: diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 7a7814d41..d32c79d20 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -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); diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 70d2c6001..5041e64ee 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -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) { diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 1e7a00628..b3e508634 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -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 */ -- 2.39.5