packages: kernel/kernel-routes.patch - http://www.ssi.bg/~ja/routes-2.6.39-...

baggins baggins at pld-linux.org
Mon Jul 11 01:19:06 CEST 2011


Author: baggins                      Date: Sun Jul 10 23:19:06 2011 GMT
Module: packages                      Tag: HEAD
---- Log message:
- http://www.ssi.bg/~ja/routes-2.6.39-16.diff

---- Files affected:
packages/kernel:
   kernel-routes.patch (1.13 -> 1.14) 

---- Diffs:

================================================================
Index: packages/kernel/kernel-routes.patch
diff -u packages/kernel/kernel-routes.patch:1.13 packages/kernel/kernel-routes.patch:1.14
--- packages/kernel/kernel-routes.patch:1.13	Mon Mar 21 20:03:58 2011
+++ packages/kernel/kernel-routes.patch	Mon Jul 11 01:19:00 2011
@@ -1,6 +1,6 @@
-diff -urp v2.6.38/linux/include/linux/rtnetlink.h linux/include/linux/rtnetlink.h
---- v2.6.38/linux/include/linux/rtnetlink.h	2011-03-20 12:05:41.000000000 +0200
-+++ linux/include/linux/rtnetlink.h	2011-03-20 12:12:11.107248055 +0200
+diff -urp v2.6.39/linux/include/linux/rtnetlink.h linux/include/linux/rtnetlink.h
+--- v2.6.39/linux/include/linux/rtnetlink.h	2011-05-15 14:05:57.000000000 +0300
++++ linux/include/linux/rtnetlink.h	2011-05-15 14:07:59.977246129 +0300
 @@ -312,6 +312,8 @@ struct rtnexthop {
  #define RTNH_F_DEAD		1	/* Nexthop is dead (used by multipath)	*/
  #define RTNH_F_PERVASIVE	2	/* Do recursive gateway lookup	*/
@@ -10,31 +10,21 @@
  
  /* Macros to handle hexthops */
  
-diff -urp v2.6.38/linux/include/net/flow.h linux/include/net/flow.h
---- v2.6.38/linux/include/net/flow.h	2011-03-20 12:01:11.000000000 +0200
-+++ linux/include/net/flow.h	2011-03-20 12:13:20.139247270 +0200
-@@ -19,6 +19,8 @@ struct flowi {
- 		struct {
- 			__be32			daddr;
- 			__be32			saddr;
-+			__be32			lsrc;
-+			__be32			gw;
- 			__u8			tos;
- 			__u8			scope;
- 		} ip4_u;
-@@ -43,6 +45,8 @@ struct flowi {
- #define fl6_flowlabel	nl_u.ip6_u.flowlabel
- #define fl4_dst		nl_u.ip4_u.daddr
- #define fl4_src		nl_u.ip4_u.saddr
-+#define fl4_lsrc	nl_u.ip4_u.lsrc
-+#define fl4_gw		nl_u.ip4_u.gw
- #define fl4_tos		nl_u.ip4_u.tos
- #define fl4_scope	nl_u.ip4_u.scope
- 
-diff -urp v2.6.38/linux/include/net/ip_fib.h linux/include/net/ip_fib.h
---- v2.6.38/linux/include/net/ip_fib.h	2011-03-20 12:05:50.000000000 +0200
-+++ linux/include/net/ip_fib.h	2011-03-20 12:12:11.107248055 +0200
-@@ -210,6 +210,8 @@ extern int fib_lookup(struct net *n, str
+diff -urp v2.6.39/linux/include/net/flow.h linux/include/net/flow.h
+--- v2.6.39/linux/include/net/flow.h	2011-05-15 14:05:57.000000000 +0300
++++ linux/include/net/flow.h	2011-05-15 14:07:59.977246129 +0300
+@@ -68,6 +68,7 @@ struct flowi4 {
+ #define fl4_ipsec_spi		uli.spi
+ #define fl4_mh_type		uli.mht.type
+ #define fl4_gre_key		uli.gre_key
++	__be32			fl4_gw;
+ };
+ 
+ struct flowi6 {
+diff -urp v2.6.39/linux/include/net/ip_fib.h linux/include/net/ip_fib.h
+--- v2.6.39/linux/include/net/ip_fib.h	2011-05-15 14:05:57.000000000 +0300
++++ linux/include/net/ip_fib.h	2011-05-15 14:07:59.978246172 +0300
+@@ -222,6 +222,8 @@ extern int fib_lookup(struct net *n, str
  extern struct fib_table *fib_new_table(struct net *net, u32 id);
  extern struct fib_table *fib_get_table(struct net *net, u32 id);
  
@@ -43,17 +33,37 @@
  #endif /* CONFIG_IP_MULTIPLE_TABLES */
  
  /* Exported by fib_frontend.c */
-@@ -270,4 +272,6 @@ static inline void fib_proc_exit(struct 
+@@ -230,7 +232,8 @@ extern void		ip_fib_init(void);
+ extern int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
+ 			       struct net_device *dev, __be32 *spec_dst,
+ 			       u32 *itag, u32 mark);
+-extern void fib_select_default(struct fib_result *res);
++extern void fib_select_default(const struct flowi4 *flp,
++			       struct fib_result *res);
+ 
+ /* Exported by fib_semantics.c */
+ extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
+@@ -238,7 +241,8 @@ extern int fib_sync_down_dev(struct net_
+ extern int fib_sync_down_addr(struct net *net, __be32 local);
+ extern void fib_update_nh_saddrs(struct net_device *dev);
+ extern int fib_sync_up(struct net_device *dev);
+-extern void fib_select_multipath(struct fib_result *res);
++extern void fib_select_multipath(const struct flowi4 *flp,
++				 struct fib_result *res);
+ 
+ /* Exported by fib_trie.c */
+ extern void fib_trie_init(void);
+@@ -281,4 +285,6 @@ static inline void fib_proc_exit(struct 
  }
  #endif
  
 +extern rwlock_t fib_nhflags_lock;
 +
  #endif  /* _NET_FIB_H */
-diff -urp v2.6.38/linux/include/net/netfilter/nf_nat.h linux/include/net/netfilter/nf_nat.h
---- v2.6.38/linux/include/net/netfilter/nf_nat.h	2011-03-20 12:01:11.000000000 +0200
-+++ linux/include/net/netfilter/nf_nat.h	2011-03-20 12:13:20.140246808 +0200
-@@ -73,6 +73,13 @@ struct nf_conn_nat {
+diff -urp v2.6.39/linux/include/net/netfilter/nf_nat.h linux/include/net/netfilter/nf_nat.h
+--- v2.6.39/linux/include/net/netfilter/nf_nat.h	2011-05-15 14:05:57.000000000 +0300
++++ linux/include/net/netfilter/nf_nat.h	2011-05-15 14:07:59.978246172 +0300
+@@ -75,6 +75,13 @@ struct nf_conn_nat {
  #endif
  };
  
@@ -67,10 +77,19 @@
  /* Set up the info structure to map into this range. */
  extern unsigned int nf_nat_setup_info(struct nf_conn *ct,
  				      const struct nf_nat_range *range,
-diff -urp v2.6.38/linux/include/net/route.h linux/include/net/route.h
---- v2.6.38/linux/include/net/route.h	2011-03-20 12:01:11.000000000 +0200
-+++ linux/include/net/route.h	2011-03-20 12:13:20.141248044 +0200
-@@ -134,6 +134,7 @@ static inline int ip_route_input_noref(s
+diff -urp v2.6.39/linux/include/net/route.h linux/include/net/route.h
+--- v2.6.39/linux/include/net/route.h	2011-05-15 14:05:57.000000000 +0300
++++ linux/include/net/route.h	2011-05-15 14:07:59.979245372 +0300
+@@ -56,6 +56,8 @@ struct rtable {
+ 	/* Lookup key. */
+ 	__be32			rt_key_dst;
+ 	__be32			rt_key_src;
++	__be32			rt_key_lsrc;
++	__be32			rt_key_gw;
+ 
+ 	int			rt_genid;
+ 	unsigned		rt_flags;
+@@ -196,6 +198,7 @@ static inline int ip_route_input_noref(s
  	return ip_route_input_common(skb, dst, src, tos, devin, true);
  }
  
@@ -78,10 +97,10 @@
  extern unsigned short	ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu, struct net_device *dev);
  extern void		ip_rt_send_redirect(struct sk_buff *skb);
  
-diff -urp v2.6.38/linux/net/bridge/br_netfilter.c linux/net/bridge/br_netfilter.c
---- v2.6.38/linux/net/bridge/br_netfilter.c	2011-03-20 12:01:11.000000000 +0200
-+++ linux/net/bridge/br_netfilter.c	2011-03-20 12:13:20.142247890 +0200
-@@ -405,6 +405,9 @@ static int br_nf_pre_routing_finish(stru
+diff -urp v2.6.39/linux/net/bridge/br_netfilter.c linux/net/bridge/br_netfilter.c
+--- v2.6.39/linux/net/bridge/br_netfilter.c	2011-05-15 14:05:57.000000000 +0300
++++ linux/net/bridge/br_netfilter.c	2011-05-15 14:07:59.980246190 +0300
+@@ -403,6 +403,9 @@ static int br_nf_pre_routing_finish(stru
  	struct rtable *rt;
  	int err;
  
@@ -91,9 +110,9 @@
  	if (nf_bridge->mask & BRNF_PKT_TYPE) {
  		skb->pkt_type = PACKET_OTHERHOST;
  		nf_bridge->mask ^= BRNF_PKT_TYPE;
-diff -urp v2.6.38/linux/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c
---- v2.6.38/linux/net/ipv4/fib_frontend.c	2011-03-20 12:05:50.000000000 +0200
-+++ linux/net/ipv4/fib_frontend.c	2011-03-20 12:12:11.109247911 +0200
+diff -urp v2.6.39/linux/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c
+--- v2.6.39/linux/net/ipv4/fib_frontend.c	2011-05-15 14:05:57.000000000 +0300
++++ linux/net/ipv4/fib_frontend.c	2011-05-15 14:07:59.981246210 +0300
 @@ -47,6 +47,8 @@
  
  #ifndef CONFIG_IP_MULTIPLE_TABLES
@@ -112,19 +131,9 @@
  struct fib_table *fib_new_table(struct net *net, u32 id)
  {
  	struct fib_table *tb;
-@@ -125,7 +129,8 @@ void fib_select_default(struct net *net,
- 	table = res->r->table;
- #endif
- 	tb = fib_get_table(net, table);
--	if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
-+	if ((FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) ||
-+	    FIB_RES_NH(*res).nh_scope == RT_SCOPE_HOST)
- 		fib_table_select_default(tb, flp, res);
- }
- 
-@@ -256,6 +261,9 @@ int fib_validate_source(__be32 src, __be
- 		.iif = oif
- 	};
+@@ -195,6 +199,9 @@ int fib_validate_source(__be32 src, __be
+ 	struct in_device *in_dev;
+ 	struct flowi4 fl4;
  	struct fib_result res;
 +	int table;
 +	unsigned char prefixlen;
@@ -132,27 +141,25 @@
  	int no_addr, rpf, accept_local;
  	bool dev_match;
  	int ret;
-@@ -302,19 +310,26 @@ int fib_validate_source(__be32 src, __be
- 		ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
- 		return ret;
+@@ -251,17 +258,24 @@ int fib_validate_source(__be32 src, __be
  	}
-+	table = FIB_RES_TABLE(&res);
-+	prefixlen = res.prefixlen;
-+	scope = res.scope;
  	if (no_addr)
  		goto last_resort;
 -	if (rpf == 1)
 -		goto e_rpf;
- 	fl.oif = dev->ifindex;
++	table = FIB_RES_TABLE(&res);
++	prefixlen = res.prefixlen;
++	scope = res.scope;
+ 	fl4.flowi4_oif = dev->ifindex;
  
  	ret = 0;
- 	if (fib_lookup(net, &fl, &res) == 0) {
+ 	if (fib_lookup(net, &fl4, &res) == 0) {
 -		if (res.type == RTN_UNICAST) {
 +		if (res.type == RTN_UNICAST &&
 +		    ((table == FIB_RES_TABLE(&res) &&
 +		      res.prefixlen >= prefixlen && res.scope >= scope) ||
 +		     !rpf)) {
- 			*spec_dst = FIB_RES_PREFSRC(res);
+ 			*spec_dst = FIB_RES_PREFSRC(net, res);
  			ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
 +			return ret;
  		}
@@ -162,180 +169,29 @@
  	return ret;
  
  last_resort:
-@@ -942,9 +957,7 @@ static int fib_inetaddr_event(struct not
+@@ -965,9 +979,7 @@ static int fib_inetaddr_event(struct not
  	switch (event) {
  	case NETDEV_UP:
  		fib_add_ifaddr(ifa);
 -#ifdef CONFIG_IP_ROUTE_MULTIPATH
  		fib_sync_up(dev);
 -#endif
+ 		atomic_inc(&net->ipv4.dev_addr_genid);
  		rt_cache_flush(dev_net(dev), -1);
  		break;
- 	case NETDEV_DOWN:
-@@ -980,9 +993,7 @@ static int fib_netdev_event(struct notif
+@@ -1006,9 +1018,7 @@ static int fib_netdev_event(struct notif
  		for_ifa(in_dev) {
  			fib_add_ifaddr(ifa);
  		} endfor_ifa(in_dev);
 -#ifdef CONFIG_IP_ROUTE_MULTIPATH
  		fib_sync_up(dev);
 -#endif
+ 		atomic_inc(&net->ipv4.dev_addr_genid);
  		rt_cache_flush(dev_net(dev), -1);
  		break;
- 	case NETDEV_DOWN:
-diff -urp v2.6.38/linux/net/ipv4/fib_hash.c linux/net/ipv4/fib_hash.c
---- v2.6.38/linux/net/ipv4/fib_hash.c	2011-03-20 12:05:41.000000000 +0200
-+++ linux/net/ipv4/fib_hash.c	2011-03-20 12:12:11.110247911 +0200
-@@ -305,27 +305,43 @@ out:
- void fib_table_select_default(struct fib_table *tb,
- 			      const struct flowi *flp, struct fib_result *res)
- {
--	int order, last_idx;
-+	int order, last_idx, last_dflt, last_nhsel, good;
-+	struct fib_alias *first_fa;
- 	struct hlist_node *node;
- 	struct fib_node *f;
--	struct fib_info *fi = NULL;
-+	struct fib_info *fi;
- 	struct fib_info *last_resort;
- 	struct fn_hash *t = (struct fn_hash *)tb->tb_data;
--	struct fn_zone *fz = t->fn_zones[0];
-+	struct fn_zone *fz = t->fn_zones[res->prefixlen];
- 	struct hlist_head *head;
-+	__be32 k;
-+	unsigned int seq;
- 
- 	if (fz == NULL)
- 		return;
- 
-+	k = fz_key(flp->fl4_dst, fz);
-+
-+	rcu_read_lock();
-+
-+retry:
-+	last_dflt = -2;
-+	last_nhsel = 0;
- 	last_idx = -1;
- 	last_resort = NULL;
- 	order = -1;
-+	fi = NULL;
-+	first_fa = NULL;
-+	good = 0;
- 
--	rcu_read_lock();
--	head = rcu_dereference(fz->fz_hash);
-+	seq = read_seqbegin(&fz->fz_lock);
-+	head = rcu_dereference(fz->fz_hash) + fn_hash(k, fz);
- 	hlist_for_each_entry_rcu(f, node, head, fn_hash) {
- 		struct fib_alias *fa;
- 
-+		if (f->fn_key != k)
-+			continue;
-+
- 		list_for_each_entry_rcu(fa, &f->fn_alias, fa_list) {
- 			struct fib_info *next_fi = fa->fa_info;
- 
-@@ -333,43 +349,66 @@ void fib_table_select_default(struct fib
- 			    fa->fa_type != RTN_UNICAST)
- 				continue;
- 
-+			if (fa->fa_tos &&
-+			    fa->fa_tos != flp->fl4_tos)
-+				continue;
- 			if (next_fi->fib_priority > res->fi->fib_priority)
- 				break;
--			if (!next_fi->fib_nh[0].nh_gw ||
--			    next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
--				continue;
- 
- 			fib_alias_accessed(fa);
- 
--			if (fi == NULL) {
--				if (next_fi != res->fi)
--					break;
--			} else if (!fib_detect_death(fi, order, &last_resort,
--						&last_idx, tb->tb_default)) {
--				fib_result_assign(res, fi);
--				tb->tb_default = order;
--				goto out;
-+			if (!first_fa) {
-+				last_dflt = fa->fa_last_dflt;
-+				first_fa = fa;
-+			}
-+			if (fi && !fib_detect_death(fi, order, &last_resort,
-+				&last_idx, &last_dflt, &last_nhsel, flp)) {
-+				good = 1;
-+				goto done1;
- 			}
- 			fi = next_fi;
- 			order++;
- 		}
-+		break;
-+	}
-+
-+done1:
-+	if (read_seqretry(&fz->fz_lock, seq))
-+		goto retry;
-+
-+	if (good) {
-+		fib_result_assign(res, fi);
-+		first_fa->fa_last_dflt = order;
-+		goto out;
- 	}
- 
- 	if (order <= 0 || fi == NULL) {
--		tb->tb_default = -1;
-+		if (fi && fi->fib_nhs > 1 &&
-+		    fib_detect_death(fi, order, &last_resort, &last_idx,
-+			&last_dflt, &last_nhsel, flp) &&
-+		    last_resort == fi) {
-+			read_lock_bh(&fib_nhflags_lock);
-+			fi->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT;
-+			read_unlock_bh(&fib_nhflags_lock);
-+		}
-+		if (first_fa) first_fa->fa_last_dflt = -1;
- 		goto out;
- 	}
- 
- 	if (!fib_detect_death(fi, order, &last_resort, &last_idx,
--				tb->tb_default)) {
-+			      &last_dflt, &last_nhsel, flp)) {
- 		fib_result_assign(res, fi);
--		tb->tb_default = order;
-+		first_fa->fa_last_dflt = order;
- 		goto out;
- 	}
- 
--	if (last_idx >= 0)
-+	if (last_idx >= 0) {
- 		fib_result_assign(res, last_resort);
--	tb->tb_default = last_idx;
-+		read_lock_bh(&fib_nhflags_lock);
-+		last_resort->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT;
-+		read_unlock_bh(&fib_nhflags_lock);
-+		first_fa->fa_last_dflt = last_idx;
-+	}
- out:
- 	rcu_read_unlock();
- }
-@@ -507,6 +546,7 @@ int fib_table_insert(struct fib_table *t
- 
- 			new_fa->fa_tos = fa->fa_tos;
- 			new_fa->fa_info = fi;
-+			new_fa->fa_last_dflt = -1;
- 			new_fa->fa_type = cfg->fc_type;
- 			new_fa->fa_scope = cfg->fc_scope;
- 			state = fa->fa_state;
-@@ -559,6 +599,7 @@ int fib_table_insert(struct fib_table *t
- 	new_fa->fa_type = cfg->fc_type;
- 	new_fa->fa_scope = cfg->fc_scope;
- 	new_fa->fa_state = 0;
-+	new_fa->fa_last_dflt = -1;
- 
- 	/*
- 	 * Insert new entry to the list.
-diff -urp v2.6.38/linux/net/ipv4/fib_lookup.h linux/net/ipv4/fib_lookup.h
---- v2.6.38/linux/net/ipv4/fib_lookup.h	2011-03-20 12:05:41.000000000 +0200
-+++ linux/net/ipv4/fib_lookup.h	2011-03-20 12:12:11.111246945 +0200
+diff -urp v2.6.39/linux/net/ipv4/fib_lookup.h linux/net/ipv4/fib_lookup.h
+--- v2.6.39/linux/net/ipv4/fib_lookup.h	2011-05-15 14:05:57.000000000 +0300
++++ linux/net/ipv4/fib_lookup.h	2011-05-15 14:07:59.982243815 +0300
 @@ -8,6 +8,7 @@
  struct fib_alias {
  	struct list_head	fa_list;
@@ -343,21 +199,21 @@
 +	int			fa_last_dflt;
  	u8			fa_tos;
  	u8			fa_type;
- 	u8			fa_scope;
-@@ -42,7 +43,8 @@ extern struct fib_alias *fib_find_alias(
+ 	u8			fa_state;
+@@ -38,7 +39,8 @@ extern struct fib_alias *fib_find_alias(
  					u8 tos, u32 prio);
  extern int fib_detect_death(struct fib_info *fi, int order,
  			    struct fib_info **last_resort,
 -			    int *last_idx, int dflt);
 +			    int *last_idx, int *dflt, int *last_nhsel,
-+			    const struct flowi *flp);
++			    const struct flowi4 *flp);
  
  static inline void fib_result_assign(struct fib_result *res,
  				     struct fib_info *fi)
-diff -urp v2.6.38/linux/net/ipv4/fib_rules.c linux/net/ipv4/fib_rules.c
---- v2.6.38/linux/net/ipv4/fib_rules.c	2011-03-20 12:05:41.000000000 +0200
-+++ linux/net/ipv4/fib_rules.c	2011-03-20 12:12:11.111246945 +0200
-@@ -53,6 +53,11 @@ u32 fib_rules_tclass(struct fib_result *
+diff -urp v2.6.39/linux/net/ipv4/fib_rules.c linux/net/ipv4/fib_rules.c
+--- v2.6.39/linux/net/ipv4/fib_rules.c	2011-05-15 14:05:57.000000000 +0300
++++ linux/net/ipv4/fib_rules.c	2011-05-15 14:07:59.982243815 +0300
+@@ -53,6 +53,11 @@ u32 fib_rules_tclass(const struct fib_re
  }
  #endif
  
@@ -366,22 +222,22 @@
 +	return res->r->table;
 +}
 +
- int fib_lookup(struct net *net, struct flowi *flp, struct fib_result *res)
+ int fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res)
  {
  	struct fib_lookup_arg arg = {
-diff -urp v2.6.38/linux/net/ipv4/fib_semantics.c linux/net/ipv4/fib_semantics.c
---- v2.6.38/linux/net/ipv4/fib_semantics.c	2011-03-20 12:05:50.000000000 +0200
-+++ linux/net/ipv4/fib_semantics.c	2011-03-20 12:13:20.143248500 +0200
+diff -urp v2.6.39/linux/net/ipv4/fib_semantics.c linux/net/ipv4/fib_semantics.c
+--- v2.6.39/linux/net/ipv4/fib_semantics.c	2011-05-15 14:05:57.000000000 +0300
++++ linux/net/ipv4/fib_semantics.c	2011-05-15 14:07:59.984246059 +0300
 @@ -51,6 +51,7 @@ static struct hlist_head *fib_info_hash;
  static struct hlist_head *fib_info_laddrhash;
- static unsigned int fib_hash_size;
+ static unsigned int fib_info_hash_size;
  static unsigned int fib_info_cnt;
-+rwlock_t fib_nhflags_lock = RW_LOCK_UNLOCKED;
++DEFINE_RWLOCK(fib_nhflags_lock);
  
  #define DEVINDEX_HASHBITS 8
  #define DEVINDEX_HASHSIZE (1U << DEVINDEX_HASHBITS)
-@@ -203,7 +204,7 @@ static inline int nh_comp(const struct f
- #ifdef CONFIG_NET_CLS_ROUTE
+@@ -201,7 +202,7 @@ static inline int nh_comp(const struct f
+ #ifdef CONFIG_IP_ROUTE_CLASSID
  		    nh->nh_tclassid != onh->nh_tclassid ||
  #endif
 -		    ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD))
@@ -389,22 +245,22 @@
  			return -1;
  		onh++;
  	} endfor_nexthops(fi);
-@@ -254,7 +255,7 @@ static struct fib_info *fib_find_info(co
+@@ -253,7 +254,7 @@ static struct fib_info *fib_find_info(co
  		    nfi->fib_priority == fi->fib_priority &&
  		    memcmp(nfi->fib_metrics, fi->fib_metrics,
- 			   sizeof(fi->fib_metrics)) == 0 &&
+ 			   sizeof(u32) * RTAX_MAX) == 0 &&
 -		    ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 &&
 +		    ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_BADSTATE) == 0 &&
  		    (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0))
  			return fi;
  	}
-@@ -365,26 +366,70 @@ struct fib_alias *fib_find_alias(struct 
+@@ -364,26 +365,70 @@ struct fib_alias *fib_find_alias(struct 
  }
  
  int fib_detect_death(struct fib_info *fi, int order,
 -		     struct fib_info **last_resort, int *last_idx, int dflt)
 +		     struct fib_info **last_resort, int *last_idx, int *dflt,
-+		     int *last_nhsel, const struct flowi *flp)
++		     int *last_nhsel, const struct flowi4 *flp)
  {
  	struct neighbour *n;
 -	int state = NUD_NONE;
@@ -416,7 +272,7 @@
 +
 +	/* change_nexthops(fi) { */
 +	for (nhsel = 0, nh = fi->fib_nh; nhsel < fi->fib_nhs; nh++, nhsel++) {
-+		if (flp->oif && flp->oif != nh->nh_oif)
++		if (flp->flowi4_oif && flp->flowi4_oif != nh->nh_oif)
 +			continue;
 +		if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw && nh->nh_gw &&
 +		    nh->nh_scope == RT_SCOPE_LINK)
@@ -445,7 +301,7 @@
 +
 +		dst = nh->nh_gw;
 +		if (!nh->nh_gw || nh->nh_scope != RT_SCOPE_LINK)
-+			dst = flp->fl4_dst;
++			dst = flp->daddr;
 +
 +		state = NUD_NONE;
 +		n = neigh_lookup(&arp_tbl, &dst, nh->nh_dev);
@@ -485,7 +341,7 @@
  }
  
  #ifdef CONFIG_IP_ROUTE_MULTIPATH
-@@ -553,8 +598,11 @@ static int fib_check_nh(struct fib_confi
+@@ -552,8 +597,11 @@ static int fib_check_nh(struct fib_confi
  			dev = __dev_get_by_index(net, nh->nh_oif);
  			if (!dev)
  				return -ENODEV;
@@ -499,10 +355,10 @@
  			nh->nh_dev = dev;
  			dev_hold(dev);
  			nh->nh_scope = RT_SCOPE_LINK;
-@@ -572,21 +620,41 @@ static int fib_check_nh(struct fib_confi
- 			if (fl.fl4_scope < RT_SCOPE_LINK)
- 				fl.fl4_scope = RT_SCOPE_LINK;
- 			err = fib_lookup(net, &fl, &res);
+@@ -571,21 +619,41 @@ static int fib_check_nh(struct fib_confi
+ 			if (fl4.flowi4_scope < RT_SCOPE_LINK)
+ 				fl4.flowi4_scope = RT_SCOPE_LINK;
+ 			err = fib_lookup(net, &fl4, &res);
 -			if (err) {
 -				rcu_read_unlock();
 -				return err;
@@ -554,7 +410,7 @@
  	} else {
  		struct in_device *in_dev;
  
-@@ -599,8 +667,11 @@ static int fib_check_nh(struct fib_confi
+@@ -598,8 +666,11 @@ static int fib_check_nh(struct fib_confi
  		if (in_dev == NULL)
  			goto out;
  		err = -ENETDOWN;
@@ -568,22 +424,7 @@
  		nh->nh_dev = in_dev->dev;
  		dev_hold(nh->nh_dev);
  		nh->nh_scope = RT_SCOPE_HOST;
-@@ -915,8 +986,12 @@ int fib_semantic_match(struct list_head 
- 				for_nexthops(fi) {
- 					if (nh->nh_flags & RTNH_F_DEAD)
- 						continue;
--					if (!flp->oif || flp->oif == nh->nh_oif)
--						break;
-+					if (flp->oif && flp->oif != nh->nh_oif)
-+						continue;
-+					if (flp->fl4_gw && flp->fl4_gw != nh->nh_gw &&
-+					    nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
-+						continue;
-+					break;
- 				}
- #ifdef CONFIG_IP_ROUTE_MULTIPATH
- 				if (nhsel < fi->fib_nhs) {
-@@ -1096,18 +1171,29 @@ int fib_sync_down_dev(struct net_device 
+@@ -1052,18 +1123,29 @@ int fib_sync_down_dev(struct net_device 
  		prev_fi = fi;
  		dead = 0;
  		change_nexthops(fi) {
@@ -621,8 +462,90 @@
  			}
  #ifdef CONFIG_IP_ROUTE_MULTIPATH
  			if (force > 1 && nexthop_nh->nh_dev == dev) {
-@@ -1125,11 +1211,8 @@ int fib_sync_down_dev(struct net_device 
- 	return ret;
+@@ -1082,12 +1164,12 @@ int fib_sync_down_dev(struct net_device 
+ }
+ 
+ /* Must be invoked inside of an RCU protected region.  */
+-void fib_select_default(struct fib_result *res)
++void fib_select_default(const struct flowi4 *flp, struct fib_result *res)
+ {
+ 	struct fib_info *fi = NULL, *last_resort = NULL;
+ 	struct list_head *fa_head = res->fa_head;
+-	struct fib_table *tb = res->table;
+-	int order = -1, last_idx = -1;
++	int order = -1, last_idx = -1, last_dflt = -2, last_nhsel = 0;
++	struct fib_alias *first_fa = NULL;
+ 	struct fib_alias *fa;
+ 
+ 	list_for_each_entry_rcu(fa, fa_head, fa_list) {
+@@ -1097,21 +1179,21 @@ void fib_select_default(struct fib_resul
+ 		    fa->fa_type != RTN_UNICAST)
+ 			continue;
+ 
++		if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos)
++			continue;
+ 		if (next_fi->fib_priority > res->fi->fib_priority)
+ 			break;
+-		if (!next_fi->fib_nh[0].nh_gw ||
+-		    next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
<<Diff was trimmed, longer than 597 lines>>

---- CVS-web:
    http://cvs.pld-linux.org/cgi-bin/cvsweb.cgi/packages/kernel/kernel-routes.patch?r1=1.13&r2=1.14&f=u



More information about the pld-cvs-commit mailing list