Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src add ipsec(4) interface, which is used for route-based VPN.



details:   https://anonhg.NetBSD.org/src/rev/ae022392476b
branches:  trunk
changeset: 828925:ae022392476b
user:      knakahara <knakahara%NetBSD.org@localhost>
date:      Wed Jan 10 10:56:30 2018 +0000

description:
add ipsec(4) interface, which is used for route-based VPN.

man and ATF are added later, please see man for details.

reviewed by christos@n.o, joerg@n.o and ozaki-r@n.o, thanks.
https://mail-index.netbsd.org/tech-net/2017/12/18/msg006557.html

diffstat:

 distrib/sets/lists/comp/mi  |     4 +-
 sys/conf/files              |     3 +-
 sys/net/Makefile            |     4 +-
 sys/net/files.net           |     3 +-
 sys/net/if_ipsec.c          |  1736 +++++++++++++++++++++++++++++++++++++++++++
 sys/net/if_ipsec.h          |   231 +++++
 sys/net/if_types.h          |     3 +-
 sys/netinet/in.c            |    42 +-
 sys/netinet/in.h            |     5 +-
 sys/netinet/ip_var.h        |     5 +-
 sys/netinet6/in6.c          |    22 +-
 sys/netinet6/in6.h          |     6 +-
 sys/netinet6/ip6_var.h      |     5 +-
 sys/netipsec/Makefile       |     3 +-
 sys/netipsec/files.netipsec |     5 +-
 sys/netipsec/ipsec.h        |     6 +-
 sys/netipsec/ipsecif.c      |   933 +++++++++++++++++++++++
 sys/netipsec/ipsecif.h      |    47 +
 sys/netipsec/key.c          |   225 ++++-
 sys/netipsec/key.h          |    18 +-
 20 files changed, 3238 insertions(+), 68 deletions(-)

diffs (truncated from 3751 to 300 lines):

diff -r 9752edbe35ff -r ae022392476b distrib/sets/lists/comp/mi
--- a/distrib/sets/lists/comp/mi        Wed Jan 10 08:47:30 2018 +0000
+++ b/distrib/sets/lists/comp/mi        Wed Jan 10 10:56:30 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: mi,v 1.2167 2018/01/09 03:31:13 christos Exp $
+#      $NetBSD: mi,v 1.2168 2018/01/10 10:56:30 knakahara Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 ./etc/mtree/set.comp                           comp-sys-root
@@ -2224,6 +2224,7 @@
 ./usr/include/net/if_hippi.h                   comp-c-include
 ./usr/include/net/if_ieee1394.h                        comp-c-include
 ./usr/include/net/if_ieee80211.h               comp-obsolete           obsolete
+./usr/include/net/if_ipsec.h                   comp-c-include
 ./usr/include/net/if_l2tp.h                    comp-c-include
 ./usr/include/net/if_llc.h                     comp-c-include
 ./usr/include/net/if_media.h                   comp-c-include
@@ -2382,6 +2383,7 @@
 ./usr/include/netipsec/ipcomp_var.h            comp-c-include
 ./usr/include/netipsec/ipip_var.h              comp-c-include
 ./usr/include/netipsec/ipsec.h                 comp-c-include
+./usr/include/netipsec/ipsecif.h               comp-c-include
 ./usr/include/netipsec/ipsec_var.h             comp-c-include
 ./usr/include/netipsec/keydb.h                 comp-obsolete           obsolete
 ./usr/include/netipsec/keysock.h               comp-c-include
diff -r 9752edbe35ff -r ae022392476b sys/conf/files
--- a/sys/conf/files    Wed Jan 10 08:47:30 2018 +0000
+++ b/sys/conf/files    Wed Jan 10 10:56:30 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files,v 1.1190 2018/01/09 03:31:12 christos Exp $
+#      $NetBSD: files,v 1.1191 2018/01/10 10:56:30 knakahara Exp $
 #      @(#)files.newconf       7.5 (Berkeley) 5/10/93
 
 version        20171118
@@ -1463,6 +1463,7 @@
 defpseudodev etherip:  ifnet, ether, arp
 defpseudodev l2tp:     ifnet, ether, arp
 defpseudo canloop:     ifnet
+defpseudo ipsecif:     ifnet           # avoid to confuse ipsec itself option
 
 defpseudo sequencer
 defpseudo clockctl
diff -r 9752edbe35ff -r ae022392476b sys/net/Makefile
--- a/sys/net/Makefile  Wed Jan 10 08:47:30 2018 +0000
+++ b/sys/net/Makefile  Wed Jan 10 10:56:30 2018 +0000
@@ -1,10 +1,10 @@
-#      $NetBSD: Makefile,v 1.33 2017/02/16 08:12:44 knakahara Exp $
+#      $NetBSD: Makefile,v 1.34 2018/01/10 10:56:30 knakahara Exp $
 
 INCSDIR= /usr/include/net
 
 INCS=  bpf.h bpfjit.h bpfdesc.h dlt.h ethertypes.h if.h if_arc.h if_arp.h \
        if_atm.h if_bridgevar.h if_dl.h if_ether.h if_etherip.h if_fddi.h if_gif.h \
