Commit 883ca833e5fb814fb03426c9d35e5489ce43e8da

Authored by Gerrit Renker
Committed by David S. Miller
1 parent 792b48780e

dccp: Initialisation and type-checking of feature sysctls

This patch takes care of initialising and type-checking sysctls
related to feature negotiation. Type checking is important since some
of the sysctls now directly impact the feature-negotiation process.

The sysctls are initialised with the known default values for each
feature.  For the type-checking the value constraints from RFC 4340
are used:

 * Sequence Window uses the specified Wmin=32, the maximum is ulong (4 bytes),
   tested and confirmed that it works up to 4294967295 - for Gbps speed;
 * Ack Ratio is between 0 .. 0xffff (2-byte unsigned integer);
 * CCIDs are between 0 .. 255;
 * request_retries, retries1, retries2 also between 0..255 for good measure;
 * tx_qlen is checked to be non-negative;
 * sync_ratelimit remains as before.

Notes:
------
 1. Die s@sysctl_dccp_feat@sysctl_dccp@g since the sysctls are now in feat.c.
 2. As pointed out by Arnaldo, the pattern of type-checking repeats itself in
    other places, sometimes with exactly the same kind of definitions (e.g.
    "static int zero;"). It may be a good idea (kernel janitors?) to consolidate
    type checking. For the sake of keeping the changeset small and in order not
    to affect other subsystems, I have not strived to generalise here.

Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 6 changed files with 46 additions and 31 deletions Side-by-side Diff

include/linux/dccp.h
... ... @@ -355,14 +355,6 @@
355 355 return __dccp_hdr_len(dccp_hdr(skb));
356 356 }
357 357  
358   -
359   -/* initial values for each feature */
360   -#define DCCPF_INITIAL_SEQUENCE_WINDOW 100
361   -#define DCCPF_INITIAL_ACK_RATIO 2
362   -#define DCCPF_INITIAL_CCID DCCPC_CCID2
363   -/* FIXME: for now we're default to 1 but it should really be 0 */
364   -#define DCCPF_INITIAL_SEND_NDP_COUNT 1
365   -
366 358 /**
367 359 * struct dccp_request_sock - represent DCCP-specific connection request
368 360 * @dreq_inet_rsk: structure inherited from
... ... @@ -95,9 +95,6 @@
95 95 extern int sysctl_dccp_request_retries;
96 96 extern int sysctl_dccp_retries1;
97 97 extern int sysctl_dccp_retries2;
98   -extern int sysctl_dccp_feat_sequence_window;
99   -extern int sysctl_dccp_feat_rx_ccid;
100   -extern int sysctl_dccp_feat_tx_ccid;
101 98 extern int sysctl_dccp_tx_qlen;
102 99 extern int sysctl_dccp_sync_ratelimit;
103 100  
... ... @@ -25,6 +25,11 @@
25 25 #include "ccid.h"
26 26 #include "feat.h"
27 27  
  28 +/* feature-specific sysctls - initialised to the defaults from RFC 4340, 6.4 */
  29 +unsigned long sysctl_dccp_sequence_window __read_mostly = 100;
  30 +int sysctl_dccp_rx_ccid __read_mostly = 2,
  31 + sysctl_dccp_tx_ccid __read_mostly = 2;
  32 +
28 33 /*
29 34 * Feature activation handlers.
30 35 *
... ... @@ -1146,7 +1151,7 @@
1146 1151  
1147 1152 /* Non-negotiable (NN) features */
1148 1153 rc = __feat_register_nn(fn, DCCPF_SEQUENCE_WINDOW, 0,
1149   - sysctl_dccp_feat_sequence_window);
  1154 + sysctl_dccp_sequence_window);
1150 1155 if (rc)
1151 1156 return rc;
1152 1157  
... ... @@ -1172,8 +1177,8 @@
1172 1177 ccid_get_builtin_ccids(&rx.val, &rx.len))
1173 1178 return -ENOBUFS;
1174 1179  
1175   - if (!dccp_feat_prefer(sysctl_dccp_feat_tx_ccid, tx.val, tx.len) ||
1176   - !dccp_feat_prefer(sysctl_dccp_feat_rx_ccid, rx.val, rx.len))
  1180 + if (!dccp_feat_prefer(sysctl_dccp_tx_ccid, tx.val, tx.len) ||
  1181 + !dccp_feat_prefer(sysctl_dccp_rx_ccid, rx.val, rx.len))
1177 1182 goto free_ccid_lists;
1178 1183  
1179 1184 rc = __feat_register_sp(fn, DCCPF_CCID, true, false, tx.val, tx.len);
... ... @@ -100,6 +100,13 @@
100 100 u8 val;
101 101 };
102 102  
  103 +/*
  104 + * Sysctls to seed defaults for feature negotiation
  105 + */
  106 +extern unsigned long sysctl_dccp_sequence_window;
  107 +extern int sysctl_dccp_rx_ccid;
  108 +extern int sysctl_dccp_tx_ccid;
  109 +
