inet: add IP_BIND_ADDRESS_NO_PORT to overcome bind(0) limitations
[cascardo/linux.git] / net / ipv6 / ip6mr.c
index 312e0ff..74ceb73 100644 (file)
@@ -56,9 +56,7 @@
 
 struct mr6_table {
        struct list_head        list;
-#ifdef CONFIG_NET_NS
-       struct net              *net;
-#endif
+       possible_net_t          net;
        u32                     id;
        struct sock             *mroute6_sk;
        struct timer_list       ipmr_expire_timer;
@@ -175,7 +173,7 @@ static int ip6mr_rule_action(struct fib_rule *rule, struct flowi *flp,
        }
 
        mrt = ip6mr_get_table(rule->fr_net, rule->table);
-       if (mrt == NULL)
+       if (!mrt)
                return -EAGAIN;
        res->mrt = mrt;
        return 0;
@@ -239,7 +237,7 @@ static int __net_init ip6mr_rules_init(struct net *net)
        INIT_LIST_HEAD(&net->ipv6.mr6_tables);
 
        mrt = ip6mr_new_table(net, RT6_TABLE_DFLT);
-       if (mrt == NULL) {
+       if (!mrt) {
                err = -ENOMEM;
                goto err1;
        }
@@ -307,11 +305,11 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id)
        unsigned int i;
 
        mrt = ip6mr_get_table(net, id);
-       if (mrt != NULL)
+       if (mrt)
                return mrt;
 
        mrt = kzalloc(sizeof(*mrt), GFP_KERNEL);
-       if (mrt == NULL)
+       if (!mrt)
                return NULL;
        mrt->id = id;
        write_pnet(&mrt->net, net);
@@ -410,7 +408,7 @@ static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos)
        struct mr6_table *mrt;
 
        mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
-       if (mrt == NULL)
+       if (!mrt)
                return ERR_PTR(-ENOENT);
 
        iter->mrt = mrt;
@@ -494,7 +492,7 @@ static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos)
        struct mr6_table *mrt;
 
        mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
-       if (mrt == NULL)
+       if (!mrt)
                return ERR_PTR(-ENOENT);
 
        it->mrt = mrt;
@@ -667,7 +665,7 @@ static int pim6_rcv(struct sk_buff *skb)
                dev_hold(reg_dev);
        read_unlock(&mrt_lock);
 
-       if (reg_dev == NULL)
+       if (!reg_dev)
                goto drop;
 
        skb->mac_header = skb->network_header;
@@ -720,8 +718,14 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
        return NETDEV_TX_OK;
 }
 
+static int reg_vif_get_iflink(const struct net_device *dev)
+{
+       return 0;
+}
+
 static const struct net_device_ops reg_vif_netdev_ops = {
        .ndo_start_xmit = reg_vif_xmit,
+       .ndo_get_iflink = reg_vif_get_iflink,
 };
 
 static void reg_vif_setup(struct net_device *dev)
@@ -745,7 +749,7 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt)
                sprintf(name, "pim6reg%u", mrt->id);
 
        dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, reg_vif_setup);
-       if (dev == NULL)
+       if (!dev)
                return NULL;
 
        dev_net_set(dev, net);
@@ -754,7 +758,6 @@ static struct net_device *ip6mr_reg_vif(struct net *net, struct mr6_table *mrt)
                free_netdev(dev);
                return NULL;
        }
-       dev->iflink = 0;
 
        if (dev_open(dev))
                goto failure;
