Author: lstewart
Date: Sat Nov  6 14:49:10 2010
New Revision: 214883
URL: http://svn.freebsd.org/changeset/base/214883

Log:
  MFC r210203:
  
  - Move common code from the hook functions that fills in a packet node struct 
to
    a separate inline function. This further reduces duplicate code that didn't
    have a good reason to stay as it was.
  
  - Reorder the malloc of a pkt_node struct in the hook functions such that it
    only occurs if we managed to find a usable tcpcb associated with the packet.
  
  - Make the inp_locally_locked variable's type consistent with the prototype of
    siftr_siftdata().
  
  Sponsored by: FreeBSD Foundation

Modified:
  stable/7/sys/netinet/siftr.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/netinet/siftr.c
==============================================================================
--- stable/7/sys/netinet/siftr.c        Sat Nov  6 14:46:24 2010        
(r214882)
+++ stable/7/sys/netinet/siftr.c        Sat Nov  6 14:49:10 2010        
(r214883)
@@ -752,6 +752,67 @@ siftr_findinpcb(int ipver, struct ip *ip
 }
 
 
+static inline void
+siftr_siftdata(struct pkt_node *pn, struct inpcb *inp, struct tcpcb *tp,
+    int ipver, int dir, int inp_locally_locked)
+{
+#ifdef SIFTR_IPV6
+       if (ipver == INP_IPV4) {
+               pn->ip_laddr[3] = inp->inp_laddr.s_addr;
+               pn->ip_faddr[3] = inp->inp_faddr.s_addr;
+#else
+               *((uint32_t *)pn->ip_laddr) = inp->inp_laddr.s_addr;
+               *((uint32_t *)pn->ip_faddr) = inp->inp_faddr.s_addr;
+#endif
+#ifdef SIFTR_IPV6
+       } else {
+               pn->ip_laddr[0] = inp->in6p_laddr.s6_addr32[0];
+               pn->ip_laddr[1] = inp->in6p_laddr.s6_addr32[1];
+               pn->ip_laddr[2] = inp->in6p_laddr.s6_addr32[2];
+               pn->ip_laddr[3] = inp->in6p_laddr.s6_addr32[3];
+               pn->ip_faddr[0] = inp->in6p_faddr.s6_addr32[0];
+               pn->ip_faddr[1] = inp->in6p_faddr.s6_addr32[1];
+               pn->ip_faddr[2] = inp->in6p_faddr.s6_addr32[2];
+               pn->ip_faddr[3] = inp->in6p_faddr.s6_addr32[3];
+       }
+#endif
+       pn->tcp_localport = inp->inp_lport;
+       pn->tcp_foreignport = inp->inp_fport;
+       pn->snd_cwnd = tp->snd_cwnd;
+       pn->snd_wnd = tp->snd_wnd;
+       pn->rcv_wnd = tp->rcv_wnd;
+       pn->snd_bwnd = tp->snd_bwnd;
+       pn->snd_ssthresh = tp->snd_ssthresh;
+       pn->snd_scale = tp->snd_scale;
+       pn->rcv_scale = tp->rcv_scale;
+       pn->conn_state = tp->t_state;
+       pn->max_seg_size = tp->t_maxseg;
+       pn->smoothed_rtt = tp->t_srtt;
+       pn->sack_enabled = (tp->t_flags & TF_SACK_PERMIT) != 0;
+       pn->flags = tp->t_flags;
+       pn->rxt_length = tp->t_rxtcur;
+       pn->snd_buf_hiwater = inp->inp_socket->so_snd.sb_hiwat;
+       pn->snd_buf_cc = inp->inp_socket->so_snd.sb_cc;
+       pn->rcv_buf_hiwater = inp->inp_socket->so_rcv.sb_hiwat;
+       pn->rcv_buf_cc = inp->inp_socket->so_rcv.sb_cc;
+       pn->sent_inflight_bytes = tp->snd_max - tp->snd_una;
+
+       /* We've finished accessing the tcb so release the lock. */
+       if (inp_locally_locked)
+               INP_RUNLOCK(inp);
+
+       pn->ipver = ipver;
+       pn->direction = dir;
+
+       /*
+        * Significantly more accurate than using getmicrotime(), but slower!
+        * Gives true microsecond resolution at the expense of a hit to
+        * maximum pps throughput processing when SIFTR is loaded and enabled.
+        */
+       microtime(&pn->tval);
+}
+
+
 /*
  * pfil hook that is called for each IPv4 packet making its way through the
  * stack in either direction.
@@ -764,13 +825,13 @@ static int
 siftr_chkpkt(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
     struct inpcb *inp)
 {
-       struct pkt_node *pkt_node;
+       struct pkt_node *pn;
        struct ip *ip;
        struct tcphdr *th;
        struct tcpcb *tp;
        struct siftr_stats *ss;
        unsigned int ip_hl;
-       uint8_t inp_locally_locked;
+       int inp_locally_locked;
 
        inp_locally_locked = 0;
        ss = DPCPU_PTR(ss);
@@ -824,18 +885,6 @@ siftr_chkpkt(void *arg, struct mbuf **m,
 
        INP_LOCK_ASSERT(inp);
 
-       pkt_node = malloc(sizeof(struct pkt_node), M_SIFTR_PKTNODE,
-           M_NOWAIT | M_ZERO);
-
-       if (pkt_node == NULL) {
-               if (dir == PFIL_IN)
-                       ss->nskip_in_malloc++;
-               else
-                       ss->nskip_out_malloc++;
-
-               goto inp_unlock;
-       }
-
        /* Find the TCP control block that corresponds with this packet */
        tp = intotcpcb(inp);
 
