On Mon, Mar 21, 2016 at 11:05:25AM +0100, Martin Pieuchot wrote:
> I like it.  Do you think it could be useful to export the value of the
> current active cache set and/or the value of ``tcp_syn_use_limit''?

When the active cache set switches, the reseed counter increments.
It might be usefull to see the current fill and use counter, but
that does not fit well in the tcpstat netstat counters.

The tcp_syn_use_limit can be added as sysctl.  Although we don't
like knobs, this one is useful to test the feature and may be handy
to defend against syn-flood in a denial of service condition.  It
is consistent to the existing two syn cache sysctls.

net.inet.tcp.syncachelimit=10255
net.inet.tcp.synbucketlimit=105
net.inet.tcp.synuselimit=100000

I moved some declarations to tcp_var.h to access syn_cache_set from
tcp_sysctl().  Note that TCPCTL_VARS had a missing NULL before.

ok?

bluhm

Index: netinet/tcp_input.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_input.c,v
retrieving revision 1.316
diff -u -p -r1.316 tcp_input.c
--- netinet/tcp_input.c 27 Mar 2016 19:19:01 -0000      1.316
+++ netinet/tcp_input.c 28 Mar 2016 21:26:14 -0000
@@ -3255,19 +3255,12 @@ tcp_mss_adv(struct mbuf *m, int af)
  */
 
 /* syn hash parameters */
-#define        TCP_SYN_HASH_SIZE       293
-#define        TCP_SYN_BUCKET_SIZE     35
 int    tcp_syn_cache_size = TCP_SYN_HASH_SIZE;
 int    tcp_syn_cache_limit = TCP_SYN_HASH_SIZE*TCP_SYN_BUCKET_SIZE;
 int    tcp_syn_bucket_limit = 3*TCP_SYN_BUCKET_SIZE;
 int    tcp_syn_use_limit = 100000;
 
-struct syn_cache_set {
-        struct         syn_cache_head scs_buckethead[TCP_SYN_HASH_SIZE];
-        int            scs_count;
-        int            scs_use;
-        u_int32_t      scs_random[5];
-} tcp_syn_cache[2];
+struct syn_cache_set tcp_syn_cache[2];
 int tcp_syn_cache_active;
 
 #define SYN_HASH(sa, sp, dp, rand) \
Index: netinet/tcp_usrreq.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.129
diff -u -p -r1.129 tcp_usrreq.c
--- netinet/tcp_usrreq.c        23 Mar 2016 15:50:36 -0000      1.129
+++ netinet/tcp_usrreq.c        28 Mar 2016 21:48:23 -0000
@@ -933,6 +933,23 @@ tcp_sysctl(name, namelen, oldp, oldlenp,
                return (sysctl_struct(oldp, oldlenp, newp, newlen,
                    &tcpstat, sizeof(tcpstat)));
 
+       case TCPCTL_SYN_USE_LIMIT:
+               error = sysctl_int(oldp, oldlenp, newp, newlen,
+                   &tcp_syn_use_limit);
+               if (error)
+                       return (error);
+               if (newp != NULL) {
+                       /*
+                        * Global tcp_syn_use_limit is used when reseeding a
+                        * new cache.  Also update the value in active cache.
+                        */
+                       if (tcp_syn_cache[0].scs_use > tcp_syn_use_limit)
+                               tcp_syn_cache[0].scs_use = tcp_syn_use_limit;
+                       if (tcp_syn_cache[1].scs_use > tcp_syn_use_limit)
+                               tcp_syn_cache[1].scs_use = tcp_syn_use_limit;
+               }
+               return (0);
+
        default:
                if (name[0] < TCPCTL_MAXID)
                        return (sysctl_int_arr(tcpctl_vars, name, namelen,
Index: netinet/tcp_var.h
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/tcp_var.h,v
retrieving revision 1.111
diff -u -p -r1.111 tcp_var.h
--- netinet/tcp_var.h   27 Mar 2016 19:19:01 -0000      1.111
+++ netinet/tcp_var.h   28 Mar 2016 21:26:14 -0000
@@ -251,6 +251,10 @@ struct tcp_opt_info {
 /*
  * Data for the TCP compressed state engine.
  */
+
+#define        TCP_SYN_HASH_SIZE       293
+#define        TCP_SYN_BUCKET_SIZE     35
+
 union syn_cache_sa {
        struct sockaddr sa;
        struct sockaddr_in sin;
@@ -311,6 +315,13 @@ struct syn_cache_head {
        u_short sch_length;                     /* # entries in bucket */
 };
 
+struct syn_cache_set {
+        struct         syn_cache_head scs_buckethead[TCP_SYN_HASH_SIZE];
+        int            scs_count;
+        int            scs_use;
+        u_int32_t      scs_random[5];
+};
+
 #endif /* _KERNEL */
 
 /*
@@ -478,7 +489,8 @@ struct      tcpstat {
 #define        TCPCTL_SACKHOLE_LIMIT  20 /* max entries for tcp sack queues */
 #define        TCPCTL_STATS           21 /* TCP statistics */
 #define        TCPCTL_ALWAYS_KEEPALIVE 22 /* assume SO_KEEPALIVE is always set 
*/
-#define        TCPCTL_MAXID           23
+#define        TCPCTL_SYN_USE_LIMIT   23 /* number of uses before reseeding 
hash */
+#define        TCPCTL_MAXID           24
 
 #define        TCPCTL_NAMES { \
        { 0, 0 }, \
@@ -503,7 +515,8 @@ struct      tcpstat {
        { "drop",       CTLTYPE_STRUCT }, \
        { "sackholelimit",      CTLTYPE_INT }, \
        { "stats",      CTLTYPE_STRUCT }, \
-       { "always_keepalive",   CTLTYPE_INT } \
+       { "always_keepalive",   CTLTYPE_INT }, \
+       { "synuselimit",        CTLTYPE_INT }, \
 }
 
 #define        TCPCTL_VARS { \
@@ -528,6 +541,8 @@ struct      tcpstat {
        NULL, \
        NULL, \
        NULL, \
+       NULL, \
+       NULL, \
        NULL \
 }
 
@@ -559,6 +574,8 @@ extern      int tcp_reass_limit;    /* max entri
 
 extern int tcp_syn_cache_limit; /* max entries for compressed state engine */
 extern int tcp_syn_bucket_limit;/* max entries per hash bucket */
+extern int tcp_syn_use_limit;   /* number of uses before reseeding hash */
+extern struct syn_cache_set tcp_syn_cache[];
 
 int     tcp_attach(struct socket *);
 void    tcp_canceltimers(struct tcpcb *);

Reply via email to