@@ -994,7 +997,7 @@ static int mif6_add(struct net *net, struct mr6_table *mrt,
        v->pkt_out = 0;
        v->link = dev->ifindex;
        if (v->flags & MIFF_REGISTER)
-               v->link = dev->iflink;
+               v->link = dev_get_iflink(dev);
 
        /* And finish update writing critical data */
        write_lock_bh(&mrt_lock);
@@ -1074,7 +1077,7 @@ skip:
 static struct mfc6_cache *ip6mr_cache_alloc(void)
 {
        struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
-       if (c == NULL)
+       if (!c)
                return NULL;
        c->mfc_un.res.minvif = MAXMIFS;
        return c;
@@ -1083,7 +1086,7 @@ static struct mfc6_cache *ip6mr_cache_alloc(void)
 static struct mfc6_cache *ip6mr_cache_alloc_unres(void)
 {
        struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
-       if (c == NULL)
+       if (!c)
                return NULL;
        skb_queue_head_init(&c->mfc_un.unres.unresolved);
        c->mfc_un.unres.expires = jiffies + 10 * HZ;
@@ -1200,7 +1203,7 @@ static int ip6mr_cache_report(struct mr6_table *mrt, struct sk_buff *pkt,
        skb->ip_summed = CHECKSUM_UNNECESSARY;
        }
 
-       if (mrt->mroute6_sk == NULL) {
+       if (!mrt->mroute6_sk) {
                kfree_skb(skb);
                return -EINVAL;
        }
@@ -1495,7 +1498,7 @@ static int ip6mr_mfc_add(struct net *net, struct mr6_table *mrt,
                return -EINVAL;
 
        c = ip6mr_cache_alloc();
-       if (c == NULL)
+       if (!c)
                return -ENOMEM;
 
        c->mf6c_origin = mfc->mf6cc_origin.sin6_addr;
@@ -1665,7 +1668,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
        struct mr6_table *mrt;
 
        mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
-       if (mrt == NULL)
+       if (!mrt)
                return -ENOENT;
 
        if (optname != MRT6_INIT) {
@@ -1814,7 +1817,7 @@ int ip6_mroute_getsockopt(struct sock *sk, int optname, char __user *optval,
        struct mr6_table *mrt;
 
        mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
-       if (mrt == NULL)
+       if (!mrt)
                return -ENOENT;
 
        switch (optname) {
@@ -1861,7 +1864,7 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
        struct mr6_table *mrt;
 
        mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
-       if (mrt == NULL)
+       if (!mrt)
                return -ENOENT;
 
        switch (cmd) {
@@ -1935,7 +1938,7 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
        struct mr6_table *mrt;
 
        mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT);
-       if (mrt == NULL)
+       if (!mrt)
                return -ENOENT;
 
        switch (cmd) {
@@ -1983,13 +1986,13 @@ int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg)
 }
 #endif
 
-static inline int ip6mr_forward2_finish(struct sk_buff *skb)
+static inline int ip6mr_forward2_finish(struct sock *sk, struct sk_buff *skb)
 {
        IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)),
                         IPSTATS_MIB_OUTFORWDATAGRAMS);
        IP6_ADD_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)),
                         IPSTATS_MIB_OUTOCTETS, skb->len);
-       return dst_output(skb);
+       return dst_output_sk(sk, skb);
 }
 
 /*
@@ -2005,7 +2008,7 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt,
        struct dst_entry *dst;
        struct flowi6 fl6;
 
-       if (vif->dev == NULL)
+       if (!vif->dev)
                goto out_free;
 
 #ifdef CONFIG_IPV6_PIMSM_V2
@@ -2061,7 +2064,8 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt,
 
        IP6CB(skb)->flags |= IP6SKB_FORWARDED;
 
-       return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, skb, skb->dev, dev,
+       return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, NULL, skb,
+                      skb->dev, dev,
                       ip6mr_forward2_finish);
 
 out_free:
@@ -2194,7 +2198,7 @@ int ip6_mr_input(struct sk_buff *skb)
        read_lock(&mrt_lock);
        cache = ip6mr_cache_find(mrt,
                                 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr);
-       if (cache == NULL) {
+       if (!cache) {
                int vif = ip6mr_find_vif(mrt, skb->dev);
 
                if (vif >= 0)
@@ -2206,7 +2210,7 @@ int ip6_mr_input(struct sk_buff *skb)
        /*
         *      No usable cache entry
         */
-       if (cache == NULL) {
+       if (!cache) {
                int vif;
 
                vif = ip6mr_find_vif(mrt, skb->dev);
@@ -2245,13 +2249,13 @@ static int __ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
            nla_put_u32(skb, RTA_IIF, mrt->vif6_table[c->mf6c_parent].dev->ifindex) < 0)
                return -EMSGSIZE;
        mp_attr = nla_nest_start(skb, RTA_MULTIPATH);
-       if (mp_attr == NULL)
+       if (!mp_attr)
                return -EMSGSIZE;
 
        for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) {
                if (MIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) {
                        nhp = nla_reserve_nohdr(skb, sizeof(*nhp));
-                       if (nhp == NULL) {
+                       if (!nhp) {
                                nla_nest_cancel(skb, mp_attr);
                                return -EMSGSIZE;
                        }
@@ -2284,7 +2288,7 @@ int ip6mr_get_route(struct net *net,
        struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
 
        mrt = ip6mr_get_table(net, RT6_TABLE_DFLT);
-       if (mrt == NULL)
+       if (!mrt)
                return -ENOENT;
 
        read_lock(&mrt_lock);
@@ -2309,7 +2313,7 @@ int ip6mr_get_route(struct net *net,
                }
 
                dev = skb->dev;
-               if (dev == NULL || (vif = ip6mr_find_vif(mrt, dev)) < 0) {
+               if (!dev || (vif = ip6mr_find_vif(mrt, dev)) < 0) {
                        read_unlock(&mrt_lock);
                        return -ENODEV;
                }
@@ -2361,7 +2365,7 @@ static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
        int err;
 
        nlh = nlmsg_put(skb, portid, seq, cmd, sizeof(*rtm), flags);
-       if (nlh == NULL)
+       if (!nlh)
                return -EMSGSIZE;
 
        rtm = nlmsg_data(nlh);
@@ -2380,8 +2384,8 @@ static int ip6mr_fill_mroute(struct mr6_table *mrt, struct sk_buff *skb,
                rtm->rtm_protocol = RTPROT_MROUTED;
        rtm->rtm_flags    = 0;
 
-       if (nla_put(skb, RTA_SRC, 16, &c->mf6c_origin) ||
-           nla_put(skb, RTA_DST, 16, &c->mf6c_mcastgrp))
+       if (nla_put_in6_addr(skb, RTA_SRC, &c->mf6c_origin) ||
+           nla_put_in6_addr(skb, RTA_DST, &c->mf6c_mcastgrp))
                goto nla_put_failure;
        err = __ip6mr_fill_mroute(mrt, skb, c, rtm);
        /* do not break the dump if cache is unresolved */
@@ -2426,7 +2430,7 @@ static void mr6_netlink_event(struct mr6_table *mrt, struct mfc6_cache *mfc,
 
        skb = nlmsg_new(mr6_msgsize(mfc->mf6c_parent >= MAXMIFS, mrt->maxvif),
                        GFP_ATOMIC);
-       if (skb == NULL)
+       if (!skb)
                goto errout;
 
        err = ip6mr_fill_mroute(mrt, skb, 0, 0, mfc, cmd, 0);