summaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_ecn.c23
-rw-r--r--sys/netinet/ip_ecn.h3
-rw-r--r--sys/netinet/ip_ipip.c10
3 files changed, 28 insertions, 8 deletions
diff --git a/sys/netinet/ip_ecn.c b/sys/netinet/ip_ecn.c
index e5d6cf249bb..b4621a019f1 100644
--- a/sys/netinet/ip_ecn.c
+++ b/sys/netinet/ip_ecn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ecn.c,v 1.8 2016/09/24 14:51:37 naddy Exp $ */
+/* $OpenBSD: ip_ecn.c,v 1.9 2018/11/14 23:55:04 dlg Exp $ */
/* $KAME: ip_ecn.c,v 1.9 2000/10/01 12:44:48 itojun Exp $ */
/*
@@ -154,3 +154,24 @@ ip_ecn_egress(int mode, u_int8_t *outer, u_int8_t *inner)
}
return (1);
}
+
+/*
+ * Patch the checksum with the difference between the old and new tos.
+ * The patching is based on what pf_patch_8() and pf_cksum_fixkup() do,
+ * but they're in pf, so we can't rely on them being available.
+ */
+void
+ip_tos_patch(struct ip *ip, uint8_t tos)
+{
+ uint16_t old;
+ uint16_t new;
+ uint32_t x;
+
+ old = htons(ip->ip_tos);
+ new = htons(tos);
+
+ ip->ip_tos = tos;
+
+ x = ip->ip_sum + old - new;
+ ip->ip_sum = (x) + (x >> 16);
+}
diff --git a/sys/netinet/ip_ecn.h b/sys/netinet/ip_ecn.h
index d6a8b166f1a..6f3d552468f 100644
--- a/sys/netinet/ip_ecn.h
+++ b/sys/netinet/ip_ecn.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ecn.h,v 1.6 2012/03/15 16:37:11 markus Exp $ */
+/* $OpenBSD: ip_ecn.h,v 1.7 2018/11/14 23:55:04 dlg Exp $ */
/* $KAME: ip_ecn.h,v 1.5 2000/03/27 04:58:38 sumikawa Exp $ */
/*
@@ -47,5 +47,6 @@
#if defined(_KERNEL)
extern void ip_ecn_ingress(int, u_int8_t *, u_int8_t *);
extern int ip_ecn_egress(int, u_int8_t *, u_int8_t *);
+void ip_tos_patch(struct ip *, uint8_t);
#endif /* _KERNEL */
#endif /* _NETINET_IP_ECN_H_ */
diff --git a/sys/netinet/ip_ipip.c b/sys/netinet/ip_ipip.c
index 60d6efdc284..b8c90fd702e 100644
--- a/sys/netinet/ip_ipip.c
+++ b/sys/netinet/ip_ipip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_ipip.c,v 1.88 2018/08/28 15:15:02 mpi Exp $ */
+/* $OpenBSD: ip_ipip.c,v 1.89 2018/11/14 23:55:04 dlg Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
* Angelos D. Keromytis (kermit@csd.uch.gr) and
@@ -239,16 +239,14 @@ ipip_input_if(struct mbuf **mp, int *offp, int proto, int oaf,
itos = ip->ip_tos;
mode = m->m_flags & (M_AUTH|M_CONF) ?
ECN_ALLOWED_IPSEC : ECN_ALLOWED;
- if (!ip_ecn_egress(mode, &otos, &ip->ip_tos)) {
+ if (!ip_ecn_egress(mode, &otos, &itos)) {
DPRINTF(("%s: ip_ecn_egress() failed\n", __func__));
ipipstat_inc(ipips_pdrops);
goto bad;
}
/* re-calculate the checksum if ip_tos was changed */
- if (itos != ip->ip_tos) {
- ip->ip_sum = 0;
- ip->ip_sum = in_cksum(m, hlen);
- }
+ if (itos != ip->ip_tos)
+ ip_tos_patch(ip, itos);
break;
#ifdef INET6
case IPPROTO_IPV6: