lib, zebra: Allow protocols to use Distance as part of RR semantics

Allow protocols to specify to zebra that they would like zebra
to use the distance passed down as part of determine sameness for
Route Replace semantics.

This will be used by the static daemon to allow it to have
backup static routes with greater distances.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2018-06-21 21:49:03 -04:00
parent 8d5cbee91d
commit 40ecd8e46d
8 changed files with 38 additions and 19 deletions

View File

@ -414,6 +414,7 @@ extern const char *zserv_command_string(unsigned int command);
#define ZEBRA_FLAG_SCOPE_LINK 0x100
#define ZEBRA_FLAG_FIB_OVERRIDE 0x200
#define ZEBRA_FLAG_EVPN_ROUTE 0x400
#define ZEBRA_FLAG_RR_USE_DISTANCE 0x800
/* ZEBRA_FLAG_BLACKHOLE was 0x04 */
/* ZEBRA_FLAG_REJECT was 0x80 */

View File

@ -403,10 +403,10 @@ void connected_down(struct interface *ifp, struct connected *ifc)
* head.
*/
rib_delete(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
&p, NULL, &nh, 0, 0, false);
&p, NULL, &nh, 0, 0, 0, false);
rib_delete(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
&p, NULL, &nh, 0, 0, false);
&p, NULL, &nh, 0, 0, 0, false);
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
char buf[PREFIX_STRLEN];

View File

@ -1043,7 +1043,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, true);
NULL, 0, 0, 0, true);
if (!nh.type) {
nh.type = NEXTHOP_TYPE_IPV4;
@ -1058,7 +1058,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,
&nh, 0, 0, true);
&nh, 0, 0, 0, true);
}
if (dest.sa.sa_family == AF_INET6) {
/* One day we might have a debug section here like one in the
@ -1089,7 +1089,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, true);
NULL, 0, 0, 0, true);
if (!nh.type) {
nh.type = ifindex ? NEXTHOP_TYPE_IPV6_IFINDEX
@ -1106,7 +1106,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,
&nh, 0, 0, true);
&nh, 0, 0, 0, true);
}
}

View File

@ -597,7 +597,7 @@ int zebra_del_import_table_entry(struct route_node *rn, struct route_entry *re)
rib_delete(afi, SAFI_UNICAST, re->vrf_id, ZEBRA_ROUTE_TABLE, re->table,
re->flags, &p, NULL, re->ng.nexthop,
zebrad.rtm_table_default, re->metric, false);
zebrad.rtm_table_default, re->metric, re->distance, false);
return 0;
}

View File

@ -311,7 +311,8 @@ extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
unsigned short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
uint32_t table_id, uint32_t metric, bool fromkernel);
uint32_t table_id, uint32_t metric, uint8_t distance,
bool fromkernel);
extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
union g_addr *addr,

View File

@ -644,12 +644,12 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
if (gate)
memcpy(&nh.gate, gate, sz);
rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
&p, &src_p, &nh, table, metric, true);
&p, &src_p, &nh, table, metric, distance, true);
} else {
/* XXX: need to compare the entire list of nexthops
* here for NLM_F_APPEND stupidity */
rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags,
&p, &src_p, NULL, table, metric, true);
&p, &src_p, NULL, table, metric, distance, true);
}
}

View File

@ -1565,7 +1565,7 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &api.prefix, src_p, NULL, table_id, api.metric,
false);
api.distance, false);
/* Stats */
switch (api.prefix.family) {
@ -1767,7 +1767,7 @@ static void zread_ipv4_delete(ZAPI_HANDLER_ARGS)
table_id = zvrf->table_id;
rib_delete(AFI_IP, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &p, NULL, NULL, table_id, 0, false);
api.flags, &p, NULL, NULL, table_id, 0, 0, false);
client->v4_route_del_cnt++;
stream_failure:
@ -2191,7 +2191,7 @@ static void zread_ipv6_delete(ZAPI_HANDLER_ARGS)
src_pp = NULL;
rib_delete(AFI_IP6, api.safi, zvrf_id(zvrf), api.type, api.instance,
api.flags, &p, src_pp, NULL, client->rtm_table, 0, false);
api.flags, &p, src_pp, NULL, client->rtm_table, 0, 0, false);
client->v6_route_del_cnt++;

View File

@ -2321,7 +2321,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
{
struct route_table *table;
struct route_node *rn;
struct route_entry *same;
struct route_entry *same = NULL;
struct nexthop *nexthop;
int ret = 0;
@ -2355,8 +2355,13 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
/* Lookup route node.*/
rn = srcdest_rnode_get(table, p, src_p);
/* If same type of route are installed, treat it as a implicit
withdraw. */
zlog_debug("Distance: %d", re->distance);
/*
* If same type of route are installed, treat it as a implicit
* withdraw.
* If the user has specified the No route replace semantics
* for the install don't do a route replace.
*/
RNODE_FOREACH_RE (rn, same) {
if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
continue;
@ -2368,14 +2373,21 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
if (same->type == ZEBRA_ROUTE_KERNEL
&& same->metric != re->metric)
continue;
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE) &&
same->distance != re->distance)
continue;
/*
* We should allow duplicate connected routes because of
* IPv6 link-local routes and unnumbered interfaces on Linux.
* We should allow duplicate connected routes
* because of IPv6 link-local routes and unnumbered
* interfaces on Linux.
*/
if (same->type != ZEBRA_ROUTE_CONNECT)
break;
}
zlog_debug("same: %p distance: %d", same, same ? same->distance : -1);
/* If this route is kernel route, set FIB flag to the route. */
if (RIB_SYSTEM_ROUTE(re))
for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
@ -2407,7 +2419,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,
unsigned short instance, int flags, struct prefix *p,
struct prefix_ipv6 *src_p, const struct nexthop *nh,
uint32_t table_id, uint32_t metric, bool fromkernel)
uint32_t table_id, uint32_t metric, uint8_t distance,
bool fromkernel)
{
struct route_table *table;
struct route_node *rn;
@ -2461,6 +2474,10 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
continue;
if (re->instance != instance)
continue;
if (CHECK_FLAG(re->flags, ZEBRA_FLAG_RR_USE_DISTANCE) &&
distance != re->distance)
continue;
if (re->type == ZEBRA_ROUTE_KERNEL && re->metric != metric)
continue;
if (re->type == ZEBRA_ROUTE_CONNECT && (rtnh = re->ng.nexthop)