Commit Graph

351 Commits

Author SHA1 Message Date
Bjoern A. Zeeb
89856f7e2d Get closer to a VIMAGE network stack teardown from top to bottom rather
than removing the network interfaces first. This change is rather larger
and convoluted as the ordering requirements cannot be separated.

Move the pfil(9) framework to SI_SUB_PROTO_PFIL, move Firewalls and
related modules to their own SI_SUB_PROTO_FIREWALL.
Move initialization of "physical" interfaces to SI_SUB_DRIVERS,
move virtual (cloned) interfaces to SI_SUB_PSEUDO.
Move Multicast to SI_SUB_PROTO_MC.

Re-work parts of multicast initialisation and teardown, not taking the
huge amount of memory into account if used as a module yet.

For interface teardown we try to do as many of them as we can on
SI_SUB_INIT_IF, but for some this makes no sense, e.g., when tunnelling
over a higher layer protocol such as IP. In that case the interface
has to go along (or before) the higher layer protocol is shutdown.

Kernel hhooks need to go last on teardown as they may be used at various
higher layers and we cannot remove them before we cleaned up the higher
layers.

For interface teardown there are multiple paths:
(a) a cloned interface is destroyed (inside a VIMAGE or in the base system),
(b) any interface is moved from a virtual network stack to a different
network stack ("vmove"), or (c) a virtual network stack is being shut down.
All code paths go through if_detach_internal() where we, depending on the
vmove flag or the vnet state, make a decision on how much to shut down;
in case we are destroying a VNET the individual protocol layers will
cleanup their own parts thus we cannot do so again for each interface as
we end up with, e.g., double-frees, destroying locks twice or acquiring
already destroyed locks.
When calling into protocol cleanups we equally have to tell them
whether they need to detach upper layer protocols ("ulp") or not
(e.g., in6_ifdetach()).

Provide or enahnce helper functions to do proper cleanup at a protocol
rather than at an interface level.

Approved by:		re (hrs)
Obtained from:		projects/vnet
Reviewed by:		gnn, jhb
Sponsored by:		The FreeBSD Foundation
MFC after:		2 weeks
Differential Revision:	https://reviews.freebsd.org/D6747
2016-06-21 13:48:49 +00:00
Conrad Meyer
ab11d379fa netipsec: Fix minor style nit
Coverity points out that 'continue' is equivalent to 'break' in a do {}
while(false) loop.

Reported by:	Coverity
CID:		1354983
Sponsored by:	EMC / Isilon Storage Division
2016-05-10 20:14:11 +00:00
Pedro F. Giffuni
a4641f4eaa sys/net*: minor spelling fixes.
No functional change.
2016-05-03 18:05:43 +00:00
Conrad Meyer
5a8c498f2e netipsec: Don't leak memory when deep copy fails
Reported by:	Coverity
CID:		1331693
Sponsored by:	EMC / Isilon Storage Division
2016-04-26 23:23:44 +00:00
Andrey V. Elsukov
0d05666462 Fix build for NOINET and NOINET6 kernels.
Use own protosw structures for both address families.
Check proto in encapcheck function and use -1 as proto argument in
encap_attach_func(), both address families can have IPPROTO_IPV4
and IPPROTO_IPV6 protocols.

Reported by:	bz
2016-04-24 17:09:51 +00:00
Andrey V. Elsukov
2ada524ece Use ipsec_address() function to print IP addresses. 2016-04-24 09:05:29 +00:00
Andrey V. Elsukov
3cbd4ec3e4 Handle non-compressed packets for IPComp in tunnel mode.
RFC3173 says that the IP datagram MUST be sent in the original
non-compressed form, when the total size of a compressed payload
and the IPComp header is not smaller than the size of the original
payload. In tunnel mode for small packets IPComp will send
encapsulated IP datagrams without IPComp header.
Add ip_encap handler for IPPROTO_IPV4 and IPPROTO_IPV6 to handle
these datagrams. The handler does lookup for SA related to IPComp
protocol and given from mbuf source and destination addresses as
tunnel endpoints. It decapsulates packets only when corresponding SA
is found.

Reported by:	gnn
Reviewed by:	gnn
Differential Revision:	https://reviews.freebsd.org/D6062
2016-04-24 09:02:17 +00:00
Andrey V. Elsukov
61a292a396 Remove stale function declaration 2016-04-21 11:02:06 +00:00
Andrey V. Elsukov
efb10c3ce7 Constify mbuf pointer for IPSEC functions where mbuf isn't modified. 2016-04-21 10:58:07 +00:00
Pedro F. Giffuni
02abd40029 kernel: use our nitems() macro when it is available through param.h.
No functional change, only trivial cases are done in this sweep,

