tproxy: split off ipv6 defragmentation to a separate module
[linux-2.6.git] / net / dccp / feat.c
index 3abacad..df7dd26 100644 (file)
@@ -3,7 +3,6 @@
  *
  *  Feature negotiation for the DCCP protocol (RFC 4340, section 6)
  *
- *  Copyright (c) 2008 The University of Aberdeen, Scotland, UK
  *  Copyright (c) 2008 Gerrit Renker <gerrit@erg.abdn.ac.uk>
  *  Rewrote from scratch, some bits from earlier code by
  *  Copyright (c) 2005 Andrea Bittau <a.bittau@cs.ucl.ac.uk>
@@ -23,6 +22,7 @@
  *  2 of the License, or (at your option) any later version.
  */
 #include <linux/module.h>
+#include <linux/slab.h>
 #include "ccid.h"
 #include "feat.h"
 
@@ -40,7 +40,7 @@ int           sysctl_dccp_rx_ccid         __read_mostly = 2,
 static int dccp_hdlr_ccid(struct sock *sk, u64 ccid, bool rx)
 {
        struct dccp_sock *dp = dccp_sk(sk);
-       struct ccid *new_ccid = ccid_new(ccid, sk, rx, gfp_any());
+       struct ccid *new_ccid = ccid_new(ccid, sk, rx);
 
        if (new_ccid == NULL)
                return -ENOMEM;
@@ -200,8 +200,13 @@ static u8 dccp_feat_type(u8 feat_num)
 static int dccp_feat_default_value(u8 feat_num)
 {
        int idx = dccp_feat_index(feat_num);
+       /*
+        * There are no default values for unknown features, so encountering a
+        * negative index here indicates a serious problem somewhere else.
+        */
+       DCCP_BUG_ON(idx < 0);
 
-       return idx < 0 ? : dccp_feat_table[idx].default_value;
+       return idx < 0 ? 0 : dccp_feat_table[idx].default_value;
 }
 
 /*
@@ -209,7 +214,7 @@ static int dccp_feat_default_value(u8 feat_num)
  */
 static const char *dccp_feat_fname(const u8 feat)
 {
-       static const char *feature_names[] = {
+       static const char *const feature_names[] = {
                [DCCPF_RESERVED]        = "Reserved",
                [DCCPF_CCID]            = "CCID",
                [DCCPF_SHORT_SEQNOS]    = "Allow Short Seqnos",
@@ -232,8 +237,9 @@ static const char *dccp_feat_fname(const u8 feat)
        return feature_names[feat];
 }
 
-static const char *dccp_feat_sname[] = { "DEFAULT", "INITIALISING", "CHANGING",
-                                        "UNSTABLE", "STABLE" };
+static const char *const dccp_feat_sname[] = {
+       "DEFAULT", "INITIALISING", "CHANGING", "UNSTABLE", "STABLE",
+};
 
 #ifdef CONFIG_IP_DCCP_DEBUG
 static const char *dccp_feat_oname(const u8 opt)
@@ -411,11 +417,12 @@ static struct dccp_feat_entry *dccp_feat_list_lookup(struct list_head *fn_list,
 {
        struct dccp_feat_entry *entry;
 
-       list_for_each_entry(entry, fn_list, node)
+       list_for_each_entry(entry, fn_list, node) {
                if (entry->feat_num == feat_num && entry->is_local == is_local)
                        return entry;
                else if (entry->feat_num > feat_num)
                        break;
+       }
        return NULL;
 }
 
@@ -1276,11 +1283,6 @@ int dccp_feat_init(struct sock *sk)
            ccid_get_builtin_ccids(&rx.val, &rx.len))
                return -ENOBUFS;
 
-       /* Pre-load all CCID modules that are going to be advertised */
-       rc = -EUNATCH;
-       if (ccid_request_modules(tx.val, tx.len))
-               goto free_ccid_lists;
-
        if (!dccp_feat_prefer(sysctl_dccp_tx_ccid, tx.val, tx.len) ||
            !dccp_feat_prefer(sysctl_dccp_rx_ccid, rx.val, rx.len))
                goto free_ccid_lists;