Browse Source

Merge branch 'fib_validate_loopback'

Cong Wang says:

====================
ipv4: fix flowi4_iif for input routing

This patchset fixes ->flowi4_iif for input routing and rp filter,
based on suggestion from Julian. See per patch for details.

v1 -> v2:
* merge the first two patches into one
* fix fib_check_nh() too
* add this cover letter
====================

Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Cong Wang <cwang@twopensource.com>
Reviewed-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: David S. Miller <davem@davemloft.net>
David S. Miller 11 years ago
parent
commit
bc383ea522

+ 9 - 1
include/net/flow.h

@@ -11,6 +11,14 @@
 #include <linux/in6.h>
 #include <linux/in6.h>
 #include <linux/atomic.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 {
 struct flowi_common {
 	int	flowic_oif;
 	int	flowic_oif;
 	int	flowic_iif;
 	int	flowic_iif;
@@ -80,7 +88,7 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
 				      __be16 dport, __be16 sport)
 				      __be16 dport, __be16 sport)
 {
 {
 	fl4->flowi4_oif = oif;
 	fl4->flowi4_oif = oif;
-	fl4->flowi4_iif = 0;
+	fl4->flowi4_iif = LOOPBACK_IFINDEX;
 	fl4->flowi4_mark = mark;
 	fl4->flowi4_mark = mark;
 	fl4->flowi4_tos = tos;
 	fl4->flowi4_tos = tos;
 	fl4->flowi4_scope = scope;
 	fl4->flowi4_scope = scope;

+ 1 - 8
include/net/net_namespace.h

@@ -9,6 +9,7 @@
 #include <linux/list.h>
 #include <linux/list.h>
 #include <linux/sysctl.h>
 #include <linux/sysctl.h>
 
 
+#include <net/flow.h>
 #include <net/netns/core.h>
 #include <net/netns/core.h>
 #include <net/netns/mib.h>
 #include <net/netns/mib.h>
 #include <net/netns/unix.h>
 #include <net/netns/unix.h>
@@ -131,14 +132,6 @@ struct net {
 	atomic_t		fnhe_genid;
 	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>
 #include <linux/seq_file_net.h>
 
 
 /* Init's network namespace */
 /* Init's network namespace */

+ 1 - 1
net/ipv4/fib_frontend.c

@@ -250,7 +250,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
 	bool dev_match;
 	bool dev_match;
 
 
 	fl4.flowi4_oif = 0;
 	fl4.flowi4_oif = 0;
-	fl4.flowi4_iif = oif;
+	fl4.flowi4_iif = oif ? : LOOPBACK_IFINDEX;
 	fl4.daddr = src;
 	fl4.daddr = src;
 	fl4.saddr = dst;
 	fl4.saddr = dst;
 	fl4.flowi4_tos = tos;
 	fl4.flowi4_tos = tos;

+ 1 - 0
net/ipv4/fib_semantics.c

@@ -631,6 +631,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
 				.daddr = nh->nh_gw,
 				.daddr = nh->nh_gw,
 				.flowi4_scope = cfg->fc_scope + 1,
 				.flowi4_scope = cfg->fc_scope + 1,
 				.flowi4_oif = nh->nh_oif,
 				.flowi4_oif = nh->nh_oif,
+				.flowi4_iif = LOOPBACK_IFINDEX,
 			};
 			};
 
 
 			/* It is not necessary, but requires a bit of thinking */
 			/* It is not necessary, but requires a bit of thinking */

+ 1 - 1
net/ipv4/ipmr.c

@@ -455,7 +455,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct mr_table *mrt;
 	struct mr_table *mrt;
 	struct flowi4 fl4 = {
 	struct flowi4 fl4 = {
 		.flowi4_oif	= dev->ifindex,
 		.flowi4_oif	= dev->ifindex,
-		.flowi4_iif	= skb->skb_iif,
+		.flowi4_iif	= skb->skb_iif ? : LOOPBACK_IFINDEX,
 		.flowi4_mark	= skb->mark,
 		.flowi4_mark	= skb->mark,
 	};
 	};
 	int err;
 	int err;

+ 1 - 4
net/ipv4/netfilter/ipt_rpfilter.c

@@ -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_multicast(iph->daddr)) {
 		if (ipv4_is_zeronet(iph->saddr))
 		if (ipv4_is_zeronet(iph->saddr))
 			return ipv4_is_local_multicast(iph->daddr) ^ invert;
 			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.daddr = iph->saddr;
 	flow.saddr = rpfilter_get_saddr(iph->daddr);
 	flow.saddr = rpfilter_get_saddr(iph->daddr);
 	flow.flowi4_oif = 0;
 	flow.flowi4_oif = 0;

+ 1 - 2
net/ipv4/route.c

@@ -1700,8 +1700,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 
 
 	if (res.type == RTN_LOCAL) {
 	if (res.type == RTN_LOCAL) {
 		err = fib_validate_source(skb, saddr, daddr, tos,
 		err = fib_validate_source(skb, saddr, daddr, tos,
-					  LOOPBACK_IFINDEX,
-					  dev, in_dev, &itag);
+					  0, dev, in_dev, &itag);
 		if (err < 0)
 		if (err < 0)
 			goto martian_source_keep_err;
 			goto martian_source_keep_err;
 		goto local_input;
 		goto local_input;

+ 1 - 1
net/ipv6/ip6mr.c

@@ -700,7 +700,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
 	struct mr6_table *mrt;
 	struct mr6_table *mrt;
 	struct flowi6 fl6 = {
 	struct flowi6 fl6 = {
 		.flowi6_oif	= dev->ifindex,
 		.flowi6_oif	= dev->ifindex,
-		.flowi6_iif	= skb->skb_iif,
+		.flowi6_iif	= skb->skb_iif ? : LOOPBACK_IFINDEX,
 		.flowi6_mark	= skb->mark,
 		.flowi6_mark	= skb->mark,
 	};
 	};
 	int err;
 	int err;