diff options
author | Timo Teräs <timo.teras@iki.fi> | 2016-01-15 17:36:32 +0200 |
---|---|---|
committer | Paul Jakma <paul.jakma@hpe.com> | 2016-02-26 14:11:46 +0000 |
commit | 4d3ae716ce86c28e3979c9ae57c4e717ac5e27e4 (patch) | |
tree | 42d84ffb3cfe8a1f267c059e3a62fea87554f1c7 | |
parent | 325823a5f07d6850318e52f6e66691eca59d24fe (diff) | |
download | quagga-4d3ae716ce86c28e3979c9ae57c4e717ac5e27e4.tar.bz2 quagga-4d3ae716ce86c28e3979c9ae57c4e717ac5e27e4.tar.xz |
zebra: remove metric from kernel
It simplifies things as we can do atomic replace of route prefix.
And it seems there's some race condition somewhere that can result
in an incorrect change request leaving prefixes in kernel when
they were intended to be replaced/deleted.
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
-rw-r--r-- | zebra/rt_netlink.c | 40 | ||||
-rw-r--r-- | zebra/rt_netlink.h | 1 |
2 files changed, 12 insertions, 29 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 6e22d63f..930271d0 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -667,7 +667,6 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, int index; int table; - int metric; u_int32_t mtu = 0; void *dest; @@ -709,7 +708,6 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, flags |= ZEBRA_FLAG_SELFROUTE; index = 0; - metric = 0; dest = NULL; gate = NULL; src = NULL; @@ -728,9 +726,6 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, if (tb[RTA_GATEWAY]) gate = RTA_DATA (tb[RTA_GATEWAY]); - if (tb[RTA_PRIORITY]) - metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]); - if (tb[RTA_METRICS]) { struct rtattr *mxrta[RTAX_MAX+1]; @@ -752,7 +747,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, if (!tb[RTA_MULTIPATH]) rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index, - vrf_id, table, metric, mtu, 0, SAFI_UNICAST); + vrf_id, table, 0, mtu, 0, SAFI_UNICAST); else { /* This is a multipath route */ @@ -767,7 +762,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, rib->type = ZEBRA_ROUTE_KERNEL; rib->distance = 0; rib->flags = flags; - rib->metric = metric; + rib->metric = 0; rib->mtu = mtu; rib->vrf_id = vrf_id; rib->table = table; @@ -819,7 +814,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h, p.prefixlen = rtm->rtm_dst_len; rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, vrf_id, - table, metric, mtu, 0, SAFI_UNICAST); + table, 0, mtu, 0, SAFI_UNICAST); } #endif /* HAVE_IPV6 */ @@ -854,7 +849,6 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, int index; int table; - int metric; u_int32_t mtu = 0; void *dest; @@ -915,7 +909,6 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, } index = 0; - metric = 0; dest = NULL; gate = NULL; src = NULL; @@ -936,9 +929,6 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, if (h->nlmsg_type == RTM_NEWROUTE) { - if (tb[RTA_PRIORITY]) - metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]); - if (tb[RTA_METRICS]) { struct rtattr *mxrta[RTAX_MAX+1]; @@ -971,7 +961,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, { if (!tb[RTA_MULTIPATH]) rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, vrf_id, - table, metric, mtu, 0, SAFI_UNICAST); + table, 0, mtu, 0, SAFI_UNICAST); else { /* This is a multipath route */ @@ -986,7 +976,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, rib->type = ZEBRA_ROUTE_KERNEL; rib->distance = 0; rib->flags = 0; - rib->metric = metric; + rib->metric = 0; rib->mtu = mtu; rib->vrf_id = vrf_id; rib->table = table; @@ -1053,7 +1043,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h, if (h->nlmsg_type == RTM_NEWROUTE) rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id, table, - metric, mtu, 0, SAFI_UNICAST); + 0, mtu, 0, SAFI_UNICAST); else rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id, SAFI_UNICAST); @@ -1663,7 +1653,7 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib) addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen); /* Metric. */ - addattr32 (&req.n, sizeof req, RTA_PRIORITY, rib->metric); + addattr32 (&req.n, sizeof req, RTA_PRIORITY, NL_DEFAULT_ROUTE_METRIC); if (rib->mtu || rib->nexthop_mtu) { @@ -1809,23 +1799,15 @@ skip: int kernel_route_rib (struct prefix *p, struct rib *old, struct rib *new) { - int ret; - if (!old && new) return netlink_route_multipath (RTM_NEWROUTE, p, new); if (old && !new) return netlink_route_multipath (RTM_DELROUTE, p, old); - /* Replace, can be done atomically if metric does not change; - * netlink uses [prefix, tos, priority] to identify prefix */ - if (old->metric == new->metric) - return netlink_route_multipath (RTM_NEWROUTE, p, new); - - /* Add + delete so the prefix does not disappear temporarily */ - ret = netlink_route_multipath (RTM_NEWROUTE, p, new); - if (netlink_route_multipath (RTM_DELROUTE, p, old) < 0) - ret = -1; - return ret; + /* Replace, can be done atomically if metric does not change; + * netlink uses [prefix, tos, priority] to identify prefix. + * Now metric is not sent to kernel, so we can just do atomic replace. */ + return netlink_route_multipath (RTM_NEWROUTE, p, new); } /* Interface address modification. */ diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index 40fa8eb4..63fbbe78 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -25,6 +25,7 @@ #ifdef HAVE_NETLINK #define NL_PKT_BUF_SIZE 8192 +#define NL_DEFAULT_ROUTE_METRIC 20 extern int addattr32 (struct nlmsghdr *n, size_t maxlen, int type, int data); |