Discussed in:	freebsd-current
2016-04-19 23:48:27 +00:00
Pedro F. Giffuni
155d72c498 sys/net* : for pointers replace 0 with NULL.
Mostly cosmetical, no functional change.

Found with devel/coccinelle.
2016-04-15 17:30:33 +00:00
Andrey V. Elsukov
6f814d0ec1 Fix handling of net.inet.ipsec.dfbit=2 variable.
IP_DF macro is in host bytes order, but ip_off field is in network bytes
order. So, use htons() for correct check.
2016-03-18 09:03:00 +00:00
Robert Watson
bc84fc89be Put IPSec's anouncement of its successful intialisation under bootverbose:
now that it's a default kernel option, we don't really need to tell the
world about it on every boot, especially as it won't be used by most users.
2016-03-13 19:27:46 +00:00
Mark Johnston
3543e138e5 Set tres to NULL to avoid a double free if the m_pullup() below fails.
Reviewed by:	glebius
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D5497
2016-03-02 05:04:04 +00:00
Andrey V. Elsukov
b833ff5ab4 Fix useless check. m_pkthdr.len should be equal to orglen.
MFC after:	2 weeks
2016-02-24 12:28:49 +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
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
Fabien Thomas
d6d3f24890 Implement the sadb_x_policy_priority field as it is done in Linux:
lower priority policies are inserted first.

Submitted by:	Emeric Poupon <emeric.poupon@stormshield.eu>
Reviewed by:	ae
Sponsored by:	Stormshield
2015-11-17 14:39:33 +00:00
Andrey V. Elsukov
0c80e7df43 Use explicitly specified ivsize instead of blocksize when we mean IV size.
Set zero ivsize for enc_xform_null and remove special handling from
xform_esp.c.

Reviewed by:	gnn
Differential Revision:	https://reviews.freebsd.org/D1503
2015-11-16 07:10:42 +00:00
George V. Neville-Neil
26882b4239 Turning on IPSEC used to introduce a slight amount of performance
degradation (7%) for host host TCP connections over 10Gbps links,
even when there were no secuirty policies in place. There is no
change in performance on 1Gbps network links. Testing GENERIC vs.
GENERIC-NOIPSEC vs. GENERIC with this change shows that the new
code removes any overhead introduced by having IPSEC always in the
kernel.

Differential Revision:	D3993
MFC after:	1 month
Sponsored by:	Rubicon Communications (Netgate)
2015-10-27 00:42:15 +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
John-Mark Gurney
a2bc81bf7c Make IPsec work with AES-GCM and AES-ICM (aka CTR) in OCF... IPsec
defines the keys differently than NIST does, so we have to muck with
key lengths and nonce/IVs to be standard compliant...

Remove the iv from secasvar as it was unused...

Add a counter protected by a mutex to ensure that the counter for GCM
and ICM will never be repeated..  This is a requirement for security..
I would use atomics, but we don't have a 64bit one on all platforms..

Fix a bug where IPsec was depending upon the OCF to ensure that the
blocksize was always at least 4 bytes to maintain alignment... Move
this logic into IPsec so changes to OCF won't break IPsec...

In one place, espx was always non-NULL, so don't test that it's
non-NULL before doing work..

minor style cleanups...

drop setting key and klen as they were not used...

Enforce that OCF won't pass invalid key lengths to AES that would
panic the machine...

This was has been tested by others too...  I tested this against
NetBSD 6.1.5 using mini-test suite in
https://github.com/jmgurney/ipseccfgs and the only things that don't
pass are keyed md5 and sha1, and 3des-deriv (setkey syntax error),
all other modes listed in setkey's man page...  The nice thing is
that NetBSD uses setkey, so same config files were used on both...

Reviewed by:	gnn
2015-08-04 17:47:11 +00:00
John-Mark Gurney
42e5fcbf2b these are comparing authenticators and need to be constant time...
This could be a side channel attack...  Now that we have a function
for this, use it...

jmgurney/ipsecgcm:	24d704cc and 7f37a14
2015-07-31 00:31:52 +00:00
John-Mark Gurney
817c7ed900 Clean up this header file...
use CTASSERTs now that we have them...

Replace a draft w/ RFC that's over 10 years old.

