mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-06-14 17:46:05 +00:00
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 <sharpd@cumulusnetworks.com>
This commit is contained in:
parent
9cdce038c5
commit
f19435a8b4
@ -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
|
/* Same logic as for connected_up_ipv4(): push the changes into the
|
||||||
* head. */
|
* head. */
|
||||||
rib_delete(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
|
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,
|
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)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
@ -501,7 +501,7 @@ void connected_down_ipv6(struct interface *ifp, struct connected *ifc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
rib_delete(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
|
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)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
|
@ -1019,7 +1019,7 @@ void rtm_read(struct rt_msghdr *rtm)
|
|||||||
if (rtm->rtm_type == RTM_CHANGE)
|
if (rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
||||||
NULL, 0, 0);
|
NULL, 0, 0, 0);
|
||||||
|
|
||||||
union g_addr ggate = {.ipv4 = gate.sin.sin_addr};
|
union g_addr ggate = {.ipv4 = gate.sin.sin_addr};
|
||||||
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
||||||
@ -1030,7 +1030,7 @@ void rtm_read(struct rt_msghdr *rtm)
|
|||||||
else
|
else
|
||||||
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
||||||
&ggate, 0, 0);
|
&ggate, 0, 0, 0);
|
||||||
}
|
}
|
||||||
if (dest.sa.sa_family == AF_INET6) {
|
if (dest.sa.sa_family == AF_INET6) {
|
||||||
/* One day we might have a debug section here like one in the
|
/* 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)
|
if (rtm->rtm_type == RTM_CHANGE)
|
||||||
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
||||||
NULL, 0, 0);
|
NULL, 0, 0, 0);
|
||||||
|
|
||||||
union g_addr ggate = {.ipv6 = gate.sin6.sin6_addr};
|
union g_addr ggate = {.ipv6 = gate.sin6.sin6_addr};
|
||||||
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
if (rtm->rtm_type == RTM_GET || rtm->rtm_type == RTM_ADD
|
||||||
@ -1072,7 +1072,7 @@ void rtm_read(struct rt_msghdr *rtm)
|
|||||||
else
|
else
|
||||||
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL,
|
||||||
&ggate, ifindex, 0);
|
&ggate, ifindex, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
rib_delete(AFI_IP, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE,
|
||||||
re->table, re->flags, &p, NULL, NULL, 0,
|
re->table, re->flags, &p, NULL, NULL, 0,
|
||||||
zebrad.rtm_table_default);
|
zebrad.rtm_table_default, re->metric);
|
||||||
}
|
}
|
||||||
/* DD: Add IPv6 code */
|
/* DD: Add IPv6 code */
|
||||||
|
|
||||||
|
@ -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,
|
u_short instance, int flags, struct prefix *p,
|
||||||
struct prefix_ipv6 *src_p, union g_addr *gate,
|
struct prefix_ipv6 *src_p, union g_addr *gate,
|
||||||
union g_addr *src, ifindex_t ifindex, u_int32_t table_id,
|
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 *,
|
extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *,
|
||||||
struct prefix_ipv6 *src_p, struct route_entry *);
|
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,
|
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,
|
u_short instance, int flags, struct prefix *p,
|
||||||
struct prefix_ipv6 *src_p, union g_addr *gate,
|
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,
|
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t,
|
||||||
union g_addr *,
|
union g_addr *,
|
||||||
|
@ -308,21 +308,19 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
|
|||||||
if (tb[RTA_GATEWAY])
|
if (tb[RTA_GATEWAY])
|
||||||
gate = RTA_DATA(tb[RTA_GATEWAY]);
|
gate = RTA_DATA(tb[RTA_GATEWAY]);
|
||||||
|
|
||||||
if (h->nlmsg_type == RTM_NEWROUTE) {
|
if (tb[RTA_PRIORITY])
|
||||||
if (tb[RTA_PRIORITY])
|
metric = *(int *)RTA_DATA(tb[RTA_PRIORITY]);
|
||||||
metric = *(int *)RTA_DATA(tb[RTA_PRIORITY]);
|
|
||||||
|
|
||||||
if (tb[RTA_METRICS]) {
|
if (tb[RTA_METRICS]) {
|
||||||
struct rtattr *mxrta[RTAX_MAX + 1];
|
struct rtattr *mxrta[RTAX_MAX + 1];
|
||||||
|
|
||||||
memset(mxrta, 0, sizeof mxrta);
|
memset(mxrta, 0, sizeof mxrta);
|
||||||
netlink_parse_rtattr(mxrta, RTAX_MAX,
|
netlink_parse_rtattr(mxrta, RTAX_MAX,
|
||||||
RTA_DATA(tb[RTA_METRICS]),
|
RTA_DATA(tb[RTA_METRICS]),
|
||||||
RTA_PAYLOAD(tb[RTA_METRICS]));
|
RTA_PAYLOAD(tb[RTA_METRICS]));
|
||||||
|
|
||||||
if (mxrta[RTAX_MTU])
|
if (mxrta[RTAX_MTU])
|
||||||
mtu = *(u_int32_t *)RTA_DATA(mxrta[RTAX_MTU]);
|
mtu = *(u_int32_t *)RTA_DATA(mxrta[RTAX_MTU]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtm->rtm_family == AF_INET) {
|
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])
|
if (!tb[RTA_MULTIPATH])
|
||||||
rib_delete(afi, SAFI_UNICAST, vrf_id,
|
rib_delete(afi, SAFI_UNICAST, vrf_id,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, gate,
|
ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, gate,
|
||||||
index, table);
|
index, table, metric);
|
||||||
else {
|
else {
|
||||||
struct rtnexthop *rtnh =
|
struct rtnexthop *rtnh =
|
||||||
(struct rtnexthop *)RTA_DATA(tb[RTA_MULTIPATH]);
|
(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,
|
rib_delete(afi, SAFI_UNICAST, vrf_id,
|
||||||
ZEBRA_ROUTE_KERNEL, 0, flags,
|
ZEBRA_ROUTE_KERNEL, 0, flags,
|
||||||
&p, NULL, gate, index,
|
&p, NULL, gate, index,
|
||||||
table);
|
table, metric);
|
||||||
|
|
||||||
len -= NLMSG_ALIGN(rtnh->rtnh_len);
|
len -= NLMSG_ALIGN(rtnh->rtnh_len);
|
||||||
rtnh = RTNH_NEXT(rtnh);
|
rtnh = RTNH_NEXT(rtnh);
|
||||||
|
@ -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,
|
void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
|
||||||
u_short instance, int flags, struct prefix *p,
|
u_short instance, int flags, struct prefix *p,
|
||||||
struct prefix_ipv6 *src_p, union g_addr *gate,
|
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_table *table;
|
||||||
struct route_node *rn;
|
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;
|
continue;
|
||||||
if (re->instance != instance)
|
if (re->instance != instance)
|
||||||
continue;
|
continue;
|
||||||
|
if (re->type == ZEBRA_ROUTE_KERNEL &&
|
||||||
|
re->metric != metric)
|
||||||
|
continue;
|
||||||
if (re->type == ZEBRA_ROUTE_CONNECT && (nexthop = re->nexthop)
|
if (re->type == ZEBRA_ROUTE_CONNECT && (nexthop = re->nexthop)
|
||||||
&& nexthop->type == NEXTHOP_TYPE_IFINDEX) {
|
&& nexthop->type == NEXTHOP_TYPE_IFINDEX) {
|
||||||
if (nexthop->ifindex != 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;
|
continue;
|
||||||
if (re->instance != instance)
|
if (re->instance != instance)
|
||||||
continue;
|
continue;
|
||||||
|
if (re->type == ZEBRA_ROUTE_KERNEL &&
|
||||||
|
re->metric != metric)
|
||||||
|
continue;
|
||||||
if (!RIB_SYSTEM_ROUTE(re)) {
|
if (!RIB_SYSTEM_ROUTE(re)) {
|
||||||
same = re;
|
same = re;
|
||||||
break;
|
break;
|
||||||
|
@ -1363,7 +1363,8 @@ static int zread_ipv4_delete(struct zserv *client, u_short length,
|
|||||||
table_id = zvrf->table_id;
|
table_id = zvrf->table_id;
|
||||||
|
|
||||||
rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
|
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++;
|
client->v4_route_del_cnt++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1761,11 +1762,11 @@ static int zread_ipv6_delete(struct zserv *client, u_short length,
|
|||||||
if (IN6_IS_ADDR_UNSPECIFIED(&nexthop))
|
if (IN6_IS_ADDR_UNSPECIFIED(&nexthop))
|
||||||
rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type,
|
rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type,
|
||||||
api.instance, api.flags, &p, src_pp, NULL, ifindex,
|
api.instance, api.flags, &p, src_pp, NULL, ifindex,
|
||||||
client->rtm_table);
|
client->rtm_table, api.metric);
|
||||||
else
|
else
|
||||||
rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type,
|
rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type,
|
||||||
api.instance, api.flags, &p, src_pp, pnexthop,
|
api.instance, api.flags, &p, src_pp, pnexthop,
|
||||||
ifindex, client->rtm_table);
|
ifindex, client->rtm_table, api.metric);
|
||||||
|
|
||||||
client->v6_route_del_cnt++;
|
client->v6_route_del_cnt++;
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user