freebsd-skq/sys/netinet6
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
..
dest6.c
frag6.c
icmp6.c Fix the handling of IPv6 On-Link Redirects. 2015-09-14 19:17:25 +00:00
icmp6.h
in6_cksum.c
in6_gif.c
in6_ifattach.c Remove IN6_IFF_NOPFX. This flag was no longer used. 2015-09-10 06:08:42 +00:00
in6_ifattach.h
in6_mcast.c
in6_pcb.c
in6_pcb.h
in6_pcbgroup.c
in6_proto.c
in6_rmx.c
in6_rss.c Implement RSS hashing/re-hashing for IPv6 ingress packets. 2015-08-29 07:14:29 +00:00
in6_rss.h Implement RSS hashing/re-hashing for IPv6 ingress packets. 2015-08-29 07:14:29 +00:00
in6_src.c
in6_var.h - Remove SIOCGDRLST_IN6 and SIOCGPRLST_IN6. These are quite old APIs and 2015-09-10 06:31:24 +00:00
in6.c * Do more fine-grained locking: call eventhandlers/free_entry 2015-09-14 16:48:19 +00:00
in6.h Add support for receiving flowtype, flowid and RSS bucket information as part of recvmsg(). 2015-09-06 20:57:57 +00:00
ip6_ecn.h
ip6_forward.c Simplify the way of attaching IPv6 link-layer header. 2015-09-16 14:26:28 +00:00
ip6_gre.c
ip6_id.c
ip6_input.c Add support for receiving flowtype, flowid and RSS bucket information as part of recvmsg(). 2015-09-06 20:57:57 +00:00
ip6_ipsec.c
ip6_ipsec.h
ip6_mroute.c
ip6_mroute.h
ip6_output.c Simplify the way of attaching IPv6 link-layer header. 2015-09-16 14:26:28 +00:00
ip6_var.h Implement RSS hashing/re-hashing for IPv6 ingress packets. 2015-08-29 07:14:29 +00:00
ip6.h
ip6protosw.h
mld6_var.h
mld6.c
mld6.h
nd6_nbr.c Do not pass lle to nd6_ns_output(). Use newly-added 2015-09-05 14:14:03 +00:00
nd6_rtr.c Fix the handling of IPv6 On-Link Redirects. 2015-09-14 19:17:25 +00:00
nd6.c Simplify the way of attaching IPv6 link-layer header. 2015-09-16 14:26:28 +00:00
nd6.h Simplify the way of attaching IPv6 link-layer header. 2015-09-16 14:26:28 +00:00
pim6_var.h
pim6.h
raw_ip6.c
raw_ip6.h
route6.c
scope6_var.h
scope6.c
sctp6_usrreq.c
sctp6_var.h
send.c
send.h
tcp6_var.h
udp6_usrreq.c remove a left-over after r220463 empty #ifdef INET check. 2015-08-28 09:38:18 +00:00
udp6_var.h