ipv4: fix nexthop attlen check in fib_nh_match
[pandora-kernel.git] / net / ipv4 / fib_semantics.c
index 8a043f0..f99f41b 100644 (file)
@@ -157,9 +157,12 @@ static void rt_fibinfo_free(struct rtable __rcu **rtp)
 
 static void free_nh_exceptions(struct fib_nh *nh)
 {
-       struct fnhe_hash_bucket *hash = nh->nh_exceptions;
+       struct fnhe_hash_bucket *hash;
        int i;
 
+       hash = rcu_dereference_protected(nh->nh_exceptions, 1);
+       if (!hash)
+               return;
        for (i = 0; i < FNHE_HASH_SIZE; i++) {
                struct fib_nh_exception *fnhe;
 
@@ -205,8 +208,7 @@ static void free_fib_info_rcu(struct rcu_head *head)
        change_nexthops(fi) {
                if (nexthop_nh->nh_dev)
                        dev_put(nexthop_nh->nh_dev);
-               if (nexthop_nh->nh_exceptions)
-                       free_nh_exceptions(nexthop_nh);
+               free_nh_exceptions(nexthop_nh);
                rt_fibinfo_free_cpus(nexthop_nh->nh_pcpu_rth_output);
                rt_fibinfo_free(&nexthop_nh->nh_rth_input);
        } endfor_nexthops(fi);
@@ -535,7 +537,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);
@@ -821,13 +823,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;