192d494a381645029c970d1ceac86da69d908e96
[safe/jmp/linux-2.6] / net / dccp / feat.c
1 /*
2  *  net/dccp/feat.c
3  *
4  *  An implementation of the DCCP protocol
5  *  Andrea Bittau <a.bittau@cs.ucl.ac.uk>
6  *
7  *  ASSUMPTIONS
8  *  -----------
9  *  o Feature negotiation is coordinated with connection setup (as in TCP), wild
10  *    changes of parameters of an established connection are not supported.
11  *  o All currently known SP features have 1-byte quantities. If in the future
12  *    extensions of RFCs 4340..42 define features with item lengths larger than
13  *    one byte, a feature-specific extension of the code will be required.
14  *
15  *  This program is free software; you can redistribute it and/or
16  *  modify it under the terms of the GNU General Public License
17  *  as published by the Free Software Foundation; either version
18  *  2 of the License, or (at your option) any later version.
19  */
20
21 #include <linux/module.h>
22
23 #include "ccid.h"
24 #include "feat.h"
25
26 #define DCCP_FEAT_SP_NOAGREE (-123)
27
28 static const struct {
29         u8                      feat_num;               /* DCCPF_xxx */
30         enum dccp_feat_type     rxtx;                   /* RX or TX  */
31         enum dccp_feat_type     reconciliation;         /* SP or NN  */
32         u8                      default_value;          /* as in 6.4 */
33 /*
34  *    Lookup table for location and type of features (from RFC 4340/4342)
35  *  +--------------------------+----+-----+----+----+---------+-----------+
36  *  | Feature                  | Location | Reconc. | Initial |  Section  |
37  *  |                          | RX | TX  | SP | NN |  Value  | Reference |
38  *  +--------------------------+----+-----+----+----+---------+-----------+
39  *  | DCCPF_CCID               |    |  X  | X  |    |   2     | 10        |
40  *  | DCCPF_SHORT_SEQNOS       |    |  X  | X  |    |   0     |  7.6.1    |
41  *  | DCCPF_SEQUENCE_WINDOW    |    |  X  |    | X  | 100     |  7.5.2    |
42  *  | DCCPF_ECN_INCAPABLE      | X  |     | X  |    |   0     | 12.1      |
43  *  | DCCPF_ACK_RATIO          |    |  X  |    | X  |   2     | 11.3      |
44  *  | DCCPF_SEND_ACK_VECTOR    | X  |     | X  |    |   0     | 11.5      |
45  *  | DCCPF_SEND_NDP_COUNT     |    |  X  | X  |    |   0     |  7.7.2    |
46  *  | DCCPF_MIN_CSUM_COVER     | X  |     | X  |    |   0     |  9.2.1    |
47  *  | DCCPF_DATA_CHECKSUM      | X  |     | X  |    |   0     |  9.3.1    |
48  *  | DCCPF_SEND_LEV_RATE      | X  |     | X  |    |   0     | 4342/8.4  |
49  *  +--------------------------+----+-----+----+----+---------+-----------+
50  */
51 } dccp_feat_table[] = {
52         { DCCPF_CCID,            FEAT_AT_TX, FEAT_SP, 2 },
53         { DCCPF_SHORT_SEQNOS,    FEAT_AT_TX, FEAT_SP, 0 },
54         { DCCPF_SEQUENCE_WINDOW, FEAT_AT_TX, FEAT_NN, 100 },
55         { DCCPF_ECN_INCAPABLE,   FEAT_AT_RX, FEAT_SP, 0 },
56         { DCCPF_ACK_RATIO,       FEAT_AT_TX, FEAT_NN, 2 },
57         { DCCPF_SEND_ACK_VECTOR, FEAT_AT_RX, FEAT_SP, 0 },
58         { DCCPF_SEND_NDP_COUNT,  FEAT_AT_TX, FEAT_SP, 0 },
59         { DCCPF_MIN_CSUM_COVER,  FEAT_AT_RX, FEAT_SP, 0 },
60         { DCCPF_DATA_CHECKSUM,   FEAT_AT_RX, FEAT_SP, 0 },
61         { DCCPF_SEND_LEV_RATE,   FEAT_AT_RX, FEAT_SP, 0 },
62 };
63 #define DCCP_FEAT_SUPPORTED_MAX         ARRAY_SIZE(dccp_feat_table)
64
65 /**
66  * dccp_feat_index  -  Hash function to map feature number into array position
67  * Returns consecutive array index or -1 if the feature is not understood.
68  */
69 static int dccp_feat_index(u8 feat_num)
70 {
71         /* The first 9 entries are occupied by the types from RFC 4340, 6.4 */
72         if (feat_num > DCCPF_RESERVED && feat_num <= DCCPF_DATA_CHECKSUM)
73                 return feat_num - 1;
74
75         /*
76          * Other features: add cases for new feature types here after adding
77          * them to the above table.
78          */
79         switch (feat_num) {
80         case DCCPF_SEND_LEV_RATE:
81                         return DCCP_FEAT_SUPPORTED_MAX - 1;
82         }
83         return -1;
84 }
85
86 static u8 dccp_feat_type(u8 feat_num)
87 {
88         int idx = dccp_feat_index(feat_num);
89
90         if (idx < 0)
91                 return FEAT_UNKNOWN;
92         return dccp_feat_table[idx].reconciliation;
93 }
94
95 static int dccp_feat_default_value(u8 feat_num)
96 {
97         int idx = dccp_feat_index(feat_num);
98         /*
99          * There are no default values for unknown features, so encountering a
100          * negative index here indicates a serious problem somewhere else.
101          */
102         DCCP_BUG_ON(idx < 0);
103
104         return idx < 0 ? 0 : dccp_feat_table[idx].default_value;
105 }
106
107 /* copy constructor, fval must not already contain allocated memory */
108 static int dccp_feat_clone_sp_val(dccp_feat_val *fval, u8 const *val, u8 len)
109 {
110         fval->sp.len = len;
111         if (fval->sp.len > 0) {
112                 fval->sp.vec = kmemdup(val, len, gfp_any());
113                 if (fval->sp.vec == NULL) {
114                         fval->sp.len = 0;
115                         return -ENOBUFS;
116                 }
117         }
118         return 0;
119 }
120
121 static void dccp_feat_val_destructor(u8 feat_num, dccp_feat_val *val)
122 {
123         if (unlikely(val == NULL))
124                 return;
125         if (dccp_feat_type(feat_num) == FEAT_SP)
126                 kfree(val->sp.vec);
127         memset(val, 0, sizeof(*val));
128 }
129
130 static struct dccp_feat_entry *
131               dccp_feat_clone_entry(struct dccp_feat_entry const *original)
132 {
133         struct dccp_feat_entry *new;
134         u8 type = dccp_feat_type(original->feat_num);
135
136         if (type == FEAT_UNKNOWN)
137                 return NULL;
138
139         new = kmemdup(original, sizeof(struct dccp_feat_entry), gfp_any());
140         if (new == NULL)
141                 return NULL;
142
143         if (type == FEAT_SP && dccp_feat_clone_sp_val(&new->val,
144                                                       original->val.sp.vec,
145                                                       original->val.sp.len)) {
146                 kfree(new);
147                 return NULL;
148         }
149         return new;
150 }
151
152 static void dccp_feat_entry_destructor(struct dccp_feat_entry *entry)
153 {
154         if (entry != NULL) {
155                 dccp_feat_val_destructor(entry->feat_num, &entry->val);
156                 kfree(entry);
157         }
158 }
159
160 /*
161  * List management functions
162  *
163  * Feature negotiation lists rely on and maintain the following invariants:
164  * - each feat_num in the list is known, i.e. we know its type and default value
165  * - each feat_num/is_local combination is unique (old entries are overwritten)
166  * - SP values are always freshly allocated
167  * - list is sorted in increasing order of feature number (faster lookup)
168  */
169
170 /**
171  * dccp_feat_entry_new  -  Central list update routine (called by all others)
172  * @head:  list to add to
173  * @feat:  feature number
174  * @local: whether the local (1) or remote feature with number @feat is meant
175  * This is the only constructor and serves to ensure the above invariants.
176  */
177 static struct dccp_feat_entry *
178               dccp_feat_entry_new(struct list_head *head, u8 feat, bool local)
179 {
180         struct dccp_feat_entry *entry;
181
182         list_for_each_entry(entry, head, node)
183                 if (entry->feat_num == feat && entry->is_local == local) {
184                         dccp_feat_val_destructor(entry->feat_num, &entry->val);
185                         return entry;
186                 } else if (entry->feat_num > feat) {
187                         head = &entry->node;
188                         break;
189                 }
190
191         entry = kmalloc(sizeof(*entry), gfp_any());
192         if (entry != NULL) {
193                 entry->feat_num = feat;
194                 entry->is_local = local;
195                 list_add_tail(&entry->node, head);
196         }
197         return entry;
198 }
199
200 /**
201  * dccp_feat_push_change  -  Add/overwrite a Change option in the list
202  * @fn_list: feature-negotiation list to update
203  * @feat: one of %dccp_feature_numbers
204  * @local: whether local (1) or remote (0) @feat_num is meant
205  * @needs_mandatory: whether to use Mandatory feature negotiation options
206  * @fval: pointer to NN/SP value to be inserted (will be copied)
207  */
208 static int dccp_feat_push_change(struct list_head *fn_list, u8 feat, u8 local,
209                                  u8 mandatory, dccp_feat_val *fval)
210 {
211         struct dccp_feat_entry *new = dccp_feat_entry_new(fn_list, feat, local);
212
213         if (new == NULL)
214                 return -ENOMEM;
215
216         new->feat_num        = feat;
217         new->is_local        = local;
218         new->state           = FEAT_INITIALISING;
219         new->needs_confirm   = 0;
220         new->empty_confirm   = 0;
221         new->val             = *fval;
222         new->needs_mandatory = mandatory;
223
224         return 0;
225 }
226
227 static inline void dccp_feat_list_pop(struct dccp_feat_entry *entry)
228 {
229         list_del(&entry->node);
230         dccp_feat_entry_destructor(entry);
231 }
232
233 void dccp_feat_list_purge(struct list_head *fn_list)
234 {
235         struct dccp_feat_entry *entry, *next;
236
237         list_for_each_entry_safe(entry, next, fn_list, node)
238                 dccp_feat_entry_destructor(entry);
239         INIT_LIST_HEAD(fn_list);
240 }
241 EXPORT_SYMBOL_GPL(dccp_feat_list_purge);
242
243 /* generate @to as full clone of @from - @to must not contain any nodes */
244 int dccp_feat_clone_list(struct list_head const *from, struct list_head *to)
245 {
246         struct dccp_feat_entry *entry, *new;
247
248         INIT_LIST_HEAD(to);
249         list_for_each_entry(entry, from, node) {
250                 new = dccp_feat_clone_entry(entry);
251                 if (new == NULL)
252                         goto cloning_failed;
253                 list_add_tail(&new->node, to);
254         }
255         return 0;
256
257 cloning_failed:
258         dccp_feat_list_purge(to);
259         return -ENOMEM;
260 }
261
262 static u8 dccp_feat_is_valid_nn_val(u8 feat_num, u64 val)
263 {
264         switch (feat_num) {
265         case DCCPF_ACK_RATIO:
266                 return val <= DCCPF_ACK_RATIO_MAX;
267         case DCCPF_SEQUENCE_WINDOW:
268                 return val >= DCCPF_SEQ_WMIN && val <= DCCPF_SEQ_WMAX;
269         }
270         return 0;       /* feature unknown - so we can't tell */
271 }
272
273 /* check that SP values are within the ranges defined in RFC 4340 */
274 static u8 dccp_feat_is_valid_sp_val(u8 feat_num, u8 val)
275 {
276         switch (feat_num) {
277         case DCCPF_CCID:
278                 return val == DCCPC_CCID2 || val == DCCPC_CCID3;
279         /* Type-check Boolean feature values: */
280         case DCCPF_SHORT_SEQNOS:
281         case DCCPF_ECN_INCAPABLE:
282         case DCCPF_SEND_ACK_VECTOR:
283         case DCCPF_SEND_NDP_COUNT:
284         case DCCPF_DATA_CHECKSUM:
285         case DCCPF_SEND_LEV_RATE:
286                 return val < 2;
287         case DCCPF_MIN_CSUM_COVER:
288                 return val < 16;
289         }
290         return 0;                       /* feature unknown */
291 }
292
293 static u8 dccp_feat_sp_list_ok(u8 feat_num, u8 const *sp_list, u8 sp_len)
294 {
295         if (sp_list == NULL || sp_len < 1)
296                 return 0;
297         while (sp_len--)
298                 if (!dccp_feat_is_valid_sp_val(feat_num, *sp_list++))
299                         return 0;
300         return 1;
301 }
302
303 /**
304  * __feat_register_nn  -  Register new NN value on socket
305  * @fn: feature-negotiation list to register with
306  * @feat: an NN feature from %dccp_feature_numbers
307  * @mandatory: use Mandatory option if 1
308  * @nn_val: value to register (restricted to 4 bytes)
309  * Note that NN features are local by definition (RFC 4340, 6.3.2).
310  */
311 static int __feat_register_nn(struct list_head *fn, u8 feat,
312                               u8 mandatory, u64 nn_val)
313 {
314         dccp_feat_val fval = { .nn = nn_val };
315
316         if (dccp_feat_type(feat) != FEAT_NN ||
317             !dccp_feat_is_valid_nn_val(feat, nn_val))
318                 return -EINVAL;
319
320         /* Don't bother with default values, they will be activated anyway. */
321         if (nn_val - (u64)dccp_feat_default_value(feat) == 0)
322                 return 0;
323
324         return dccp_feat_push_change(fn, feat, 1, mandatory, &fval);
325 }
326
327 /**
328  * __feat_register_sp  -  Register new SP value/list on socket
329  * @fn: feature-negotiation list to register with
330  * @feat: an SP feature from %dccp_feature_numbers
331  * @is_local: whether the local (1) or the remote (0) @feat is meant
332  * @mandatory: use Mandatory option if 1
333  * @sp_val: SP value followed by optional preference list
334  * @sp_len: length of @sp_val in bytes
335  */
336 static int __feat_register_sp(struct list_head *fn, u8 feat, u8 is_local,
337                               u8 mandatory, u8 const *sp_val, u8 sp_len)
338 {
339         dccp_feat_val fval;
340
341         if (dccp_feat_type(feat) != FEAT_SP ||
342             !dccp_feat_sp_list_ok(feat, sp_val, sp_len))
343                 return -EINVAL;
344
345         if (dccp_feat_clone_sp_val(&fval, sp_val, sp_len))
346                 return -ENOMEM;
347
348         return dccp_feat_push_change(fn, feat, is_local, mandatory, &fval);
349 }
350
351 int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
352                      u8 *val, u8 len, gfp_t gfp)
353 {
354         struct dccp_opt_pend *opt;
355
356         dccp_feat_debug(type, feature, *val);
357
358         if (len > 3) {
359                 DCCP_WARN("invalid length %d\n", len);
360                 return -EINVAL;
361         }
362         /* XXX add further sanity checks */
363
364         /* check if that feature is already being negotiated */
365         list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) {
366                 /* ok we found a negotiation for this option already */
367                 if (opt->dccpop_feat == feature && opt->dccpop_type == type) {
368                         dccp_pr_debug("Replacing old\n");
369                         /* replace */
370                         BUG_ON(opt->dccpop_val == NULL);
371                         kfree(opt->dccpop_val);
372                         opt->dccpop_val  = val;
373                         opt->dccpop_len  = len;
374                         opt->dccpop_conf = 0;
375                         return 0;
376                 }
377         }
378
379         /* negotiation for a new feature */
380         opt = kmalloc(sizeof(*opt), gfp);
381         if (opt == NULL)
382                 return -ENOMEM;
383
384         opt->dccpop_type = type;
385         opt->dccpop_feat = feature;
386         opt->dccpop_len  = len;
387         opt->dccpop_val  = val;
388         opt->dccpop_conf = 0;
389         opt->dccpop_sc   = NULL;
390
391         BUG_ON(opt->dccpop_val == NULL);
392
393         list_add_tail(&opt->dccpop_node, &dmsk->dccpms_pending);
394         return 0;
395 }
396
397 EXPORT_SYMBOL_GPL(dccp_feat_change);
398
399 static int dccp_feat_update_ccid(struct sock *sk, u8 type, u8 new_ccid_nr)
400 {
401         struct dccp_sock *dp = dccp_sk(sk);
402         struct dccp_minisock *dmsk = dccp_msk(sk);
403         /* figure out if we are changing our CCID or the peer's */
404         const int rx = type == DCCPO_CHANGE_R;
405         const u8 ccid_nr = rx ? dmsk->dccpms_rx_ccid : dmsk->dccpms_tx_ccid;
406         struct ccid *new_ccid;
407
408         /* Check if nothing is being changed. */
409         if (ccid_nr == new_ccid_nr)
410                 return 0;
411
412         new_ccid = ccid_new(new_ccid_nr, sk, rx, GFP_ATOMIC);
413         if (new_ccid == NULL)
414                 return -ENOMEM;
415
416         if (rx) {
417                 ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
418                 dp->dccps_hc_rx_ccid = new_ccid;
419                 dmsk->dccpms_rx_ccid = new_ccid_nr;
420         } else {
421                 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
422                 dp->dccps_hc_tx_ccid = new_ccid;
423                 dmsk->dccpms_tx_ccid = new_ccid_nr;
424         }
425
426         return 0;
427 }
428
429 static int dccp_feat_update(struct sock *sk, u8 type, u8 feat, u8 val)
430 {
431         dccp_feat_debug(type, feat, val);
432
433         switch (feat) {
434         case DCCPF_CCID:
435                 return dccp_feat_update_ccid(sk, type, val);
436         default:
437                 dccp_pr_debug("UNIMPLEMENTED: %s(%d, ...)\n",
438                               dccp_feat_typename(type), feat);
439                 break;
440         }
441         return 0;
442 }
443
444 static int dccp_feat_reconcile(struct sock *sk, struct dccp_opt_pend *opt,
445                                u8 *rpref, u8 rlen)
446 {
447         struct dccp_sock *dp = dccp_sk(sk);
448         u8 *spref, slen, *res = NULL;
449         int i, j, rc, agree = 1;
450
451         BUG_ON(rpref == NULL);
452
453         /* check if we are the black sheep */
454         if (dp->dccps_role == DCCP_ROLE_CLIENT) {
455                 spref = rpref;
456                 slen  = rlen;
457                 rpref = opt->dccpop_val;
458                 rlen  = opt->dccpop_len;
459         } else {
460                 spref = opt->dccpop_val;
461                 slen  = opt->dccpop_len;
462         }
463         /*
464          * Now we have server preference list in spref and client preference in
465          * rpref
466          */
467         BUG_ON(spref == NULL);
468         BUG_ON(rpref == NULL);
469
470         /* FIXME sanity check vals */
471
472         /* Are values in any order?  XXX Lame "algorithm" here */
473         for (i = 0; i < slen; i++) {
474                 for (j = 0; j < rlen; j++) {
475                         if (spref[i] == rpref[j]) {
476                                 res = &spref[i];
477                                 break;
478                         }
479                 }
480                 if (res)
481                         break;
482         }
483
484         /* we didn't agree on anything */
485         if (res == NULL) {
486                 /* confirm previous value */
487                 switch (opt->dccpop_feat) {
488                 case DCCPF_CCID:
489                         /* XXX did i get this right? =P */
490                         if (opt->dccpop_type == DCCPO_CHANGE_L)
491                                 res = &dccp_msk(sk)->dccpms_tx_ccid;
492                         else
493                                 res = &dccp_msk(sk)->dccpms_rx_ccid;
494                         break;
495
496                 default:
497                         DCCP_BUG("Fell through, feat=%d", opt->dccpop_feat);
498                         /* XXX implement res */
499                         return -EFAULT;
500                 }
501
502                 dccp_pr_debug("Don't agree... reconfirming %d\n", *res);
503                 agree = 0; /* this is used for mandatory options... */
504         }
505
506         /* need to put result and our preference list */
507         rlen = 1 + opt->dccpop_len;
508         rpref = kmalloc(rlen, GFP_ATOMIC);
509         if (rpref == NULL)
510                 return -ENOMEM;
511
512         *rpref = *res;
513         memcpy(&rpref[1], opt->dccpop_val, opt->dccpop_len);
514
515         /* put it in the "confirm queue" */
516         if (opt->dccpop_sc == NULL) {
517                 opt->dccpop_sc = kmalloc(sizeof(*opt->dccpop_sc), GFP_ATOMIC);
518                 if (opt->dccpop_sc == NULL) {
519                         kfree(rpref);
520                         return -ENOMEM;
521                 }
522         } else {
523                 /* recycle the confirm slot */
524                 BUG_ON(opt->dccpop_sc->dccpoc_val == NULL);
525                 kfree(opt->dccpop_sc->dccpoc_val);
526                 dccp_pr_debug("recycling confirm slot\n");
527         }
528         memset(opt->dccpop_sc, 0, sizeof(*opt->dccpop_sc));
529
530         opt->dccpop_sc->dccpoc_val = rpref;
531         opt->dccpop_sc->dccpoc_len = rlen;
532
533         /* update the option on our side [we are about to send the confirm] */
534         rc = dccp_feat_update(sk, opt->dccpop_type, opt->dccpop_feat, *res);
535         if (rc) {
536                 kfree(opt->dccpop_sc->dccpoc_val);
537                 kfree(opt->dccpop_sc);
538                 opt->dccpop_sc = NULL;
539                 return rc;
540         }
541
542         dccp_pr_debug("Will confirm %d\n", *rpref);
543
544         /* say we want to change to X but we just got a confirm X, suppress our
545          * change
546          */
547         if (!opt->dccpop_conf) {
548                 if (*opt->dccpop_val == *res)
549                         opt->dccpop_conf = 1;
550                 dccp_pr_debug("won't ask for change of same feature\n");
551         }
552
553         return agree ? 0 : DCCP_FEAT_SP_NOAGREE; /* used for mandatory opts */
554 }
555
556 static int dccp_feat_sp(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
557 {
558         struct dccp_minisock *dmsk = dccp_msk(sk);
559         struct dccp_opt_pend *opt;
560         int rc = 1;
561         u8 t;
562
563         /*
564          * We received a CHANGE.  We gotta match it against our own preference
565          * list.  If we got a CHANGE_R it means it's a change for us, so we need
566          * to compare our CHANGE_L list.
567          */
568         if (type == DCCPO_CHANGE_L)
569                 t = DCCPO_CHANGE_R;
570         else
571                 t = DCCPO_CHANGE_L;
572
573         /* find our preference list for this feature */
574         list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) {
575                 if (opt->dccpop_type != t || opt->dccpop_feat != feature)
576                         continue;
577
578                 /* find the winner from the two preference lists */
579                 rc = dccp_feat_reconcile(sk, opt, val, len);
580                 break;
581         }
582
583         /* We didn't deal with the change.  This can happen if we have no
584          * preference list for the feature.  In fact, it just shouldn't
585          * happen---if we understand a feature, we should have a preference list
586          * with at least the default value.
587          */
588         BUG_ON(rc == 1);
589
590         return rc;
591 }
592
593 static int dccp_feat_nn(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
594 {
595         struct dccp_opt_pend *opt;
596         struct dccp_minisock *dmsk = dccp_msk(sk);
597         u8 *copy;
598         int rc;
599
600         /* NN features must be Change L (sec. 6.3.2) */
601         if (type != DCCPO_CHANGE_L) {
602                 dccp_pr_debug("received %s for NN feature %d\n",
603                                 dccp_feat_typename(type), feature);
604                 return -EFAULT;
605         }
606
607         /* XXX sanity check opt val */
608
609         /* copy option so we can confirm it */
610         opt = kzalloc(sizeof(*opt), GFP_ATOMIC);
611         if (opt == NULL)
612                 return -ENOMEM;
613
614         copy = kmemdup(val, len, GFP_ATOMIC);
615         if (copy == NULL) {
616                 kfree(opt);
617                 return -ENOMEM;
618         }
619
620         opt->dccpop_type = DCCPO_CONFIRM_R; /* NN can only confirm R */
621         opt->dccpop_feat = feature;
622         opt->dccpop_val  = copy;
623         opt->dccpop_len  = len;
624
625         /* change feature */
626         rc = dccp_feat_update(sk, type, feature, *val);
627         if (rc) {
628                 kfree(opt->dccpop_val);
629                 kfree(opt);
630                 return rc;
631         }
632
633         dccp_feat_debug(type, feature, *copy);
634
635         list_add_tail(&opt->dccpop_node, &dmsk->dccpms_conf);
636
637         return 0;
638 }
639
640 static void dccp_feat_empty_confirm(struct dccp_minisock *dmsk,
641                                     u8 type, u8 feature)
642 {
643         /* XXX check if other confirms for that are queued and recycle slot */
644         struct dccp_opt_pend *opt = kzalloc(sizeof(*opt), GFP_ATOMIC);
645
646         if (opt == NULL) {
647                 /* XXX what do we do?  Ignoring should be fine.  It's a change
648                  * after all =P
649                  */
650                 return;
651         }
652
653         switch (type) {
654         case DCCPO_CHANGE_L:
655                 opt->dccpop_type = DCCPO_CONFIRM_R;
656                 break;
657         case DCCPO_CHANGE_R:
658                 opt->dccpop_type = DCCPO_CONFIRM_L;
659                 break;
660         default:
661                 DCCP_WARN("invalid type %d\n", type);
662                 kfree(opt);
663                 return;
664         }
665         opt->dccpop_feat = feature;
666         opt->dccpop_val  = NULL;
667         opt->dccpop_len  = 0;
668
669         /* change feature */
670         dccp_pr_debug("Empty %s(%d)\n", dccp_feat_typename(type), feature);
671
672         list_add_tail(&opt->dccpop_node, &dmsk->dccpms_conf);
673 }
674
675 static void dccp_feat_flush_confirm(struct sock *sk)
676 {
677         struct dccp_minisock *dmsk = dccp_msk(sk);
678         /* Check if there is anything to confirm in the first place */
679         int yes = !list_empty(&dmsk->dccpms_conf);
680
681         if (!yes) {
682                 struct dccp_opt_pend *opt;
683
684                 list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) {
685                         if (opt->dccpop_conf) {
686                                 yes = 1;
687                                 break;
688                         }
689                 }
690         }
691
692         if (!yes)
693                 return;
694
695         /* OK there is something to confirm... */
696         /* XXX check if packet is in flight?  Send delayed ack?? */
697         if (sk->sk_state == DCCP_OPEN)
698                 dccp_send_ack(sk);
699 }
700
701 int dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
702 {
703         int rc;
704
705         /* Ignore Change requests other than during connection setup */
706         if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING)
707                 return 0;
708         dccp_feat_debug(type, feature, *val);
709
710         /* figure out if it's SP or NN feature */
711         switch (feature) {
712         /* deal with SP features */
713         case DCCPF_CCID:
714                 rc = dccp_feat_sp(sk, type, feature, val, len);
715                 break;
716
717         /* deal with NN features */
718         case DCCPF_ACK_RATIO:
719                 rc = dccp_feat_nn(sk, type, feature, val, len);
720                 break;
721
722         /* XXX implement other features */
723         default:
724                 dccp_pr_debug("UNIMPLEMENTED: not handling %s(%d, ...)\n",
725                               dccp_feat_typename(type), feature);
726                 rc = -EFAULT;
727                 break;
728         }
729
730         /* check if there were problems changing features */
731         if (rc) {
732                 /* If we don't agree on SP, we sent a confirm for old value.
733                  * However we propagate rc to caller in case option was
734                  * mandatory
735                  */
736                 if (rc != DCCP_FEAT_SP_NOAGREE)
737                         dccp_feat_empty_confirm(dccp_msk(sk), type, feature);
738         }
739
740         /* generate the confirm [if required] */
741         dccp_feat_flush_confirm(sk);
742
743         return rc;
744 }
745
746 EXPORT_SYMBOL_GPL(dccp_feat_change_recv);
747
748 int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
749                            u8 *val, u8 len)
750 {
751         u8 t;
752         struct dccp_opt_pend *opt;
753         struct dccp_minisock *dmsk = dccp_msk(sk);
754         int found = 0;
755         int all_confirmed = 1;
756
757         /* Ignore Confirm options other than during connection setup */
758         if (sk->sk_state != DCCP_LISTEN && sk->sk_state != DCCP_REQUESTING)
759                 return 0;
760         dccp_feat_debug(type, feature, *val);
761
762         /* locate our change request */
763         switch (type) {
764         case DCCPO_CONFIRM_L: t = DCCPO_CHANGE_R; break;
765         case DCCPO_CONFIRM_R: t = DCCPO_CHANGE_L; break;
766         default:              DCCP_WARN("invalid type %d\n", type);
767                               return 1;
768
769         }
770         /* XXX sanity check feature value */
771
772         list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) {
773                 if (!opt->dccpop_conf && opt->dccpop_type == t &&
774                     opt->dccpop_feat == feature) {
775                         found = 1;
776                         dccp_pr_debug("feature %d found\n", opt->dccpop_feat);
777
778                         /* XXX do sanity check */
779
780                         opt->dccpop_conf = 1;
781
782                         /* We got a confirmation---change the option */
783                         dccp_feat_update(sk, opt->dccpop_type,
784                                          opt->dccpop_feat, *val);
785
786                         /* XXX check the return value of dccp_feat_update */
787                         break;
788                 }
789
790                 if (!opt->dccpop_conf)
791                         all_confirmed = 0;
792         }
793
794         if (!found)
795                 dccp_pr_debug("%s(%d, ...) never requested\n",
796                               dccp_feat_typename(type), feature);
797         return 0;
798 }
799
800 EXPORT_SYMBOL_GPL(dccp_feat_confirm_recv);
801
802 void dccp_feat_clean(struct dccp_minisock *dmsk)
803 {
804         struct dccp_opt_pend *opt, *next;
805
806         list_for_each_entry_safe(opt, next, &dmsk->dccpms_pending,
807                                  dccpop_node) {
808                 BUG_ON(opt->dccpop_val == NULL);
809                 kfree(opt->dccpop_val);
810
811                 if (opt->dccpop_sc != NULL) {
812                         BUG_ON(opt->dccpop_sc->dccpoc_val == NULL);
813                         kfree(opt->dccpop_sc->dccpoc_val);
814                         kfree(opt->dccpop_sc);
815                 }
816
817                 kfree(opt);
818         }
819         INIT_LIST_HEAD(&dmsk->dccpms_pending);
820
821         list_for_each_entry_safe(opt, next, &dmsk->dccpms_conf, dccpop_node) {
822                 BUG_ON(opt == NULL);
823                 if (opt->dccpop_val != NULL)
824                         kfree(opt->dccpop_val);
825                 kfree(opt);
826         }
827         INIT_LIST_HEAD(&dmsk->dccpms_conf);
828 }
829
830 EXPORT_SYMBOL_GPL(dccp_feat_clean);
831
832 /* this is to be called only when a listening sock creates its child.  It is
833  * assumed by the function---the confirm is not duplicated, but rather it is
834  * "passed on".
835  */
836 int dccp_feat_clone(struct sock *oldsk, struct sock *newsk)
837 {
838         struct dccp_minisock *olddmsk = dccp_msk(oldsk);
839         struct dccp_minisock *newdmsk = dccp_msk(newsk);
840         struct dccp_opt_pend *opt;
841         int rc = 0;
842
843         INIT_LIST_HEAD(&newdmsk->dccpms_pending);
844         INIT_LIST_HEAD(&newdmsk->dccpms_conf);
845
846         list_for_each_entry(opt, &olddmsk->dccpms_pending, dccpop_node) {
847                 struct dccp_opt_pend *newopt;
848                 /* copy the value of the option */
849                 u8 *val = kmemdup(opt->dccpop_val, opt->dccpop_len, GFP_ATOMIC);
850
851                 if (val == NULL)
852                         goto out_clean;
853
854                 newopt = kmemdup(opt, sizeof(*newopt), GFP_ATOMIC);
855                 if (newopt == NULL) {
856                         kfree(val);
857                         goto out_clean;
858                 }
859
860                 /* insert the option */
861                 newopt->dccpop_val = val;
862                 list_add_tail(&newopt->dccpop_node, &newdmsk->dccpms_pending);
863
864                 /* XXX what happens with backlogs and multiple connections at
865                  * once...
866                  */
867                 /* the master socket no longer needs to worry about confirms */
868                 opt->dccpop_sc = NULL; /* it's not a memleak---new socket has it */
869
870                 /* reset state for a new socket */
871                 opt->dccpop_conf = 0;
872         }
873
874         /* XXX not doing anything about the conf queue */
875
876 out:
877         return rc;
878
879 out_clean:
880         dccp_feat_clean(newdmsk);
881         rc = -ENOMEM;
882         goto out;
883 }
884
885 EXPORT_SYMBOL_GPL(dccp_feat_clone);
886
887 int dccp_feat_init(struct sock *sk)
888 {
889         struct dccp_sock *dp = dccp_sk(sk);
890         struct dccp_minisock *dmsk = dccp_msk(sk);
891         int rc;
892
893         INIT_LIST_HEAD(&dmsk->dccpms_pending);  /* XXX no longer used */
894         INIT_LIST_HEAD(&dmsk->dccpms_conf);     /* XXX no longer used */
895
896         /* CCID L */
897         rc = __feat_register_sp(&dp->dccps_featneg, DCCPF_CCID, 1, 0,
898                                 &dmsk->dccpms_tx_ccid, 1);
899         if (rc)
900                 goto out;
901
902         /* CCID R */
903         rc = __feat_register_sp(&dp->dccps_featneg, DCCPF_CCID, 0, 0,
904                                 &dmsk->dccpms_rx_ccid, 1);
905         if (rc)
906                 goto out;
907
908         /* Ack ratio */
909         rc = __feat_register_nn(&dp->dccps_featneg, DCCPF_ACK_RATIO, 0,
910                                 dmsk->dccpms_ack_ratio);
911 out:
912         return rc;
913 }
914
915 EXPORT_SYMBOL_GPL(dccp_feat_init);
916
917 #ifdef CONFIG_IP_DCCP_DEBUG
918 const char *dccp_feat_typename(const u8 type)
919 {
920         switch(type) {
921         case DCCPO_CHANGE_L:  return("ChangeL");
922         case DCCPO_CONFIRM_L: return("ConfirmL");
923         case DCCPO_CHANGE_R:  return("ChangeR");
924         case DCCPO_CONFIRM_R: return("ConfirmR");
925         /* the following case must not appear in feature negotation  */
926         default:              dccp_pr_debug("unknown type %d [BUG!]\n", type);
927         }
928         return NULL;
929 }
930
931 EXPORT_SYMBOL_GPL(dccp_feat_typename);
932
933 const char *dccp_feat_name(const u8 feat)
934 {
935         static const char *feature_names[] = {
936                 [DCCPF_RESERVED]        = "Reserved",
937                 [DCCPF_CCID]            = "CCID",
938                 [DCCPF_SHORT_SEQNOS]    = "Allow Short Seqnos",
939                 [DCCPF_SEQUENCE_WINDOW] = "Sequence Window",
940                 [DCCPF_ECN_INCAPABLE]   = "ECN Incapable",
941                 [DCCPF_ACK_RATIO]       = "Ack Ratio",
942                 [DCCPF_SEND_ACK_VECTOR] = "Send ACK Vector",
943                 [DCCPF_SEND_NDP_COUNT]  = "Send NDP Count",
944                 [DCCPF_MIN_CSUM_COVER]  = "Min. Csum Coverage",
945                 [DCCPF_DATA_CHECKSUM]   = "Send Data Checksum",
946         };
947         if (feat > DCCPF_DATA_CHECKSUM && feat < DCCPF_MIN_CCID_SPECIFIC)
948                 return feature_names[DCCPF_RESERVED];
949
950         if (feat ==  DCCPF_SEND_LEV_RATE)
951                 return "Send Loss Event Rate";
952         if (feat >= DCCPF_MIN_CCID_SPECIFIC)
953                 return "CCID-specific";
954
955         return feature_names[feat];
956 }
957
958 EXPORT_SYMBOL_GPL(dccp_feat_name);
959 #endif /* CONFIG_IP_DCCP_DEBUG */