Commit 883ca833 authored by Gerrit Renker's avatar Gerrit Renker Committed by David S. Miller

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: default avatarGerrit Renker <gerrit@erg.abdn.ac.uk>
Acked-by: default avatarIan McDonald <ian.mcdonald@jandi.co.nz>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 792b4878
...@@ -355,14 +355,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb) ...@@ -355,14 +355,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
return __dccp_hdr_len(dccp_hdr(skb)); return __dccp_hdr_len(dccp_hdr(skb));
} }
/* initial values for each feature */
#define DCCPF_INITIAL_SEQUENCE_WINDOW 100
#define DCCPF_INITIAL_ACK_RATIO 2
#define DCCPF_INITIAL_CCID DCCPC_CCID2
/* FIXME: for now we're default to 1 but it should really be 0 */
#define DCCPF_INITIAL_SEND_NDP_COUNT 1
/** /**
* struct dccp_request_sock - represent DCCP-specific connection request * struct dccp_request_sock - represent DCCP-specific connection request
* @dreq_inet_rsk: structure inherited from * @dreq_inet_rsk: structure inherited from
......
...@@ -95,9 +95,6 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo); ...@@ -95,9 +95,6 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo);
extern int sysctl_dccp_request_retries; extern int sysctl_dccp_request_retries;
extern int sysctl_dccp_retries1; extern int sysctl_dccp_retries1;
extern int sysctl_dccp_retries2; extern int sysctl_dccp_retries2;
extern int sysctl_dccp_feat_sequence_window;
extern int sysctl_dccp_feat_rx_ccid;
extern int sysctl_dccp_feat_tx_ccid;
extern int sysctl_dccp_tx_qlen; extern int sysctl_dccp_tx_qlen;
extern int sysctl_dccp_sync_ratelimit; extern int sysctl_dccp_sync_ratelimit;
......
...@@ -25,6 +25,11 @@ ...@@ -25,6 +25,11 @@
#include "ccid.h" #include "ccid.h"
#include "feat.h" #include "feat.h"
/* feature-specific sysctls - initialised to the defaults from RFC 4340, 6.4 */
unsigned long sysctl_dccp_sequence_window __read_mostly = 100;
int sysctl_dccp_rx_ccid __read_mostly = 2,
sysctl_dccp_tx_ccid __read_mostly = 2;
/* /*
* Feature activation handlers. * Feature activation handlers.
* *
...@@ -1146,7 +1151,7 @@ int dccp_feat_init(struct sock *sk) ...@@ -1146,7 +1151,7 @@ int dccp_feat_init(struct sock *sk)
/* Non-negotiable (NN) features */ /* Non-negotiable (NN) features */
rc = __feat_register_nn(fn, DCCPF_SEQUENCE_WINDOW, 0, rc = __feat_register_nn(fn, DCCPF_SEQUENCE_WINDOW, 0,
sysctl_dccp_feat_sequence_window); sysctl_dccp_sequence_window);
if (rc) if (rc)
return rc; return rc;
...@@ -1172,8 +1177,8 @@ int dccp_feat_init(struct sock *sk) ...@@ -1172,8 +1177,8 @@ int dccp_feat_init(struct sock *sk)
ccid_get_builtin_ccids(&rx.val, &rx.len)) ccid_get_builtin_ccids(&rx.val, &rx.len))
return -ENOBUFS; return -ENOBUFS;
if (!dccp_feat_prefer(sysctl_dccp_feat_tx_ccid, tx.val, tx.len) || if (!dccp_feat_prefer(sysctl_dccp_tx_ccid, tx.val, tx.len) ||
!dccp_feat_prefer(sysctl_dccp_feat_rx_ccid, rx.val, rx.len)) !dccp_feat_prefer(sysctl_dccp_rx_ccid, rx.val, rx.len))
goto free_ccid_lists; goto free_ccid_lists;
rc = __feat_register_sp(fn, DCCPF_CCID, true, false, tx.val, tx.len); rc = __feat_register_sp(fn, DCCPF_CCID, true, false, tx.val, tx.len);
......
...@@ -100,6 +100,13 @@ struct ccid_dependency { ...@@ -100,6 +100,13 @@ struct ccid_dependency {
u8 val; u8 val;
}; };
/*
* Sysctls to seed defaults for feature negotiation
*/
extern unsigned long sysctl_dccp_sequence_window;
extern int sysctl_dccp_rx_ccid;
extern int sysctl_dccp_tx_ccid;
#ifdef CONFIG_IP_DCCP_DEBUG #ifdef CONFIG_IP_DCCP_DEBUG
extern const char *dccp_feat_typename(const u8 type); extern const char *dccp_feat_typename(const u8 type);
extern const char *dccp_feat_name(const u8 feat); extern const char *dccp_feat_name(const u8 feat);
...@@ -114,6 +121,7 @@ static inline void dccp_feat_debug(const u8 type, const u8 feat, const u8 val) ...@@ -114,6 +121,7 @@ static inline void dccp_feat_debug(const u8 type, const u8 feat, const u8 val)
#endif /* CONFIG_IP_DCCP_DEBUG */ #endif /* CONFIG_IP_DCCP_DEBUG */
extern int dccp_feat_init(struct sock *sk); extern int dccp_feat_init(struct sock *sk);
extern void dccp_feat_initialise_sysctls(void);
extern int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local, extern int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
u8 const *list, u8 len); u8 const *list, u8 len);
extern int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val); extern int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val);
......
...@@ -23,10 +23,6 @@ ...@@ -23,10 +23,6 @@
#include "dccp.h" #include "dccp.h"
#include "feat.h" #include "feat.h"
int sysctl_dccp_feat_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW;
int sysctl_dccp_feat_rx_ccid = DCCPF_INITIAL_CCID;
int sysctl_dccp_feat_tx_ccid = DCCPF_INITIAL_CCID;
u64 dccp_decode_value_var(const u8 *bf, const u8 len) u64 dccp_decode_value_var(const u8 *bf, const u8 len)
{ {
u64 value = 0; u64 value = 0;
......
...@@ -18,55 +18,72 @@ ...@@ -18,55 +18,72 @@
#error This file should not be compiled without CONFIG_SYSCTL defined #error This file should not be compiled without CONFIG_SYSCTL defined
#endif #endif
/* Boundary values */
static int zero = 0,
u8_max = 0xFF;
static unsigned long seqw_min = 32;
static struct ctl_table dccp_default_table[] = { static struct ctl_table dccp_default_table[] = {
{ {
.procname = "seq_window", .procname = "seq_window",
.data = &sysctl_dccp_feat_sequence_window, .data = &sysctl_dccp_sequence_window,
.maxlen = sizeof(sysctl_dccp_feat_sequence_window), .maxlen = sizeof(sysctl_dccp_sequence_window),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_doulongvec_minmax,
.extra1 = &seqw_min, /* RFC 4340, 7.5.2 */
}, },
{ {
.procname = "rx_ccid", .procname = "rx_ccid",
.data = &sysctl_dccp_feat_rx_ccid, .data = &sysctl_dccp_rx_ccid,
.maxlen = sizeof(sysctl_dccp_feat_rx_ccid), .maxlen = sizeof(sysctl_dccp_rx_ccid),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
.extra2 = &u8_max, /* RFC 4340, 10. */
}, },
{ {
.procname = "tx_ccid", .procname = "tx_ccid",
.data = &sysctl_dccp_feat_tx_ccid, .data = &sysctl_dccp_tx_ccid,
.maxlen = sizeof(sysctl_dccp_feat_tx_ccid), .maxlen = sizeof(sysctl_dccp_tx_ccid),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
.extra2 = &u8_max, /* RFC 4340, 10. */
}, },
{ {
.procname = "request_retries", .procname = "request_retries",
.data = &sysctl_dccp_request_retries, .data = &sysctl_dccp_request_retries,
.maxlen = sizeof(sysctl_dccp_request_retries), .maxlen = sizeof(sysctl_dccp_request_retries),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
.extra2 = &u8_max,
}, },
{ {
.procname = "retries1", .procname = "retries1",
.data = &sysctl_dccp_retries1, .data = &sysctl_dccp_retries1,
.maxlen = sizeof(sysctl_dccp_retries1), .maxlen = sizeof(sysctl_dccp_retries1),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
.extra2 = &u8_max,
}, },
{ {
.procname = "retries2", .procname = "retries2",
.data = &sysctl_dccp_retries2, .data = &sysctl_dccp_retries2,
.maxlen = sizeof(sysctl_dccp_retries2), .maxlen = sizeof(sysctl_dccp_retries2),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
.extra2 = &u8_max,
}, },
{ {
.procname = "tx_qlen", .procname = "tx_qlen",
.data = &sysctl_dccp_tx_qlen, .data = &sysctl_dccp_tx_qlen,
.maxlen = sizeof(sysctl_dccp_tx_qlen), .maxlen = sizeof(sysctl_dccp_tx_qlen),
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
}, },
{ {
.procname = "sync_ratelimit", .procname = "sync_ratelimit",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment