summaryrefslogtreecommitdiffstats
path: root/bgpd
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2015-04-29 09:43:04 +0300
committerDavid Lamparter <equinox@opensourcerouting.org>2015-05-20 18:52:22 +0200
commitef757700d0fd51dc0b46df9d3631208919f9b779 (patch)
tree722b3898fc1793cda897fa685df7128df4dfbc56 /bgpd
parent6b2672f3c9493aef3495192e113f95a7db4b65bc (diff)
downloadquagga-ef757700d0fd51dc0b46df9d3631208919f9b779.tar.bz2
quagga-ef757700d0fd51dc0b46df9d3631208919f9b779.tar.xz
bgpd: allow using rtt in route-map's set metric
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>
Diffstat (limited to 'bgpd')
-rw-r--r--bgpd/bgp_packet.c2
-rw-r--r--bgpd/bgp_routemap.c56
-rw-r--r--bgpd/bgp_vty.c5
-rw-r--r--bgpd/bgpd.h1
4 files changed, 52 insertions, 12 deletions
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 18114ad5..7d27972e 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 4a0dac76..5467cfdc 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 00d766d6..62331635 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 40c381c2..58d1ecaf 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 */