Author: lstewart
Date: Tue Dec 28 12:13:30 2010
New Revision: 216758
URL: http://svn.freebsd.org/changeset/base/216758

Log:
  - Add some helper hook points to the TCP stack. The hooks allow Khelp modules 
to
    access inbound/outbound events and associated data for established TCP
    connections. The hooks only run if at least one hook function is registered
    for the hook point, ensuring the impact on the stack is effectively nil when
    no TCP Khelp modules are loaded. struct tcp_hhook_data is passed as 
contextual
    data to any registered Khelp module hook functions.
  
  - Add an OSD (Object Specific Data) pointer to struct tcpcb to allow Khelp
    modules to associate per-connection data with the TCP control block.
  
  - Bump __FreeBSD_version and add a note to UPDATING regarding to ABI changes
    introduced by this commit and r216753.
  
  In collaboration with:        David Hayes <dahayes at swin edu au> and
                                Grenville Armitage <garmitage at swin edu au>
  Sponsored by: FreeBSD Foundation
  Reviewed by:  bz, others along the way
  MFC after:    3 months

Modified:
  head/UPDATING
  head/sys/netinet/tcp_input.c
  head/sys/netinet/tcp_output.c
  head/sys/netinet/tcp_subr.c
  head/sys/netinet/tcp_var.h
  head/sys/sys/param.h

Modified: head/UPDATING
==============================================================================
--- head/UPDATING       Tue Dec 28 11:34:59 2010        (r216757)
+++ head/UPDATING       Tue Dec 28 12:13:30 2010        (r216758)
@@ -22,6 +22,13 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 9.
        machines to maximize performance.  (To disable malloc debugging, run
        ln -s aj /etc/malloc.conf.)
 
+20101228:
+       The TCP stack has been modified to allow Khelp modules to interact with
+       it via helper hook points and store per-connection data in the TCP
+       control block. Bump __FreeBSD_version to 900029. User space tools that
+       rely on the size of struct tcpcb in tcp_var.h (e.g. sockstat) need to
+       be recompiled.
+
 20101114:
        Generic IEEE 802.3 annex 31B full duplex flow control support has been
        added to mii(4) and bge(4), bce(4), msk(4), nfe(4) and stge(4) along

Modified: head/sys/netinet/tcp_input.c
==============================================================================
--- head/sys/netinet/tcp_input.c        Tue Dec 28 11:34:59 2010        
(r216757)
+++ head/sys/netinet/tcp_input.c        Tue Dec 28 12:13:30 2010        
(r216758)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
+#include <sys/hhook.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/proc.h>          /* for proc0 declaration */
@@ -218,6 +219,8 @@ static void inline  cc_ack_received(struc
                            uint16_t type);
 static void inline     cc_conn_init(struct tcpcb *tp);
 static void inline     cc_post_recovery(struct tcpcb *tp, struct tcphdr *th);
+static void inline     hhook_run_tcp_est_in(struct tcpcb *tp,
+                           struct tcphdr *th, struct tcpopt *to);
 
 /*
  * Kernel module interface for updating tcpstat.  The argument is an index
@@ -234,6 +237,24 @@ kmod_tcpstat_inc(int statnum)
 }
 
 /*
+ * Wrapper for the TCP established input helper hook.
+ */
+static void inline
+hhook_run_tcp_est_in(struct tcpcb *tp, struct tcphdr *th, struct tcpopt *to)
+{
+       struct tcp_hhook_data hhook_data;
+
+       if (V_tcp_hhh[HHOOK_TCP_EST_IN]->hhh_nhooks > 0) {
+               hhook_data.tp = tp;
+               hhook_data.th = th;
+               hhook_data.to = to;
+
+               hhook_run_hooks(V_tcp_hhh[HHOOK_TCP_EST_IN], &hhook_data,
+                   tp->osd);
+       }
+}
+
+/*
  * CC wrapper hook functions
  */
 static void inline
@@ -1486,6 +1507,10 @@ tcp_do_segment(struct mbuf *m, struct tc
                                                        ticks - tp->t_rtttime);
                                }
                                acked = BYTES_THIS_ACK(tp, th);
+
+                               /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */
+                               hhook_run_tcp_est_in(tp, th, &to);
+
                                TCPSTAT_INC(tcps_rcvackpack);
                                TCPSTAT_ADD(tcps_rcvackbyte, acked);
                                sbdrop(&so->so_snd, acked);
