summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordlg <dlg@openbsd.org>2019-01-27 05:13:04 +0000
committerdlg <dlg@openbsd.org>2019-01-27 05:13:04 +0000
commit48e57f09d5758881a3cdb5e05f525ce547dce1a1 (patch)
tree8f6e9d6c8a3c9aa67a032370a851a4ddf5646aec
parentrework mpe_input so it patches ipv4 cksum, and handles ipv6 too. (diff)
downloadwireguard-openbsd-48e57f09d5758881a3cdb5e05f525ce547dce1a1.tar.xz
wireguard-openbsd-48e57f09d5758881a3cdb5e05f525ce547dce1a1.zip
use mpls_ip_adjttl and mpls_ip6_adjttl in mpe instead of rolling it again.
mpls_ip_adjttl now patches the checksum rather than check it and calculate it again. both mpls_ip_adjttl and mpls_ip6_adjttl now rely on the caller to check the sysctls for whether they should run or not, which paves the way for making it configurable in mpe via the tunnel ioctls.
-rw-r--r--sys/net/if_mpe.c33
-rw-r--r--sys/netmpls/mpls.h8
-rw-r--r--sys/netmpls/mpls_input.c78
3 files changed, 47 insertions, 72 deletions
diff --git a/sys/net/if_mpe.c b/sys/net/if_mpe.c
index 1e556d96401..826cbdb1530 100644
--- a/sys/net/if_mpe.c
+++ b/sys/net/if_mpe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_mpe.c,v 1.69 2019/01/27 04:54:06 dlg Exp $ */
+/* $OpenBSD: if_mpe.c,v 1.70 2019/01/27 05:13:04 dlg Exp $ */
/*
* Copyright (c) 2008 Pierre-Yves Ritschard <pyr@spootnik.org>
@@ -408,22 +408,9 @@ mpe_input(struct ifnet *ifp, struct mbuf *m)
switch (*mtod(n, uint8_t *) >> 4) {
case 4:
if (mpls_mapttl_ip) {
- struct ip *ip;
- uint16_t old, new, x;
-
- if (m->m_len < sizeof(*ip)) {
- m = m_pullup(m, sizeof(*ip));
- if (m == NULL)
- return;
- }
- ip = mtod(m, struct ip *);
-
- old = htons(ip->ip_ttl << 8);
- new = htons(ttl << 8);
- x = ip->ip_sum + old - new;
-
- ip->ip_ttl = ttl;
- ip->ip_sum = (x) + (x >> 16);
+ m = mpls_ip_adjttl(m, ttl);
+ if (m == NULL)
+ return;
}
input = ipv4_input;
m->m_pkthdr.ph_family = AF_INET;
@@ -431,15 +418,9 @@ mpe_input(struct ifnet *ifp, struct mbuf *m)
#ifdef INET6
case 6:
if (mpls_mapttl_ip6) {
- struct ip6_hdr *ip6;
-
- if (m->m_len < sizeof(*ip6)) {
- m = m_pullup(m, sizeof(*ip6));
- if (m == NULL)
- return;
- }
- ip6 = mtod(m, struct ip6_hdr *);
- ip6->ip6_hlim = ttl;
+ m = mpls_ip6_adjttl(m, ttl);
+ if (m == NULL)
+ return;
}
input = ipv6_input;
m->m_pkthdr.ph_family = AF_INET6;
diff --git a/sys/netmpls/mpls.h b/sys/netmpls/mpls.h
index bc6ee28196a..80116558739 100644
--- a/sys/netmpls/mpls.h
+++ b/sys/netmpls/mpls.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpls.h,v 1.40 2019/01/27 04:20:59 dlg Exp $ */
+/* $OpenBSD: mpls.h,v 1.41 2019/01/27 05:13:04 dlg Exp $ */
/*
* Copyright (C) 1999, 2000 and 2001 AYAME Project, WIDE Project.
@@ -155,7 +155,6 @@ struct ifmpwreq {
extern struct domain mplsdomain;
-
extern int mpls_defttl;
extern int mpls_mapttl_ip;
extern int mpls_mapttl_ip6;
@@ -166,6 +165,11 @@ struct mbuf *mpls_shim_pop(struct mbuf *);
struct mbuf *mpls_shim_swap(struct mbuf *, struct rt_mpls *);
struct mbuf *mpls_shim_push(struct mbuf *, struct rt_mpls *);
+struct mbuf *mpls_ip_adjttl(struct mbuf *, u_int8_t);
+#ifdef INET6
+struct mbuf *mpls_ip6_adjttl(struct mbuf *, u_int8_t);
+#endif
+
int mpls_output(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
void mpls_input(struct ifnet *, struct mbuf *);
diff --git a/sys/netmpls/mpls_input.c b/sys/netmpls/mpls_input.c
index 57355e287cb..093d662246e 100644
--- a/sys/netmpls/mpls_input.c
+++ b/sys/netmpls/mpls_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: mpls_input.c,v 1.72 2019/01/27 04:20:59 dlg Exp $ */
+/* $OpenBSD: mpls_input.c,v 1.73 2019/01/27 05:13:04 dlg Exp $ */
/*
* Copyright (c) 2008 Claudio Jeker <claudio@openbsd.org>
@@ -45,11 +45,6 @@
#define MPLS_TTL_GET(l) (ntohl((l) & MPLS_TTL_MASK))
#endif
-struct mbuf *mpls_ip_adjttl(struct mbuf *, u_int8_t);
-#ifdef INET6
-struct mbuf *mpls_ip6_adjttl(struct mbuf *, u_int8_t);
-#endif
-
struct mbuf *mpls_do_error(struct mbuf *, int, int, int);
void mpls_input_local(struct rtentry *, struct mbuf *);
@@ -128,15 +123,21 @@ mpls_input(struct ifnet *ifp, struct mbuf *m)
switch (ntohl(smpls->smpls_label)) {
case MPLS_LABEL_IPV4NULL:
do_v4:
- if ((m = mpls_ip_adjttl(m, ttl)) == NULL)
- return;
+ if (mpls_mapttl_ip) {
+ m = mpls_ip_adjttl(m, ttl);
+ if (m == NULL)
+ return;
+ }
ipv4_input(ifp, m);
return;
#ifdef INET6
case MPLS_LABEL_IPV6NULL:
do_v6:
- if ((m = mpls_ip6_adjttl(m, ttl)) == NULL)
- return;
+ if (mpls_mapttl_ip6) {
+ m = mpls_ip6_adjttl(m, ttl);
+ if (m == NULL)
+ return;
+ }
ipv6_input(ifp, m);
return;
#endif /* INET6 */
@@ -302,52 +303,41 @@ struct mbuf *
mpls_ip_adjttl(struct mbuf *m, u_int8_t ttl)
{
struct ip *ip;
- int hlen;
+ uint16_t old, new, x;
- if (mpls_mapttl_ip) {
- if (m->m_len < sizeof(struct ip) &&
- (m = m_pullup(m, sizeof(struct ip))) == NULL)
- return NULL;
- ip = mtod(m, struct ip *);
- hlen = ip->ip_hl << 2;
- if (m->m_len < hlen) {
- if ((m = m_pullup(m, hlen)) == NULL)
- return NULL;
- ip = mtod(m, struct ip *);
- }
- /* make sure we have a valid header */
- if (in_cksum(m, hlen) != 0) {
- m_freem(m);
- return NULL;
- }
+ if (m->m_len < sizeof(*ip)) {
+ m = m_pullup(m, sizeof(*ip));
+ if (m == NULL)
+ return (NULL);
+ }
+ ip = mtod(m, struct ip *);
- /* set IP ttl from MPLS ttl */
- ip->ip_ttl = ttl;
+ old = htons(ip->ip_ttl << 8);
+ new = htons(ttl << 8);
+ x = ip->ip_sum + old - new;
- /* recalculate checksum */
- ip->ip_sum = 0;
- ip->ip_sum = in_cksum(m, hlen);
- }
- return m;
+ ip->ip_ttl = ttl;
+ ip->ip_sum = (x) + (x >> 16);
+
+ return (m);
}
#ifdef INET6
struct mbuf *
mpls_ip6_adjttl(struct mbuf *m, u_int8_t ttl)
{
- struct ip6_hdr *ip6hdr;
+ struct ip6_hdr *ip6;
- if (mpls_mapttl_ip6) {
- if (m->m_len < sizeof(struct ip6_hdr) &&
- (m = m_pullup(m, sizeof(struct ip6_hdr))) == NULL)
- return NULL;
+ if (m->m_len < sizeof(*ip6)) {
+ m = m_pullup(m, sizeof(*ip6));
+ if (m == NULL)
+ return (NULL);
+ }
+ ip6 = mtod(m, struct ip6_hdr *);
- ip6hdr = mtod(m, struct ip6_hdr *);
+ ip6->ip6_hlim = ttl;
- /* set IPv6 ttl from MPLS ttl */
- ip6hdr->ip6_hlim = ttl;
- }
- return m;
+ return (m);
}
#endif /* INET6 */