Module Name: src Committed By: knakahara Date: Wed Oct 30 03:45:59 UTC 2019
Modified Files: src/sys/net: if_gif.c if_gif.h src/sys/netinet6: in6.h in6_gif.c in6_gif.h Log Message: Add sysctl nodes to control fragmentation with IPv[46] over IPv6 gif(4). New sysctl node "net.inet6.ip6.gifpmtu" means - 0 (default) Fragment by IPV6_MMTU. All packets reach the destination certainly, however the long packet performance is poor. This is same behavior as before. - 1 Fragment by outer interface's MTU. The long packet performance would be good, however the packets may be dropped in some network paths whose path MTU less than the interface's MTU. - others undefined yet New sysctl node "net.interfaces.gif*.pmtu" means - -1 (default) Use system default value (net.inet6.ip6.gifpmtu). - 0 Fragment by IPV6_MMTU for this gif(4) tunnel. - 1 Fragment by outer interface's MTU for this gif(4) tunnel. - others undefined yet See RFC4459 for more information and other solutions. To generate a diff of this commit: cvs rdiff -u -r1.149 -r1.150 src/sys/net/if_gif.c cvs rdiff -u -r1.33 -r1.34 src/sys/net/if_gif.h cvs rdiff -u -r1.96 -r1.97 src/sys/netinet6/in6.h cvs rdiff -u -r1.94 -r1.95 src/sys/netinet6/in6_gif.c cvs rdiff -u -r1.17 -r1.18 src/sys/netinet6/in6_gif.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_gif.c diff -u src/sys/net/if_gif.c:1.149 src/sys/net/if_gif.c:1.150 --- src/sys/net/if_gif.c:1.149 Thu Sep 19 06:07:24 2019 +++ src/sys/net/if_gif.c Wed Oct 30 03:45:59 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_gif.c,v 1.149 2019/09/19 06:07:24 knakahara Exp $ */ +/* $NetBSD: if_gif.c,v 1.150 2019/10/30 03:45:59 knakahara Exp $ */ /* $KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.149 2019/09/19 06:07:24 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.150 2019/10/30 03:45:59 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -142,6 +142,58 @@ static int max_gif_nesting = MAX_GIF_NES static struct sysctllog *gif_sysctl; +#ifdef INET6 +static int +sysctl_gif_pmtu_global(SYSCTLFN_ARGS) +{ + int error, pmtu; + struct sysctlnode node = *rnode; + + pmtu = ip6_gif_pmtu; + node.sysctl_data = &pmtu; + error = sysctl_lookup(SYSCTLFN_CALL(&node)); + if (error || newp == NULL) + return error; + + switch (pmtu) { + case GIF_PMTU_MINMTU: + case GIF_PMTU_OUTERMTU: + ip6_gif_pmtu = pmtu; + break; + default: + return EINVAL; + } + + return 0; +} + +static int +sysctl_gif_pmtu_perif(SYSCTLFN_ARGS) +{ + int error, pmtu; + struct sysctlnode node = *rnode; + struct gif_softc *sc = (struct gif_softc *)node.sysctl_data; + + pmtu = sc->gif_pmtu; + node.sysctl_data = &pmtu; + error = sysctl_lookup(SYSCTLFN_CALL(&node)); + if (error || newp == NULL) + return error; + + switch (pmtu) { + case GIF_PMTU_SYSDEFAULT: + case GIF_PMTU_MINMTU: + case GIF_PMTU_OUTERMTU: + sc->gif_pmtu = pmtu; + break; + default: + return EINVAL; + } + + return 0; +} +#endif + static void gif_sysctl_setup(void) { @@ -196,6 +248,52 @@ gif_sysctl_setup(void) NULL, 0, &ip6_gif_hlim, 0, CTL_NET, PF_INET6, IPPROTO_IPV6, IPV6CTL_GIF_HLIM, CTL_EOL); + + sysctl_createv(&gif_sysctl, 0, NULL, NULL, + CTLFLAG_PERMANENT | CTLFLAG_READWRITE, + CTLTYPE_INT, "gifpmtu", + SYSCTL_DESCR("Default Path MTU setting for gif tunnels"), + sysctl_gif_pmtu_global, 0, NULL, 0, + CTL_NET, PF_INET6, IPPROTO_IPV6, + IPV6CTL_GIF_PMTU, CTL_EOL); +#endif +} + +static void +gif_perif_sysctl_setup(struct sysctllog **clog, struct gif_softc *sc) +{ +#ifdef INET6 + const struct sysctlnode *cnode, *rnode; + struct ifnet *ifp = &sc->gif_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, + CTLTYPE_INT, "pmtu", + SYSCTL_DESCR("Path MTU setting for this gif tunnel"), + sysctl_gif_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->gif_pmtu = GIF_PMTU_SYSDEFAULT; #endif } @@ -248,6 +346,7 @@ gif_clone_create(struct if_clone *ifc, i { struct gif_softc *sc; struct gif_variant *var; + struct ifnet *ifp; int rv; sc = kmem_zalloc(sizeof(struct gif_softc), KM_SLEEP); @@ -260,6 +359,9 @@ gif_clone_create(struct if_clone *ifc, i return rv; } + ifp = &sc->gif_if; + gif_perif_sysctl_setup(&ifp->if_sysctl_log, sc); + var = kmem_zalloc(sizeof(*var), KM_SLEEP); var->gv_softc = sc; psref_target_init(&var->gv_psref, gv_psref_class); Index: src/sys/net/if_gif.h diff -u src/sys/net/if_gif.h:1.33 src/sys/net/if_gif.h:1.34 --- src/sys/net/if_gif.h:1.33 Thu Sep 19 06:07:24 2019 +++ src/sys/net/if_gif.h Wed Oct 30 03:45:59 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: if_gif.h,v 1.33 2019/09/19 06:07:24 knakahara Exp $ */ +/* $NetBSD: if_gif.h,v 1.34 2019/10/30 03:45:59 knakahara Exp $ */ /* $KAME: if_gif.h,v 1.23 2001/07/27 09:21:42 itojun Exp $ */ /* @@ -76,6 +76,8 @@ struct gif_softc { kmutex_t gif_lock; /* writer lock for gif_var */ pserialize_t gif_psz; + int gif_pmtu; + LIST_ENTRY(gif_softc) gif_list; /* list of all gifs */ }; #define GIF_ROUTE_TTL 10 Index: src/sys/netinet6/in6.h diff -u src/sys/netinet6/in6.h:1.96 src/sys/netinet6/in6.h:1.97 --- src/sys/netinet6/in6.h:1.96 Thu Sep 5 20:17:27 2019 +++ src/sys/netinet6/in6.h Wed Oct 30 03:45:59 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: in6.h,v 1.96 2019/09/05 20:17:27 kamil Exp $ */ +/* $NetBSD: in6.h,v 1.97 2019/10/30 03:45:59 knakahara Exp $ */ /* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */ /* @@ -536,6 +536,7 @@ struct ip6_mtuinfo { /* via router advertisement */ #define IPV6CTL_RTADV_NUMROUTES 44 /* current number of routes */ /* via router advertisement */ +#define IPV6CTL_GIF_PMTU 45 /* gif(4) Path MTU setting */ #endif /* _NETBSD_SOURCE */ #ifdef _KERNEL Index: src/sys/netinet6/in6_gif.c diff -u src/sys/netinet6/in6_gif.c:1.94 src/sys/netinet6/in6_gif.c:1.95 --- src/sys/netinet6/in6_gif.c:1.94 Thu Sep 19 06:07:25 2019 +++ src/sys/netinet6/in6_gif.c Wed Oct 30 03:45:59 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: in6_gif.c,v 1.94 2019/09/19 06:07:25 knakahara Exp $ */ +/* $NetBSD: in6_gif.c,v 1.95 2019/10/30 03:45:59 knakahara Exp $ */ /* $KAME: in6_gif.c,v 1.62 2001/07/29 04:27:25 itojun Exp $ */ /* @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.94 2019/09/19 06:07:25 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.95 2019/10/30 03:45:59 knakahara Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -73,6 +73,7 @@ static int gif_validate6(const struct ip struct ifnet *); int ip6_gif_hlim = GIF_HLIM; +int ip6_gif_pmtu = 0; static const struct encapsw in6_gif_encapsw; @@ -198,12 +199,54 @@ in6_gif_output(struct gif_variant *var, rtcache_unref(rt, ro_pc); #ifdef IPV6_MINMTU + int flags; + /* - * force fragmentation to minimum MTU, to avoid path MTU discovery. - * it is too painful to ask for resend of inner packet, to achieve + * - GIF_PMTU_MINMTU + * Force fragmentation to minimum MTU to avoid path MTU discovery + * - GIF_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, IPV6_MINMTU, NULL, NULL, NULL); + if (sc->gif_pmtu == GIF_PMTU_SYSDEFAULT) { + switch (ip6_gif_pmtu) { + case GIF_PMTU_MINMTU: + flags = IPV6_MINMTU; + break; + case GIF_PMTU_OUTERMTU: + flags = 0; + break; + default: +#ifdef DEBUG + log(LOG_DEBUG, "%s: ignore unexpected ip6_gif_pmtu %d\n", + __func__, ip6_gif_pmtu); +#endif + flags = IPV6_MINMTU; + break; + } + } else { + switch (sc->gif_pmtu) { + case GIF_PMTU_MINMTU: + flags = IPV6_MINMTU; + break; + case GIF_PMTU_OUTERMTU: + flags = 0; + break; + default: +#ifdef DEBUG + log(LOG_DEBUG, "%s: ignore unexpected gif_pmtu of %s %d\n", + __func__, ifp->if_xname, sc->gif_pmtu); +#endif + flags = IPV6_MINMTU; + break; + } + } + + error = ip6_output(m, 0, ro_pc, flags, NULL, NULL, NULL); #else error = ip6_output(m, 0, ro_pc, 0, NULL, NULL, NULL); #endif Index: src/sys/netinet6/in6_gif.h diff -u src/sys/netinet6/in6_gif.h:1.17 src/sys/netinet6/in6_gif.h:1.18 --- src/sys/netinet6/in6_gif.h:1.17 Mon Nov 27 05:02:22 2017 +++ src/sys/netinet6/in6_gif.h Wed Oct 30 03:45:59 2019 @@ -1,4 +1,4 @@ -/* $NetBSD: in6_gif.h,v 1.17 2017/11/27 05:02:22 knakahara Exp $ */ +/* $NetBSD: in6_gif.h,v 1.18 2019/10/30 03:45:59 knakahara Exp $ */ /* $KAME: in6_gif.h,v 1.7 2001/07/26 06:53:16 jinmei Exp $ */ /* @@ -35,6 +35,11 @@ #define GIF_HLIM 30 extern int ip6_gif_hlim; /* Hop limit for gif encap packet */ +extern int ip6_gif_pmtu; /* Default Path MTU setting for gif tunnels */ + +#define GIF_PMTU_SYSDEFAULT -1 /* Use system default value (ip6_gif_pmtu) */ +#define GIF_PMTU_MINMTU 0 /* Fragmented by IPV6_MINMTU */ +#define GIF_PMTU_OUTERMTU 1 /* Fragmented by Path MTU of outer path */ struct gif_variant; struct sockaddr;