103 110 #ifdef CONFIG_IP_DCCP_DEBUG
104 111 extern const char *dccp_feat_typename(const u8 type);
105 112 extern const char *dccp_feat_name(const u8 feat);
... ... @@ -114,6 +121,7 @@
114 121 #endif /* CONFIG_IP_DCCP_DEBUG */
115 122  
116 123 extern int dccp_feat_init(struct sock *sk);
  124 +extern void dccp_feat_initialise_sysctls(void);
117 125 extern int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
118 126 u8 const *list, u8 len);
119 127 extern int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val);
... ... @@ -23,10 +23,6 @@
23 23 #include "dccp.h"
24 24 #include "feat.h"
25 25  
26   -int sysctl_dccp_feat_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW;
27   -int sysctl_dccp_feat_rx_ccid = DCCPF_INITIAL_CCID;
28   -int sysctl_dccp_feat_tx_ccid = DCCPF_INITIAL_CCID;
29   -
30 26 u64 dccp_decode_value_var(const u8 *bf, const u8 len)
31 27 {
32 28 u64 value = 0;
... ... @@ -18,55 +18,72 @@
18 18 #error This file should not be compiled without CONFIG_SYSCTL defined
19 19 #endif
20 20  
  21 +/* Boundary values */
  22 +static int zero = 0,
  23 + u8_max = 0xFF;
  24 +static unsigned long seqw_min = 32;
  25 +
21 26 static struct ctl_table dccp_default_table[] = {
22 27 {
23 28 .procname = "seq_window",
24   - .data = &sysctl_dccp_feat_sequence_window,
25   - .maxlen = sizeof(sysctl_dccp_feat_sequence_window),
  29 + .data = &sysctl_dccp_sequence_window,
  30 + .maxlen = sizeof(sysctl_dccp_sequence_window),
26 31 .mode = 0644,
27   - .proc_handler = proc_dointvec,
  32 + .proc_handler = proc_doulongvec_minmax,
  33 + .extra1 = &seqw_min, /* RFC 4340, 7.5.2 */
28 34 },
29 35 {
30 36 .procname = "rx_ccid",
31   - .data = &sysctl_dccp_feat_rx_ccid,
32   - .maxlen = sizeof(sysctl_dccp_feat_rx_ccid),
  37 + .data = &sysctl_dccp_rx_ccid,
  38 + .maxlen = sizeof(sysctl_dccp_rx_ccid),
33 39 .mode = 0644,
34   - .proc_handler = proc_dointvec,
  40 + .proc_handler = proc_dointvec_minmax,
  41 + .extra1 = &zero,
  42 + .extra2 = &u8_max, /* RFC 4340, 10. */
35 43 },
36 44 {
37 45 .procname = "tx_ccid",
38   - .data = &sysctl_dccp_feat_tx_ccid,
39   - .maxlen = sizeof(sysctl_dccp_feat_tx_ccid),
  46 + .data = &sysctl_dccp_tx_ccid,
  47 + .maxlen = sizeof(sysctl_dccp_tx_ccid),
40 48 .mode = 0644,
41   - .proc_handler = proc_dointvec,
  49 + .proc_handler = proc_dointvec_minmax,
  50 + .extra1 = &zero,
  51 + .extra2 = &u8_max, /* RFC 4340, 10. */
42 52 },
43 53 {
44 54 .procname = "request_retries",
45 55 .data = &sysctl_dccp_request_retries,
46 56 .maxlen = sizeof(sysctl_dccp_request_retries),
47 57 .mode = 0644,
48   - .proc_handler = proc_dointvec,
  58 + .proc_handler = proc_dointvec_minmax,
  59 + .extra1 = &zero,
  60 + .extra2 = &u8_max,
49 61 },
50 62 {
51 63 .procname = "retries1",
52 64 .data = &sysctl_dccp_retries1,
53 65 .maxlen = sizeof(sysctl_dccp_retries1),
54 66 .mode = 0644,
55   - .proc_handler = proc_dointvec,
  67 + .proc_handler = proc_dointvec_minmax,
  68 + .extra1 = &zero,
  69 + .extra2 = &u8_max,
56 70 },
57 71 {
58 72 .procname = "retries2",
59 73 .data = &sysctl_dccp_retries2,
60 74 .maxlen = sizeof(sysctl_dccp_retries2),
61 75 .mode = 0644,
62   - .proc_handler = proc_dointvec,
  76 + .proc_handler = proc_dointvec_minmax,
  77 + .extra1 = &zero,
  78 + .extra2 = &u8_max,
63 79 },
64 80 {
65 81 .procname = "tx_qlen",
66 82 .data = &sysctl_dccp_tx_qlen,
67 83 .maxlen = sizeof(sysctl_dccp_tx_qlen),
68 84 .mode = 0644,
69   - .proc_handler = proc_dointvec,
  85 + .proc_handler = proc_dointvec_minmax,
  86 + .extra1 = &zero,
70 87 },
71 88 {
72 89 .procname = "sync_ratelimit",