ipv4, fib: pass LOOPBACK_IFINDEX instead of 0 to flowi4_iif
authorCong Wang <cwang@twopensource.com>
Tue, 15 Apr 2014 23:25:34 +0000 (16:25 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 16 Apr 2014 19:05:11 +0000 (15:05 -0400)
As suggested by Julian:

Simply, flowi4_iif must not contain 0, it does not
look logical to ignore all ip rules with specified iif.

because in fib_rule_match() we do:

        if (rule->iifindex && (rule->iifindex != fl->flowi_iif))
                goto out;

flowi4_iif should be LOOPBACK_IFINDEX by default.

We need to move LOOPBACK_IFINDEX to include/net/flow.h:

1) It is mostly used by flowi_iif

2) Fix the following compile error if we use it in flow.h
by the patches latter:

In file included from include/linux/netfilter.h:277:0,
                 from include/net/netns/netfilter.h:5,
                 from include/net/net_namespace.h:21,
                 from include/linux/netdevice.h:43,
                 from include/linux/icmpv6.h:12,
                 from include/linux/ipv6.h:61,
                 from include/net/ipv6.h:16,
                 from include/linux/sunrpc/clnt.h:27,
                 from include/linux/nfs_fs.h:30,
                 from init/do_mounts.c:32:
include/net/flow.h: In function ‘flowi4_init_output’:
include/net/flow.h:84:32: error: ‘LOOPBACK_IFINDEX’ undeclared (first use in this function)

Cc: Eric Biederman <ebiederm@xmission.com>
Cc: Julian Anastasov <ja@ssi.bg>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Cong Wang <cwang@twopensource.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/flow.h
include/net/net_namespace.h
net/ipv4/fib_frontend.c
net/ipv4/fib_semantics.c
net/ipv4/ipmr.c
net/ipv4/netfilter/ipt_rpfilter.c
net/ipv6/ip6mr.c

index 64fd248..8109a15 100644 (file)
 #include <linux/in6.h>
 #include <linux/atomic.h>
 
+/*
+ * ifindex generation is per-net namespace, and loopback is
+ * always the 1st device in ns (see net_dev_init), thus any
+ * loopback device should get ifindex 1
+ */
+
+#define LOOPBACK_IFINDEX       1
+
 struct flowi_common {
        int     flowic_oif;
        int     flowic_iif;
@@ -80,7 +88,7 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
                                      __be16 dport, __be16 sport)
 {
        fl4->flowi4_oif = oif;
-       fl4->flowi4_iif = 0;
+       fl4->flowi4_iif = LOOPBACK_IFINDEX;
        fl4->flowi4_mark = mark;
        fl4->flowi4_tos = tos;
        fl4->flowi4_scope = scope;
index 79387f7..5f9eb26 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/list.h>
 #include <linux/sysctl.h>
 
+#include <net/flow.h>
 #include <net/netns/core.h>
 #include <net/netns/mib.h>
 #include <net/netns/unix.h>
@@ -131,14 +132,6 @@ struct net {
        atomic_t                fnhe_genid;
 };
 
-/*
- * ifindex generation is per-net namespace, and loopback is
- * always the 1st device in ns (see net_dev_init), thus any
- * loopback device should get ifindex 1
- */
-
-#define LOOPBACK_IFINDEX       1
-
 #include <linux/seq_file_net.h>
 
 /* Init's network namespace */
index 1a629f8..255aa99 100644 (file)
@@ -250,7 +250,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
        bool dev_match;
 
        fl4.flowi4_oif = 0;
-       fl4.flowi4_iif = oif;
+       fl4.flowi4_iif = oif ? : LOOPBACK_IFINDEX;
        fl4.daddr = src;
        fl4.saddr = dst;
        fl4.flowi4_tos = tos;
index b53f0bf..8a043f0 100644 (file)
@@ -631,6 +631,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
                                .daddr = nh->nh_gw,
                                .flowi4_scope = cfg->fc_scope + 1,
                                .flowi4_oif = nh->nh_oif,
+                               .flowi4_iif = LOOPBACK_IFINDEX,
                        };
 
                        /* It is not necessary, but requires a bit of thinking */
index 2886357..d84dc8d 100644 (file)
@@ -455,7 +455,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
        struct mr_table *mrt;
        struct flowi4 fl4 = {
                .flowi4_oif     = dev->ifindex,
-               .flowi4_iif     = skb->skb_iif,
+               .flowi4_iif     = skb->skb_iif ? : LOOPBACK_IFINDEX,
                .flowi4_mark    = skb->mark,
        };
        int err;
index c49dcd0..4bfaedf 100644 (file)
@@ -89,11 +89,8 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
        if (ipv4_is_multicast(iph->daddr)) {
                if (ipv4_is_zeronet(iph->saddr))
                        return ipv4_is_local_multicast(iph->daddr) ^ invert;
-               flow.flowi4_iif = 0;
-       } else {
-               flow.flowi4_iif = LOOPBACK_IFINDEX;
        }
-
+       flow.flowi4_iif = LOOPBACK_IFINDEX;
        flow.daddr = iph->saddr;
        flow.saddr = rpfilter_get_saddr(iph->daddr);
        flow.flowi4_oif = 0;
index 8737400..8659067 100644 (file)
@@ -700,7 +700,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
        struct mr6_table *mrt;
        struct flowi6 fl6 = {
                .flowi6_oif     = dev->ifindex,
-               .flowi6_iif     = skb->skb_iif,
+               .flowi6_iif     = skb->skb_iif ? : LOOPBACK_IFINDEX,
                .flowi6_mark    = skb->mark,
        };
        int err;