Module Name: src Committed By: maxv Date: Wed Mar 14 09:32:04 UTC 2018
Modified Files: src/sys/net/npf: npf_sendpkt.c Log Message: Fix the "return-rst" rule on IPv6 packets. The scopes needed to be set on the addresses before invoking ip6_output, because ip6_output needs them. The reason they are not here already is because pfil_run_hooks (in ip6_input) is called _before_ the kernel initializes the scopes. Until now ip6_output was always failing, and the IPv6-TCP-RST packet was never actually sent. Perhaps it would be better to have the kernel initialize the scopes before invoking pfil_run_hooks, but several things will need to be fixed in several places. Tested with a simple TCPv6 server. Until now the client would block waiting for an answer that never came; now it receives an RST right away and closes the connection, as expected. I believe that the same problem exists in the "return-icmp" rules, but I can't investigate this right now (some problems with wireshark). To generate a diff of this commit: cvs rdiff -u -r1.16 -r1.17 src/sys/net/npf/npf_sendpkt.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_sendpkt.c diff -u src/sys/net/npf/npf_sendpkt.c:1.16 src/sys/net/npf/npf_sendpkt.c:1.17 --- src/sys/net/npf/npf_sendpkt.c:1.16 Mon Dec 26 23:05:06 2016 +++ src/sys/net/npf/npf_sendpkt.c Wed Mar 14 09:32:04 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: npf_sendpkt.c,v 1.16 2016/12/26 23:05:06 christos Exp $ */ +/* $NetBSD: npf_sendpkt.c,v 1.17 2018/03/14 09:32:04 maxv Exp $ */ /*- * Copyright (c) 2010-2011 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #ifdef _KERNEL #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.16 2016/12/26 23:05:06 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: npf_sendpkt.c,v 1.17 2018/03/14 09:32:04 maxv Exp $"); #include <sys/param.h> #include <sys/types.h> @@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: npf_sendpkt. #include <netinet/ip6.h> #include <netinet/icmp6.h> #include <netinet6/ip6_var.h> +#include <netinet6/scope6_var.h> #include <sys/mbuf.h> #endif @@ -175,11 +176,29 @@ npf_return_tcp(npf_cache_t *npc) sizeof(struct tcphdr)); } + /* Handle IPv6 scopes */ + if (npf_iscached(npc, NPC_IP6)) { + const struct ifnet *rcvif = npc->npc_nbuf->nb_ifp; + + if (in6_clearscope(&ip6->ip6_src) || + in6_clearscope(&ip6->ip6_dst)) { + goto bad; + } + if (in6_setscope(&ip6->ip6_src, rcvif, NULL) || + in6_setscope(&ip6->ip6_dst, rcvif, NULL)) { + goto bad; + } + } + /* Pass to IP layer. */ if (npf_iscached(npc, NPC_IP4)) { return ip_output(m, NULL, NULL, IP_FORWARDING, NULL, NULL); } return ip6_output(m, NULL, NULL, IPV6_FORWARDING, NULL, NULL, NULL); + +bad: + m_freem(m); + return EINVAL; } /*