mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-06-15 05:40:03 +00:00
Merge pull request #7993 from mjstapp/reorg_resolve
zebra: reorg nexthop resolution code
This commit is contained in:
commit
0a7edab036
@ -371,8 +371,8 @@ void zebra_nhe_init(struct nhg_hash_entry *nhe, afi_t afi,
|
|||||||
*/
|
*/
|
||||||
if (nh && (nh->next == NULL)) {
|
if (nh && (nh->next == NULL)) {
|
||||||
switch (nh->type) {
|
switch (nh->type) {
|
||||||
case (NEXTHOP_TYPE_IFINDEX):
|
case NEXTHOP_TYPE_IFINDEX:
|
||||||
case (NEXTHOP_TYPE_BLACKHOLE):
|
case NEXTHOP_TYPE_BLACKHOLE:
|
||||||
/*
|
/*
|
||||||
* This switch case handles setting the afi different
|
* This switch case handles setting the afi different
|
||||||
* for ipv4/v6 routes. Ifindex/blackhole nexthop
|
* for ipv4/v6 routes. Ifindex/blackhole nexthop
|
||||||
@ -383,12 +383,12 @@ void zebra_nhe_init(struct nhg_hash_entry *nhe, afi_t afi,
|
|||||||
*/
|
*/
|
||||||
nhe->afi = afi;
|
nhe->afi = afi;
|
||||||
break;
|
break;
|
||||||
case (NEXTHOP_TYPE_IPV4_IFINDEX):
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||||
case (NEXTHOP_TYPE_IPV4):
|
case NEXTHOP_TYPE_IPV4:
|
||||||
nhe->afi = AFI_IP;
|
nhe->afi = AFI_IP;
|
||||||
break;
|
break;
|
||||||
case (NEXTHOP_TYPE_IPV6_IFINDEX):
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||||
case (NEXTHOP_TYPE_IPV6):
|
case NEXTHOP_TYPE_IPV6:
|
||||||
nhe->afi = AFI_IP6;
|
nhe->afi = AFI_IP6;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1789,8 +1789,9 @@ static bool nexthop_valid_resolve(const struct nexthop *nexthop,
|
|||||||
* if at all possible. Set the nexthop->ifindex and resolved_id
|
* if at all possible. Set the nexthop->ifindex and resolved_id
|
||||||
* as appropriate
|
* as appropriate
|
||||||
*/
|
*/
|
||||||
static int nexthop_active(afi_t afi, struct route_entry *re,
|
static int nexthop_active(afi_t afi, struct nexthop *nexthop,
|
||||||
struct nexthop *nexthop, struct route_node *top)
|
const struct prefix *top, int type, uint32_t flags,
|
||||||
|
uint32_t *pmtu)
|
||||||
{
|
{
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct route_table *table;
|
struct route_table *table;
|
||||||
@ -1805,33 +1806,58 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
struct in_addr local_ipv4;
|
struct in_addr local_ipv4;
|
||||||
struct in_addr *ipv4;
|
struct in_addr *ipv4;
|
||||||
|
|
||||||
|
/* Reset some nexthop attributes that we'll recompute if necessary */
|
||||||
if ((nexthop->type == NEXTHOP_TYPE_IPV4)
|
if ((nexthop->type == NEXTHOP_TYPE_IPV4)
|
||||||
|| nexthop->type == NEXTHOP_TYPE_IPV6)
|
|| (nexthop->type == NEXTHOP_TYPE_IPV6))
|
||||||
nexthop->ifindex = 0;
|
nexthop->ifindex = 0;
|
||||||
|
|
||||||
|
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE);
|
||||||
nexthops_free(nexthop->resolved);
|
nexthops_free(nexthop->resolved);
|
||||||
nexthop->resolved = NULL;
|
nexthop->resolved = NULL;
|
||||||
re->nexthop_mtu = 0;
|
|
||||||
|
|
||||||
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
|
||||||
zlog_debug("%s: re %p, nexthop %pNHv",
|
|
||||||
__func__, re, nexthop);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the kernel has sent us a NEW route, then
|
* Some nexthop types get special handling, possibly skipping
|
||||||
* by golly gee whiz it's a good route.
|
* the normal processing.
|
||||||
*
|
|
||||||
* If its an already INSTALLED route we have already handled, then the
|
|
||||||
* kernel route's nexthop might have became unreachable
|
|
||||||
* and we have to handle that.
|
|
||||||
*/
|
*/
|
||||||
if (!CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)
|
switch (nexthop->type) {
|
||||||
&& (re->type == ZEBRA_ROUTE_KERNEL
|
case NEXTHOP_TYPE_IFINDEX:
|
||||||
|| re->type == ZEBRA_ROUTE_SYSTEM))
|
ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id);
|
||||||
|
/*
|
||||||
|
* If the interface exists and its operative or its a kernel
|
||||||
|
* route and interface is up, its active. We trust kernel routes
|
||||||
|
* to be good.
|
||||||
|
*/
|
||||||
|
if (ifp
|
||||||
|
&& (if_is_operative(ifp)
|
||||||
|
|| (if_is_up(ifp)
|
||||||
|
&& (type == ZEBRA_ROUTE_KERNEL
|
||||||
|
|| type == ZEBRA_ROUTE_SYSTEM))))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NEXTHOP_TYPE_IPV6_IFINDEX:
|
||||||
|
if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) {
|
||||||
|
ifp = if_lookup_by_index(nexthop->ifindex,
|
||||||
|
nexthop->vrf_id);
|
||||||
|
if (ifp && if_is_operative(ifp))
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NEXTHOP_TYPE_BLACKHOLE:
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
case NEXTHOP_TYPE_IPV4:
|
||||||
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||||
|
case NEXTHOP_TYPE_IPV6:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the nexthop has been marked as 'onlink' we just need to make
|
* If the nexthop has been marked as 'onlink' we just need to make
|
||||||
* sure the nexthop's interface is known and is operational.
|
* sure the nexthop's interface is known and is operational.
|
||||||
@ -1853,10 +1879,11 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((top->p.family == AF_INET && top->p.prefixlen == 32
|
if (top &&
|
||||||
&& nexthop->gate.ipv4.s_addr == top->p.u.prefix4.s_addr)
|
((top->family == AF_INET && top->prefixlen == 32
|
||||||
|| (top->p.family == AF_INET6 && top->p.prefixlen == 128
|
&& nexthop->gate.ipv4.s_addr == top->u.prefix4.s_addr)
|
||||||
&& memcmp(&nexthop->gate.ipv6, &top->p.u.prefix6, 16) == 0)) {
|
|| (top->family == AF_INET6 && top->prefixlen == 128
|
||||||
|
&& memcmp(&nexthop->gate.ipv6, &top->u.prefix6, 16) == 0))) {
|
||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
" :%s: Attempting to install a max prefixlength route through itself",
|
" :%s: Attempting to install a max prefixlength route through itself",
|
||||||
@ -1873,6 +1900,9 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
ipv4 = &nexthop->gate.ipv4;
|
ipv4 = &nexthop->gate.ipv4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Processing for nexthops with SR 'color' attribute, using
|
||||||
|
* the corresponding SR policy object.
|
||||||
|
*/
|
||||||
if (nexthop->srte_color) {
|
if (nexthop->srte_color) {
|
||||||
struct ipaddr endpoint = {0};
|
struct ipaddr endpoint = {0};
|
||||||
struct zebra_sr_policy *policy;
|
struct zebra_sr_policy *policy;
|
||||||
@ -1950,7 +1980,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
* resolved by a route NH1. The exception is if the route is a
|
* resolved by a route NH1. The exception is if the route is a
|
||||||
* host route.
|
* host route.
|
||||||
*/
|
*/
|
||||||
if (rn == top)
|
if (prefix_same(&rn->p, top))
|
||||||
if (((afi == AFI_IP) && (rn->p.prefixlen != 32))
|
if (((afi == AFI_IP) && (rn->p.prefixlen != 32))
|
||||||
|| ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) {
|
|| ((afi == AFI_IP6) && (rn->p.prefixlen != 128))) {
|
||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
@ -2020,7 +2050,7 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
match->nhe->id, newhop);
|
match->nhe->id, newhop);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} else if (CHECK_FLAG(re->flags, ZEBRA_FLAG_ALLOW_RECURSION)) {
|
} else if (CHECK_FLAG(flags, ZEBRA_FLAG_ALLOW_RECURSION)) {
|
||||||
struct nexthop_group *nhg;
|
struct nexthop_group *nhg;
|
||||||
|
|
||||||
resolved = 0;
|
resolved = 0;
|
||||||
@ -2079,10 +2109,14 @@ static int nexthop_active(afi_t afi, struct route_entry *re,
|
|||||||
NULL);
|
NULL);
|
||||||
resolved = 1;
|
resolved = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
done_with_match:
|
done_with_match:
|
||||||
if (resolved)
|
/* Capture resolving mtu */
|
||||||
re->nexthop_mtu = match->mtu;
|
if (resolved) {
|
||||||
else if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (pmtu)
|
||||||
|
*pmtu = match->mtu;
|
||||||
|
|
||||||
|
} else if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
" %s: Recursion failed to find",
|
" %s: Recursion failed to find",
|
||||||
__func__);
|
__func__);
|
||||||
@ -2092,9 +2126,9 @@ done_with_match:
|
|||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
" %s: Route Type %s has not turned on recursion",
|
" %s: Route Type %s has not turned on recursion",
|
||||||
__func__, zebra_route_string(re->type));
|
__func__, zebra_route_string(type));
|
||||||
if (re->type == ZEBRA_ROUTE_BGP
|
if (type == ZEBRA_ROUTE_BGP
|
||||||
&& !CHECK_FLAG(re->flags, ZEBRA_FLAG_IBGP))
|
&& !CHECK_FLAG(flags, ZEBRA_FLAG_IBGP))
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
" EBGP: see \"disable-ebgp-connected-route-check\" or \"disable-connected-check\"");
|
" EBGP: see \"disable-ebgp-connected-route-check\" or \"disable-connected-check\"");
|
||||||
}
|
}
|
||||||
@ -2113,20 +2147,17 @@ done_with_match:
|
|||||||
* appropriately as well. An existing route map can turn an
|
* appropriately as well. An existing route map can turn an
|
||||||
* otherwise active nexthop into inactive, but not vice versa.
|
* otherwise active nexthop into inactive, but not vice versa.
|
||||||
*
|
*
|
||||||
* If it finds a nexthop recursively, set the resolved_id
|
|
||||||
* to match that nexthop's nhg_hash_entry ID;
|
|
||||||
*
|
|
||||||
* The return value is the final value of 'ACTIVE' flag.
|
* The return value is the final value of 'ACTIVE' flag.
|
||||||
*/
|
*/
|
||||||
static unsigned nexthop_active_check(struct route_node *rn,
|
static unsigned nexthop_active_check(struct route_node *rn,
|
||||||
struct route_entry *re,
|
struct route_entry *re,
|
||||||
struct nexthop *nexthop)
|
struct nexthop *nexthop)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
|
||||||
route_map_result_t ret = RMAP_PERMITMATCH;
|
route_map_result_t ret = RMAP_PERMITMATCH;
|
||||||
afi_t family;
|
afi_t family;
|
||||||
const struct prefix *p, *src_p;
|
const struct prefix *p, *src_p;
|
||||||
struct zebra_vrf *zvrf;
|
struct zebra_vrf *zvrf;
|
||||||
|
uint32_t mtu = 0;
|
||||||
|
|
||||||
srcdest_rnode_prefixes(rn, &p, &src_p);
|
srcdest_rnode_prefixes(rn, &p, &src_p);
|
||||||
|
|
||||||
@ -2137,19 +2168,28 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
else
|
else
|
||||||
family = 0;
|
family = 0;
|
||||||
|
|
||||||
|
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
|
||||||
|
zlog_debug("%s: re %p, nexthop %pNHv", __func__, re, nexthop);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the kernel has sent us a NEW route, then
|
||||||
|
* by golly gee whiz it's a good route.
|
||||||
|
*
|
||||||
|
* If its an already INSTALLED route we have already handled, then the
|
||||||
|
* kernel route's nexthop might have became unreachable
|
||||||
|
* and we have to handle that.
|
||||||
|
*/
|
||||||
|
if (!CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED) &&
|
||||||
|
(re->type == ZEBRA_ROUTE_KERNEL ||
|
||||||
|
re->type == ZEBRA_ROUTE_SYSTEM)) {
|
||||||
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
|
goto skip_check;
|
||||||
|
}
|
||||||
|
|
||||||
switch (nexthop->type) {
|
switch (nexthop->type) {
|
||||||
case NEXTHOP_TYPE_IFINDEX:
|
case NEXTHOP_TYPE_IFINDEX:
|
||||||
ifp = if_lookup_by_index(nexthop->ifindex, nexthop->vrf_id);
|
if (nexthop_active(AFI_IP, nexthop, &rn->p, re->type,
|
||||||
/*
|
re->flags, &mtu))
|
||||||
* If the interface exists and its operative or its a kernel
|
|
||||||
* route and interface is up, its active. We trust kernel routes
|
|
||||||
* to be good.
|
|
||||||
*/
|
|
||||||
if (ifp
|
|
||||||
&& (if_is_operative(ifp)
|
|
||||||
|| (if_is_up(ifp)
|
|
||||||
&& (re->type == ZEBRA_ROUTE_KERNEL
|
|
||||||
|| re->type == ZEBRA_ROUTE_SYSTEM))))
|
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
else
|
else
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
@ -2157,14 +2197,16 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
case NEXTHOP_TYPE_IPV4:
|
case NEXTHOP_TYPE_IPV4:
|
||||||
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
case NEXTHOP_TYPE_IPV4_IFINDEX:
|
||||||
family = AFI_IP;
|
family = AFI_IP;
|
||||||
if (nexthop_active(AFI_IP, re, nexthop, rn))
|
if (nexthop_active(AFI_IP, nexthop, &rn->p, re->type,
|
||||||
|
re->flags, &mtu))
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
else
|
else
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
break;
|
break;
|
||||||
case NEXTHOP_TYPE_IPV6:
|
case NEXTHOP_TYPE_IPV6:
|
||||||
family = AFI_IP6;
|
family = AFI_IP6;
|
||||||
if (nexthop_active(AFI_IP6, re, nexthop, rn))
|
if (nexthop_active(AFI_IP6, nexthop, &rn->p, re->type,
|
||||||
|
re->flags, &mtu))
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
else
|
else
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
@ -2173,19 +2215,12 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
/* RFC 5549, v4 prefix with v6 NH */
|
/* RFC 5549, v4 prefix with v6 NH */
|
||||||
if (rn->p.family != AF_INET)
|
if (rn->p.family != AF_INET)
|
||||||
family = AFI_IP6;
|
family = AFI_IP6;
|
||||||
if (IN6_IS_ADDR_LINKLOCAL(&nexthop->gate.ipv6)) {
|
|
||||||
ifp = if_lookup_by_index(nexthop->ifindex,
|
if (nexthop_active(AFI_IP6, nexthop, &rn->p, re->type,
|
||||||
nexthop->vrf_id);
|
re->flags, &mtu))
|
||||||
if (ifp && if_is_operative(ifp))
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
else
|
||||||
else
|
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
|
||||||
} else {
|
|
||||||
if (nexthop_active(AFI_IP6, re, nexthop, rn))
|
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
|
||||||
else
|
|
||||||
UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case NEXTHOP_TYPE_BLACKHOLE:
|
case NEXTHOP_TYPE_BLACKHOLE:
|
||||||
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE);
|
||||||
@ -2194,6 +2229,8 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip_check:
|
||||||
|
|
||||||
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) {
|
if (!CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) {
|
||||||
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
|
||||||
zlog_debug(" %s: Unable to find active nexthop",
|
zlog_debug(" %s: Unable to find active nexthop",
|
||||||
@ -2201,6 +2238,18 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Capture recursive nexthop mtu.
|
||||||
|
* TODO -- the code used to just reset the re's value to zero
|
||||||
|
* for each nexthop, and then jam any resolving route's mtu value in,
|
||||||
|
* whether or not that was zero, or lt/gt any existing value? The
|
||||||
|
* way this is used appears to be as a floor value, so let's try
|
||||||
|
* using it that way here.
|
||||||
|
*/
|
||||||
|
if (mtu > 0) {
|
||||||
|
if (re->nexthop_mtu == 0 || re->nexthop_mtu > mtu)
|
||||||
|
re->nexthop_mtu = mtu;
|
||||||
|
}
|
||||||
|
|
||||||
/* XXX: What exactly do those checks do? Do we support
|
/* XXX: What exactly do those checks do? Do we support
|
||||||
* e.g. IPv4 routes with IPv6 nexthops or vice versa?
|
* e.g. IPv4 routes with IPv6 nexthops or vice versa?
|
||||||
*/
|
*/
|
||||||
@ -2214,7 +2263,7 @@ static unsigned nexthop_active_check(struct route_node *rn,
|
|||||||
* Possibly it may be better to use only the rib_table_info
|
* Possibly it may be better to use only the rib_table_info
|
||||||
* in every case.
|
* in every case.
|
||||||
*/
|
*/
|
||||||
if (!family) {
|
if (family == 0) {
|
||||||
struct rib_table_info *info;
|
struct rib_table_info *info;
|
||||||
|
|
||||||
info = srcdest_rnode_table_info(rn);
|
info = srcdest_rnode_table_info(rn);
|
||||||
@ -2292,6 +2341,9 @@ static uint32_t nexthop_list_active_update(struct route_node *rn,
|
|||||||
|
|
||||||
nexthop = nhg->nexthop;
|
nexthop = nhg->nexthop;
|
||||||
|
|
||||||
|
/* Init recursive nh mtu */
|
||||||
|
re->nexthop_mtu = 0;
|
||||||
|
|
||||||
/* Process nexthops one-by-one */
|
/* Process nexthops one-by-one */
|
||||||
for ( ; nexthop; nexthop = nexthop->next) {
|
for ( ; nexthop; nexthop = nexthop->next) {
|
||||||
|
|
||||||
|
@ -180,8 +180,9 @@ struct nhg_ctx {
|
|||||||
|
|
||||||
vrf_id_t vrf_id;
|
vrf_id_t vrf_id;
|
||||||
afi_t afi;
|
afi_t afi;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This should only every be ZEBRA_ROUTE_NHG unless we get a a kernel
|
* This should only ever be ZEBRA_ROUTE_NHG unless we get a a kernel
|
||||||
* created nexthop not made by us.
|
* created nexthop not made by us.
|
||||||
*/
|
*/
|
||||||
int type;
|
int type;
|
||||||
|
Loading…
Reference in New Issue
Block a user