Note that _AALG and _EALG do not need to match what the IKE daemons
think they should be..  This is part of the KABI...  I decided to
renumber AESCTR, but since we've never had working AESCTR mode, I'm
not really breaking anything..  and it shortens a loop by quite
a bit..

remove SKIPJACK IPsec support...  SKIPJACK never made it out of draft
(in 1999), only has 80bit key, NIST recommended it stop being used
after 2010, and setkey nor any of the IKE daemons I checked supported
it...

jmgurney/ipsecgcm: a357a33, c75808b, e008669, b27b6d6

Reviewed by:	gnn (earlier version)
2015-07-31 00:23:21 +00:00
Ermal Luçi
59959de526 Correct IPSec SA statistic keeping
The IPsec SA statistic keeping is used even for decision making on expiry/rekeying SAs.
When there are multiple transformations being done the statistic keeping might be wrong.

This mostly impacts multiple encapsulations on IPsec since the usual scenario it is not noticed due to the code path not taken.

Differential Revision:	https://reviews.freebsd.org/D3239
Reviewed by:		ae, gnn
Approved by:		gnn(mentor)
2015-07-30 20:56:27 +00:00
John-Mark Gurney
a09a7146a7 RFC4868 section 2.3 requires that the output be half... This fixes
problems that was introduced in r285336...  I have verified that
HMAC-SHA2-256 both ah only and w/ AES-CBC interoperate w/ a NetBSD
6.1.5 vm...

Reviewed by:	gnn
2015-07-29 07:15:16 +00:00
Ermal Luçi
705f4d9c6a IPSEC, remove variable argument function its already due.
Differential Revision:		https://reviews.freebsd.org/D3080
Reviewed by:	gnn, ae
Approved by:	gnn(mentor)
2015-07-21 21:46:24 +00:00
George V. Neville-Neil
0b75d21e18 Summary: Fix LINT build. The names of the new AES modes were not
correctly used under the REGRESSION kernel option.
2015-07-10 02:23:50 +00:00
George V. Neville-Neil
16de9ac1b5 Add support for AES modes to IPSec. These modes work both in software only
mode and with hardware support on systems that have AESNI instructions.

Differential Revision:	D2936
Reviewed by:	jmg, eri, cognet
Sponsored by:	Rubicon Communications (Netgate)
2015-07-09 18:16:35 +00:00
Andrey V. Elsukov
280d77a3bb Fill the port and protocol information in the SADB_ACQUIRE message
in case when security policy has it as required by RFC 2367.

PR:		192774
Differential Revision:	https://reviews.freebsd.org/D2972
MFC after:	1 week
2015-07-06 12:40:31 +00:00
Ermal Luçi
c1fc5e9601 Reduce overhead of IPSEC for traffic generated from host
When IPSEC is enabled on the kernel the forwarding path has an optimization to not enter the code paths
for checking security policies but first checks if there is any security policy active at all.

The patch introduces the same optimization but for traffic generated from the host itself.
This reduces the overhead by 50% on my tests for generated host traffic without and SP active.

Differential Revision:	https://reviews.freebsd.org/D2980
Reviewed by:	ae, gnn
Approved by:	gnn(mentor)
2015-07-03 15:31:56 +00:00
John-Mark Gurney
49672bcc54 drop key_sa_stir_iv as it isn't used...
Reviewed by:	eri, ae
2015-06-11 13:05:37 +00:00
Jung-uk Kim
fd90e2ed54 CALLOUT_MPSAFE has lost its meaning since r141428, i.e., for more than ten
years for head.  However, it is continuously misused as the mpsafe argument
for callout_init(9).  Deprecate the flag and clean up callout_init() calls
to make them more consistent.

Differential Revision:	https://reviews.freebsd.org/D2613
Reviewed by:	jhb
MFC after:	2 weeks
2015-05-22 17:05:21 +00:00
Andrey V. Elsukov
dc4ea824d4 In the reply to SADB_X_SPDGET message use the same sequence number that
was in the request. Some IKE deamons expect it will the same. Linux and
NetBSD also follow this behaviour.

PR:		137309
MFC after:	2 weeks
2015-05-20 11:59:53 +00:00
Andrey V. Elsukov
4ec5fcbe09 Remove unneded mbuf length adjustment, M_PREPEND() already did that.
PR:		139387
MFC after:	1 week
2015-05-19 17:14:27 +00:00
Andrey V. Elsukov
5bae2b34a4 Change SA's state before sending SADB_EXPIRE message. This state will
be reported to keying daemon.

