diff options
-rw-r--r-- | bgpd/bgp_packet.c | 2 | ||||
-rw-r--r-- | bgpd/bgp_routemap.c | 56 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 5 | ||||
-rw-r--r-- | bgpd/bgpd.h | 1 |
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 */ |