freebsd-dev/sys/netpfil/pf
Alexander V. Chernikov 1fe201c322 Simplify the way of attaching IPv6 link-layer header.
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
2015-09-16 14:26:28 +00:00
..
if_pflog.c Mechanically convert to if_inc_counter(). 2014-09-19 09:19:29 +00:00
if_pfsync.c CALLOUT_MPSAFE has lost its meaning since r141428, i.e., for more than ten 2015-05-22 17:05:21 +00:00
in4_cksum.c
pf_altq.h Add ALTQ(9) support for the CoDel algorithm. 2015-08-21 22:02:22 +00:00
pf_if.c Reapply r196551 which was accidentally reverted by r223637 (update to 2015-08-24 21:41:05 +00:00
pf_ioctl.c Fix the copy of addresses passed from userland in table replace command. 2015-08-17 23:03:54 +00:00
pf_lb.c Do not lookup source node twice when pf_map_addr() is used. 2014-08-15 14:16:08 +00:00
pf_mtag.h ALTQ FAIRQ discipline import from DragonFLY 2015-06-24 19:16:41 +00:00
pf_norm.c pf: Remove support for 'scrub fragment crop|drop-ovl' 2015-08-27 21:27:47 +00:00
pf_osfp.c The r48589 promised to remove implicit inclusion of if_var.h soon. Prepare 2013-10-26 17:58:36 +00:00
pf_ruleset.c Provide includes that are needed in these files, and before were read 2013-10-26 18:18:50 +00:00
pf_table.c Back out r276841, r276756, r276747, r276746. The change in r276747 is very 2015-01-22 01:23:16 +00:00
pf.c Simplify the way of attaching IPv6 link-layer header. 2015-09-16 14:26:28 +00:00
pf.h In the forwarding case refragment the reassembled packets with the same 2015-02-16 07:01:02 +00:00