From f19435a8b432bbeddf484df54b02e2bd3e847350 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 9 Aug 2017 09:13:33 -0400 Subject: [PATCH] zebra: Pay attention to metric from kernel When the linux kernel adds/deletes routes, the metric is important, but our routing protocols add/delete in a slightly different manner, so allow kernel metrics to match so that our rib matches the kernel's fib. Signed-off-by: Donald Sharp --- zebra/connected.c | 6 +++--- zebra/kernel_socket.c | 8 ++++---- zebra/redistribute.c | 2 +- zebra/rib.h | 5 +++-- zebra/rt_netlink.c | 26 ++++++++++++-------------- zebra/zebra_rib.c | 9 ++++++++- zebra/zserv.c | 7 ++++--- 7 files changed, 35 insertions(+), 28 deletions(-) diff --git a/zebra/connected.c b/zebra/connected.c index 80f9ebe5ea..701314f246 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -323,10 +323,10 @@ void connected_down_ipv4(struct interface *ifp, struct connected *ifc) /* Same logic as for connected_up_ipv4(): push the changes into the * head. */ rib_delete(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, NULL, ifp->ifindex, 0); + &p, NULL, NULL, ifp->ifindex, 0, 0); rib_delete(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, - 0, &p, NULL, NULL, ifp->ifindex, 0); + 0, &p, NULL, NULL, ifp->ifindex, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( @@ -501,7 +501,7 @@ void connected_down_ipv6(struct interface *ifp, struct connected *ifc) return; rib_delete(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, - 0, &p, NULL, NULL, ifp->ifindex, 0); + 0, &p, NULL, NULL, ifp->ifindex, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 5ca6a488c3..84d01bca6f 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1019,7 +1019,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_CHANGE) rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - NULL, 0, 0); + NULL, 0, 0, 0); union g_addr ggate = {.ipv4 = gate.sin.sin_addr}; if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD @@ -1030,7 +1030,7 @@ void rtm_read(struct rt_msghdr *rtm) else rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &ggate, 0, 0); + &ggate, 0, 0, 0); } if (dest.sa.sa_family == AF_INET6) { /* One day we might have a debug section here like one in the @@ -1061,7 +1061,7 @@ void rtm_read(struct rt_msghdr *rtm) if (rtm->rtm_type == RTM_CHANGE) rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - NULL, 0, 0); + NULL, 0, 0, 0); union g_addr ggate = {.ipv6 = gate.sin6.sin6_addr}; if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD @@ -1072,7 +1072,7 @@ void rtm_read(struct rt_msghdr *rtm) else rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &ggate, ifindex, 0); + &ggate, ifindex, 0, 0); } } diff --git a/zebra/redistribute.c b/zebra/redistribute.c index c3bbf40b3f..b37a54758c 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -573,7 +573,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re) rib_delete(AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table, re->flags, &p, NULL, NULL, 0, - zebrad.rtm_table_default); + zebrad.rtm_table_default, re->metric); } /* DD: Add IPv6 code */ diff --git a/zebra/rib.h b/zebra/rib.h index de941bcbbe..495b731e88 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -296,7 +296,7 @@ extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, union g_addr *gate, union g_addr *src, ifindex_t ifindex, u_int32_t table_id, - u_int32_t, u_int32_t, u_char); + u_int32_t metric, u_int32_t mtu, u_char distance); extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *, struct prefix_ipv6 *src_p, struct route_entry *); @@ -304,7 +304,8 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *, extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, union g_addr *gate, - ifindex_t ifindex, u_int32_t table_id); + ifindex_t ifindex, u_int32_t table_id, + u_int32_t metric); extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t, union g_addr *, diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 192fffd29c..e28fe5630a 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -308,21 +308,19 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, if (tb[RTA_GATEWAY]) gate = RTA_DATA(tb[RTA_GATEWAY]); - if (h->nlmsg_type == RTM_NEWROUTE) { - if (tb[RTA_PRIORITY]) - metric = *(int *)RTA_DATA(tb[RTA_PRIORITY]); + if (tb[RTA_PRIORITY]) + metric = *(int *)RTA_DATA(tb[RTA_PRIORITY]); - if (tb[RTA_METRICS]) { - struct rtattr *mxrta[RTAX_MAX + 1]; + if (tb[RTA_METRICS]) { + struct rtattr *mxrta[RTAX_MAX + 1]; - memset(mxrta, 0, sizeof mxrta); - netlink_parse_rtattr(mxrta, RTAX_MAX, - RTA_DATA(tb[RTA_METRICS]), - RTA_PAYLOAD(tb[RTA_METRICS])); + memset(mxrta, 0, sizeof mxrta); + netlink_parse_rtattr(mxrta, RTAX_MAX, + RTA_DATA(tb[RTA_METRICS]), + RTA_PAYLOAD(tb[RTA_METRICS])); - if (mxrta[RTAX_MTU]) - mtu = *(u_int32_t *)RTA_DATA(mxrta[RTAX_MTU]); - } + if (mxrta[RTAX_MTU]) + mtu = *(u_int32_t *)RTA_DATA(mxrta[RTAX_MTU]); } if (rtm->rtm_family == AF_INET) { @@ -449,7 +447,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, if (!tb[RTA_MULTIPATH]) rib_delete(afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, gate, - index, table); + index, table, metric); else { struct rtnexthop *rtnh = (struct rtnexthop *)RTA_DATA(tb[RTA_MULTIPATH]); @@ -476,7 +474,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, rib_delete(afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, gate, index, - table); + table, metric); len -= NLMSG_ALIGN(rtnh->rtnh_len); rtnh = RTNH_NEXT(rtnh); diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index e61c2e7b0e..ed53554265 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2274,7 +2274,8 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, union g_addr *gate, - ifindex_t ifindex, u_int32_t table_id) + ifindex_t ifindex, u_int32_t table_id, + u_int32_t metric) { struct route_table *table; struct route_node *rn; @@ -2328,6 +2329,9 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, continue; if (re->instance != instance) continue; + if (re->type == ZEBRA_ROUTE_KERNEL && + re->metric != metric) + continue; if (re->type == ZEBRA_ROUTE_CONNECT && (nexthop = re->nexthop) && nexthop->type == NEXTHOP_TYPE_IFINDEX) { if (nexthop->ifindex != ifindex) @@ -2468,6 +2472,9 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, continue; if (re->instance != instance) continue; + if (re->type == ZEBRA_ROUTE_KERNEL && + re->metric != metric) + continue; if (!RIB_SYSTEM_ROUTE(re)) { same = re; break; diff --git a/zebra/zserv.c b/zebra/zserv.c index bdb7755b63..55c9a97aa9 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -1363,7 +1363,8 @@ static int zread_ipv4_delete(struct zserv *client, u_short length, table_id = zvrf->table_id; rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance, - api.flags, &p, NULL, nexthop_p, ifindex, table_id); + api.flags, &p, NULL, nexthop_p, ifindex, table_id, + api.metric); client->v4_route_del_cnt++; return 0; } @@ -1761,11 +1762,11 @@ static int zread_ipv6_delete(struct zserv *client, u_short length, if (IN6_IS_ADDR_UNSPECIFIED(&nexthop)) rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance, api.flags, &p, src_pp, NULL, ifindex, - client->rtm_table); + client->rtm_table, api.metric); else rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance, api.flags, &p, src_pp, pnexthop, - ifindex, client->rtm_table); + ifindex, client->rtm_table, api.metric); client->v6_route_del_cnt++; return 0; -- 2.39.5