From 10583b590af670cd86ae7e794e87d49057885252 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Thu, 14 Sep 2017 10:14:59 +0100 Subject: [PATCH] pathmtu/pathmtu.c: Support IPv6 in Linux probing method. --- pathmtu/pathmtu.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/pathmtu/pathmtu.c b/pathmtu/pathmtu.c index 8cf7d18a..a3526331 100644 --- a/pathmtu/pathmtu.c +++ b/pathmtu/pathmtu.c @@ -664,7 +664,9 @@ static const struct probe_ops raw_ops = { #endif struct linux_state { + int sol, so_mtu_discover, so_mtu; int sk; + size_t hdrlen; }; static int linux_setup(void *stv, int sk, const struct param *pp) @@ -675,8 +677,21 @@ static int linux_setup(void *stv, int sk, const struct param *pp) /* Check that the address is OK. */ switch (pp->a.sa.sa_family) { - case AF_INET: break; - default: errno = EPFNOSUPPORT; return (-1); + case AF_INET: + st->sol = IPPROTO_IP; + st->so_mtu_discover = IP_MTU_DISCOVER; + st->so_mtu = IP_MTU; + st->hdrlen = 28; + break; + case AF_INET6: + st->sol = IPPROTO_IPV6; + st->so_mtu_discover = IPV6_MTU_DISCOVER; + st->so_mtu = IPV6_MTU; + st->hdrlen = 48; + break; + default: + errno = EPFNOSUPPORT; + return (-1); } /* Snaffle the UDP socket. */ @@ -684,12 +699,12 @@ static int linux_setup(void *stv, int sk, const struct param *pp) /* Turn on kernel path-MTU discovery and force DF on. */ i = IP_PMTUDISC_PROBE; - if (setsockopt(st->sk, IPPROTO_IP, IP_MTU_DISCOVER, &i, sizeof(i))) + if (setsockopt(st->sk, st->sol, st->so_mtu_discover, &i, sizeof(i))) return (-1); /* Read the initial MTU guess back and report it. */ sz = sizeof(mtu); - if (getsockopt(st->sk, IPPROTO_IP, IP_MTU, &mtu, &sz)) + if (getsockopt(st->sk, st->sol, st->so_mtu, &mtu, &sz)) return (-1); /* Done. */ @@ -706,7 +721,7 @@ static int linux_xmit(void *stv, int mtu) struct linux_state *st = stv; /* Write the packet. */ - if (write(st->sk, buf, mtu - 28) >= 0) return (RC_OK); + if (write(st->sk, buf, mtu - st->hdrlen) >= 0) return (RC_OK); else if (errno == EMSGSIZE) return (RC_LOWER); else return (RC_FAIL); } @@ -733,7 +748,7 @@ static int linux_selproc(void *stv, fd_set *fd_in, struct probestate *ps) errno == ECONNREFUSED || errno == EHOSTUNREACH) return (RC_HIGHER); sz = sizeof(mtu); - if (getsockopt(st->sk, IPPROTO_IP, IP_MTU, &mtu, &sz)) + if (getsockopt(st->sk, st->sol, st->so_mtu, &mtu, &sz)) return (RC_FAIL); return (mtu); } -- 2.11.0