mirror of
https://github.com/opnsense/src.git
synced 2026-05-04 17:05:14 -04:00
Problem description:
How do we currently perform layer 2 resolution and header imposition:
For IPv4 we have the following chain:
ip_output() -> (ether|atm|whatever)_output() -> arpresolve()
Lookup is done in proper place (link-layer output routine) and it is possible
to provide cached lle data.
For IPv6 situation is more complex:
ip6_output() -> nd6_output() -> nd6_output_ifp() -> (whatever)_output() ->
nd6_storelladdr()
We have ip6_ouput() which calls nd6_output() instead of link output routine.
nd6_output() does the following:
* checks if lle exists, creates it if needed (similar to arpresolve())
* performes lle state transitions (similar to arpresolve())
* calls nd6_output_ifp() which pushes packets to link output routine along
with running SeND/MAC hooks regardless of lle state
(e.g. works as run-hooks placeholder).
After that, iface output routine like ether_output() calls nd6_storelladdr()
which performs lle lookup once again.
As a result, we perform lookup twice for each outgoing packet for most types
of interfaces. We also need to maintain runtime-checked table of 'nd6-free'
interfaces (see nd6_need_cache()).
Fix this behavior by eliminating first ND lookup. To be more specific:
* make all nd6_output() consumers use nd6_output_ifp() instead
* rename nd6_output[_slow]() to nd6_resolve_[slow]()
* convert nd6_resolve() and nd6_resolve_slow() to arpresolve() semantics,
e.g. copy L2 address to buffer instead of pushing packet towards lower
layers
* Make all nd6_storelladdr() users use nd6_resolve()
* eliminate nd6_storelladdr()
The resulting callchain is the following:
ip6_output() -> nd6_output_ifp() -> (whatever)_output() -> nd6_resolve()
Error handling:
Currently sending packet to non-existing la results in ip6_<output|forward>
-> nd6_output() -> nd6_output _lle() which returns 0.
In new scenario packet is propagated to <ether|whatever>_output() ->
nd6_resolve() which will return EWOULDBLOCK, and that result
will be converted to 0.
(And EWOULDBLOCK is actually used by IB/TOE code).
Sponsored by: Yandex LLC
Differential Revision: https://reviews.freebsd.org/D1469
|
||
|---|---|---|
| .. | ||
| altq | ||
| bpf.c | ||
| bpf.h | ||
| bpf_buffer.c | ||
| bpf_buffer.h | ||
| bpf_filter.c | ||
| bpf_jitter.c | ||
| bpf_jitter.h | ||
| bpf_zerocopy.c | ||
| bpf_zerocopy.h | ||
| bpfdesc.h | ||
| bridgestp.c | ||
| bridgestp.h | ||
| ethernet.h | ||
| fddi.h | ||
| firewire.h | ||
| flowtable.c | ||
| flowtable.h | ||
| ieee8023ad_lacp.c | ||
| ieee8023ad_lacp.h | ||
| ieee_oui.h | ||
| if.c | ||
| if.h | ||
| if_arc.h | ||
| if_arcsubr.c | ||
| if_arp.h | ||
| if_atm.h | ||
| if_atmsubr.c | ||
| if_bridge.c | ||
| if_bridgevar.h | ||
| if_clone.c | ||
| if_clone.h | ||
| if_dead.c | ||
| if_debug.c | ||
| if_disc.c | ||
| if_dl.h | ||
| if_edsc.c | ||
| if_enc.c | ||
| if_enc.h | ||
| if_epair.c | ||
| if_ethersubr.c | ||
| if_fddisubr.c | ||
| if_fwsubr.c | ||
| if_gif.c | ||
| if_gif.h | ||
| if_gre.c | ||
| if_gre.h | ||
| if_iso88025subr.c | ||
| if_lagg.c | ||
| if_lagg.h | ||
| if_llatbl.c | ||
| if_llatbl.h | ||
| if_llc.h | ||
| if_loop.c | ||
| if_me.c | ||
| if_media.c | ||
| if_media.h | ||
| if_mib.c | ||
| if_mib.h | ||
| if_pflog.h | ||
| if_pfsync.h | ||
| if_sppp.h | ||
| if_spppfr.c | ||
| if_spppsubr.c | ||
| if_stf.c | ||
| if_tap.c | ||
| if_tap.h | ||
| if_tapvar.h | ||
| if_tun.c | ||
| if_tun.h | ||
| if_types.h | ||
| if_var.h | ||
| if_vlan.c | ||
| if_vlan_var.h | ||
| if_vxlan.c | ||
| if_vxlan.h | ||
| ifq.h | ||
| iso88025.h | ||
| netisr.c | ||
| netisr.h | ||
| netisr_internal.h | ||
| netmap.h | ||
| netmap_user.h | ||
| paravirt.h | ||
| pfil.c | ||
| pfil.h | ||
| pfkeyv2.h | ||
| pfvar.h | ||
| ppp_defs.h | ||
| radix.c | ||
| radix.h | ||
| radix_mpath.c | ||
| radix_mpath.h | ||
| raw_cb.c | ||
| raw_cb.h | ||
| raw_usrreq.c | ||
| route.c | ||
| route.h | ||
| rss_config.c | ||
| rss_config.h | ||
| rtsock.c | ||
| sff8436.h | ||
| sff8472.h | ||
| slcompress.c | ||
| slcompress.h | ||
| toeplitz.c | ||
| toeplitz.h | ||
| vnet.c | ||
| vnet.h | ||