-       if_gre.h if_hippi.h if_ieee1394.h if_llc.h if_media.h if_mpls.h \
+       if_gre.h if_hippi.h if_ieee1394.h if_ipsec.h if_llc.h if_media.h if_mpls.h \
        if_pflog.h if_ppp.h if_pppoe.h if_l2tp.h if_sppp.h if_srt.h if_stf.h \
        if_tap.h if_token.h if_tun.h if_types.h if_vlanvar.h net_stats.h \
        netisr.h pfil.h pfkeyv2.h pfvar.h ppp-comp.h ppp_defs.h radix.h \
diff -r 9752edbe35ff -r ae022392476b sys/net/files.net
--- a/sys/net/files.net Wed Jan 10 08:47:30 2018 +0000
+++ b/sys/net/files.net Wed Jan 10 10:56:30 2018 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.net,v 1.13 2017/02/16 08:12:44 knakahara Exp $
+#      $NetBSD: files.net,v 1.14 2018/01/10 10:56:30 knakahara Exp $
 
 # XXX CLEANUP
 define net
@@ -22,6 +22,7 @@
 file   net/if_gre.c                    gre                     needs-flag
 file   net/if_hippisubr.c              hippi                   needs-flag
 file   net/if_ieee1394subr.c           ieee1394
+file   net/if_ipsec.c                  ipsec & ipsecif
 file   net/if_llatbl.c                 inet | inet6
 file   net/if_l2tp.c                   l2tp                    needs-flag
 file   net/if_loop.c                   loop
