diff options
author | Alexandr Nedvedicky <sashan@cvs.openbsd.org> | 2015-12-03 21:11:55 +0000 |
---|---|---|
committer | Alexandr Nedvedicky <sashan@cvs.openbsd.org> | 2015-12-03 21:11:55 +0000 |
commit | a9c1ebbf0861392583f5cd5ee7fe259fbf261e52 (patch) | |
tree | 0fd7b59251c450f677a61f1dd940e05f02897c5c /sys/netinet6 | |
parent | 3389f73d3859bdb82aa4f339dee4f72c34852e88 (diff) |
ip_send()/ip6_send() allow PF to send response packet in ipsoftnet task.
this avoids current recursion to pf_test() function. the change also
switches icmp_error()/icmp6_error() to use ip_send()/ip6_send() so
they are safe for PF.
The idea comes from Markus Friedl. bluhm, mikeb and mpi helped me
a lot to get it into shape.
OK bluhm@, mpi@
Diffstat (limited to 'sys/netinet6')
-rw-r--r-- | sys/netinet6/icmp6.c | 4 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 37 | ||||
-rw-r--r-- | sys/netinet6/ip6_var.h | 3 |
3 files changed, 40 insertions, 4 deletions
diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index f0100428732..192837e6900 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.181 2015/12/02 16:35:53 bluhm Exp $ */ +/* $OpenBSD: icmp6.c,v 1.182 2015/12/03 21:11:53 sashan Exp $ */ /* $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */ /* @@ -1302,7 +1302,7 @@ icmp6_reflect(struct mbuf *m, size_t off) #if NPF > 0 pf_pkt_addr_changed(m); #endif - ip6_output(m, NULL, NULL, IPV6_MINMTU, NULL, NULL); + ip6_send(m); return; bad: diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 3479082b849..08e015d103e 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.151 2015/11/11 10:23:23 mpi Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.152 2015/12/03 21:11:54 sashan Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -77,6 +77,7 @@ #include <sys/timeout.h> #include <sys/kernel.h> #include <sys/syslog.h> +#include <sys/task.h> #include <net/if.h> #include <net/if_var.h> @@ -89,6 +90,7 @@ #include <netinet/ip.h> #include <netinet/in_pcb.h> +#include <netinet/ip_var.h> #include <netinet6/in6_var.h> #include <netinet/ip6.h> #include <netinet6/ip6_var.h> @@ -123,6 +125,12 @@ int ip6_check_rh0hdr(struct mbuf *, int *); int ip6_hopopts_input(u_int32_t *, u_int32_t *, struct mbuf **, int *); struct mbuf *ip6_pullexthdr(struct mbuf *, size_t, int); +static struct mbuf_queue ip6send_mq; + +static void ip6_send_dispatch(void *); +static struct task ip6send_task = + TASK_INITIALIZER(ip6_send_dispatch, &ip6send_mq); + /* * IP6 initialization: fill in IP6 protocol switch table. * All protocols not implemented in kernel go to raw IP6 protocol handler. @@ -149,6 +157,8 @@ ip6_init(void) nd6_init(); frag6_init(); ip6_init2((void *)0); + + mq_init(&ip6send_mq, 64, IPL_SOFTNET); } void @@ -1431,3 +1441,28 @@ ip6_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, } /* NOTREACHED */ } + +void +ip6_send_dispatch(void *xmq) +{ + struct mbuf_queue *mq = xmq; + struct mbuf *m; + struct mbuf_list ml; + int s; + + mq_delist(mq, &ml); + KERNEL_LOCK(); + s = splsoftnet(); + while ((m = ml_dequeue(&ml)) != NULL) { + ip6_output(m, NULL, NULL, IPV6_MINMTU, NULL, NULL); + } + splx(s); + KERNEL_UNLOCK(); +} + +void +ip6_send(struct mbuf *m) +{ + mq_enqueue(&ip6send_mq, m); + task_add(softnettq, &ip6send_task); +} diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index 2af3a05d810..b7c99c5887b 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_var.h,v 1.56 2015/10/25 14:43:06 florian Exp $ */ +/* $OpenBSD: ip6_var.h,v 1.57 2015/12/03 21:11:54 sashan Exp $ */ /* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */ /* @@ -275,6 +275,7 @@ int ip6_setpktopts(struct mbuf *, struct ip6_pktopts *, void ip6_clearpktopts(struct ip6_pktopts *, int); void ip6_randomid_init(void); u_int32_t ip6_randomid(void); +void ip6_send(struct mbuf *); int route6_input(struct mbuf **, int *, int); |