]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Pay attention to metric from kernel 935/head
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 9 Aug 2017 13:13:33 +0000 (09:13 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 9 Aug 2017 13:17:20 +0000 (09:17 -0400)
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 <sharpd@cumulusnetworks.com>
zebra/connected.c
zebra/kernel_socket.c
zebra/redistribute.c
zebra/rib.h
zebra/rt_netlink.c
zebra/zebra_rib.c
zebra/zserv.c

index 80f9ebe5ea48786cf184aa93f81a90a5d858018b..701314f2461acd56423217b842712ecd3d7577b1 100644 (file)
@@ -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(
index 5ca6a488c31b8171742943185cfdea0d3c23cf65..84d01bca6f045f28e4f452f5d5c333a197b7cd68 100644 (file)
@@ -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);
        }
 }
 
index c3bbf40b3f0da91433a38e05cff5446dcb609a8c..b37a54758c6ddeb5392a877bc707a69baa693fd2 100644 (file)
@@ -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 */
 
index de941bcbbe111dc8b39df43c0f862c763146f670..495b731e885a973a28cafce6246e66e50da7ec91 100644 (file)
@@ -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 *,
index 192fffd29c9469eb0adfef8e9c55d8a50e3f8aca..e28fe5630aeeb53360bc073599f099e2259c498b 100644 (file)
@@ -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);
index e61c2e7b0e8c3cf8910a8e369f78548d9a111ef0..ed5355426524bdb528654c5bca083d8f061f5137 100644 (file)
@@ -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;
index bdb7755b63ce42748b0c15c7977e1ee57ae096c7..55c9a97aa9537f1e5ec6b114b3f50f934fe5f3d7 100644 (file)
@@ -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;