MFC after:	2 weeks
2015-05-19 08:37:03 +00:00
Andrey V. Elsukov
664802113f Teach key_expire() send SADB_EXPIRE message with the SADB_EXT_LIFETIME_HARD
extension header type. The key_flush_sad() now will send SADB_EXPIRE
message when HARD lifetime expires. This is required by RFC 2367 and some
keying daemons rely on these messages. HARD lifetime messages have
precedence over SOFT lifetime messages, so now they will be checked first.
Also now SADB_EXPIRE messages will be send even the SA has not been used,
because keying daemons might want to rekey such SA.

PR:		200282, 200283
Submitted by:	Tobias Brunner <tobias at strongswan dot org>
MFC after:	2 weeks
2015-05-19 08:30:04 +00:00
George V. Neville-Neil
a9b294b433 Summary: Remove spurious, extra, next header comments.
Correct the name of the pad length field.
2015-05-15 18:04:49 +00:00
Andrey V. Elsukov
6508929bc2 Fix the comment. We will not do SPD lookup again, because
ip[6]_ipsec_output() will find PACKET_TAG_IPSEC_OUT_DONE mbuf tag.

Sponsored by:	Yandex LLC
2015-04-28 11:03:47 +00:00
Andrey V. Elsukov
574fde00be Since PFIL can change mbuf pointer, we should update pointers after
calling ipsec_filter().

Sponsored by:	Yandex LLC
2015-04-28 09:29:28 +00:00
Andrey V. Elsukov
a9b9f6b6c6 Make ipsec_in_reject() static. We use ipsec[46]_in_reject() instead.
Sponsored by:	Yandex LLC
2015-04-27 01:12:51 +00:00
Andrey V. Elsukov
3d80e82d60 Fix possible use after free due to security policy deletion.
When we are passing mbuf to IPSec processing via ipsec[46]_process_packet(),
we hold one reference to security policy and release it just after return
from this function. But IPSec processing can be deffered and when we release
reference to security policy after ipsec[46]_process_packet(), user can
delete this security policy from SPDB. And when IPSec processing will be
done, xform's callback function will do access to already freed memory.

To fix this move KEY_FREESP() into callback function. Now IPSec code will
release reference to SP after processing will be finished.

Differential Revision:	https://reviews.freebsd.org/D2324
No objections from:	#network
Sponsored by:	Yandex LLC
2015-04-27 00:55:56 +00:00
Andrey V. Elsukov
962ac6c727 Change ipsec_address() and ipsec_logsastr() functions to take two
additional arguments - buffer and size of this buffer.

ipsec_address() is used to convert sockaddr structure to presentation
format. The IPv6 part of this function returns pointer to the on-stack
buffer and at the moment when it will be used by caller, it becames
invalid. IPv4 version uses 4 static buffers and returns pointer to
new buffer each time when it called. But anyway it is still possible
to get corrupted data when several threads will use this function.

ipsec_logsastr() is used to format string about SA entry. It also
uses static buffer and has the same problem with concurrent threads.

To fix these problems add the buffer pointer and size of this
buffer to arguments. Now each caller will pass buffer and its size
to these functions. Also convert all places where these functions
are used (except disabled code).

And now ipsec_address() uses inet_ntop() function from libkern.

PR:		185996
Differential Revision:	https://reviews.freebsd.org/D2321
Reviewed by:	gnn
Sponsored by:	Yandex LLC
2015-04-18 16:58:33 +00:00
Andrey V. Elsukov
1d3b268c04 Requeue mbuf via netisr when we use IPSec tunnel mode and IPv6.
ipsec6_common_input_cb() uses partial copy of ip6_input() to parse
headers. But this isn't correct, when we use tunnel mode IPSec.

When we stripped outer IPv6 header from the decrypted packet, it
can become IPv4 packet and should be handled by ip_input. Also when
we use tunnel mode IPSec with IPv6 traffic, we should pass decrypted
packet with inner IPv6 header to ip6_input, it will correctly handle
it and also can decide to forward it.

The "skip" variable points to offset where payload starts. In tunnel
mode we reset it to zero after stripping the outer header. So, when
it is zero, we should requeue mbuf via netisr.

Differential Revision:	https://reviews.freebsd.org/D2306
Reviewed by:	adrian, gnn
Sponsored by:	Yandex LLC
2015-04-18 16:51:24 +00:00
Andrey V. Elsukov
1ae800e7a6 Fix handling of scoped IPv6 addresses in IPSec code.
* in ipsec_encap() embed scope zone ids into link-local addresses
  in the new IPv6 header, this helps ip6_output() disambiguate the
  scope;