diff -r 9752edbe35ff -r ae022392476b sys/net/if_ipsec.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/net/if_ipsec.c        Wed Jan 10 10:56:30 2018 +0000
@@ -0,0 +1,1736 @@
+/*     $NetBSD: if_ipsec.c,v 1.1 2018/01/10 10:56:30 knakahara Exp $  */
+
+/*
+ * Copyright (c) 2017 Internet Initiative Japan Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.1 2018/01/10 10:56:30 knakahara Exp $");
+
+#ifdef _KERNEL_OPT
+#include "opt_inet.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/syslog.h>
+#include <sys/cpu.h>
+#include <sys/kmem.h>
+#include <sys/mutex.h>
+#include <sys/pserialize.h>
+#include <sys/psref.h>
+
+#include <net/if.h>
+#include <net/if_types.h>
+#include <net/route.h>
+#include <net/bpf.h>
+#include <net/pfkeyv2.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#ifdef INET
+#include <netinet/in_var.h>
+#endif /* INET */
+
+#ifdef INET6
+#include <netinet6/in6_var.h>
+#include <netinet/ip6.h>
+#include <netinet6/ip6_var.h>
+#endif /* INET6 */
+
+#include <netinet/ip_encap.h>
+
+#include <net/if_ipsec.h>
+
+#include <net/raw_cb.h>
+#include <net/pfkeyv2.h>
+
+#include <netipsec/key.h>
+#include <netipsec/ipsec.h>
+#include <netipsec/ipsecif.h>
+
+static void if_ipsec_ro_init_pc(void *, void *, struct cpu_info *);
+static void if_ipsec_ro_fini_pc(void *, void *, struct cpu_info *);
+
+static int if_ipsec_clone_create(struct if_clone *, int);
+static int if_ipsec_clone_destroy(struct ifnet *);
+
+static inline int if_ipsec_out_direct(struct ipsec_variant *, struct mbuf *, int);
+static inline void if_ipsec_in_enqueue(struct mbuf *, int, struct ifnet *);
+
+static int if_ipsec_encap_attach(struct ipsec_variant *);
+static int if_ipsec_encap_detach(struct ipsec_variant *);
+static int if_ipsec_set_tunnel(struct ifnet *,
+    struct sockaddr *, struct sockaddr *);
+static void if_ipsec_delete_tunnel(struct ifnet *);
+static int if_ipsec_ensure_flags(struct ifnet *, short);
+static void if_ipsec_attach0(struct ipsec_softc *);
+
+static int if_ipsec_update_variant(struct ipsec_softc *,
+    struct ipsec_variant *, struct ipsec_variant *);
+
+/* sadb_msg */
+static inline void if_ipsec_add_mbuf(struct mbuf *, void *, size_t);
+static inline void if_ipsec_add_pad(struct mbuf *, size_t);
+static inline size_t if_ipsec_set_sadb_addr(struct sadb_address *,
+    struct sockaddr *, int, uint16_t);
+static inline size_t if_ipsec_set_sadb_src(struct sadb_address *,
+    struct sockaddr *, int);
+static inline size_t if_ipsec_set_sadb_dst(struct sadb_address *,
+    struct sockaddr *, int);
+static inline size_t if_ipsec_set_sadb_x_policy(struct sadb_x_policy *,
+    struct sadb_x_ipsecrequest *, uint16_t, uint8_t, uint32_t, uint8_t);
+static inline void if_ipsec_set_sadb_msg(struct sadb_msg *, uint16_t, uint8_t);
+static inline void if_ipsec_set_sadb_msg_add(struct sadb_msg *, uint16_t);
+static inline void if_ipsec_set_sadb_msg_del(struct sadb_msg *, uint16_t);
+/* SPD */
+static int if_ipsec_share_sp(struct ipsec_variant *);
+static int if_ipsec_unshare_sp(struct ipsec_variant *);
+static inline struct secpolicy *if_ipsec_add_sp0(struct sockaddr *,
+    in_port_t, struct sockaddr *, in_port_t, int, int, int, u_int);
+static inline int if_ipsec_del_sp0(struct secpolicy *);
+static int if_ipsec_add_sp(struct ipsec_variant *,
+    struct sockaddr *, in_port_t, struct sockaddr *, in_port_t);
+static void if_ipsec_del_sp(struct ipsec_variant *);
+static int if_ipsec_replace_sp(struct ipsec_softc *, struct ipsec_variant *,
+    struct ipsec_variant *);
+
+static int if_ipsec_set_addr_port(struct sockaddr *, struct sockaddr *,
+    in_port_t);
+#define IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, target)                    \
+       if_ipsec_set_addr_port(target, (var)->iv_psrc, (var)->iv_sport)
+#define IF_IPSEC_GATHER_PDST_ADDR_PORT(var, target)                    \
+       if_ipsec_set_addr_port(target, (var)->iv_pdst, (var)->iv_dport)
+
+/*
+ * ipsec global variable definitions
+ */
+
+/* This list is used in ioctl context only. */
+LIST_HEAD(ipsec_sclist, ipsec_softc);
+static struct {
+       struct ipsec_sclist list;
+       kmutex_t lock;
+} ipsec_softcs __cacheline_aligned;
+
+pserialize_t ipsec_psz __read_mostly;
+struct psref_class *iv_psref_class __read_mostly;
+
+struct if_clone ipsec_cloner =
+    IF_CLONE_INITIALIZER("ipsec", if_ipsec_clone_create, if_ipsec_clone_destroy);
+static int max_ipsec_nesting = MAX_IPSEC_NEST;
+
+/* ARGSUSED */
+void
+ipsecifattach(int count)
+{
+
+       mutex_init(&ipsec_softcs.lock, MUTEX_DEFAULT, IPL_NONE);
+       LIST_INIT(&ipsec_softcs.list);
+
+       ipsec_psz = pserialize_create();
+       iv_psref_class = psref_class_create("ipsecvar", IPL_SOFTNET);
+
+       if_clone_attach(&ipsec_cloner);
+}
+
+static int
+if_ipsec_clone_create(struct if_clone *ifc, int unit)
+{
+       struct ipsec_softc *sc;
+       struct ipsec_variant *var;
+
+       sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
+
+       if_initname(&sc->ipsec_if, ifc->ifc_name, unit);
+
+       if_ipsec_attach0(sc);
+
+       var = kmem_zalloc(sizeof(*var), KM_SLEEP);
+       var->iv_softc = sc;
+       psref_target_init(&var->iv_psref, iv_psref_class);
+
+       sc->ipsec_var = var;
+       mutex_init(&sc->ipsec_lock, MUTEX_DEFAULT, IPL_NONE);
+       sc->ipsec_ro_percpu = percpu_alloc(sizeof(struct ipsec_ro));
+       percpu_foreach(sc->ipsec_ro_percpu, if_ipsec_ro_init_pc, NULL);
+
+       mutex_enter(&ipsec_softcs.lock);
+       LIST_INSERT_HEAD(&ipsec_softcs.list, sc, ipsec_list);
+       mutex_exit(&ipsec_softcs.lock);
+       return 0;
+}
+
+static void
+if_ipsec_attach0(struct ipsec_softc *sc)
+{
+
+       sc->ipsec_if.if_addrlen = 0;
+       sc->ipsec_if.if_mtu    = IPSEC_MTU;
+       sc->ipsec_if.if_flags  = IFF_POINTOPOINT | IFF_MULTICAST;
+       /* set ipsec(4) specific default flags. */
+       sc->ipsec_if.if_flags  |= IFF_FWD_IPV6;
+       sc->ipsec_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE | IFEF_MPSAFE;
+       sc->ipsec_if.if_ioctl  = if_ipsec_ioctl;
+       sc->ipsec_if.if_output = if_ipsec_output;
+       sc->ipsec_if.if_type   = IFT_IPSEC;
+       sc->ipsec_if.if_dlt    = DLT_NULL;
+       sc->ipsec_if.if_softc  = sc;
+       IFQ_SET_READY(&sc->ipsec_if.if_snd);
+       if_initialize(&sc->ipsec_if);
+       if_alloc_sadl(&sc->ipsec_if);
+       bpf_attach(&sc->ipsec_if, DLT_NULL, sizeof(u_int));
+       if_register(&sc->ipsec_if);
+}
+
+static void
+if_ipsec_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
+{
+       struct ipsec_ro *iro = p;
+
+       mutex_init(&iro->ir_lock, MUTEX_DEFAULT, IPL_NONE);



Home | Main Index | Thread Index | Old Index