Commit Graph

1654 Commits

Author SHA1 Message Date
Gleb Smirnoff
56a5f52e80 New way to manage reference counting of mbuf external storage.
The m_ext.ext_cnt pointer becomes a union. It can now hold the refcount
value itself. To tell that m_ext.ext_flags flag EXT_FLAG_EMBREF is used.
The first mbuf to attach a cluster stores the refcount. The further mbufs
to reference the cluster point at refcount in the first mbuf. The first
mbuf is freed only when the last reference is freed.

The benefit over refcounts stored in separate slabs is that now refcounts
of different, unrelated mbufs do not share a cache line.

For EXT_EXTREF mbufs the zone_ext_refcnt is no longer needed, and m_extadd()
becomes void, making widely used M_EXTADD macro safe.

For EXT_SFBUF mbufs the sf_ext_ref() is removed, which was an optimization
exactly against the cache aliasing problem with regular refcounting.

Discussed with:		rrs, rwatson, gnn, hiren, sbruno, np
Reviewed by:		rrs
Differential Revision:	https://reviews.freebsd.org/D5396
Sponsored by:		Netflix
2016-03-01 00:17:14 +00:00
Mark Johnston
4de485fe5f Lock the NDP default router list and count defrouter references.
This addresses a number of race conditions that can cause crashes as a
result of unsynchronized access to the list.

PR:		206904
Tested by:	Larry Rosenman <ler@lerctr.org>,
		Kevin Bowling <kevin.bowling@kev009.com>
MFC after:	2 months
Differential Revision: https://reviews.freebsd.org/D5315
2016-02-25 20:12:05 +00:00
Michael Tuexen
9a59fb36b2 Don't leak an address in an error path.
CID:		1351729
MFC after:	3 days
2016-02-23 18:50:34 +00:00
Michael Tuexen
6df7c000d3 Fix reporting of mapped addressed in getpeername() and getsockname() for
IPv6 SCTP sockets.
This bugs were found because of an issue reported by PVS / D5245.
2016-02-18 21:05:04 +00:00
Mark Johnston
c15064c27a Release the ref acquired in nd6_dad_find() if DAD is already in progress.
MFC after:	1 week
2016-02-18 00:00:51 +00:00
Mark Johnston
38dd603f8c Use pfxrtr_del() instead of freeing advertising routers directly.
MFC after:	1 week
2016-02-17 23:55:24 +00:00
Mark Johnston
19fa242679 Remove a prototype for the non-existent prelist_del().
MFC after:	1 week
2016-02-17 23:53:24 +00:00
Gleb Smirnoff
c619ab95b3 Ternary operator has lower priority than OR.
Found by:	PVS-Studio
2016-02-17 21:17:14 +00:00
Mark Johnston
eb3ff358dc Add a missing newline to a log message.
MFC after:	1 week
2016-02-12 21:17:00 +00:00
Mark Johnston
01869be58e Rename the flags field of struct nd_defrouter to "raflags".
This field contains the flags inherited from the corresponding router
advertisement message and is not for storing private state.

MFC after:	1 week
2016-02-12 21:15:57 +00:00
Mark Johnston
a4a7c8254c Simplify defrtrlist_update() slightly in preparation for future changes.
No functional change intended.

MFC after:	1 week
2016-02-12 21:06:48 +00:00
Mark Johnston
f60d595f34 Remove a bogus comment from nd6_na_input().
The splnet() call that it refers to has been removed, and a lock for the
default router list is in fact needed.

MFC after:	1 week
2016-02-12 21:01:53 +00:00
Mark Johnston
baebd3e54f Remove superfluous return statements from the neighbour discovery code.
MFC after:	1 week
2016-02-12 20:55:22 +00:00
Mark Johnston
fc31564185 Fix style around allocations from M_IP6NDP.
- Don't cast the return value of malloc(9).
- Use M_ZERO instead of explicitly calling bzero(9).

MFC after:	1 week
2016-02-12 20:52:53 +00:00
Mark Johnston
97dca6a207 Remove some unreferenced NDP debug variable definitions.
MFC after:	1 week
2016-02-12 20:46:53 +00:00
Devin Teske
41c0ec9a16 Merge SVN r295220 (bz) from projects/vnet/
Fix a panic that occurs when a vnet interface is unavailable at the time the
vnet jail referencing said interface is stopped.

Sponsored by:	FIS Global, Inc.
2016-02-11 17:07:19 +00:00
Bjoern A. Zeeb
a5243af262 Code duplication but rib_head is special. Not found an easy way to go
back and harmize the use cases among RIB, IPFW, PF yet but it's also not
the scope of this work.   Prevents instant panics on teardown and frees
the FIB bits again.

Sponsored by:	The FreeBSD Foundation
2016-02-03 21:56:51 +00:00
Bjoern A. Zeeb
2414e86439 MfH @r295202
Expect to see panics in routing code at least now.
2016-02-03 11:49:51 +00:00
Gleb Smirnoff
8ec07310fa These files were getting sys/malloc.h and vm/uma.h with header pollution
via sys/mbuf.h
2016-02-01 17:41:21 +00:00
Alexander V. Chernikov
61eee0e202 MFP r287070,r287073: split radix implementation and route table structure.
There are number of radix consumers in kernel land (pf,ipfw,nfs,route)
  with different requirements. In fact, first 3 don't have _any_ requirements
  and first 2 does not use radix locking. On the other hand, routing
  structure do have these requirements (rnh_gen, multipath, custom
  to-be-added control plane functions, different locking).
Additionally, radix should not known anything about its consumers internals.

So, radix code now uses tiny 'struct radix_head' structure along with
  internal 'struct radix_mask_head' instead of 'struct radix_node_head'.
  Existing consumers still uses the same 'struct radix_node_head' with
  slight modifications: they need to pass pointer to (embedded)
  'struct radix_head' to all radix callbacks.