@@ -850,53 +899,21 @@ siftr_chkpkt(void *arg, struct mbuf **m,
                else
                        ss->nskip_out_tcpcb++;
 
-               free(pkt_node, M_SIFTR_PKTNODE);
                goto inp_unlock;
        }
 
-       /* Fill in pkt_node data */
-#ifdef SIFTR_IPV6
-       pkt_node->ip_laddr[3] = inp->inp_laddr.s_addr;
-       pkt_node->ip_faddr[3] = inp->inp_faddr.s_addr;
-#else
-       *((uint32_t *)pkt_node->ip_laddr) = inp->inp_laddr.s_addr;
-       *((uint32_t *)pkt_node->ip_faddr) = inp->inp_faddr.s_addr;
-#endif
-       pkt_node->tcp_localport = inp->inp_lport;
-       pkt_node->tcp_foreignport = inp->inp_fport;
-       pkt_node->snd_cwnd = tp->snd_cwnd;
-       pkt_node->snd_wnd = tp->snd_wnd;
-       pkt_node->rcv_wnd = tp->rcv_wnd;
-       pkt_node->snd_bwnd = tp->snd_bwnd;
-       pkt_node->snd_ssthresh = tp->snd_ssthresh;
-       pkt_node->snd_scale = tp->snd_scale;
-       pkt_node->rcv_scale = tp->rcv_scale;
-       pkt_node->conn_state = tp->t_state;
-       pkt_node->max_seg_size = tp->t_maxseg;
-       pkt_node->smoothed_rtt = tp->t_srtt;
-       pkt_node->sack_enabled = (tp->t_flags & TF_SACK_PERMIT) != 0;
-       pkt_node->flags = tp->t_flags;
-       pkt_node->rxt_length = tp->t_rxtcur;
-       pkt_node->snd_buf_hiwater = inp->inp_socket->so_snd.sb_hiwat;
-       pkt_node->snd_buf_cc = inp->inp_socket->so_snd.sb_cc;
-       pkt_node->rcv_buf_hiwater = inp->inp_socket->so_rcv.sb_hiwat;
-       pkt_node->rcv_buf_cc = inp->inp_socket->so_rcv.sb_cc;
-       pkt_node->sent_inflight_bytes = tp->snd_max - tp->snd_una;
+       pn = malloc(sizeof(struct pkt_node), M_SIFTR_PKTNODE, M_NOWAIT|M_ZERO);
 
-       /* We've finished accessing the tcb so release the lock. */
-       if (inp_locally_locked)
-               INP_RUNLOCK(inp);
+       if (pn == NULL) {
+               if (dir == PFIL_IN)
+                       ss->nskip_in_malloc++;
+               else
+                       ss->nskip_out_malloc++;
 
-       /* These are safe to access without the inp lock. */
-       pkt_node->ipver = INP_IPV4;
-       pkt_node->direction = dir;
+               goto inp_unlock;
+       }
 
