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