Hello,

below is final patch I'm going to commit. Summary of changes:
        - softnettq declaration moved to net/if_var.h (by bluhm@)
        - lock order swapped: KERNEL_LOCK() goes first folllowed
          by spl (by bluhm@)
        - long line got fixed (by bluhm@)
        - ip_insertoptions() prototype deleted in ip_output.c (by bluhm@)
        - avoiding mix of tab/space at netinet6/ip6_var.h (by bluhm@)
        - static at ip*_send_dispatch() got removed (by mpi@)
        - ip*_send_dispatch() functions look more like if_input_process()
          now (by mpi@)

thanks and
regards
sasha

--------8<---------------8<---------------8<------------------8<--------

Index: net/if_var.h
===================================================================
RCS file: /cvs/src/sys/net/if_var.h,v
retrieving revision 1.62
diff -u -p -r1.62 if_var.h
--- net/if_var.h        3 Dec 2015 16:27:32 -0000       1.62
+++ net/if_var.h        3 Dec 2015 20:43:46 -0000
@@ -361,6 +361,7 @@ int         niq_enlist(struct niqueue *, struct
 
 extern struct ifnet_head ifnet;
 extern unsigned int lo0ifidx;
+extern struct taskq *softnettq;
 
 void   if_start(struct ifnet *);
 void   if_start_barrier(struct ifnet *);
Index: net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.956
diff -u -p -r1.956 pf.c
--- net/pf.c    3 Dec 2015 14:05:28 -0000       1.956
+++ net/pf.c    3 Dec 2015 20:43:47 -0000
@@ -2424,11 +2424,11 @@ pf_send_tcp(const struct pf_rule *r, sa_
 
        switch (af) {
        case AF_INET:
-               ip_output(m, NULL, NULL, 0, NULL, NULL, 0);
+               ip_send(m);
                break;
 #ifdef INET6
        case AF_INET6:
-               ip6_output(m, NULL, NULL, 0, NULL, NULL);
+               ip6_send(m);
                break;
 #endif /* INET6 */
        }
Index: netinet/ip_icmp.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_icmp.c,v
retrieving revision 1.149
diff -u -p -r1.149 ip_icmp.c
--- netinet/ip_icmp.c   2 Dec 2015 16:35:53 -0000       1.149
+++ netinet/ip_icmp.c   3 Dec 2015 20:43:47 -0000
@@ -854,7 +854,10 @@ icmp_send(struct mbuf *m, struct mbuf *o
                printf("icmp_send dst %s src %s\n", dst, src);
        }
 #endif
-       ip_output(m, opts, NULL, 0, NULL, NULL, 0);
+       if (opts != NULL)
+               m = ip_insertoptions(m, opts, &hlen);
+
+       ip_send(m);
 }
 
 u_int32_t
Index: netinet/ip_input.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_input.c,v
retrieving revision 1.264
diff -u -p -r1.264 ip_input.c
--- netinet/ip_input.c  3 Dec 2015 15:12:59 -0000       1.264
+++ netinet/ip_input.c  3 Dec 2015 20:43:47 -0000
@@ -44,6 +44,7 @@
 #include <sys/socketvar.h>
 #include <sys/sysctl.h>
 #include <sys/pool.h>
+#include <sys/task.h>
 
 #include <net/if.h>
 #include <net/if_var.h>
@@ -121,6 +122,8 @@ struct pool ipq_pool;
 
 struct ipstat ipstat;
 
+static struct mbuf_queue       ipsend_mq;
+
 void   ip_ours(struct mbuf *);
 int    ip_dooptions(struct mbuf *, struct ifnet *);
 int    in_ouraddr(struct mbuf *, struct ifnet *, struct in_addr);
@@ -130,6 +133,8 @@ int ip_input_ipsec_fwd_check(struct mbuf
 int    ip_input_ipsec_ours_check(struct mbuf *, int);
 #endif /* IPSEC */
 
+static void ip_send_dispatch(void *);
+static struct task ipsend_task = TASK_INITIALIZER(ip_send_dispatch, 
&ipsend_mq);
 /*
  * Used to save the IP options in case a protocol wants to respond
  * to an incoming packet over the same route if the packet got here
@@ -188,6 +193,8 @@ ip_init(void)
        strlcpy(ipsec_def_enc, IPSEC_DEFAULT_DEF_ENC, sizeof(ipsec_def_enc));
        strlcpy(ipsec_def_auth, IPSEC_DEFAULT_DEF_AUTH, sizeof(ipsec_def_auth));
        strlcpy(ipsec_def_comp, IPSEC_DEFAULT_DEF_COMP, sizeof(ipsec_def_comp));
+
+       mq_init(&ipsend_mq, 64, IPL_SOFTNET);
 }
 
 struct route ipforward_rt;
@@ -1752,3 +1759,27 @@ ip_savecontrol(struct inpcb *inp, struct
        }
 }
 
+void
+ip_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) {
+               ip_output(m, NULL, NULL, 0, NULL, NULL, 0);
+       }
+       splx(s);
+       KERNEL_UNLOCK();
+}
+
+void
+ip_send(struct mbuf *m)
+{
+       mq_enqueue(&ipsend_mq, m);
+       task_add(softnettq, &ipsend_task);
+}
Index: netinet/ip_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_var.h,v
retrieving revision 1.60
diff -u -p -r1.60 ip_var.h
--- netinet/ip_var.h    16 Jul 2015 21:14:21 -0000      1.60
+++ netinet/ip_var.h    3 Dec 2015 20:43:47 -0000
@@ -180,6 +180,8 @@ void         ip_freef(struct ipq *);
 void    ip_freemoptions(struct ip_moptions *);
 int     ip_getmoptions(int, struct ip_moptions *, struct mbuf **);
 void    ip_init(void);
+struct mbuf*
+        ip_insertoptions(struct mbuf *, struct mbuf *, int *);
 int     ip_mforward(struct mbuf *, struct ifnet *);
 int     ip_optcopy(struct ip *, struct ip *);
 int     ip_output(struct mbuf *, struct mbuf *, struct route *, int,
@@ -191,6 +193,7 @@ struct in_ifaddr *
         ip_rtaddr(struct in_addr, u_int);
 u_int16_t
         ip_randomid(void);
+void    ip_send(struct mbuf *);
 int     ip_setmoptions(int, struct ip_moptions **, struct mbuf *, u_int);
 void    ip_slowtimo(void);
 struct mbuf *
@@ -207,5 +210,6 @@ void         rip_input(struct mbuf *, ...);
 int     rip_output(struct mbuf *, ...);
 int     rip_usrreq(struct socket *,
            int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
+
 #endif /* _KERNEL */
 #endif /* _NETINET_IP_VAR_H_ */
Index: netinet6/icmp6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/icmp6.c,v
retrieving revision 1.181
diff -u -p -r1.181 icmp6.c
--- netinet6/icmp6.c    2 Dec 2015 16:35:53 -0000       1.181
+++ netinet6/icmp6.c    3 Dec 2015 20:43:47 -0000
@@ -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:
Index: netinet6/ip6_input.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_input.c,v
retrieving revision 1.151
diff -u -p -r1.151 ip6_input.c
--- netinet6/ip6_input.c        11 Nov 2015 10:23:23 -0000      1.151
+++ netinet6/ip6_input.c        3 Dec 2015 20:43:47 -0000
@@ -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
@@ -1430,4 +1440,29 @@ ip6_sysctl(int *name, u_int namelen, voi
                return (EOPNOTSUPP);
        }
        /* 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);
 }
Index: netinet6/ip6_var.h
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_var.h,v
retrieving revision 1.56
diff -u -p -r1.56 ip6_var.h
--- netinet6/ip6_var.h  25 Oct 2015 14:43:06 -0000      1.56
+++ netinet6/ip6_var.h  3 Dec 2015 20:43:47 -0000
@@ -275,6 +275,7 @@ int ip6_setpktopts(struct mbuf *, struct
 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);
 

Reply via email to