summaryrefslogtreecommitdiffstats
path: root/zebra
diff options
context:
space:
mode:
authorRuss White <russ@riw.us>2017-09-13 22:18:41 +0200
committerGitHub <noreply@github.com>2017-09-13 22:18:41 +0200
commitdcc4574ae63716e15c5a6df7f76a3e01eea70afe (patch)
tree3b193c225a6e61e7ac6472225c33b37b3a56354b /zebra
parentMerge pull request #1170 from donaldsharp/ospf6d_crashasplat (diff)
parentzebra: Allow 'show ip route...' to display uptime for all routes (diff)
downloadfrr-dcc4574ae63716e15c5a6df7f76a3e01eea70afe.tar.xz
frr-dcc4574ae63716e15c5a6df7f76a3e01eea70afe.zip
Merge pull request #1163 from donaldsharp/deduplicate_nexthops
zebra: deduplicate nexthops
Diffstat (limited to 'zebra')
-rw-r--r--zebra/rt_netlink.c6
-rw-r--r--zebra/rt_socket.c4
-rw-r--r--zebra/zebra_rib.c16
-rw-r--r--zebra/zebra_vty.c140
4 files changed, 85 insertions, 81 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 12b618539..e59d5f00f 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -1383,7 +1383,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
continue;
if (cmd == RTM_NEWROUTE
- && !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ && !NEXTHOP_IS_ACTIVE(nexthop->flags))
continue;
if (cmd == RTM_DELROUTE
&& !CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
@@ -1438,7 +1438,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
}
if ((cmd == RTM_NEWROUTE
- && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ && NEXTHOP_IS_ACTIVE(nexthop->flags))
|| (cmd == RTM_DELROUTE
&& CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_FIB))) {
@@ -1521,7 +1521,7 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
}
if ((cmd == RTM_NEWROUTE
- && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ && NEXTHOP_IS_ACTIVE(nexthop->flags))
|| (cmd == RTM_DELROUTE
&& CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_FIB))) {
diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c
index d8e37a10c..75207a2dd 100644
--- a/zebra/rt_socket.c
+++ b/zebra/rt_socket.c
@@ -136,7 +136,7 @@ static int kernel_rtm_ipv4(int cmd, struct prefix *p, struct route_entry *re)
* other than ADD and DELETE?
*/
if ((cmd == RTM_ADD
- && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ && NEXTHOP_IS_ACTIVE(nexthop->flags))
|| (cmd == RTM_DELETE
&& CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))) {
if (nexthop->type == NEXTHOP_TYPE_IPV4
@@ -314,7 +314,7 @@ static int kernel_rtm_ipv6(int cmd, struct prefix *p, struct route_entry *re)
gate = 0;
if ((cmd == RTM_ADD
- && CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
+ && NEXTHOP_IS_ACTIVE(nexthop->flags))
|| (cmd == RTM_DELETE
#if 0
&& CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 376425329..d04b64b19 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1000,8 +1000,24 @@ int rib_install_kernel(struct route_node *rn, struct route_entry *re,
for (ALL_NEXTHOPS(re->nexthop, nexthop))
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
return ret;
+ } else {
+ struct nexthop *prev;
+
+ for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
+ UNSET_FLAG (nexthop->flags, NEXTHOP_FLAG_DUPLICATE);
+ for (ALL_NEXTHOPS(re->nexthop, prev)) {
+ if (prev == nexthop)
+ break;
+ if (nexthop_same_firsthop (nexthop, prev))
+ {
+ SET_FLAG (nexthop->flags, NEXTHOP_FLAG_DUPLICATE);
+ break;
+ }
+ }
+ }
}
+
/*
* Make sure we update the FPM any time we send new information to
* the kernel.
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 1573646ad..1ce4f66b1 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -408,39 +408,34 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
vty_out(vty, ", best");
vty_out(vty, "\n");
- if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF
- || re->type == ZEBRA_ROUTE_ISIS
- || re->type == ZEBRA_ROUTE_NHRP
- || re->type == ZEBRA_ROUTE_TABLE
- || re->type == ZEBRA_ROUTE_BGP) {
- time_t uptime;
- struct tm *tm;
-
- uptime = time(NULL);
- uptime -= re->uptime;
- tm = gmtime(&uptime);
-
- vty_out(vty, " Last update ");
-
- if (uptime < ONE_DAY_SECOND)
- vty_out(vty, "%02d:%02d:%02d", tm->tm_hour,
- tm->tm_min, tm->tm_sec);
- else if (uptime < ONE_WEEK_SECOND)
- vty_out(vty, "%dd%02dh%02dm", tm->tm_yday,
- tm->tm_hour, tm->tm_min);
- else
- vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7,
- tm->tm_yday - ((tm->tm_yday / 7) * 7),
- tm->tm_hour);
- vty_out(vty, " ago\n");
- }
+ time_t uptime;
+ struct tm *tm;
+
+ uptime = time(NULL);
+ uptime -= re->uptime;
+ tm = gmtime(&uptime);
+
+ vty_out(vty, " Last update ");
+
+ if (uptime < ONE_DAY_SECOND)
+ vty_out(vty, "%02d:%02d:%02d", tm->tm_hour,
+ tm->tm_min, tm->tm_sec);
+ else if (uptime < ONE_WEEK_SECOND)
+ vty_out(vty, "%dd%02dh%02dm", tm->tm_yday,
+ tm->tm_hour, tm->tm_min);
+ else
+ vty_out(vty, "%02dw%dd%02dh", tm->tm_yday / 7,
+ tm->tm_yday - ((tm->tm_yday / 7) * 7),
+ tm->tm_hour);
+ vty_out(vty, " ago\n");
for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
char addrstr[32];
vty_out(vty, " %c%s",
CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
- ? '*'
+ ? CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)
+ ? ' ' : '*'
: ' ',
nexthop->rparent ? " " : "");
@@ -489,6 +484,9 @@ static void vty_show_ip_route_detail(struct vty *vty, struct route_node *rn,
default:
break;
}
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
+ vty_out(vty, " (duplicate nexthop removed)");
+
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
vty_out(vty, " inactive");
@@ -553,6 +551,12 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
json_object *json_nexthop = NULL;
json_object *json_route = NULL;
json_object *json_labels = NULL;
+ time_t uptime;
+ struct tm *tm;
+
+ uptime = time(NULL);
+ uptime -= re->uptime;
+ tm = gmtime(&uptime);
if (json) {
json_route = json_object_new_object();
@@ -579,35 +583,26 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
json_object_int_add(json_route, "metric", re->metric);
}
- if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF
- || re->type == ZEBRA_ROUTE_ISIS
- || re->type == ZEBRA_ROUTE_NHRP
- || re->type == ZEBRA_ROUTE_TABLE
- || re->type == ZEBRA_ROUTE_BGP) {
- time_t uptime;
- struct tm *tm;
-
- uptime = time(NULL);
- uptime -= re->uptime;
- tm = gmtime(&uptime);
-
- if (uptime < ONE_DAY_SECOND)
- sprintf(buf, "%02d:%02d:%02d", tm->tm_hour,
- tm->tm_min, tm->tm_sec);
- else if (uptime < ONE_WEEK_SECOND)
- sprintf(buf, "%dd%02dh%02dm", tm->tm_yday,
- tm->tm_hour, tm->tm_min);
- else
- sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7,
- tm->tm_yday - ((tm->tm_yday / 7) * 7),
- tm->tm_hour);
+ if (uptime < ONE_DAY_SECOND)
+ sprintf(buf, "%02d:%02d:%02d", tm->tm_hour,
+ tm->tm_min, tm->tm_sec);
+ else if (uptime < ONE_WEEK_SECOND)
+ sprintf(buf, "%dd%02dh%02dm", tm->tm_yday,
+ tm->tm_hour, tm->tm_min);
+ else
+ sprintf(buf, "%02dw%dd%02dh", tm->tm_yday / 7,
+ tm->tm_yday - ((tm->tm_yday / 7) * 7),
+ tm->tm_hour);
- json_object_string_add(json_route, "uptime", buf);
- }
+ json_object_string_add(json_route, "uptime", buf);
for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
json_nexthop = json_object_new_object();
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
+ json_object_boolean_true_add(json_nexthop,
+ "duplicate");
+
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB))
json_object_boolean_true_add(json_nexthop,
"fib");
@@ -687,6 +682,10 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
break;
}
+ if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE))
+ json_object_boolean_true_add(json_nexthop,
+ "duplicate");
+
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
json_object_boolean_true_add(json_nexthop,
"active");
@@ -774,12 +773,14 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
if (re->type != ZEBRA_ROUTE_CONNECT)
len += vty_out(vty, " [%d/%d]", re->distance,
re->metric);
- } else
+ } else {
vty_out(vty, " %c%*c",
CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
- ? '*'
+ ? CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)
+ ? ' ' : '*'
: ' ',
len - 3 + (2 * nexthop_level(nexthop)), ' ');
+ }
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4:
@@ -862,29 +863,16 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,
sizeof buf, 1));
}
- if (re->type == ZEBRA_ROUTE_RIP || re->type == ZEBRA_ROUTE_OSPF
- || re->type == ZEBRA_ROUTE_ISIS
- || re->type == ZEBRA_ROUTE_NHRP
- || re->type == ZEBRA_ROUTE_TABLE
- || re->type == ZEBRA_ROUTE_BGP) {
- time_t uptime;
- struct tm *tm;
-
- uptime = time(NULL);
- uptime -= re->uptime;
- tm = gmtime(&uptime);
-
- if (uptime < ONE_DAY_SECOND)
- vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour,
- tm->tm_min, tm->tm_sec);
- else if (uptime < ONE_WEEK_SECOND)
- vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday,
- tm->tm_hour, tm->tm_min);
- else
- vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7,
- tm->tm_yday - ((tm->tm_yday / 7) * 7),
- tm->tm_hour);
- }
+ if (uptime < ONE_DAY_SECOND)
+ vty_out(vty, ", %02d:%02d:%02d", tm->tm_hour,
+ tm->tm_min, tm->tm_sec);
+ else if (uptime < ONE_WEEK_SECOND)
+ vty_out(vty, ", %dd%02dh%02dm", tm->tm_yday,
+ tm->tm_hour, tm->tm_min);
+ else
+ vty_out(vty, ", %02dw%dd%02dh", tm->tm_yday / 7,
+ tm->tm_yday - ((tm->tm_yday / 7) * 7),
+ tm->tm_hour);
vty_out(vty, "\n");
}
}