From 6a006fd4a3095d74aff2cfe0f12b4b6c6261882a Mon Sep 17 00:00:00 2001 From: bluhm Date: Tue, 4 Apr 2023 10:12:03 +0000 Subject: [PATCH] When sending IP packets to userland with divert-packet rules, the checksum may be wrong. Locally generated packets diverted by pf out rules may have no checksum due to to hardware offloading. Calculate the checksum in that case. OK mvs@ sashan@ --- sys/netinet/ip_divert.c | 15 ++++++++++++++- sys/netinet6/ip6_divert.c | 8 +++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 1ca49a1738f..77d7698076a 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_divert.c,v 1.89 2022/10/17 14:49:02 mvs Exp $ */ +/* $OpenBSD: ip_divert.c,v 1.90 2023/04/04 10:12:03 bluhm Exp $ */ /* * Copyright (c) 2009 Michele Marchetto @@ -190,6 +190,8 @@ divert_packet(struct mbuf *m, int dir, u_int16_t divert_port) struct inpcb *inp = NULL; struct socket *so; struct sockaddr_in sin; + struct ip *ip; + int off; divstat_inc(divs_ipackets); @@ -232,6 +234,17 @@ divert_packet(struct mbuf *m, int dir, u_int16_t divert_port) break; } if_put(ifp); + } else { + /* + * Calculate IP and protocol checksums for outbound packet + * diverted to userland. pf rule diverts before cksum offload. + */ + ip = mtod(m, struct ip *); + off = ip->ip_hl << 2; + + ip->ip_sum = 0; + ip->ip_sum = in_cksum(m, off); + in_proto_cksum_out(m, NULL); } mtx_enter(&inp->inp_mtx); diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c index c7539f64a26..aa7fc4ccdcc 100644 --- a/sys/netinet6/ip6_divert.c +++ b/sys/netinet6/ip6_divert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_divert.c,v 1.88 2022/10/17 14:49:02 mvs Exp $ */ +/* $OpenBSD: ip6_divert.c,v 1.89 2023/04/04 10:12:03 bluhm Exp $ */ /* * Copyright (c) 2009 Michele Marchetto @@ -238,6 +238,12 @@ divert6_packet(struct mbuf *m, int dir, u_int16_t divert_port) break; } if_put(ifp); + } else { + /* + * Calculate protocol checksum for outbound packet diverted + * to userland. pf out rule diverts before cksum offload. + */ + in6_proto_cksum_out(m, NULL); } mtx_enter(&inp->inp_mtx); -- 2.20.1