Routing code now uses new 'struct rib_head' with different locking macro:
  RADIX_NODE_HEAD prefix was renamed to RIB_ (which stands for routing
  information base).

New net/route_var.h header was added to hold routing subsystem internal
  data. 'struct rib_head' was placed there. 'struct rtentry' will also
  be moved there soon.
2016-01-25 06:33:15 +00:00
Bjoern A. Zeeb
0ea826e094 MFp4 @180892:
With pr_destroy being gone, call ip6_destroy from an ordered
	NET_SYSUNINT.  Make ip6_destroy() static as well.

Sponsored by:	The FreeBSD Foundation
2016-01-22 18:09:25 +00:00
Bjoern A. Zeeb
009e81b164 MFH @r294567 2016-01-22 15:11:40 +00:00
Bjoern A. Zeeb
1f12da0e82 Just checkpoint the WIP in order to be able to make the tree update
easier.  Note:  this is currently not in a usable state as certain
teardown parts are not called and the DOMAIN rework is missing.
More to come soon and find its way to head.

Obtained from:	P4 //depot/user/bz/vimage/...
Sponsored by:	The FreeBSD Foundation
2016-01-22 15:00:01 +00:00
Alexander V. Chernikov
af8451a51e Fix rte refcount leak in ip6_forward().
Reviewed by:	ae
MFC after:	2 weeks
Sponsored by:	Yandex LLC
2016-01-20 11:25:30 +00:00
Gleb Smirnoff
479795819a Verify the packet length in sctp6_input().
The sctp6_ctlinput() function does not properly check the length of the packet
it receives from the ICMP6 input routine. This means that an attacker can craft
a packet that will cause a kernel panic.

When the kernel receives an ICMP6 error message with one of the types/codes
it handles, it calls icmp6_notify_error() to deliver it to the upper-level
protocol. icmp6_notify_error() cycles through the extension headers (if any)
to find the protocol number of the first non-extension header. It does NOT
verify the length of the non-extension header.

It passes information about the packet (including the actual packet) to the
upper-level protocol's pr_ctlinput function. In the case of SCTP for IPv6,
icmp6_notify_error() calls sctp6_ctlinput().

sctp6_ctlinput() assumes that the incoming packet contains a sufficiently-long
SCTP header and calls m_copydata() to extract a copy of that header. In turn,
m_copydata() assumes that the caller has already verified that the offset and
length parameters are correct. If they are incorrect, it will dereference a
NULL pointer and cause a kernel panic.

In short, no one is sufficiently verifying the input, and the result is a
kernel panic.

Submitted by:	jtl
Security:	SA-16:01.sctp
2016-01-14 10:11:10 +00:00
Alexander V. Chernikov
59747033cd Bring RADIX_MPATH support to new routing KPI to ease migration.
Move actual rte selection process from rtalloc_mpath_fib()
  to the rt_path_selectrte() function. Add public
  rt_mpath_select() to use in fibX_lookup_ functions.
2016-01-11 08:45:28 +00:00
Alexander V. Chernikov
601c0b8bcc Split in6_selectsrc() into in6_selectsrc_addr() and in6_selectsrc_socket().
in6_selectsrc() has 2 class of users: socket-based one (raw/udp/pcb/etc) and
  socket-less (ND code). The main reason for that change is inability to
  specify non-default FIB for callers w/o socket since (internally) inpcb
  is used to determine fib.

As as result, add 2 wrappers for in6_selectsrc() (making in6_selectsrc()
  static):
1) in6_selectsrc_socket() for the former class. Embed scope_ambiguous check
  along with returning hop limit when needed.
2) in6_selectsrc_addr() for the latter case. Add 'fibnum' argument and
  pass IPv6 address  w/ explicitly specified scope as separate argument.

Reviewed by:	ae (previous version)
2016-01-10 13:40:29 +00:00
Alexander V. Chernikov
ab861e6c06 Do not hold ifaddr reference for the whole icmp6_reflect() exec time.
Copy source address, calculate hlim and release refcount instead.
2016-01-10 11:59:55 +00:00
Alexander V. Chernikov
5dba456c14 Remove prefix check from in6_addroute().
This check was added in initial? netinet6/ import
  back in 1999 (r53541).
It effectively became unnecessary after 'address/prefix clean-ups'
  KAME commit 90ff8792e676132096a440dd787f99a5a5860ee8 (github) in 2001
  (merged to FreeBSD in r78064) where prefix check was added to
  nd6_prefix_onlink(). Similar IPv4 check (in_addroute() was added
  in r137628).
Additionally, the right plance for this (or similar) check is the prefix
  addition code (nd6_prefix_onlink(), nd6_prefix_onlink_rtrequest(),
  in_addprefix() or rtinit()), but not the generic radix insert routine.
2016-01-09 11:41:37 +00:00
Alexander V. Chernikov
ea8d14925c Remove sys/eventhandler.h from net/route.h
Reviewed by:	ae
2016-01-09 09:34:39 +00:00
Alexander V. Chernikov
bacf668430 Finish r293098: make ip6_getpmtu() and ip6_getpmtu_ctl() use new routing API 2016-01-04 18:32:24 +00:00
Alexander V. Chernikov
9a1b64d5a0 Add rib_lookup_info() to provide API for retrieving individual route
entries data in unified format.

There are control plane functions that require information other than
  just next-hop data (e.g. individual rtentry fields like flags or
  prefix/mask). Given that the goal is to avoid rte reference/refcounting,
  re-use rt_addrinfo structure to store most rte fields. If caller wants
  to retrieve key/mask or gateway (which are sockaddrs and are allocated
  separately), it needs to provide sufficient-sized sockaddrs structures
  w/ ther pointers saved in passed rt_addrinfo.

Convert:
  * lltable new records checks (in_lltable_rtcheck(),
    nd6_is_new_addr_neighbor().
  * rtsock pre-add/change route check.
  * IPv6 NS ND-proxy check (RADIX_MPATH code was eliminated because
     1) we don't support RTF_ANNOUNCE ND-proxy for networks and there should
       not be multiple host routes for such hosts 2) if we have multiple
       routes we should inspect them (which is not done). 3) the entire idea
       of abusing KRT as storage for ND proxy seems odd. Userland programs
       should be used for that purpose).
2016-01-04 15:03:20 +00:00
Alexander V. Chernikov
357ce739b9 Remove 'struct route_int6' argument from in6_selectsrc() and
in6_selectif().

The main task of in6_selectsrc() is to return IPv6 SAS (along with
  output interface used for scope checks). No data-path code uses
  route argument for caching. The only users are icmp6 (reflect code),
  ND6 ns/na generation code. All this fucntions are control-plane, so
  there is no reason to try to 'optimize' something by passing cached
  route into to ip6_output(). Given that, simplify code by eliminating
  in6_selectsrc() 'struct route_in6' argument. Since in6_selectif() is
  used only by in6_selectsrc(), eliminate its 'struct route_in6' argument,
  too. While here, reshape rte-related code inside in6_selectif() to
  free lookup result immediately after saving all the needed fields.
2016-01-03 10:43:23 +00:00
Alexander V. Chernikov
0d4df0290e Handle IPV6_PATHMTU option by spliting ip6_getpmtu_ctl() from ip6_getpmtu().
Add ro_mtu field to 'struct route' to be able to pass lookup MTU back to
  the caller.

Currently, ip6_getpmtu() has 2 totally different use cases:
1) control plane (IPV6_PATHMTU req), where we just need to calculate MTU
  and return it, w/o any reusability.
2) Actual ip6_output() data path where we (nearly) always use the provided
  route lookup data. If this data is not 'valid' we need to perform another
  lookup and save the result (which cannot be re-used by ip6_output()).

Given that, handle 1) by calling separate function doing rte lookup itself.
  Resulting MTU is calculated by (newly-added) ip6_calcmtu() used by both
  ip6_getpmtu_ctl() and ip6_getpmtu().
For 2) instead of storing ref'ed rte, store mtu (the only needed data
  from the lookup result) inside newly-added ro_mtu field.
  'struct route' was shrinked by 8(or 4 bytes) in r292978. Grow it again
  by 4 bytes. New ro_mtu field will be used in other places like
  ip/tcp_output (EMSGSIZE handling from output routines).

Reviewed by:	ae
2016-01-03 09:54:03 +00:00
Alexander V. Chernikov
9a7ee988b5 Use lltable_get_ifp() instead of direct access to lltable fields. 2016-01-01 12:35:33 +00:00
Alexander V. Chernikov
4fb3a8208c Implement interface link header precomputation API.
Add if_requestencap() interface method which is capable of calculating
  various link headers for given interface. Right now there is support
  for INET/INET6/ARP llheader calculation (IFENCAP_LL type request).
  Other types are planned to support more complex calculation
  (L2 multipath lagg nexthops, tunnel encap nexthops, etc..).

Reshape 'struct route' to be able to pass additional data (with is length)
  to prepend to mbuf.

These two changes permits routing code to pass pre-calculated nexthop data
  (like L2 header for route w/gateway) down to the stack eliminating the
  need for other lookups. It also brings us closer to more complex scenarios
  like transparently handling MPLS nexthops and tunnel interfaces.
  Last, but not least, it removes layering violation introduced by flowtable
  code (ro_lle) and simplifies handling of existing if_output consumers.

ARP/ND changes:
Make arp/ndp stack pre-calculate link header upon installing/updating lle
  record. Interface link address change are handled by re-calculating
  headers for all lles based on if_lladdr event. After these changes,
  arpresolve()/nd6_resolve() returns full pre-calculated header for
  supported interfaces thus simplifying if_output().
Move these lookups to separate ether_resolve_addr() function which ether
  returs error or fully-prepared link header. Add <arp|nd6_>resolve_addr()
  compat versions to return link addresses instead of pre-calculated data.

BPF changes:
Raw bpf writes occupied _two_ cases: AF_UNSPEC and pseudo_AF_HDRCMPLT.
Despite the naming, both of there have ther header "complete". The only
  difference is that interface source mac has to be filled by OS for
  AF_UNSPEC (controlled via BIOCGHDRCMPLT). This logic has to stay inside
  BPF and not pollute if_output() routines. Convert BPF to pass prepend data
  via new 'struct route' mechanism. Note that it does not change
  non-optimized if_output(): ro_prepend handling is purely optional.
Side note: hackish pseudo_AF_HDRCMPLT is supported for ethernet and FDDI.
  It is not needed for ethernet anymore. The only remaining FDDI user is
  dev/pdq mostly untouched since 2007. FDDI support was eliminated from
  OpenBSD in 2013 (sys/net/if_fddisubr.c rev 1.65).

Flowtable changes:
  Flowtable violates layering by saving (and not correctly managing)
  rtes/lles. Instead of passing lle pointer, pass pointer to pre-calculated
  header data from that lle.

Differential Revision:	https://reviews.freebsd.org/D4102
2015-12-31 05:03:27 +00:00
Jonathan T. Looney
912568c881 Add the appropriate case statement for IPV6_BINDMULTI so the option can be
retrieved with getsockopt().

CID:	1229928
Differential Revision:	https://reviews.freebsd.org/D4737
Reviewed by:	adrian
Sponsored by:	Juniper Networks
2015-12-30 18:08:05 +00:00
Bjoern A. Zeeb
88310b4011 This code is not in modules that need KPI stability so no need to use
the wrapper functions as used in r252511.  We can directly use the
locking macros.

