ipv4: fix nexthop attlen check in fib_nh_match
[pandora-kernel.git] / net / ipv4 / fib_semantics.c
index 80106d8..1cdb4a9 100644 (file)
@@ -146,6 +146,12 @@ static void free_fib_info_rcu(struct rcu_head *head)
 {
        struct fib_info *fi = container_of(head, struct fib_info, rcu);
 
+       change_nexthops(fi) {
+               if (nexthop_nh->nh_dev)
+                       dev_put(nexthop_nh->nh_dev);
+       } endfor_nexthops(fi);
+
+       release_net(fi->fib_net);
        if (fi->fib_metrics != (u32 *) dst_default_metrics)
                kfree(fi->fib_metrics);
        kfree(fi);
@@ -157,13 +163,7 @@ void free_fib_info(struct fib_info *fi)
                pr_warning("Freeing alive fib_info %p\n", fi);
                return;
        }
-       change_nexthops(fi) {
-               if (nexthop_nh->nh_dev)
-                       dev_put(nexthop_nh->nh_dev);
-               nexthop_nh->nh_dev = NULL;
-       } endfor_nexthops(fi);
        fib_info_cnt--;
-       release_net(fi->fib_net);
        call_rcu(&fi->rcu, free_fib_info_rcu);
 }
 
@@ -467,7 +467,7 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
                        return 1;
 
                attrlen = rtnh_attrlen(rtnh);
-               if (attrlen < 0) {
+               if (attrlen > 0) {
                        struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
 
                        nla = nla_find(attrs, attrlen, RTA_GATEWAY);
@@ -752,13 +752,13 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
        fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
        if (fi == NULL)
                goto failure;
+       fib_info_cnt++;
        if (cfg->fc_mx) {
                fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL);
                if (!fi->fib_metrics)
                        goto failure;
        } else
                fi->fib_metrics = (u32 *) dst_default_metrics;
-       fib_info_cnt++;
 
        fi->fib_net = hold_net(net);
        fi->fib_protocol = cfg->fc_protocol;