aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/feat.c
diff options
context:
space:
mode:
authorGerrit Renker <gerrit@erg.abdn.ac.uk>2008-11-17 01:51:23 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-17 01:51:23 -0500
commit49aebc66d6b896f9c7c5739d85c4548c00015aa7 (patch)
tree0b12afdd2e742c3eb481aef8d2adcb7b1aeca9f1 /net/dccp/feat.c
parent0c1168398ecbfacbb27203b281bde20ec9f78017 (diff)
dccp: Deprecate old setsockopt framework
The previous setsockopt interface, which passed socket options via struct dccp_so_feat, is complicated/difficult to use. Continuing to support it leads to ugly code since the old approach did not distinguish between NN and SP values. This patch removes the old setsockopt interface and replaces it with two new functions to register NN/SP values for feature negotiation. These are essentially wrappers around the internal __feat_register functions, with checking added to avoid * wrong usage (type); * changing values while the connection is in progress. Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp/feat.c')
-rw-r--r--net/dccp/feat.c72
1 files changed, 27 insertions, 45 deletions
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index 4f86a48723f6..47ce9abaf72b 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -364,53 +364,35 @@ static int __feat_register_sp(struct list_head *fn, u8 feat, u8 is_local,
364 return dccp_feat_push_change(fn, feat, is_local, mandatory, &fval); 364 return dccp_feat_push_change(fn, feat, is_local, mandatory, &fval);
365} 365}
366 366
367int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature, 367/**
368 u8 *val, u8 len, gfp_t gfp) 368 * dccp_feat_register_sp - Register requests to change SP feature values
369{ 369 * @sk: client or listening socket
370 struct dccp_opt_pend *opt; 370 * @feat: one of %dccp_feature_numbers
371 371 * @is_local: whether the local (1) or remote (0) @feat is meant
372 dccp_feat_debug(type, feature, *val); 372 * @list: array of preferred values, in descending order of preference
373 373 * @len: length of @list in bytes
374 if (len > 3) { 374 */
375 DCCP_WARN("invalid length %d\n", len); 375int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
376 u8 const *list, u8 len)
377{ /* any changes must be registered before establishing the connection */
378 if (sk->sk_state != DCCP_CLOSED)
379 return -EISCONN;
380 if (dccp_feat_type(feat) != FEAT_SP)
376 return -EINVAL; 381 return -EINVAL;
377 } 382 return __feat_register_sp(&dccp_sk(sk)->dccps_featneg, feat, is_local,
378 /* XXX add further sanity checks */ 383 0, list, len);
379
380 /* check if that feature is already being negotiated */
381 list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) {
382 /* ok we found a negotiation for this option already */
383 if (opt->dccpop_feat == feature && opt->dccpop_type == type) {
384 dccp_pr_debug("Replacing old\n");
385 /* replace */
386 BUG_ON(opt->dccpop_val == NULL);
387 kfree(opt->dccpop_val);
388 opt->dccpop_val = val;
389 opt->dccpop_len = len;
390 opt->dccpop_conf = 0;
391 return 0;
392 }
393 }
394
395 /* negotiation for a new feature */
396 opt = kmalloc(sizeof(*opt), gfp);
397 if (opt == NULL)
398 return -ENOMEM;
399
400 opt->dccpop_type = type;
401 opt->dccpop_feat = feature;
402 opt->dccpop_len = len;
403 opt->dccpop_val = val;
404 opt->dccpop_conf = 0;
405 opt->dccpop_sc = NULL;
406
407 BUG_ON(opt->dccpop_val == NULL);
408
409 list_add_tail(&opt->dccpop_node, &dmsk->dccpms_pending);
410 return 0;
411} 384}
412 385
413EXPORT_SYMBOL_GPL(dccp_feat_change); 386/* Analogous to dccp_feat_register_sp(), but for non-negotiable values */
387int dccp_feat_register_nn(struct sock *sk, u8 feat, u64 val)
388{
389 /* any changes must be registered before establishing the connection */
390 if (sk->sk_state != DCCP_CLOSED)
391 return -EISCONN;
392 if (dccp_feat_type(feat) != FEAT_NN)
393 return -EINVAL;
394 return __feat_register_nn(&dccp_sk(sk)->dccps_featneg, feat, 0, val);
395}
414 396
415/* 397/*
416 * Tracking features whose value depend on the choice of CCID 398 * Tracking features whose value depend on the choice of CCID
@@ -1108,7 +1090,7 @@ int dccp_feat_init(struct sock *sk)
1108 1090
1109 /* Ack ratio */ 1091 /* Ack ratio */
1110 rc = __feat_register_nn(&dp->dccps_featneg, DCCPF_ACK_RATIO, 0, 1092 rc = __feat_register_nn(&dp->dccps_featneg, DCCPF_ACK_RATIO, 0,
1111 dmsk->dccpms_ack_ratio); 1093 dp->dccps_l_ack_ratio);
1112out: 1094out:
1113 return rc; 1095 return rc;
1114} 1096}