Page MenuHomeFreeBSD

Streamline ifa selection when adding a route.
ClosedPublic

Authored by melifaro on Apr 26 2019, 3:07 PM.
Tags
None
Referenced Files
F103757855: D20076.diff
Fri, Nov 29, 12:58 AM
Unknown Object (File)
Tue, Nov 26, 7:50 AM
Unknown Object (File)
Wed, Nov 13, 7:59 AM
Unknown Object (File)
Mon, Nov 4, 4:35 AM
Unknown Object (File)
Mon, Nov 4, 4:35 AM
Unknown Object (File)
Mon, Nov 4, 4:16 AM
Unknown Object (File)
Oct 23 2024, 9:59 AM
Unknown Object (File)
Oct 21 2024, 10:10 PM
Subscribers

Details

Summary

Problem statement

Currently for the loopback routes addition requests with link-level gateway, source ifa selection (rt_ifa) is really hackish. The route goes through the entire insertion process with invalid ifa and got it changed immediately after insertion. This leads to complications in the various parts of routing stack.

Let's trace addition of the loopback interfaces route:

ifa_add_loopback_route() # is a wrapper for
ifa_maintain_loopback_route() # fills in _info_ structure with interface set to loopback but not filling in ifa.
rtequest1_fib() # validates and fills in remaining data, determes ifa by calling
rt_getifa_fib() # which uses gw & interface to call
ifaof_ifpforaddr() # which returns the link-level ifa matching link-level gw (AF_LINK "base" ifa for lo0)

Then, the route gets inserted into the routing table with invalid rt_ifa, we drop RIB_WLOCK and call ifa routing hook.
This hook is

link_rtrequest() # which again calls
ifaof_ifpforaddr() # this time with the `dst` as the socket, changes ifa to be the "proper" one and calls that rta handler.

This behaviour complicates routing code:

  • at the moment of insertion ifa pointer is plain wrong
  • ifa selection is way more complex

Proposed solution

First, setup ifa explicitly for the loopback routes (always loopback IPv4/IPv6 address). This is effectively what we do now for both IPv4/IPv6 (see below).
Note: for IPv6 route IFA plays less important role as it uses its own SAS process, which selects the proper address by its own.

Second, move the logic from the link_rtrequest() to the rt_ifa_ifp(). High-level description: if the gateway is set, use gateway, otherwise use dst to guess ifa. However, still retain existing behaviour to ensure we still have _some_ ifa.
For example, it can be helpful if one adds directly-reachable interface prefix to an interface without any IP address.

Side effects

Userland applications do not currently receive and RTM_ADD notifications for the loopback route. Though, they scn routing table periodically, so the returned loopback route data matters. The test section addresses verification of the (lack of change) .
The only kernel applications subscribed for such notifications are IPv6 and SCTP handlers. Both don't care about the IFA in that particular case.

Testing

Combination of 'route -n monitor' output for the 'route -n get ....' are shown below as stock route get / netstat -rn does not show ifa.

Before

m@devel0 route -n get -6 2a01:4f8:13a:70c:ffff::6
sockaddrs: <DST,GATEWAY,IFP,IFA>
2a01:4f8:13a:70c:ffff::6 link#1 lo0 ::1

m@devel0 route -n get -6 fe80::5054:ff:fe42:fef%vtnet0
sockaddrs: <DST,GATEWAY,IFP,IFA>
fe80::5054:ff:fe42:fef%vtnet0 link#1 lo0 ::1

14:48 [2] m@devel0 route -n get -6 ::1
sockaddrs: <DST,GATEWAY,IFP,IFA>
::1 link#2 lo0 ::1

19:15 [1] m@devel2 route -n get -6 fe80::1%lo0
sockaddrs: <DST,GATEWAY,IFP,IFA>
fe80::1%lo0 link#2 lo0 fe80::1%lo0

After

route -n get 10.0.0.157
sockaddrs: <DST,GATEWAY,IFP,IFA>
10.0.0.157 link#1 lo0 127.0.0.1

route -n get -6 ::ffff:0.0.0.0
sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA>
::ffff:0.0.0.0 ::1 ffff:ffff:ffff:ffff:ffff:ffff:: lo0 ::1

route -n get -6 2a01:4f8:13a:70c:ffff::6
sockaddrs: <DST,GATEWAY,IFP,IFA>
2a01:4f8:13a:70c:ffff::6 link#1 lo0 ::1

route -n get -6 fe80::5054:ff:fe42:fef%vtnet0
sockaddrs: <DST,GATEWAY,IFP,IFA>
fe80::5054:ff:fe42:fef%vtnet0 link#1 lo0 ::1

route -n get -6 fe80::1%lo0
sockaddrs: <DST,GATEWAY,IFP,IFA>
fe80::1%lo0 link#2 lo0 fe80::1%lo0

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 23942
Build 22859: arc lint + arc unit

Event Timeline

melifaro changed the visibility from "Public (No Login Required)" to "All Users".Apr 26 2019, 3:10 PM
melifaro edited the summary of this revision. (Show Details)

Update revision.

melifaro added reviewers: ae, network.
sys/net/if.c
1906

It looks like info.rti_ifp can not be NULL.

sys/net/if.c
1906

However, V_loif can be NULL in some cases, so I think this comment can be ignored.

This revision was not accepted when it landed; it landed in state Needs Review.May 19 2019, 9:50 PM
This revision was automatically updated to reflect the committed changes.
melifaro changed the visibility from "All Users" to "Public (No Login Required)".May 20 2019, 11:46 PM