Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys Make global and per-interface ipsecif(4) pmtu tunable li...
details: https://anonhg.NetBSD.org/src/rev/49eeba9d66ad
branches: trunk
changeset: 460708:49eeba9d66ad
user: knakahara <knakahara%NetBSD.org@localhost>
date: Fri Nov 01 04:28:14 2019 +0000
description:
Make global and per-interface ipsecif(4) pmtu tunable like gif(4).
And make hop limit tunable same as gif(4).
See http://mail-index.netbsd.org/source-changes/2019/10/30/msg110426.html
diffstat:
sys/net/if_ipsec.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++-
sys/net/if_ipsec.h | 3 +-
sys/netinet6/in6.h | 4 +-
sys/netipsec/ipsecif.c | 56 ++++++++++++++++---
sys/netipsec/ipsecif.h | 11 +++-
5 files changed, 203 insertions(+), 14 deletions(-)
diffs (truncated from 345 to 300 lines):
diff -r 4c445623b264 -r 49eeba9d66ad sys/net/if_ipsec.c
--- a/sys/net/if_ipsec.c Fri Nov 01 04:23:21 2019 +0000
+++ b/sys/net/if_ipsec.c Fri Nov 01 04:28:14 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ipsec.c,v 1.24 2019/09/19 06:07:24 knakahara Exp $ */
+/* $NetBSD: if_ipsec.c,v 1.25 2019/11/01 04:28:14 knakahara Exp $ */
/*
* Copyright (c) 2017 Internet Initiative Japan Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.24 2019/09/19 06:07:24 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.25 2019/11/01 04:28:14 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -48,6 +48,7 @@
#include <sys/mutex.h>
#include <sys/pserialize.h>
#include <sys/psref.h>
+#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_types.h>
@@ -147,6 +148,138 @@
IF_CLONE_INITIALIZER("ipsec", if_ipsec_clone_create, if_ipsec_clone_destroy);
static int max_ipsec_nesting = MAX_IPSEC_NEST;
+static struct sysctllog *if_ipsec_sysctl;
+
+#ifdef INET6
+static int
+sysctl_if_ipsec_pmtu_global(SYSCTLFN_ARGS)
+{
+ int error, pmtu;
+ struct sysctlnode node = *rnode;
+
+ pmtu = ip6_ipsec_pmtu;
+ node.sysctl_data = &pmtu;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL)
+ return error;
+
+ switch (pmtu) {
+ case IPSEC_PMTU_MINMTU:
+ case IPSEC_PMTU_OUTERMTU:
+ ip6_ipsec_pmtu = pmtu;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+sysctl_if_ipsec_pmtu_perif(SYSCTLFN_ARGS)
+{
+ int error, pmtu;
+ struct sysctlnode node = *rnode;
+ struct ipsec_softc *sc = (struct ipsec_softc *)node.sysctl_data;
+
+ pmtu = sc->ipsec_pmtu;
+ node.sysctl_data = &pmtu;
+ error = sysctl_lookup(SYSCTLFN_CALL(&node));
+ if (error || newp == NULL)
+ return error;
+
+ switch (pmtu) {
+ case IPSEC_PMTU_SYSDEFAULT:
+ case IPSEC_PMTU_MINMTU:
+ case IPSEC_PMTU_OUTERMTU:
+ sc->ipsec_pmtu = pmtu;
+ break;
+ default:
+ return EINVAL;
+ }
+
+ return 0;
+}
+#endif
+
+static void
+if_ipsec_sysctl_setup(void)
+{
+ if_ipsec_sysctl = NULL;
+
+#ifdef INET6
+ /*
+ * Previously create "net.inet6.ip6" entry to avoid sysctl_createv error.
+ */
+ sysctl_createv(NULL, 0, NULL, NULL,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "inet6",
+ SYSCTL_DESCR("PF_INET6 related settings"),
+ NULL, 0, NULL, 0,
+ CTL_NET, PF_INET6, CTL_EOL);
+ sysctl_createv(NULL, 0, NULL, NULL,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "ip6",
+ SYSCTL_DESCR("IPv6 related settings"),
+ NULL, 0, NULL, 0,
+ CTL_NET, PF_INET6, IPPROTO_IPV6, CTL_EOL);
+
+ sysctl_createv(&if_ipsec_sysctl, 0, NULL, NULL,
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+ CTLTYPE_INT, "ipsecifhlim",
+ SYSCTL_DESCR("Default hop limit for a ipsec tunnel datagram"),
+ NULL, 0, &ip6_ipsec_hlim, 0,
+ CTL_NET, PF_INET6, IPPROTO_IPV6,
+ IPV6CTL_IPSEC_HLIM, CTL_EOL);
+
+ sysctl_createv(&if_ipsec_sysctl, 0, NULL, NULL,
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+ CTLTYPE_INT, "ipsecifpmtu",
+ SYSCTL_DESCR("Default Path MTU setting for ipsec tunnels"),
+ sysctl_if_ipsec_pmtu_global, 0, NULL, 0,
+ CTL_NET, PF_INET6, IPPROTO_IPV6,
+ IPV6CTL_IPSEC_PMTU, CTL_EOL);
+#endif
+}
+
+static void
+if_ipsec_perif_sysctl_setup(struct sysctllog **clog, struct ipsec_softc *sc)
+{
+#ifdef INET6
+ const struct sysctlnode *cnode, *rnode;
+ struct ifnet *ifp = &sc->ipsec_if;
+ const char *ifname = ifp->if_xname;
+ int rv;
+
+ /*
+ * Already created in sysctl_sndq_setup().
+ */
+ sysctl_createv(clog, 0, NULL, &rnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, "interfaces",
+ SYSCTL_DESCR("Per-interface controls"),
+ NULL, 0, NULL, 0,
+ CTL_NET, CTL_CREATE, CTL_EOL);
+ sysctl_createv(clog, 0, &rnode, &rnode,
+ CTLFLAG_PERMANENT,
+ CTLTYPE_NODE, ifname,
+ SYSCTL_DESCR("Interface controls"),
+ NULL, 0, NULL, 0,
+ CTL_CREATE, CTL_EOL);
+
+ rv = sysctl_createv(clog, 0, &rnode, &cnode,
+ CTLFLAG_PERMANENT | CTLFLAG_READWRITE,
+ CTLTYPE_INT, "pmtu",
+ SYSCTL_DESCR("Path MTU setting for this ipsec tunnel"),
+ sysctl_if_ipsec_pmtu_perif, 0, (void *)sc, 0,
+ CTL_CREATE, CTL_EOL);
+ if (rv != 0)
+ log(LOG_WARNING, "%s: could not attach sysctl node pmtu\n", ifname);
+
+ sc->ipsec_pmtu = IPSEC_PMTU_SYSDEFAULT;
+#endif
+}
+
/* ARGSUSED */
void
ipsecifattach(int count)
@@ -157,6 +290,8 @@
iv_psref_class = psref_class_create("ipsecvar", IPL_SOFTNET);
+ if_ipsec_sysctl_setup();
+
if_clone_attach(&ipsec_cloner);
}
@@ -165,6 +300,7 @@
{
struct ipsec_softc *sc;
struct ipsec_variant *var;
+ struct ifnet *ifp;
sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
@@ -172,6 +308,9 @@
if_ipsec_attach0(sc);
+ ifp = &sc->ipsec_if;
+ if_ipsec_perif_sysctl_setup(&ifp->if_sysctl_log, sc);
+
var = kmem_zalloc(sizeof(*var), KM_SLEEP);
var->iv_softc = sc;
psref_target_init(&var->iv_psref, iv_psref_class);
diff -r 4c445623b264 -r 49eeba9d66ad sys/net/if_ipsec.h
--- a/sys/net/if_ipsec.h Fri Nov 01 04:23:21 2019 +0000
+++ b/sys/net/if_ipsec.h Fri Nov 01 04:28:14 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_ipsec.h,v 1.5 2019/09/19 06:07:24 knakahara Exp $ */
+/* $NetBSD: if_ipsec.h,v 1.6 2019/11/01 04:28:14 knakahara Exp $ */
/*
* Copyright (c) 2017 Internet Initiative Japan Inc.
@@ -95,6 +95,7 @@
*/
kmutex_t ipsec_lock; /* writer lock for ipsec_var */
pserialize_t ipsec_psz;
+ int ipsec_pmtu;
LIST_ENTRY(ipsec_softc) ipsec_list; /* list of all gifs */
};
diff -r 4c445623b264 -r 49eeba9d66ad sys/netinet6/in6.h
--- a/sys/netinet6/in6.h Fri Nov 01 04:23:21 2019 +0000
+++ b/sys/netinet6/in6.h Fri Nov 01 04:28:14 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in6.h,v 1.97 2019/10/30 03:45:59 knakahara Exp $ */
+/* $NetBSD: in6.h,v 1.98 2019/11/01 04:28:14 knakahara Exp $ */
/* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */
/*
@@ -537,6 +537,8 @@
#define IPV6CTL_RTADV_NUMROUTES 44 /* current number of routes */
/* via router advertisement */
#define IPV6CTL_GIF_PMTU 45 /* gif(4) Path MTU setting */
+#define IPV6CTL_IPSEC_HLIM 46 /* default HLIM for ipsecif encap packet */
+#define IPV6CTL_IPSEC_PMTU 47 /* ipsecif(4) Path MTU setting */
#endif /* _NETBSD_SOURCE */
#ifdef _KERNEL
diff -r 4c445623b264 -r 49eeba9d66ad sys/netipsec/ipsecif.c
--- a/sys/netipsec/ipsecif.c Fri Nov 01 04:23:21 2019 +0000
+++ b/sys/netipsec/ipsecif.c Fri Nov 01 04:28:14 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ipsecif.c,v 1.17 2019/09/19 06:07:25 knakahara Exp $ */
+/* $NetBSD: ipsecif.c,v 1.18 2019/11/01 04:28:14 knakahara Exp $ */
/*
* Copyright (c) 2017 Internet Initiative Japan Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.17 2019/09/19 06:07:25 knakahara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.18 2019/11/01 04:28:14 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -87,8 +87,8 @@
static int ip_ipsec_ttl = IPSEC_TTL;
static int ip_ipsec_copy_tos = 0;
#ifdef INET6
-static int ip6_ipsec_hlim = IPSEC_HLIM;
-static int ip6_ipsec_pmtu = 0; /* XXX: per interface configuration?? */
+int ip6_ipsec_hlim = IPSEC_HLIM;
+int ip6_ipsec_pmtu = 0;
static int ip6_ipsec_copy_tos = 0;
#endif
@@ -506,7 +506,7 @@
struct sockaddr_in6 *sin6_src;
struct sockaddr_in6 *sin6_dst;
struct ip6_hdr *ip6;
- int proto, error;
+ int proto, error, flags;
u_int8_t itos, otos;
union {
struct sockaddr dst;
@@ -626,12 +626,50 @@
}
/*
- * force fragmentation to minimum MTU, to avoid path MTU discovery.
- * it is too painful to ask for resend of inner packet, to achieve
+ * - IPSEC_PMTU_MINMTU
+ * Force fragmentation to minimum MTU to avoid path MTU discovery
+ * - IPSEC_PMTU_OUTERMTU
+ * Trust outer MTU is large enough to send all packets
+ *
+ * It is too painful to ask for resend of inner packet, to achieve
* path MTU discovery for encapsulated packets.
+ *
+ * See RFC4459.
*/
- error = ip6_output(m, 0, ro_pc,
- ip6_ipsec_pmtu ? 0 : IPV6_MINMTU, 0, NULL, NULL);
+ if (sc->ipsec_pmtu == IPSEC_PMTU_SYSDEFAULT) {
+ switch (ip6_ipsec_pmtu) {
+ case IPSEC_PMTU_MINMTU:
+ flags = IPV6_MINMTU;
+ break;
+ case IPSEC_PMTU_OUTERMTU:
+ flags = 0;
+ break;
+ default:
+#ifdef DEBUG
+ log(LOG_DEBUG, "%s: ignore unexpected ip6_ipsec_pmtu %d\n",
+ __func__, ip6_ipsec_pmtu);
+#endif
+ flags = IPV6_MINMTU;
+ break;
+ }
+ } else {
Home |
Main Index |
Thread Index |
Old Index