-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Local connected #16300
Local connected #16300
Conversation
zebra/zebra_rib.c
Outdated
@@ -1599,7 +1599,8 @@ static void zebra_rib_fixup_system(struct route_node *rn) | |||
} | |||
|
|||
/* Route comparison logic, with various special cases. */ | |||
static bool rib_compare_routes(const struct route_entry *re1, | |||
static bool rib_compare_routes(const struct route_node *rn, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't see "rn" used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah that is left over from some debugging I added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
zebra/zebra_rib.c
Outdated
@@ -1619,6 +1620,11 @@ static bool rib_compare_routes(const struct route_entry *re1, | |||
* v6 link-locals, and we also support multiple addresses in the same | |||
* subnet on a single interface. | |||
*/ | |||
if ((re1->type == ZEBRA_ROUTE_CONNECT && | |||
re2->type == ZEBRA_ROUTE_CONNECT) && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already tested that the two types are equal - can just test either re1 or re2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, fixed
struct interface *ifp; | ||
|
||
if (p->family == AF_INET6 && | ||
IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interesting - don't protocols sometimes want to know about the link-locals though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not as a kernel route. We already have code that handles the link locals. This is just a special case for how we are receiving the v6 LL routes from the kernel as far as I can tell.
} | ||
|
||
if (!alive) { | ||
struct rib_table_info *rib_table = srcdest_rnode_table_info(rn); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems a little too bad to have to do these lookups for each prefix - could we pass something useful down from rib_update_table or rib_update_route_node, like the afi/safi?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked at that and it was adding several layers of parameters. Just seemed very very easy to look it up in this special case instead of changing a whole bunch of functions to just pass afi/safi in for the !alive case( which should not be many routes)
60806f3
to
e506c59
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good
looks like this might be related --
but I'm trying to rerun just that test again to make certain |
e506c59
to
cb12b33
Compare
ifp = if_lookup_prefix(p, re->vrf_id); | ||
if (ifp) { | ||
if (ifp->ifindex == ng->nexthop->ifindex) | ||
re->type = ZEBRA_ROUTE_CONNECT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this only considers a route to be connected if it exactly matches a prefix installed on the interface. However, the kernel is perfectly happy to accept "connected" prefixes where this is not the case (and routing works just fine with them):
# ip -br a
lo UNKNOWN 127.0.0.1/8 ::1/128
veth0@if5 UP 10.10.10.10/32 fe80::2ceb:48ff:fe4a:954f/64
# ip r
# ip r add 10.1.1.0/24 dev veth0
# ip r add 10.10.10.11/32 dev veth0
# ip r add default dev veth0
# ip r
default dev veth0 scope link
10.1.1.0/24 dev veth0 scope link
10.10.10.11 dev veth0 scope link
# ping -c 1 10.1.1.1
PING 10.1.1.1 (10.1.1.1) 56(84) bytes of data.
64 bytes from 10.1.1.1: icmp_seq=1 ttl=64 time=0.072 ms
--- 10.1.1.1 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.072/0.072/0.072/0.000 ms
So with that in mind, wouldn't it be better to use the kernel's notion of a connected route (scope link
) to set the ZEBRA_ROUTE_CONNECT
type, instead of using this heuristic? That's the approach I took in #16418 for the same reason, but cf the discussion there, it's probably easier to incorporate that bit into this PR? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer that we keep things the way we have them as that this is how we think about the problem in FRR. I'm not sure that it matters though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to clarify, my point a bit more. I do not want any route that has link scope to become a connected route. A connected route is a route that has an address associated with it on the interface in question. That is the definition that I want to stick with.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, okay. My concern was mostly that by not mirroring the exact semantics of the kernel FRR can end up with a different view of how packets will be routed than what the forwarding plane actually does. However, I don't have a concrete use case where this will lead to problems, and I guess for the original "set noprefixroute but install another replacement route for the prefix in the kernel" use case, this is fine :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
be aware that this patch will just turn those local scope routes into kernel routes so nothing to worry about
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, right, so FRR will still end up with a consistent view of the forwarding state (because it no longer skips all RTPROT_KERNEL
routes), but only those with a matching interface prefix will be considered connected? Makes sense!
cb12b33
to
b8cb706
Compare
b8cb706
to
8b6f1df
Compare
|
||
rib_delete(rib_table->afi, rib_table->safi, re->vrf_id, | ||
re->type, re->instance, re->flags, p, src_p, NULL, 0, | ||
re->table, re->metric, re->distance, true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that last "true" is the "fromkernel" boolean, right? Will that cause problems, since that usually indicates an update arriving from the kernel, where this is an update that zebra is generating?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in this code path I intentionally wanted to hit the code in zebra_rib.c:
if (same) {
struct nexthop *tmp_nh;
if (ere->fromkernel &&
CHECK_FLAG(ere->re->flags, ZEBRA_FLAG_SELFROUTE) &&
!zrouter.allow_delete) {
rib_install_kernel(rn, same, NULL);
route_unlock_node(rn);
early_route_memory_free(ere);
return;
}```
if (rn->info && | ||
CHECK_FLAG(rib_dest_from_rnode(rn)->flags, | ||
RIB_ROUTE_ANY_QUEUED) && | ||
event != RIB_UPDATE_INTERFACE_DOWN) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could the comment be updated a bit to explain this added test?
are there any possible ordering problems, if the dest is already queued for processing, and then we enqueue a delete event in rib_update_handle_kernel_route_down_possibility()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
@@ -1058,6 +1058,8 @@ void if_down(struct interface *ifp) | |||
|
|||
/* Delete all neighbor addresses learnt through IPv6 RA */ | |||
if_down_del_nbr_connected(ifp); | |||
|
|||
rib_update_handle_vrf_all(RIB_UPDATE_INTERFACE_DOWN, ZEBRA_ROUTE_KERNEL); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this is going to do this processing synchronously. that "handle_vrf_all()" is currently an async event callback, via "rib_update()": why not use that path to do the work? was there some issue with doing it async?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that whole system area is a mess of code. I was just hooking into it quickly. I need to rethink that whole mess if we want to do it async. Although I am not sure it matters at this point in time. Can I add it to the list of things that needs to be reworked and rethought?
8b6f1df
to
9b9f23d
Compare
The prefix'es p and src_p are not const. Let's make them so. Useful to signal that we will not change this data. Signed-off-by: Donald Sharp <[email protected]>
This function will be used on interface down events to allow for kernel routes to be cleaned up. Signed-off-by: Donald Sharp <[email protected]>
Current code intentionally ignores kernel routes. Modify zebra to allow these routes to be read in on linux. Also modify zebra to look to see if a route should be treated as a connected and mark it as such. Additionally this should properly handle some of the issues being seen with NOPREFIXROUTE. Signed-off-by: Donald Sharp <[email protected]>
There exists a path in rib_add_multipath where if a decision is made to not use the passed in re, we just drop the memory instead of freeing it. Let's free it. Signed-off-by: Donald Sharp <[email protected]>
a) A noprefix address by itself should not create a connected route. This was pre-existing. b) A noprefix address with a corresponding route should result in a connected route. This is how NetworkManager appears to work. This is new behavior, so a new test. c) A route is added to the system from someone else. This is new behavior, so a new test. Signed-off-by: Donald Sharp <[email protected]>
9b9f23d
to
37dd518
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, approving
New Features Highlight: - PIM candidate BSR/RP [#16438] - Static IGMP join without an IGMP report [1#6450] - PIM AutoRP discovery/announcements [#16634] - IGMP proxy [#16861] - SRv6 SID Manager [#15604] - Add `bgp ipv6-auto-ra` command [#16354] - Implement `neighbor x remote-as auto` for BGP [#16345] - Implement `bgp dual-as` for BGP [#16816] - Implement BGP-wide configuration for graceful restart [#16099] - Handle kernel routes appropriately (should fix recent NOPREFIXROUTE issue) [#16300] - Add `cisco-authentication` password support for NHRP [#16172] Signed-off-by: Jafar Al-Gharaibeh <[email protected]>
Allow kernel routes to be read in when they are created in linux. Additionally treat the connected routes as connected. This fixes one of the issues seen with NOPREFIXROUTE