diff -r 6ead007de089 sys/netinet/tcp_input.c --- a/sys/netinet/tcp_input.c Mon Dec 13 22:23:19 2010 +1100 +++ b/sys/netinet/tcp_input.c Mon Dec 13 22:24:02 2010 +1100 @@ -54,6 +54,7 @@ #include #include +#include #include #include #include /* for proc0 declaration */ @@ -1259,7 +1260,7 @@ int rstreason, todrop, win; u_long tiwin; struct tcpopt to; - + struct tcp_hhook_data hhook_data; #ifdef TCPDEBUG /* * The size of tcp_saveipgen must be the size of the max ip header, @@ -1486,6 +1487,15 @@ ticks - tp->t_rtttime); } acked = BYTES_THIS_ACK(tp, th); + + /* Run HHOOK_TCP_ESTABLISHED_IN helper hook functions. */ + hhook_data.new_sacked_bytes = 0; + hhook_data.tp = tp; + hhook_data.th = th; + hhook_data.to = &to; + HHOOKS_RUN_IF(V_tcp_hhh[HHOOK_TCP_EST_IN], + &hhook_data, tp->osd); + TCPSTAT_INC(tcps_rcvackpack); TCPSTAT_ADD(tcps_rcvackbyte, acked); sbdrop(&so->so_snd, acked); @@ -2195,10 +2205,21 @@ TCPSTAT_INC(tcps_rcvacktoomuch); goto dropafterack; } + hhook_data.new_sacked_bytes = 0; if ((tp->t_flags & TF_SACK_PERMIT) && ((to.to_flags & TOF_SACK) || - !TAILQ_EMPTY(&tp->snd_holes))) + !TAILQ_EMPTY(&tp->snd_holes))) { tcp_sack_doack(tp, &to, th->th_ack); + /* XXXDH: should only be one if a productive SACK */ + hhook_data.new_sacked_bytes = 1; + } + + hhook_data.tp = tp; + hhook_data.th = th; + hhook_data.to = &to; + HHOOKS_RUN_IF(V_tcp_hhh[HHOOK_TCP_EST_IN], &hhook_data, + tp->osd); + if (SEQ_LEQ(th->th_ack, tp->snd_una)) { if (tlen == 0 && tiwin == tp->snd_wnd) { TCPSTAT_INC(tcps_rcvdupack); diff -r 6ead007de089 sys/netinet/tcp_output.c --- a/sys/netinet/tcp_output.c Mon Dec 13 22:23:19 2010 +1100 +++ b/sys/netinet/tcp_output.c Mon Dec 13 22:24:02 2010 +1100 @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -163,6 +164,7 @@ struct sackhole *p; int tso; struct tcpopt to; + struct tcp_hhook_data hhook_data; #if 0 int maxburst = TCP_MAXBURST; #endif @@ -1134,6 +1136,14 @@ tp->snd_max = tp->snd_nxt + len; } + hhook_data.th = th; + hhook_data.tp = tp; + hhook_data.to = &to; + hhook_data.len = len; + hhook_data.tso = tso; + HHOOKS_RUN_IF(V_tcp_hhh[HHOOK_TCP_EST_OUT], &hhook_data, tp->osd); + + #ifdef TCPDEBUG /* * Trace. diff -r 6ead007de089 sys/netinet/tcp_sack.c --- a/sys/netinet/tcp_sack.c Mon Dec 13 22:23:19 2010 +1100 +++ b/sys/netinet/tcp_sack.c Mon Dec 13 22:24:02 2010 +1100 @@ -425,6 +425,7 @@ * are received. */ sblkp = &sack_blocks[num_sack_blks - 1]; /* Last SACK block */ + tp->sackhint.last_sack_ack = sblkp->end; if (SEQ_LT(tp->snd_fack, sblkp->start)) { /* * The highest SACK block is beyond fack. Append new SACK diff -r 6ead007de089 sys/netinet/tcp_subr.c --- a/sys/netinet/tcp_subr.c Mon Dec 13 22:23:19 2010 +1100 +++ b/sys/netinet/tcp_subr.c Mon Dec 13 22:24:02 2010 +1100 @@ -41,7 +41,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -214,6 +216,8 @@ 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 tcb; struct tcp_timer tt; struct cc_var ccv; + struct osd osd; }; static VNET_DEFINE(uma_zone_t, tcpcb_zone); @@ -278,6 +283,13 @@ { 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 @@ 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 @@ 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; diff -r 6ead007de089 sys/netinet/tcp_var.h --- a/sys/netinet/tcp_var.h Mon Dec 13 22:23:19 2010 +1100 +++ b/sys/netinet/tcp_var.h Mon Dec 13 22:24:02 2010 +1100 @@ -70,7 +70,7 @@ struct sackhint { struct sackhole *nexthole; int sack_bytes_rexmit; - + tcp_seq last_sack_ack; /* Last sack block acked with current pkt - used for enhanced RTT calculations*/ int ispare; /* explicit pad for 64bit alignment */ uint64_t _pad[2]; /* 1 sacked_bytes, 1 TBD */ }; @@ -200,6 +200,7 @@ int t_bytes_acked; /* # bytes acked during current RTT */ struct cc_algo *cc_algo; /* congestion control algorithm */ struct cc_var *ccv; + struct osd *osd; int t_ispare; /* explicit pad for 64bit alignment */ void *t_pspare2[4]; /* 4 TBD */ @@ -253,6 +254,26 @@ #define BYTES_THIS_ACK(tp, th) (th->th_ack - tp->snd_una) /* + * 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 + +VNET_DECLARE(struct hhook_head *, tcp_hhh[HHOOK_TCP_LAST+1]); +#define V_tcp_hhh VNET(tcp_hhh) + +struct tcp_hhook_data { + struct tcpcb *tp; + struct tcphdr *th; + struct tcpopt *to; + long len; + int tso; + tcp_seq curack; + int new_sacked_bytes; +}; + +/* * Flags for the t_oobflags field. */ #define TCPOOB_HAVEDATA 0x01