Reviewed by:		jtl, rwatson
MFC after:		2 weeks
Differential Revision:	https://reviews.freebsd.org/D4731
2015-12-30 17:10:03 +00:00
Garrett Wollman
2832ade6b8 in6_if2idlen: treat bridge(4) interfaces like other Ethernet interfaces
bridge(4) interfaces have an if_type of IFT_BRIDGE, rather than
IFT_ETHER, even though they only support Ethernet-style links.  This
caused in6_if2idlen to emit an "unknown link type (209)" warning to
the console every time it was called.  Add IFT_BRIDGE to the case
statement in the appropriate place, indicating that it uses the same
IPv6 address format as other Ethernet-like interfaces.

MFC after:	1 week
2015-12-28 18:29:47 +00:00
Bjoern A. Zeeb
bf72bf1281 Remove superfluous return (1) missed in r292601.
Reported by:	Matthew D. Fuller (fullermd over-yonder.net),
		Kevin Bowling (kevin.bowling kev009.com)
MFC after:	13 days
X-MFC with:	r292601
Sponsored by:	The FreeBSD Foundation
2015-12-23 10:23:47 +00:00
Bjoern A. Zeeb
0a03cf8ca6 Since r256624 we've been leaking routing table allocations
on vnet enabled jail shutdown. Call the provided cleanup
routines for IP versions 4 and 6 to plug these leaks.

Sponsored by:		The FreeBSD Foundation
MFC atfer:		2 weeks
Reviewed by:		gnn
Differential Revision:	https://reviews.freebsd.org/D4530
2015-12-22 14:53:19 +00:00
Steven Hartland
d6e82913c1 Revert r292275 & r292379
glebius has concerns about these changes so reverting those can be discussed
and addressed.

Sponsored by:	Multiplay
2015-12-17 14:41:30 +00:00
Steven Hartland
3a909afe8e Fix issues introduced by r292275
* Fix panic for etherswitches which don't have a LLADDR.
* Disabled DELAY in unsolicited NDA, which needs further work.
* Fixed missing DELAY in carp_send_na.
* style(9) fix.

Reported by:	kp & melifaro
X-MFC-With:	r292275
MFC after:	1 month
Sponsored by:	Multiplay
2015-12-16 22:26:28 +00:00
Alexander V. Chernikov
427c2f4ef0 Provide additional lle data in IPv6 lltable dump used by ndp(8).
Before the change, things like lle state were queried via
  SIOCGNBRINFO_IN6 by ndp(8) for _each_ lle entry in dump.
This ioctl was added in 1999, probably to avoid touching rtsock code.

This change maps SIOCGNBRINFO_IN6 data to standard rtsock dump the
 following way:
  expire (already) maps to rtm_rmx.rmx_expire
  isrouter -> rtm_flags & RTF_GATEWAY
  asked -> rtm_rmx.rmx_pksent
  state -> rtm_rmx.rmx_state (maps to rmx_weight via define)

Reviewed by:	ae
2015-12-16 10:14:16 +00:00
Steven Hartland
52e53e2de0 Fix lagg failover due to missing notifications
When using lagg failover mode neither Gratuitous ARP (IPv4) or Unsolicited
Neighbour Advertisements (IPv6) are sent to notify other nodes that the
address may have moved.

This results is slow failover, dropped packets and network outages for the
lagg interface when the primary link goes down.

We now use the new if_link_state_change_cond with the force param set to
allow lagg to force through link state changes and hence fire a
ifnet_link_event which are now monitored by rip and nd6.

Upon receiving these events each protocol trigger the relevant
notifications:
* inet4 => Gratuitous ARP
* inet6 => Unsolicited Neighbour Announce

This also fixes the carp IPv6 NA's that stopped working after r251584 which
added the ipv6_route__llma route.

The new behavour can be controlled using the sysctls:
* net.link.ether.inet.arp_on_link
* net.inet6.icmp6.nd6_on_link

Also removed unused param from lagg_port_state and added descriptions for the
sysctls while here.

PR:		156226
MFC after:	1 month
Sponsored by:	Multiplay
Differential Revision:	https://reviews.freebsd.org/D4111
2015-12-15 16:02:11 +00:00
Kristof Provost
7e037c12f2 inet6: Do not assume every interface has ip6 enabled.
Certain interfaces (e.g. pfsync0) do not have ip6 addresses (in other words,
ifp->if_afdata[AF_INET6] is NULL). Ensure we don't panic when the MTU is
updated.

pfsync interfaces will never have ip6 support, because it's explicitly disabled
in in6_domifattach().

PR:		205194
Reviewed by:	melifaro, hrs
Differential Revision:	https://reviews.freebsd.org/D4522
2015-12-14 19:44:49 +00:00
Alexander V. Chernikov
12cb7521c2 Remove LLE read lock from IPv6 fast path.
LLE structure is mostly unchanged during its lifecycle: there are only 2
things relevant for fast path lookup code:
1) link-level address change. Since r286722, these updates are performed
  under AFDATA WLOCK.
2) Some sort of feedback indicating that this particular entry is used so
  we send NS to perform reachability verification instead of expiring entry.
  The only signal that is needed from fast path is something like binary
  yes/no.
The latter is solved by the following changes:

Special r_skip_req (introduced in D3688) value is used for fast path feedback.
  It is read lockless by fast path, but updated under req_mutex mutex. If this
  field is non-zero, then fast path will acquire lock and set it back to 0.

After transitioning to STALE state, callout timer is armed to run each
  V_nd6_delay seconds to make sure that if packet was transmitted at the start
  of given interval, we would be able to switch to PROBE state in V_nd6_delay
  seconds as user expects.
(in STALE state) timer is rescheduled until original V_nd6_gctimer expires
  keeping lle in STALE state (remaining timer value stored in lle_remtime).
(in STALE state) timer is rescheduled if packet was transmitted less that
  V_nd6_delay seconds ago to make sure we transition to PROBE state exactly
  after V_n6_delay seconds.

As a result, all packets towards lle in REACHABLE/STALE/PROBE states are handled
  by fast path without acquiring lle read lock.