@@ -2199,6 +2224,10 @@ tcp_do_segment(struct mbuf *m, struct tc
                    ((to.to_flags & TOF_SACK) ||
                     !TAILQ_EMPTY(&tp->snd_holes)))
                        tcp_sack_doack(tp, &to, th->th_ack);
+
+               /* Run HHOOK_TCP_ESTABLISHED_IN helper hooks. */
+               hhook_run_tcp_est_in(tp, th, &to);
+
                if (SEQ_LEQ(th->th_ack, tp->snd_una)) {
                        if (tlen == 0 && tiwin == tp->snd_wnd) {
                                TCPSTAT_INC(tcps_rcvdupack);

Modified: head/sys/netinet/tcp_output.c
==============================================================================
--- head/sys/netinet/tcp_output.c       Tue Dec 28 11:34:59 2010        
(r216757)
+++ head/sys/netinet/tcp_output.c       Tue Dec 28 12:13:30 2010        
(r216758)
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/domain.h>
+#include <sys/hhook.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
 #include <sys/mbuf.h>
@@ -126,9 +127,33 @@ SYSCTL_VNET_INT(_net_inet_tcp, OID_AUTO,
        &VNET_NAME(tcp_autosndbuf_max), 0,
        "Max size of automatic send buffer");
 
+static void inline     hhook_run_tcp_est_out(struct tcpcb *tp,
+                           struct tcphdr *th, struct tcpopt *to,
+                           long len, int tso);
 static void inline     cc_after_idle(struct tcpcb *tp);
 
 /*
+ * Wrapper for the TCP established ouput helper hook.
+ */
+static void inline
+hhook_run_tcp_est_out(struct tcpcb *tp, struct tcphdr *th,
+    struct tcpopt *to, long len, int tso)
+{
+       struct tcp_hhook_data hhook_data;
+
+       if (V_tcp_hhh[HHOOK_TCP_EST_OUT]->hhh_nhooks > 0) {
+               hhook_data.tp = tp;
+               hhook_data.th = th;
+               hhook_data.to = to;
+               hhook_data.len = len;
+               hhook_data.tso = tso;
+
+               hhook_run_hooks(V_tcp_hhh[HHOOK_TCP_EST_OUT], &hhook_data,
+                   tp->osd);
+       }
+}
+
+/*
  * CC wrapper hook functions
  */
 static void inline
@@ -1134,6 +1159,9 @@ timer:
                        tp->snd_max = tp->snd_nxt + len;
        }
 
+       /* Run HHOOK_TCP_ESTABLISHED_OUT helper hooks. */
+       hhook_run_tcp_est_out(tp, th, &to, len, tso);
+
 #ifdef TCPDEBUG
        /*
         * Trace.

Modified: head/sys/netinet/tcp_subr.c
==============================================================================
--- head/sys/netinet/tcp_subr.c Tue Dec 28 11:34:59 2010        (r216757)
+++ head/sys/netinet/tcp_subr.c Tue Dec 28 12:13:30 2010        (r216758)
@@ -41,7 +41,9 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/callout.h>
+#include <sys/hhook.h>
 #include <sys/kernel.h>
+#include <sys/khelp.h>
 #include <sys/sysctl.h>
 #include <sys/jail.h>
 #include <sys/malloc.h>
@@ -214,6 +216,8 @@ SYSCTL_INT(_net_inet_tcp, OID_AUTO, sore
 VNET_DEFINE(uma_zone_t, sack_hole_zone);
 #define        V_sack_hole_zone                VNET(sack_hole_zone)
 
+VNET_DEFINE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST+1]);
+
 static struct inpcb *tcp_notify(struct inpcb *, int);
 static void    tcp_isn_tick(void *);
 static char *  tcp_log_addr(struct in_conninfo *inc, struct tcphdr *th,
@@ -239,6 +243,7 @@ struct tcpcb_mem {
        struct  tcpcb           tcb;
        struct  tcp_timer       tt;
        struct  cc_var          ccv;
+       struct  osd             osd;
 };
 
 static VNET_DEFINE(uma_zone_t, tcpcb_zone);
@@ -278,6 +283,13 @@ tcp_init(void)
 {
        int hashsize;
 
+       if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_IN,
+           &V_tcp_hhh[HHOOK_TCP_EST_IN], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 0)
+               printf("%s: WARNING: unable to register helper hook\n", 
__func__);
+       if (hhook_head_register(HHOOK_TYPE_TCP, HHOOK_TCP_EST_OUT,
+           &V_tcp_hhh[HHOOK_TCP_EST_OUT], HHOOK_NOWAIT|HHOOK_HEADISINVNET) != 
0)
+               printf("%s: WARNING: unable to register helper hook\n", 
__func__);
+
        hashsize = TCBHASHSIZE;
        TUNABLE_INT_FETCH("net.inet.tcp.tcbhashsize", &hashsize);
        if (!powerof2(hashsize)) {
@@ -661,6 +673,12 @@ tcp_newtcpcb(struct inpcb *inp)
                        return (NULL);
                }
 
+       tp->osd = &tm->osd;
+       if (khelp_init_osd(HELPER_CLASS_TCP, tp->osd)) {
+               uma_zfree(V_tcpcb_zone, tm);
+               return (NULL);
+       }
+
 #ifdef VIMAGE
        tp->t_vnet = inp->inp_vnet;
 #endif
@@ -894,6 +912,8 @@ tcp_discardcb(struct tcpcb *tp)
        if (CC_ALGO(tp)->cb_destroy != NULL)
                CC_ALGO(tp)->cb_destroy(tp->ccv);
 
+       khelp_destroy_osd(tp->osd);
+
        CC_ALGO(tp) = NULL;
        inp->inp_ppcb = NULL;
        tp->t_inpcb = NULL;

Modified: head/sys/netinet/tcp_var.h
==============================================================================
--- head/sys/netinet/tcp_var.h  Tue Dec 28 11:34:59 2010        (r216757)
+++ head/sys/netinet/tcp_var.h  Tue Dec 28 12:13:30 2010        (r216758)
@@ -201,6 +201,7 @@ struct tcpcb {
        int     t_bytes_acked;          /* # bytes acked during current RTT */
        struct cc_algo  *cc_algo;       /* congestion control algorithm */
        struct cc_var   *ccv;
+       struct osd      *osd;           /* storage for Khelp module data */
 
        int     t_ispare;               /* explicit pad for 64bit alignment */
        void    *t_pspare2[4];          /* 4 TBD */
@@ -501,6 +502,22 @@ struct     tcpstat {
 void   kmod_tcpstat_inc(int statnum);
 #define        KMOD_TCPSTAT_INC(name)                                          
\
        kmod_tcpstat_inc(offsetof(struct tcpstat, name) / sizeof(u_long))
+
+/*
+ * TCP specific helper hook point identifiers.
+ */
+#define        HHOOK_TCP_EST_IN                0
+#define        HHOOK_TCP_EST_OUT               1
+#define        HHOOK_TCP_LAST                  HHOOK_TCP_EST_OUT
+
+struct tcp_hhook_data {
+       struct tcpcb *tp;
+       struct tcphdr *th;
+       struct tcpopt *to;
+       long len;
+       int tso;
+       tcp_seq  curack;
+};
 #endif
 
 /*
@@ -608,6 +625,9 @@ VNET_DECLARE(int, tcp_ecn_maxretries);
 #define        V_tcp_do_ecn            VNET(tcp_do_ecn)
 #define        V_tcp_ecn_maxretries    VNET(tcp_ecn_maxretries)
 
+VNET_DECLARE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST+1]);
+#define        V_tcp_hhh               VNET(tcp_hhh)
+
 int     tcp_addoptions(struct tcpopt *, u_char *);
 int     tcp_ccalgounload(struct cc_algo *unload_algo);
 struct tcpcb *

Modified: head/sys/sys/param.h
==============================================================================
--- head/sys/sys/param.h        Tue Dec 28 11:34:59 2010        (r216757)
+++ head/sys/sys/param.h        Tue Dec 28 12:13:30 2010        (r216758)
@@ -58,7 +58,7 @@
  *             in the range 5 to 9.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 900028       /* Master, propagated to newvers */
+#define __FreeBSD_version 900029       /* Master, propagated to newvers */
 
 #ifdef _KERNEL
 #define        P_OSREL_SIGSEGV         700004
_______________________________________________
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