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

_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to