Differential Revision:		https://reviews.freebsd.org/D3780
2015-12-13 07:39:49 +00:00
Alexander V. Chernikov
9cce04b061 Use correct lookup key for gif route lookups.
This fixes r291993 change.
2015-12-09 22:09:33 +00:00
Alexander V. Chernikov
9977be4a64 Make in_arpinput(), inp_lookup_mcast_ifp(), icmp_reflect(),
ip_dooptions(), icmp6_redirect_input(), in6_lltable_rtcheck(),
  in6p_lookup_mcast_ifp() and in6_selecthlim() use new routing api.

Eliminate now-unused ip_rtaddr().
Fix lookup key fib6_lookup_nh_basic() which was lost diring merge.
Make fib6_lookup_nh_basic() and fib6_lookup_nh_extended() always
  return IPv6 destination address with embedded scope. Currently
  rw_gateway has it scope embedded, do the same for non-gatewayed
  destinations.

Sponsored by:	Yandex LLC
2015-12-09 11:14:27 +00:00
Alexander V. Chernikov
65ff3638df Merge helper fib* functions used for basic lookups.
Vast majority of rtalloc(9) users require only basic info from
route table (e.g. "does the rtentry interface match with the interface
  I have?". "what is the MTU?", "Give me the IPv4 source address to use",
  etc..).
Instead of hand-rolling lookups, checking if rtentry is up, valid,
  dealing with IPv6 mtu, finding "address" ifp (almost never done right),
  provide easy-to-use API hiding all the complexity and returning the
  needed info into small on-stack structure.

This change also helps hiding route subsystem internals (locking, direct
  rtentry accesses).
Additionaly, using this API improves lookup performance since rtentry is not
  locked.
(This is safe, since all the rtentry changes happens under both radix WLOCK
  and rtentry WLOCK).

Sponsored by:	Yandex LLC
2015-12-08 10:50:03 +00:00
Michael Tuexen
c979034b18 Fix the allocation of outgoing streams:
* When processing a cookie, use the number of
  streams announced in the INIT-ACK.
* When sending an INIT-ACK for an existing
  association, use the value from the association,
  not from the end-point.

MFC after:	1 week
2015-12-06 16:17:57 +00:00
Andrey V. Elsukov
9f8b8e793b mld_v2_dispatch_general_query() is used by mld_fasttimo_vnet() to send
a reply to the MLDv2 General Query. In case when router has a lot of
multicast groups, the reply can take several packets due to MTU limitation.
Also we have a limit MLD_MAX_RESPONSE_BURST == 4, that limits the number
of packets we send in one shot. Then we recalculate the timer value and
schedule the remaining packets for sending.
The problem is that when we call mld_v2_dispatch_general_query() to send
remaining packets, we queue new reply in the same mbuf queue. And when
number of packets is bigger than MLD_MAX_RESPONSE_BURST, we get endless
reply of MLDv2 reports.
To fix this, add the check for remaining packets in the queue.

PR:		204831
MFC after:	1 week
Sponsored by:	Yandex LLC
2015-12-01 11:17:41 +00:00
Alexander V. Chernikov
e8b0643eee Add new rt_foreach_fib_walk_del() function for deleting route entries
by filter function instead of picking into routing table details in
  each consumer.
Remove now-unused rt_expunge() (eliminating last external RTF_RNH_LOCKED
 user).
This simplifies future nexthops/mulitipath changes and rtrequest1_fib()
  locking refactoring.

Actual changes:
Add "rt_chain" field to permit rte grouping while doing batched delete
  from routing table (thus growing rte 200->208 on amd64).
Add "rti_filter" /  "rti_filterdata" / "rti_spare" fields to rt_addrinfo
  to pass filter function to various routing subsystems in standard way.
Convert all rt_expunge() customers to new rt_addinfo-based api and eliminate
  rt_expunge().
2015-11-30 05:51:14 +00:00
Andrey V. Elsukov
ef91a9765d Overhaul if_enc(4) and make it loadable in run-time.
Use hhook(9) framework to achieve ability of loading and unloading
if_enc(4) kernel module. INET and INET6 code on initialization registers
two helper hooks points in the kernel. if_enc(4) module uses these helper
hook points and registers its hooks. IPSEC code uses these hhook points
to call helper hooks implemented in if_enc(4).
2015-11-25 07:31:59 +00:00
Conrad Meyer
55faae77fa in6_mc_get: Fix recursion on if_addr_lock on malloc failure
Analogously to r291040, in6_mc_get recurses on if_addr_lock if the
M_NOWAIT allocation fails.  The fix is the same.

Suggested by:	Andrey V. Elsukov
Reviewed by:	jhb (ip4 version)
Sponsored by:	EMC / Isilon Storage Division
Differential Revision:	https://reviews.freebsd.org/D4138 (ip4 version)
2015-11-19 00:27:26 +00:00
Alexander V. Chernikov
637670e77e Bring back the ability of passing cached route via nd6_output_ifp(). 2015-11-15 16:02:22 +00:00
Randall Stewart
7c4676ddee This fixes several places where callout_stops return is examined. The
new return codes of -1 were mistakenly being considered "true". Callout_stop
now returns -1 to indicate the callout had either already completed or
was not running and 0 to indicate it could not be stopped.  Also update
the manual page to make it more consistent no non-zero in the callout_stop
or callout_reset descriptions.

MFC after:	1 Month with associated callout change.
2015-11-13 22:51:35 +00:00
Alexander V. Chernikov
ddd208f7ad Unify setting lladdr for AF_INET[6]. 2015-11-07 11:12:00 +00:00
Adrian Chadd
aaa46574b0 [netinet6]: Create a new IPv6 netisr which expects the frames to have been verified.
This is required for fragments and encapsulated data (eg tunneling) to be redistributed
to the RSS bucket based on the eventual IPv6 header and protocol (TCP, UDP, etc) header.

