]> err.no Git - linux-2.6/blobdiff - net/dccp/feat.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / net / dccp / feat.c
index 12cde2f2f13b5fce1dc526e24281d2794ae69c3a..5ebdd86c1b99f34ae2c86c36e8cbda2b23fed0cc 100644 (file)
@@ -25,11 +25,11 @@ int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
        dccp_feat_debug(type, feature, *val);
 
        if (!dccp_feat_is_valid_type(type)) {
-               pr_info("option type %d invalid in negotiation\n", type);
+               DCCP_WARN("option type %d invalid in negotiation\n", type);
                return 1;
        }
        if (!dccp_feat_is_valid_length(type, feature, len)) {
-               pr_info("invalid length %d\n", len);
+               DCCP_WARN("invalid length %d\n", len);
                return 1;
        }
        /* XXX add further sanity checks */
@@ -169,7 +169,8 @@ static int dccp_feat_reconcile(struct sock *sk, struct dccp_opt_pend *opt,
                        break;
 
                default:
-                       WARN_ON(1); /* XXX implement res */
+                       DCCP_BUG("Fell through, feat=%d", opt->dccpop_feat);
+                       /* XXX implement res */
                        return -EFAULT;
                }
 
@@ -286,12 +287,11 @@ static int dccp_feat_nn(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
        if (opt == NULL)
                return -ENOMEM;
 
-       copy = kmalloc(len, GFP_ATOMIC);
+       copy = kmemdup(val, len, GFP_ATOMIC);
        if (copy == NULL) {
                kfree(opt);
                return -ENOMEM;
        }
-       memcpy(copy, val, len);
 
        opt->dccpop_type = DCCPO_CONFIRM_R; /* NN can only confirm R */
        opt->dccpop_feat = feature;
@@ -327,10 +327,16 @@ static void dccp_feat_empty_confirm(struct dccp_minisock *dmsk,
        }
 
        switch (type) {
-       case DCCPO_CHANGE_L: opt->dccpop_type = DCCPO_CONFIRM_R; break;
-       case DCCPO_CHANGE_R: opt->dccpop_type = DCCPO_CONFIRM_L; break;
-       default:             pr_info("invalid type %d\n", type); return;
-
+       case DCCPO_CHANGE_L:
+               opt->dccpop_type = DCCPO_CONFIRM_R;
+               break;
+       case DCCPO_CHANGE_R:
+               opt->dccpop_type = DCCPO_CONFIRM_L;
+               break;
+       default:
+               DCCP_WARN("invalid type %d\n", type);
+               kfree(opt);
+               return;
        }
        opt->dccpop_feat = feature;
        opt->dccpop_val  = NULL;
@@ -427,7 +433,7 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
        switch (type) {
        case DCCPO_CONFIRM_L: t = DCCPO_CHANGE_R; break;
        case DCCPO_CONFIRM_R: t = DCCPO_CHANGE_L; break;
-       default:              pr_info("invalid type %d\n", type);
+       default:              DCCP_WARN("invalid type %d\n", type);
                              return 1;
 
        }
@@ -480,8 +486,8 @@ void dccp_feat_clean(struct dccp_minisock *dmsk)
 
        list_for_each_entry_safe(opt, next, &dmsk->dccpms_pending,
                                 dccpop_node) {
-                BUG_ON(opt->dccpop_val == NULL);
-                kfree(opt->dccpop_val);
+               BUG_ON(opt->dccpop_val == NULL);
+               kfree(opt->dccpop_val);
 
                if (opt->dccpop_sc != NULL) {
                        BUG_ON(opt->dccpop_sc->dccpoc_val == NULL);
@@ -489,8 +495,8 @@ void dccp_feat_clean(struct dccp_minisock *dmsk)
                        kfree(opt->dccpop_sc);
                }
 
-                kfree(opt);
-        }
+               kfree(opt);
+       }
        INIT_LIST_HEAD(&dmsk->dccpms_pending);
 
        list_for_each_entry_safe(opt, next, &dmsk->dccpms_conf, dccpop_node) {
@@ -521,20 +527,18 @@ int dccp_feat_clone(struct sock *oldsk, struct sock *newsk)
        list_for_each_entry(opt, &olddmsk->dccpms_pending, dccpop_node) {
                struct dccp_opt_pend *newopt;
                /* copy the value of the option */
-               u8 *val = kmalloc(opt->dccpop_len, GFP_ATOMIC);
+               u8 *val = kmemdup(opt->dccpop_val, opt->dccpop_len, GFP_ATOMIC);
 
                if (val == NULL)
                        goto out_clean;
-               memcpy(val, opt->dccpop_val, opt->dccpop_len);
 
-               newopt = kmalloc(sizeof(*newopt), GFP_ATOMIC);
+               newopt = kmemdup(opt, sizeof(*newopt), GFP_ATOMIC);
                if (newopt == NULL) {
                        kfree(val);
                        goto out_clean;
                }
 
                /* insert the option */
-               memcpy(newopt, opt, sizeof(*newopt));
                newopt->dccpop_val = val;
                list_add_tail(&newopt->dccpop_node, &newdmsk->dccpms_pending);
 
@@ -565,10 +569,9 @@ static int __dccp_feat_init(struct dccp_minisock *dmsk, u8 type, u8 feat,
                            u8 *val, u8 len)
 {
        int rc = -ENOMEM;
-       u8 *copy = kmalloc(len, GFP_KERNEL);
+       u8 *copy = kmemdup(val, len, GFP_KERNEL);
 
        if (copy != NULL) {
-               memcpy(copy, val, len);
                rc = dccp_feat_change(dmsk, type, feat, copy, len, GFP_KERNEL);
                if (rc)
                        kfree(copy);
@@ -613,7 +616,7 @@ const char *dccp_feat_typename(const u8 type)
        case DCCPO_CHANGE_R:  return("ChangeR");
        case DCCPO_CONFIRM_R: return("ConfirmR");
        /* the following case must not appear in feature negotation  */
-       default:              dccp_pr_debug("unknown type %d [BUG!]\n", type);
+       default:              dccp_pr_debug("unknown type %d [BUG!]\n", type);
        }
        return NULL;
 }