Module Name: src Committed By: rmind Date: Sun Dec 10 00:07:36 UTC 2017
Modified Files: src/sys/net/npf: npf_alg_icmp.c npf_bpf.c npf_conn.c npf_conn.h npf_ext_normalize.c Log Message: - npf_cop_table: handle non-IP packets in the ether (fixes PR/52290). - npfa_icmp_nat: do not recompute the checksum if no port translation. - npf_normalize (MSS clamping): fix the checksum handling on PFIL_OUT. - npflog: report the packet direction correctly. To generate a diff of this commit: cvs rdiff -u -r1.24 -r1.25 src/sys/net/npf/npf_alg_icmp.c cvs rdiff -u -r1.12 -r1.13 src/sys/net/npf/npf_bpf.c \ src/sys/net/npf/npf_conn.h cvs rdiff -u -r1.23 -r1.24 src/sys/net/npf/npf_conn.c cvs rdiff -u -r1.5 -r1.6 src/sys/net/npf/npf_ext_normalize.c 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/npf/npf_alg_icmp.c diff -u src/sys/net/npf/npf_alg_icmp.c:1.24 src/sys/net/npf/npf_alg_icmp.c:1.25 --- src/sys/net/npf/npf_alg_icmp.c:1.24 Mon Dec 26 23:05:06 2016 +++ src/sys/net/npf/npf_alg_icmp.c Sun Dec 10 00:07:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_alg_icmp.c,v 1.24 2016/12/26 23:05:06 christos Exp $ */ +/* $NetBSD: npf_alg_icmp.c,v 1.25 2017/12/10 00:07:36 rmind Exp $ */ /*- * Copyright (c) 2010 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #ifdef _KERNEL #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.24 2016/12/26 23:05:06 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_alg_icmp.c,v 1.25 2017/12/10 00:07:36 rmind Exp $"); #include <sys/param.h> #include <sys/module.h> @@ -336,31 +336,25 @@ npfa_icmp_nat(npf_cache_t *npc, npf_nat_ /* * Fetch the IP and port in the _embedded_ packet. Also, fetch * the IPv4 and TCP/UDP checksums before they are rewritten. - * Calculate the part of the ICMP checksum fixup. */ const int proto = enpc.npc_proto; uint16_t ipcksum = 0, l4cksum = 0; - npf_addr_t *addr; - in_port_t port; - - npf_nat_getorig(nt, &addr, &port); + in_port_t old_port = 0; if (npf_iscached(&enpc, NPC_IP4)) { const struct ip *eip = enpc.npc_ip.v4; ipcksum = eip->ip_sum; } - cksum = npf_addr_cksum(cksum, enpc.npc_alen, enpc.npc_ips[which], addr); - switch (proto) { case IPPROTO_TCP: { const struct tcphdr *th = enpc.npc_l4.tcp; - cksum = npf_fixup16_cksum(cksum, th->th_sport, port); + old_port = th->th_sport; l4cksum = th->th_sum; break; } case IPPROTO_UDP: { const struct udphdr *uh = enpc.npc_l4.udp; - cksum = npf_fixup16_cksum(cksum, uh->uh_sport, port); + old_port = uh->uh_sport; l4cksum = uh->uh_sum; break; } @@ -372,6 +366,20 @@ npfa_icmp_nat(npf_cache_t *npc, npf_nat_ } /* + * Get the original IP address and port. + * Calculate the part of the ICMP checksum fixup. + */ + npf_addr_t *addr; + in_port_t port; + + npf_nat_getorig(nt, &addr, &port); + + cksum = npf_addr_cksum(cksum, enpc.npc_alen, enpc.npc_ips[which], addr); + if (port) { + cksum = npf_fixup16_cksum(cksum, old_port, port); + } + + /* * Translate the embedded packet. The following changes will * be performed by npf_napt_rwr(): * Index: src/sys/net/npf/npf_bpf.c diff -u src/sys/net/npf/npf_bpf.c:1.12 src/sys/net/npf/npf_bpf.c:1.13 --- src/sys/net/npf/npf_bpf.c:1.12 Mon Dec 26 23:05:06 2016 +++ src/sys/net/npf/npf_bpf.c Sun Dec 10 00:07:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_bpf.c,v 1.12 2016/12/26 23:05:06 christos Exp $ */ +/* $NetBSD: npf_bpf.c,v 1.13 2017/12/10 00:07:36 rmind Exp $ */ /*- * Copyright (c) 2009-2013 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #ifdef _KERNEL #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.12 2016/12/26 23:05:06 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_bpf.c,v 1.13 2017/12/10 00:07:36 rmind Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -181,9 +181,11 @@ npf_cop_table(const bpf_ctx_t *bc, bpf_a const npf_addr_t *addr; npf_table_t *t; - KASSERT(npf_iscached(npc, NPC_IP46)); - - if ((t = npf_tableset_getbyid(tblset, tid)) == NULL) { + if (!npf_iscached(npc, NPC_IP46)) { + return 0; + } + t = npf_tableset_getbyid(tblset, tid); + if (__predict_false(!t)) { return 0; } addr = npc->npc_ips[(A & SRC_FLAG_BIT) ? NPF_SRC : NPF_DST]; Index: src/sys/net/npf/npf_conn.h diff -u src/sys/net/npf/npf_conn.h:1.12 src/sys/net/npf/npf_conn.h:1.13 --- src/sys/net/npf/npf_conn.h:1.12 Sun Jan 29 00:15:54 2017 +++ src/sys/net/npf/npf_conn.h Sun Dec 10 00:07:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_conn.h,v 1.12 2017/01/29 00:15:54 christos Exp $ */ +/* $NetBSD: npf_conn.h,v 1.13 2017/12/10 00:07:36 rmind Exp $ */ /*- * Copyright (c) 2009-2014 The NetBSD Foundation, Inc. @@ -88,7 +88,12 @@ struct npf_conn { npf_state_t c_state; u_int c_refcnt; uint64_t c_atime; - npf_match_info_t c_mi; + + /* + * Save the matching rule ID and flags. + */ + uint64_t c_rid; + u_int c_retfl; }; #endif Index: src/sys/net/npf/npf_conn.c diff -u src/sys/net/npf/npf_conn.c:1.23 src/sys/net/npf/npf_conn.c:1.24 --- src/sys/net/npf/npf_conn.c:1.23 Sun Jan 29 00:15:54 2017 +++ src/sys/net/npf/npf_conn.c Sun Dec 10 00:07:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_conn.c,v 1.23 2017/01/29 00:15:54 christos Exp $ */ +/* $NetBSD: npf_conn.c,v 1.24 2017/12/10 00:07:36 rmind Exp $ */ /*- * Copyright (c) 2014-2015 Mindaugas Rasiukevicius <rmind at netbsd org> @@ -100,7 +100,7 @@ #ifdef _KERNEL #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.23 2017/01/29 00:15:54 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_conn.c,v 1.24 2017/12/10 00:07:36 rmind Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -727,7 +727,8 @@ npf_conn_pass(const npf_conn_t *con, npf { KASSERT(con->c_refcnt > 0); if (__predict_true(con->c_flags & CONN_PASS)) { - *mi = con->c_mi; + mi->mi_rid = con->c_rid; + mi->mi_retfl = con->c_retfl; *rp = con->c_rproc; return true; } @@ -752,8 +753,10 @@ npf_conn_setpass(npf_conn_t *con, const */ atomic_or_uint(&con->c_flags, CONN_PASS); con->c_rproc = rp; - if (rp) - con->c_mi = *mi; + if (rp) { + con->c_rid = mi->mi_rid; + con->c_retfl = mi->mi_retfl; + } } /* Index: src/sys/net/npf/npf_ext_normalize.c diff -u src/sys/net/npf/npf_ext_normalize.c:1.5 src/sys/net/npf/npf_ext_normalize.c:1.6 --- src/sys/net/npf/npf_ext_normalize.c:1.5 Sun Jan 29 00:15:54 2017 +++ src/sys/net/npf/npf_ext_normalize.c Sun Dec 10 00:07:36 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_ext_normalize.c,v 1.5 2017/01/29 00:15:54 christos Exp $ */ +/* $NetBSD: npf_ext_normalize.c,v 1.6 2017/12/10 00:07:36 rmind Exp $ */ /*- * Copyright (c) 2009-2012 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ #ifdef _KERNEL #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_ext_normalize.c,v 1.5 2017/01/29 00:15:54 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_ext_normalize.c,v 1.6 2017/12/10 00:07:36 rmind Exp $"); #include <sys/types.h> #include <sys/module.h> @@ -147,8 +147,8 @@ npf_normalize(npf_cache_t *npc, void *pa int *decision) { npf_normalize_t *np = params; - struct tcphdr *th = npc->npc_l4.tcp; uint16_t cksum, mss, maxmss = np->n_maxmss; + struct tcphdr *th; int wscale; /* Skip, if already blocking. */ @@ -160,6 +160,7 @@ npf_normalize(npf_cache_t *npc, void *pa if (npf_iscached(npc, NPC_IP4) && (np->n_random_id || np->n_minttl)) { npf_normalize_ip4(npc, np); } + th = npc->npc_l4.tcp; /* * TCP Maximum Segment Size (MSS) "clamping". Only if SYN packet. @@ -180,8 +181,13 @@ npf_normalize(npf_cache_t *npc, void *pa } maxmss = htons(maxmss); - /* Store new MSS, calculate TCP checksum and update it. */ - if (npf_fetch_tcpopts(npc, &maxmss, &wscale)) { + /* + * Store new MSS, calculate TCP checksum and update it. + * WARNING: must re-fetch the TCP header after the modification. + */ + if (npf_fetch_tcpopts(npc, &maxmss, &wscale) && + nbuf_cksum_barrier(npc->npc_nbuf, mi->mi_di)) { + th = npc->npc_l4.tcp; cksum = npf_fixup16_cksum(th->th_sum, mss, maxmss); th->th_sum = cksum; }