* Add an mbuf tag with the state of IPv6 options parsing before the frame is queued
  into the direct dispatch handler;
* Continue processing and complete the frame reception in the correct RSS bucket /
  netisr context.

Testing results are in the phabricator review.

Differential Revision:	https://reviews.freebsd.org/D3563
Submitted by:	Tiwei Bie <btw@mail.ustc.edu.cn>
2015-11-06 23:07:43 +00:00
Alexander V. Chernikov
ba99cc0b86 Use m_cat() to reassembly IPv6 packets.
Submitted by:	jonloony_gmail.com
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D3863
2015-10-27 22:11:09 +00:00
Alexander V. Chernikov
ab415c8307 Invoke lle_event for new entry iff it has lladdr set. 2015-10-04 19:10:27 +00:00
Alexander V. Chernikov
7503e0c783 Simplify if (lladdr) condition in nd6_cache_lladdr():
For case (7) (new entry) nothing has to be done except lle_event.
  Invoke this event directly from "create new lle" code block.
  For case (4) (existing entry, same mac) useless mac update was performed,
  along with LLENTRY_RESOLVED lle_event. There was no sense in doing that,
  since nothing really had changed. Simply avoid this condition instead.
  Given that, condition was simplified to (3),(5) states which can be merged
  with previous block.
2015-10-04 12:42:07 +00:00
Alexander V. Chernikov
9b420b3da4 Eliminate nd6_llinfo_settimer(). All consumers were converted to
use nd6_llinfo_settimer_locked() in r216022.
Make nd6_llinfo_settimer_locked() static: last external consumer was
converted in r288124.
2015-10-04 08:33:16 +00:00
Alexander V. Chernikov
c0b8aeae2d Add __noinline attribute to several functions to ease dtrace instrumentation 2015-10-04 08:21:15 +00:00
Alexander V. Chernikov
06a60e4bb0 Fix condition for nd6_llinfo_getholdsrc() introduced in r287484.
Effectively it always returned NULL so SAS was always performed and
  sometimes the result might have been different.

Fix state machine change accidentally introduced in r287985:
  state (4) inside nd6_cache_lladdr() (existing entry got nd message
  with the same lladdress) started to cause lle state transition to STALE
  instead of no-action.
2015-10-04 07:02:17 +00:00
Hiroki Sato
6401c828ce - Schedule DAD for IN6_IFF_TENTATIVE addresses in nd6_timer(). This
catches cases that DAD probes cannot be sent because of
  IFF_UP && !IFF_DRV_RUNNING.

- nd6_dad_starttimer() now calls nd6_dad_ns_output(), instead of
  calling it before nd6_dad_starttimer().

- Do not release an entry in dadq when a duplicate entry is being
  added.
2015-10-03 12:09:12 +00:00
Andrey V. Elsukov
f367798498 Take extra reference to security policy before calling crypto_dispatch().
Currently we perform crypto requests for IPSEC synchronous for most of
crypto providers (software, aesni) and only VIA padlock calls crypto
callback asynchronous. In synchronous mode it is possible, that security
policy will be removed during the processing crypto request. And crypto
callback will release the last reference to SP. Then upon return into
ipsec[46]_process_packet() IPSECREQUEST_UNLOCK() will be called to already
freed request. To prevent this we will take extra reference to SP.

PR:		201876
Sponsored by:	Yandex LLC
2015-09-30 08:16:33 +00:00
Alexander V. Chernikov
1558cb2448 Eliminate nd6_nud_hint() and its TCP bindings.
Initially function was introduced in r53541 (KAME initial commit) to
  "provide hints from upper layer protocols that indicate a connection
  is making "forward progress"" (quote from RFC 2461 7.3.1 Reachability
  Confirmation).
However, it was converted to do nothing (e.g. just return) in r122922
  (tcp_hostcache implementation) back in 2003. Some defines were moved
  to tcp_var.h in r169541. Then, it was broken (for non-corner cases)
  by r186119 (L2<>L3 split) in 2008 (NULL ifp in nd6_lookup). So,
  right now this code is broken and has no "real" base users.

Differential Revision:	https://reviews.freebsd.org/D3699
2015-09-27 05:29:34 +00:00
Alexander V. Chernikov
4a336ef40c rtsock requests for deleting interface address lles started to return EPERM
instead of old "ignore-and-return 0" in r287789. This broke arp -da /
  ndp -cn behavior (they exit on rtsock command failure). Fix this by
  translating LLE_IFADDR to RTM_PINNED flag, passing it to userland and
  making arp/ndp ignore these entries in batched delete.

MFC after:	2 weeks
2015-09-27 04:54:29 +00:00
Alexander V. Chernikov
f506d933b5 Use standard lle LLE_EXCLUSIVE request flags instead of
its redefined version.
2015-09-22 20:45:04 +00:00
Bjoern A. Zeeb
7af7c754e4 Compare mbuf pointer to NULL rather than to 0.
No functional change.

MFC after:	2 weeks
2015-09-21 12:53:26 +00:00
Bjoern A. Zeeb
b1ce89f2bc In the UDP over IPv6 implementation several cases are using the wrong protocol,
e.g., based on wrong "next header" assumptions (which does not have to point to
the upper layer protocol), or using hard-coded UDP instead of UDP or UDP-Lite
possibly switching protocols.  Fix those cases for UDP-Lite to work correctly.

PR:			202788
Submitted by:		Tiwei Bie (btw mail.ustc.edu.cn) [parts]
Reviewed by:		gnn, Tiwei Bie (btw mail.ustc.edu.cn),
			kevlo (earlier version)
MFC after:		2 weeks
Differential Revision:	https://reviews.freebsd.org/D3686
2015-09-21 12:32:36 +00:00
Alexander V. Chernikov
aa5f023eaf Unify nd6 state switching by using newly-created nd6_llinfo_setstate()
function. The change is mostly mechanical with the following exception:
Last piece of nd6_resolve_slow() was refactored: ND6_LLINFO_PERMANENT
  condition was removed as always-true, explicit ND6_LLINFO_NOSTATE ->
  ND6_LLINFO_INCOMPLETE state transition was removed as duplicate.

Reviewed by:	ae
Sponsored by:	Yandex LLC
2015-09-21 11:19:53 +00:00
Alexander V. Chernikov
1496229a91 Add "stale" timer back to nd6_cache_lladdr().
Setting timer was accidentally removed in r276844 due to misleading
  comment on its meaningless. Add it back to restore proper behaviour.
2015-09-21 10:24:34 +00:00
Alexander V. Chernikov
501adf0140 Cleanup nd6_cache_lladdr(). No functional changes.
* Since new extries are now allocated explicitly, fill in
  all the necessary fields for lle _before_ attaching it to the table.
* Remove ND6_LLINFO_INCOMPLETE check which was unused even in
  first KAME merge (r53541).
* After that, the only new state that function can set, was
  ND6_LLINFO_STALE. Given everything above, simplify logic besides
  do_update and is_newentry.
* Fix nd_resolve() comment.
2015-09-19 11:50:02 +00:00
Alexander V. Chernikov
41a31e783e * Simplify logic besides llchange variable.
* Refresh nd6_is_router() comment.
2015-09-18 07:18:10 +00:00
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
Alexander V. Chernikov
f0316e1acb Constantify lookup key in several nd6_* functions. 2015-09-16 11:06:07 +00:00
Alexander V. Chernikov
0e2dcee6b2 Simplify nd6_cache_lladdr:
* Move isRouter calculation code to separate nd6_is_router() function.
* Make nd6_cache_lladdr() return void: its return value hasn't been used
  since r53541 KAME import in 1999.

Sponsored by:	Yandex LLC
2015-09-15 17:16:31 +00:00
Alexander V. Chernikov
d3cdb71655 * Require explicitl lle unlink prior to calling llentry_delete().
This one slightly decreases time of holding afdata wlock.
* While here, make nd6_free() return void. No one has used its return value
  since r186119.
2015-09-15 06:48:19 +00:00
Eric van Gyzen
17a036563d Fix the handling of IPv6 On-Link Redirects.
On receipt of a redirect message, install an interface route for the
redirected destination.  On removal of the corresponding Neighbor Cache
entry, remove the interface route.

This requires changes in rtredirect_fib() to cope with an AF_LINK
address for the gateway and with the absence of RTF_GATEWAY.

This fixes the "Redirected On-Link" test cases in the Tahi IPv6 Ready Logo
Phase 2 test suite.

Unrelated to the above, fix a recursion on the radix node head lock
triggered by the Tahi Redirected to Alternate Router test cases.

When I first wrote this patch in October 2012, all Section 2
(Neighbor Discovery) test cases passed on 10-CURRENT, 9-STABLE,
and 8-STABLE.  cem@ recently rebased the 10.x patch onto head and reported
that it passes Tahi.  (Thanks!)

These other test cases also passed in 2012:

* the RTF_MODIFIED case, with IPv4 and IPv6 (using a
  RTF_HOST|RTF_GATEWAY route for the destination)

* the redirected-to-self case, with IPv4 and IPv6

* a valid IPv4 redirect

All testing in 2012 was done with WITNESS and INVARIANTS.

Tested by:    EMC / Isilon Storage Division via Conrad Meyer (cem) in 2015,
              Mark Kelley <mark_kelley@dell.com> in 2012,
              TC Telkamp <terence_telkamp@dell.com> in 2012
PR:           152791
Reviewed by:  melifaro (current rev), bz (earlier rev)
Approved by:  kib (mentor)
MFC after:    1 month
Relnotes:     yes
Sponsored by: Dell Inc.
Differential Revision: https://reviews.freebsd.org/D3602
2015-09-14 19:17:25 +00:00
Alexander V. Chernikov
3e7a2321e3 * Do more fine-grained locking: call eventhandlers/free_entry
without holding afdata wlock
* convert per-af delete_address callback to global lltable_delete_entry() and
  more low-level "delete this lle" per-af callback
* fix some bugs/inconsistencies in IPv4/IPv6 ifscrub procedures

Sponsored by:		Yandex LLC
Differential Revision:	https://reviews.freebsd.org/D3573
2015-09-14 16:48:19 +00:00
Hiroki Sato
120ff2d73d Remove SIOCGDRLST_IN6 and SIOCGPRLST_IN6 forgotten in the previous commit.
MFC after:	3 days
2015-09-10 08:37:03 +00:00
Hiroki Sato
e3884653f6 - Remove SIOCGDRLST_IN6 and SIOCGPRLST_IN6. These are quite old APIs and
there is no consumer now.

MFC after:	3 days
2015-09-10 06:31:24 +00:00
Hiroki Sato
d0bec2c522 - Remove SIOCGDRLST_IN6 and SIOCGPRLST_IN6. These are quite old APIs and
there is no consumer now.

- Simplify first and duplicate LLA check.

MFC after:	3 days
2015-09-10 06:29:18 +00:00
Hiroki Sato
1fce58fc62 Do not add IN6_IFF_TENTATIVE when ND6_IFF_NO_DAD.
MFC after:	3 days
2015-09-10 06:10:30 +00:00
Hiroki Sato
3ba7e4ce9c Remove IN6_IFF_NOPFX. This flag was no longer used.
MFC after:	3 days
2015-09-10 06:08:42 +00:00
Adrian Chadd
68bb8d6249 Add support for receiving flowtype, flowid and RSS bucket information as part of recvmsg().
Submitted by:	Tiwei Bie <btw@mail.ustc.edu.cn>
Differential Revision:	https://reviews.freebsd.org/D3562
2015-09-06 20:57:57 +00:00
Alexander V. Chernikov
26deb8826c Do not pass lle to nd6_ns_output(). Use newly-added
nd6_llinfo_get_holdsrc() to extract desired IPv6 source
  from holdchain and pass it to the nd6_ns_output().