-       /*
-        * Significantly more accurate than using getmicrotime(), but slower!
-        * Gives true microsecond resolution at the expense of a hit to
-        * maximum pps throughput processing when SIFTR is loaded and enabled.
-        */
-       microtime(&(pkt_node->tval));
+       siftr_siftdata(pn, inp, tp, INP_IPV4, dir, inp_locally_locked);
 
        if (siftr_generate_hashes) {
                if ((*m)->m_pkthdr.csum_flags & CSUM_TCP) {
@@ -956,11 +973,11 @@ siftr_chkpkt(void *arg, struct mbuf **m,
                 * find a way to create the hash and checksum in the same pass
                 * over the bytes.
                 */
-               pkt_node->hash = hash_pkt(*m, ip_hl);
+               pn->hash = hash_pkt(*m, ip_hl);
        }
 
        mtx_lock(&siftr_pkt_queue_mtx);
-       STAILQ_INSERT_TAIL(&pkt_queue, pkt_node, nodes);
+       STAILQ_INSERT_TAIL(&pkt_queue, pn, nodes);
        mtx_unlock(&siftr_pkt_queue_mtx);
        goto ret;
 
@@ -979,13 +996,13 @@ static int
 siftr_chkpkt6(void *arg, struct mbuf **m, struct ifnet *ifp, int dir,
     struct inpcb *inp)
 {
-       struct pkt_node *pkt_node;
+       struct pkt_node *pn;
        struct ip6_hdr *ip6;
        struct tcphdr *th;
        struct tcpcb *tp;
        struct siftr_stats *ss;
        unsigned int ip6_hl;
-       uint8_t inp_locally_locked;
+       int inp_locally_locked;
 
        inp_locally_locked = 0;
        ss = DPCPU_PTR(ss);
@@ -1043,18 +1060,6 @@ siftr_chkpkt6(void *arg, struct mbuf **m
                        inp_locally_locked = 1;
        }
 
-       pkt_node = malloc(sizeof(struct pkt_node), M_SIFTR_PKTNODE,
-           M_NOWAIT | M_ZERO);
-
-       if (pkt_node == NULL) {
-               if (dir == PFIL_IN)
-                       ss->nskip_in_malloc++;
-               else
-                       ss->nskip_out_malloc++;
-
-               goto inp_unlock6;
-       }
-
        /* Find the TCP control block that corresponds with this packet. */
        tp = intotcpcb(inp);
 
@@ -1069,59 +1074,26 @@ siftr_chkpkt6(void *arg, struct mbuf **m
                else
                        ss->nskip_out_tcpcb++;
 
-               free(pkt_node, M_SIFTR_PKTNODE);
                goto inp_unlock6;
        }
 
-       /* Fill in pkt_node data. */
-       pkt_node->ip_laddr[0] = inp->in6p_laddr.s6_addr32[0];
-       pkt_node->ip_laddr[1] = inp->in6p_laddr.s6_addr32[1];
-       pkt_node->ip_laddr[2] = inp->in6p_laddr.s6_addr32[2];
-       pkt_node->ip_laddr[3] = inp->in6p_laddr.s6_addr32[3];
-       pkt_node->ip_faddr[0] = inp->in6p_faddr.s6_addr32[0];
-       pkt_node->ip_faddr[1] = inp->in6p_faddr.s6_addr32[1];
-       pkt_node->ip_faddr[2] = inp->in6p_faddr.s6_addr32[2];
-       pkt_node->ip_faddr[3] = inp->in6p_faddr.s6_addr32[3];
-       pkt_node->tcp_localport = inp->inp_lport;
-       pkt_node->tcp_foreignport = inp->inp_fport;
-       pkt_node->snd_cwnd = tp->snd_cwnd;
-       pkt_node->snd_wnd = tp->snd_wnd;
-       pkt_node->rcv_wnd = tp->rcv_wnd;
-       pkt_node->snd_bwnd = tp->snd_bwnd;
-       pkt_node->snd_ssthresh = tp->snd_ssthresh;
-       pkt_node->snd_scale = tp->snd_scale;
-       pkt_node->rcv_scale = tp->rcv_scale;
-       pkt_node->conn_state = tp->t_state;
-       pkt_node->max_seg_size = tp->t_maxseg;
-       pkt_node->smoothed_rtt = tp->t_srtt;
-       pkt_node->sack_enabled = (tp->t_flags & TF_SACK_PERMIT) != 0;
-       pkt_node->flags = tp->t_flags;
-       pkt_node->rxt_length = tp->t_rxtcur;
-       pkt_node->snd_buf_hiwater = inp->inp_socket->so_snd.sb_hiwat;
-       pkt_node->snd_buf_cc = inp->inp_socket->so_snd.sb_cc;
-       pkt_node->rcv_buf_hiwater = inp->inp_socket->so_rcv.sb_hiwat;
-       pkt_node->rcv_buf_cc = inp->inp_socket->so_rcv.sb_cc;
-       pkt_node->sent_inflight_bytes = tp->snd_max - tp->snd_una;
+       pn = malloc(sizeof(struct pkt_node), M_SIFTR_PKTNODE, M_NOWAIT|M_ZERO);
 
-       /* We've finished accessing the tcb so release the lock. */
-       if (inp_locally_locked)
-               INP_RUNLOCK(inp);
+       if (pn == NULL) {
+               if (dir == PFIL_IN)
+                       ss->nskip_in_malloc++;
+               else
+                       ss->nskip_out_malloc++;
 
-       /* These are safe to access without the inp lock. */
-       pkt_node->ipver = INP_IPV6;
-       pkt_node->direction = dir;
+               goto inp_unlock6;
+       }
 
-       /*
-        * Significantly more accurate than using getmicrotime(), but slower!
-        * Gives true microsecond resolution at the expense of a hit to
-        * maximum pps throughput processing when SIFTR is loaded and enabled.
-        */
-       microtime(&(pkt_node->tval));
+       siftr_siftdata(pn, inp, tp, INP_IPV6, dir, inp_locally_locked);
 
-       /* XXX: Figure out how to do hash calcs for IPv6 */
+       /* XXX: Figure out how to generate hashes for IPv6 packets. */
 
        mtx_lock(&siftr_pkt_queue_mtx);
-       STAILQ_INSERT_TAIL(&pkt_queue, pkt_node, nodes);
+       STAILQ_INSERT_TAIL(&pkt_queue, pn, nodes);
        mtx_unlock(&siftr_pkt_queue_mtx);
        goto ret6;
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to