* teach key_ismyaddr6() use in6_localip(). in6_localip() is less
  strict than key_sockaddrcmp(). It doesn't compare all fileds of
  struct sockaddr_in6, but it is faster and it should be safe,
  because all SA's data was checked for correctness. Also, since
  IPv6 link-local addresses in the &V_in6_ifaddrhead are stored in
  kernel-internal form, we need to embed scope zone id from SA into
  the address before calling in6_localip.
* in ipsec_common_input() take scope zone id embedded in the address
  and use it to initialize sin6_scope_id, then use this sockaddr
  structure to lookup SA, because we keep addresses in the SADB without
  embedded scope zone id.

Differential Revision:	https://reviews.freebsd.org/D2304
Reviewed by:	gnn
Sponsored by:	Yandex LLC
2015-04-18 16:46:31 +00:00
Andrey V. Elsukov
61f376155d Remove xform_ipip.c and code related to XF_IP4.
The only thing is used from this code is ipip_output() function, that does
IPIP encapsulation. Other parts of XF_IP4 code were removed in r275133.
Also it isn't possible to configure the use of XF_IP4, nor from userland
via setkey(8), nor from the kernel.

Simplify the ipip_output() function and rename it to ipsec_encap().
* move IP_DF handling from ipsec4_process_packet() into ipsec_encap();
* since ipsec_encap() called from ipsec[64]_process_packet(), it
  is safe to assume that mbuf is contiguous at least to IP header
  for used IP version. Remove all unneeded m_pullup(), m_copydata
  and related checks.
* use V_ip_defttl and V_ip6_defhlim for outer headers;
* use V_ip4_ipsec_ecn and V_ip6_ipsec_ecn for outer headers;
* move all diagnostic messages to the ipsec_encap() callers;
* simplify handling of ipsec_encap() results: if it returns non zero
  value, print diagnostic message and free mbuf.
* some style(9) fixes.

Differential Revision:	https://reviews.freebsd.org/D2303
Reviewed by:	glebius
Sponsored by:	Yandex LLC
2015-04-18 16:38:45 +00:00
Gleb Smirnoff
6d947416cc o Use new function ip_fillid() in all places throughout the kernel,
where we want to create a new IP datagram.
o Add support for RFC6864, which allows to set IP ID for atomic IP
  datagrams to any value, to improve performance. The behaviour is
  controlled by net.inet.ip.rfc6864 sysctl knob, which is enabled by
  default.
o In case if we generate IP ID, use counter(9) to improve performance.
o Gather all code related to IP ID into ip_id.c.

Differential Revision:		https://reviews.freebsd.org/D2177
Reviewed by:			adrian, cy, rpaulo
Tested by:			Emeric POUPON <emeric.poupon stormshield.eu>
Sponsored by:			Netflix
Sponsored by:			Nginx, Inc.
Relnotes:			yes
2015-04-01 22:26:39 +00:00
Andrey V. Elsukov
ba76ce40b4 Remove extra '&'. sin6 is already a pointer.
PR:		195011
MFC after:	1 week
2015-03-07 18:44:52 +00:00
Andrey V. Elsukov
47568136c5 Fix possible memory leak and several races in the IPsec policy management
code.

Resurrect the state field in the struct secpolicy, it has
IPSEC_SPSTATE_ALIVE value when security policy linked in the chain,
and IPSEC_SPSTATE_DEAD value in all other cases. This field protects
from trying to unlink one security policy several times from the different
threads.

Take additional reference in the key_flush_spd() to be sure that policy
won't be freed from the different thread while we are sending SPDEXPIRE message.

Add KEY_FREESP() call to the key_unlink() to release additional reference
that we take when use key_getsp*() functions.

Differential Revision:	https://reviews.freebsd.org/D1914
Tested by:		Emeric POUPON <emeric.poupon at stormshield dot eu>
Reviewed by:	hrs
Sponsored by:	Yandex LLC
2015-02-24 10:35:07 +00:00
Andrey V. Elsukov
b489a49fc0 key_spdget uses key_setdumpsp() without SPTREE_RLOCK held (it uses
referenced pointer to sp). Remove SPTREE_RLOCK_ASSERT from
key_setdumpsp() to fix wrong assertion.

Reported by:	Emeric POUPON
Obtained from:	Yandex LLC
Sponsored by:	Yandex LLC
2015-01-27 17:46:55 +00:00