2015-09-05 14:14:03 +00:00
Alexander V. Chernikov
deeedaa549 Do not skip entries without LLE_VALID flag.
This one fixes showing incomplete entries in ndp -an.

MFC after:	2 weeks
2015-09-05 06:24:00 +00:00
Alexander V. Chernikov
91bfd68e38 Make in6ifa_ifpwithaddr() take const param.
Remove unneded DECONST from in6_lltable_rtcheck().
2015-09-05 05:54:09 +00:00
Alexander V. Chernikov
3b0fd911fa Simplify lla_rt_output()/nd6_add_ifa_lle() by setting lle state in
alloc handler, based on flags.
2015-08-31 05:03:36 +00:00
Adrian Chadd
0be189151f Implement RSS hashing/re-hashing for IPv6 ingress packets.
This mirrors the basic IPv4 implementation - IPv6 packets under RSS
now are checked for a correct RSS hash and if one isn't provided,
it's done in software.

This only handles the initial receive - it doesn't yet handle
reinjecting / rehashing packets after being decapsulated from
various tunneling setups.  That'll come in some follow-up work.

For non-RSS users, this is almost a giant no-op.

It does change a couple of ipv6 methods to use const mbuf * instead of
mbuf * but it doesn't have any functional changes.

So, the following now occurs:

* If the NIC doesn't do any RSS hashing, it's all done in software.
  Single-queue, non-RSS NICs will now have the RX path distributed
  into multiple receive netisr queues.

* If the NIC provides the wrong hash (eg only IPv6 hash when we needed
  an IPv6 TCP hash, or IPv6 UDP hash when we expected IPv6 hash)
  then the hash is recalculated.

* .. if the hash is recalculated, it'll end up being injected into
  the correct netisr queue for v6 processing.

Submitted by:	Tiwei Bie <btw@mail.ustc.edu.cn>
Differential Revision:	https://reviews.freebsd.org/D3504
2015-08-29 07:14:29 +00:00
Bjoern A. Zeeb
196074f3b2 remove a left-over after r220463 empty #ifdef INET check.
MFC after:	1 week
2015-08-28 09:38:18 +00:00
Adrian Chadd
e5562eb934 Replace the printf()s with optional rate limited debugging for RSS.
Submitted by:	Tiwei Bie <btw@mail.ustc.edu.cn>
Differential Revision:	https://reviews.freebsd.org/D3471
2015-08-28 05:58:16 +00:00
Bjoern A. Zeeb
a86e5c96af get_inpcbinfo() and get_pcblist() are UDP local functions and
do not do what one would expect by name. Prefix them with "udp_"
to at least obviously limit the scope.

This is a non-functional change.

Reviewed by:		gnn, rwatson
MFC after:		2 weeks
Differential Revision:	https://reviews.freebsd.org/D3505
2015-08-27 15:27:41 +00:00
Adrian Chadd
2bf1d4880d Call the new RSS hash calculation function to correctly calculate a hash
based on the configured requirements for the protocol.

Tested:

* UDP IPv6 TX/RX testing, w/ RSS enabled, 82599 ixgbe(4) hardware
2015-08-25 06:12:59 +00:00
Adrian Chadd
20dbdf88a5 Implement the IPv6 RSS software hash function.
This isn't yet linked into the receive/transmit paths anywhere just yet.

This is part of a GSoC 2015 project.

Submitted by:	Tiwei Bie <btw@mail.ustc.edu.cn>
Reviewed by:	hiren, gnn
Differential Revision:	https://reviews.freebsd.org/D3423
2015-08-24 05:36:08 +00:00
Hiroki Sato
fb583bd228 - Deprecate IN6_IFF_NODAD. It was used to prevent DAD on a loopback
interface but in6if_do_dad() already had a check for IFF_LOOPBACK.

- Remove in6if_do_dad() check in in6_broadcast_ifa().  An address
  which needs DAD always has IN6_IFF_TENTATIVE there.

- in6if_do_dad() now returns EAGAIN when the interface is not ready
  since DAD callout handler ignores such an interface.

- In DAD callout handler, mark an address as IN6_IFF_TENTATIVE
  when the interface has ND6_IFF_IFDISABLED.  And Do IFF_UP and
  IFF_DRV_RUNNING check consistently when DAD is required.

- draft-ietf-6man-enhanced-dad is now published as RFC 7527.

- Fix some typos.
2015-08-24 05:21:49 +00:00
Alexander V. Chernikov
5a2555160f * Split allocation and table linking for lle's.
Before that, the logic besides lle_create() was the following:
  return existing if found, create if not. This behaviour was error-prone
  since we had to deal with 'sudden' static<>dynamic lle changes.
  This commit fixes bunch of different issues like:
  - refcount leak when lle is converted to static.
    Simple check case:
    console 1:
    while true;
      do for i in `arp -an|awk '$4~/incomp/{print$2}'|tr -d '()'`;
        do arp -s $i 00:22:44:66:88:00 ; arp -d $i;
      done;
    done
   console 2:
    ping -f any-dead-host-in-L2
   console 3:
    # watch for memory consumption:
    vmstat -m | awk '$1~/lltable/{print$2}'
  - possible problems in arptimer() / nd6_timer() when dropping/reacquiring
   lock.
  New logic explicitly handles use-or-create cases in every lla_create
  user. Basically, most of the changes are purely mechanical. However,
  we explicitly avoid using existing lle's for interface/static LLE records.
* While here, call lle_event handlers on all real table lle change.
* Create lltable_free_entry() calling existing per-lltable
  lle_free_t callback for entry deletion
2015-08-20 12:05:17 +00:00