]> git.pld-linux.org Git - packages/kernel.git/blob - 01_alt_routes-2.5.50-8.diff
- CSZ scheduler removed from kernel tree.
[packages/kernel.git] / 01_alt_routes-2.5.50-8.diff
1 diff -ur v2.5.50/linux/include/linux/rtnetlink.h linux/include/linux/rtnetlink.h
2 --- v2.5.50/linux/include/linux/rtnetlink.h     Thu Oct 31 04:03:27 2002
3 +++ linux/include/linux/rtnetlink.h     Sun Dec  1 17:04:46 2002
4 @@ -229,6 +229,8 @@
5  #define RTNH_F_DEAD            1       /* Nexthop is dead (used by multipath)  */
6  #define RTNH_F_PERVASIVE       2       /* Do recursive gateway lookup  */
7  #define RTNH_F_ONLINK          4       /* Gateway is forced on link    */
8 +#define RTNH_F_SUSPECT         8       /* We don't know the real state */
9 +#define RTNH_F_BADSTATE                (RTNH_F_DEAD | RTNH_F_SUSPECT)
10  
11  /* Macros to handle hexthops */
12  
13 diff -ur v2.5.50/linux/include/net/ip_fib.h linux/include/net/ip_fib.h
14 --- v2.5.50/linux/include/net/ip_fib.h  Tue Nov 19 00:13:38 2002
15 +++ linux/include/net/ip_fib.h  Sun Dec  1 17:04:46 2002
16 @@ -162,7 +162,8 @@
17  
18  static inline void fib_select_default(const struct flowi *flp, struct fib_result *res)
19  {
20 -       if (FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK)
21 +       if ((FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) ||
22 +           FIB_RES_NH(*res).nh_scope == RT_SCOPE_HOST)
23                 ip_fib_main_table->tb_select_default(ip_fib_main_table, flp, res);
24  }
25  
26 @@ -174,6 +175,7 @@
27  extern int fib_lookup(const struct flowi *flp, struct fib_result *res);
28  extern struct fib_table *__fib_new_table(int id);
29  extern void fib_rule_put(struct fib_rule *r);
30 +extern __inline__ int fib_result_table(struct fib_result *res);
31  
32  static inline struct fib_table *fib_get_table(int id)
33  {
34 diff -ur v2.5.50/linux/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c
35 --- v2.5.50/linux/net/ipv4/fib_frontend.c       Thu Oct 17 03:43:21 2002
36 +++ linux/net/ipv4/fib_frontend.c       Sun Dec  1 17:04:46 2002
37 @@ -53,6 +53,8 @@
38  struct fib_table *ip_fib_local_table;
39  struct fib_table *ip_fib_main_table;
40  
41 +#define FIB_RES_TABLE(r) (RT_TABLE_MAIN)
42 +
43  #else
44  
45  #define RT_TABLE_MIN 1
46 @@ -70,6 +72,7 @@
47         return tb;
48  }
49  
50 +#define FIB_RES_TABLE(r) (fib_result_table(r))
51  
52  #endif /* CONFIG_IP_MULTIPLE_TABLES */
53  
54 @@ -167,6 +170,9 @@
55                                         .tos = tos } },
56                             .iif = oif };
57         struct fib_result res;
58 +       int table;
59 +       unsigned char prefixlen;
60 +       unsigned char scope;
61         int no_addr, rpf;
62         int ret;
63  
64 @@ -188,31 +194,35 @@
65                 goto e_inval_res;
66         *spec_dst = FIB_RES_PREFSRC(res);
67         fib_combine_itag(itag, &res);
68 -#ifdef CONFIG_IP_ROUTE_MULTIPATH
69 -       if (FIB_RES_DEV(res) == dev || res.fi->fib_nhs > 1)
70 -#else
71         if (FIB_RES_DEV(res) == dev)
72 -#endif
73         {
74                 ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
75                 fib_res_put(&res);
76                 return ret;
77         }
78 +       table = FIB_RES_TABLE(&res);
79 +       prefixlen = res.prefixlen;
80 +       scope = res.scope;
81         fib_res_put(&res);
82         if (no_addr)
83                 goto last_resort;
84 -       if (rpf)
85 -               goto e_inval;
86         fl.oif = dev->ifindex;
87  
88         ret = 0;
89         if (fib_lookup(&fl, &res) == 0) {
90 -               if (res.type == RTN_UNICAST) {
91 +               if (res.type == RTN_UNICAST &&
92 +                   ((table == FIB_RES_TABLE(&res) &&
93 +                     res.prefixlen >= prefixlen && res.scope >= scope) ||
94 +                    !rpf)) {
95                         *spec_dst = FIB_RES_PREFSRC(res);
96                         ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
97 +                       fib_res_put(&res);
98 +                       return ret;
99                 }
100                 fib_res_put(&res);
101         }
102 +       if (rpf)
103 +               goto e_inval;
104         return ret;
105  
106  last_resort:
107 diff -ur v2.5.50/linux/net/ipv4/fib_hash.c linux/net/ipv4/fib_hash.c
108 --- v2.5.50/linux/net/ipv4/fib_hash.c   Tue Nov 19 00:13:40 2002
109 +++ linux/net/ipv4/fib_hash.c   Sun Dec  1 17:04:46 2002
110 @@ -71,6 +71,7 @@
111         struct fib_info         *fn_info;
112  #define FIB_INFO(f)    ((f)->fn_info)
113         fn_key_t                fn_key;
114 +       int                     fn_last_dflt;
115         u8                      fn_tos;
116         u8                      fn_type;
117         u8                      fn_scope;
118 @@ -312,72 +313,120 @@
119         return err;
120  }
121  
122 -static int fn_hash_last_dflt=-1;
123 -
124 -static int fib_detect_death(struct fib_info *fi, int order,
125 -                           struct fib_info **last_resort, int *last_idx)
126 +static int fib_detect_death(struct fib_info *fi, int order, int last_dflt,
127 +                           struct fib_info **last_resort, int *last_idx,
128 +                           int *last_nhsel, const struct flowi *flp)
129  {
130         struct neighbour *n;
131 -       int state = NUD_NONE;
132 +       int nhsel;
133 +       int state;
134 +       struct fib_nh * nh;
135 +       u32 dst;
136 +       int flag, dead = 1;
137 +
138 +       /* change_nexthops(fi) { */
139 +       for (nhsel = 0, nh = fi->fib_nh; nhsel < fi->fib_nhs; nh++, nhsel++) {
140 +               if (flp->oif && flp->oif != nh->nh_oif)
141 +                       continue;
142 +               if (nh->nh_flags & RTNH_F_DEAD)
143 +                       continue;
144 +
145 +               flag = 0;
146 +               if (nh->nh_dev->flags & IFF_NOARP) {
147 +                       dead = 0;
148 +                       goto setfl;
149 +               }
150 +
151 +               dst = nh->nh_gw;
152 +               if (!nh->nh_gw || nh->nh_scope != RT_SCOPE_LINK)
153 +                       dst = flp->fl4_dst;
154 +
155 +               state = NUD_NONE;
156 +               n = neigh_lookup(&arp_tbl, &dst, nh->nh_dev);
157 +               if (n) {
158 +                       state = n->nud_state;
159 +                       neigh_release(n);
160 +               }
161 +               if (state==NUD_REACHABLE ||
162 +                       ((state&NUD_VALID) && order != last_dflt)) {
163 +                       dead = 0;
164 +                       goto setfl;
165 +               }
166 +               if (!(state&NUD_VALID))
167 +                       flag = 1;
168 +               if (!dead)
169 +                       goto setfl;
170 +               if ((state&NUD_VALID) ||
171 +                   (*last_idx<0 && order >= last_dflt)) {
172 +                       *last_resort = fi;
173 +                       *last_idx = order;
174 +                       *last_nhsel = nhsel;
175 +               }
176  
177 -       n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev);
178 -       if (n) {
179 -               state = n->nud_state;
180 -               neigh_release(n);
181 -       }
182 -       if (state==NUD_REACHABLE)
183 -               return 0;
184 -       if ((state&NUD_VALID) && order != fn_hash_last_dflt)
185 -               return 0;
186 -       if ((state&NUD_VALID) ||
187 -           (*last_idx<0 && order > fn_hash_last_dflt)) {
188 -               *last_resort = fi;
189 -               *last_idx = order;
190 +               setfl:
191 +
192 +               read_lock_bh(&fib_nhflags_lock);
193 +               if (flag)
194 +                       nh->nh_flags |= RTNH_F_SUSPECT;
195 +               else
196 +                       nh->nh_flags &= ~RTNH_F_SUSPECT;
197 +               read_unlock_bh(&fib_nhflags_lock);
198         }
199 -       return 1;
200 +       /* } endfor_nexthops(fi) */
201 +
202 +       return dead;
203  }
204  
205  static void
206  fn_hash_select_default(struct fib_table *tb, const struct flowi *flp, struct fib_result *res)
207  {
208 -       int order, last_idx;
209 -       struct fib_node *f;
210 +       int order, last_idx, last_dflt, last_nhsel;
211 +       struct fib_node *f, *first_node;
212         struct fib_info *fi = NULL;
213         struct fib_info *last_resort;
214         struct fn_hash *t = (struct fn_hash*)tb->tb_data;
215 -       struct fn_zone *fz = t->fn_zones[0];
216 +       struct fn_zone *fz = t->fn_zones[res->prefixlen];
217 +       fn_key_t k;
218  
219         if (fz == NULL)
220                 return;
221  
222 +       k = fz_key(flp->fl4_dst, fz);
223 +       last_dflt = -2;
224 +       first_node = NULL;
225         last_idx = -1;
226         last_resort = NULL;
227 +       last_nhsel = 0;
228         order = -1;
229  
230         read_lock(&fib_hash_lock);
231 -       for (f = fz->fz_hash[0]; f; f = f->fn_next) {
232 +       for (f = fz_chain(k, fz); f; f = f->fn_next) {
233                 struct fib_info *next_fi = FIB_INFO(f);
234  
235 -               if ((f->fn_state&FN_S_ZOMBIE) ||
236 +               if (!fn_key_eq(k, f->fn_key) ||
237 +                   (f->fn_state&FN_S_ZOMBIE) ||
238                     f->fn_scope != res->scope ||
239 +#ifdef CONFIG_IP_ROUTE_TOS
240 +                   (f->fn_tos && f->fn_tos != flp->fl4_tos) ||
241 +#endif
242                     f->fn_type != RTN_UNICAST)
243                         continue;
244  
245                 if (next_fi->fib_priority > res->fi->fib_priority)
246                         break;
247 -               if (!next_fi->fib_nh[0].nh_gw || next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
248 -                       continue;
249                 f->fn_state |= FN_S_ACCESSED;
250  
251 -               if (fi == NULL) {
252 -                       if (next_fi != res->fi)
253 -                               break;
254 -               } else if (!fib_detect_death(fi, order, &last_resort, &last_idx)) {
255 +               if (!first_node) {
256 +                       last_dflt = f->fn_last_dflt;
257 +                       first_node = f;
258 +               }
259 +               if (fi && !fib_detect_death(fi, order, last_dflt,
260 +                               &last_resort, &last_idx, &last_nhsel, flp)) {
261                         if (res->fi)
262                                 fib_info_put(res->fi);
263                         res->fi = fi;
264                         atomic_inc(&fi->fib_clntref);
265 -                       fn_hash_last_dflt = order;
266 +                       first_node->fn_last_dflt = order;
267                         goto out;
268                 }
269                 fi = next_fi;
270 @@ -385,16 +434,25 @@
271         }
272  
273         if (order<=0 || fi==NULL) {
274 -               fn_hash_last_dflt = -1;
275 +               if (fi && fi->fib_nhs > 1 &&
276 +                   fib_detect_death(fi, order, last_dflt,
277 +                       &last_resort, &last_idx, &last_nhsel, flp) &&
278 +                   last_resort == fi) {
279 +                       read_lock_bh(&fib_nhflags_lock);
280 +                       fi->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT;
281 +                       read_unlock_bh(&fib_nhflags_lock);
282 +               }
283 +               if (first_node) first_node->fn_last_dflt = -1;
284                 goto out;
285         }
286  
287 -       if (!fib_detect_death(fi, order, &last_resort, &last_idx)) {
288 +       if (!fib_detect_death(fi, order, last_dflt, &last_resort, &last_idx,
289 +                             &last_nhsel, flp)) {
290                 if (res->fi)
291                         fib_info_put(res->fi);
292                 res->fi = fi;
293                 atomic_inc(&fi->fib_clntref);
294 -               fn_hash_last_dflt = order;
295 +               first_node->fn_last_dflt = order;
296                 goto out;
297         }
298  
299 @@ -404,8 +462,11 @@
300                 res->fi = last_resort;
301                 if (last_resort)
302                         atomic_inc(&last_resort->fib_clntref);
303 +               read_lock_bh(&fib_nhflags_lock);
304 +               last_resort->fib_nh[last_nhsel].nh_flags &= ~RTNH_F_SUSPECT;
305 +               read_unlock_bh(&fib_nhflags_lock);
306 +               first_node->fn_last_dflt = last_idx;
307         }
308 -       fn_hash_last_dflt = last_idx;
309  out:
310         read_unlock(&fib_hash_lock);
311  }
312 @@ -567,6 +628,7 @@
313  
314         memset(new_f, 0, sizeof(struct fib_node));
315  
316 +       new_f->fn_last_dflt = -1;
317         new_f->fn_key = key;
318  #ifdef CONFIG_IP_ROUTE_TOS
319         new_f->fn_tos = tos;
320 diff -ur v2.5.50/linux/net/ipv4/fib_rules.c linux/net/ipv4/fib_rules.c
321 --- v2.5.50/linux/net/ipv4/fib_rules.c  Thu Oct 17 03:43:21 2002
322 +++ linux/net/ipv4/fib_rules.c  Sun Dec  1 17:04:46 2002
323 @@ -307,6 +307,11 @@
324         }
325  }
326  
327 +int fib_result_table(struct fib_result *res)
328 +{
329 +       return res->r->r_table;
330 +}
331 +
332  int fib_lookup(const struct flowi *flp, struct fib_result *res)
333  {
334         int err;
335 @@ -371,8 +376,10 @@
336  
337  void fib_select_default(const struct flowi *flp, struct fib_result *res)
338  {
339 -       if (res->r && res->r->r_action == RTN_UNICAST &&
340 -           FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) {
341 +       if (res->r &&
342 +           (res->r->r_action == RTN_UNICAST || res->r->r_action == RTN_NAT) &&
343 +           ((FIB_RES_GW(*res) && FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) ||
344 +            FIB_RES_NH(*res).nh_scope == RT_SCOPE_HOST)) {
345                 struct fib_table *tb;
346                 if ((tb = fib_get_table(res->r->r_table)) != NULL)
347                         tb->tb_select_default(tb, flp, res);
348 diff -ur v2.5.50/linux/net/ipv4/fib_semantics.c linux/net/ipv4/fib_semantics.c
349 --- v2.5.50/linux/net/ipv4/fib_semantics.c      Thu Oct 31 04:03:33 2002
350 +++ linux/net/ipv4/fib_semantics.c      Sun Dec  1 17:45:35 2002
351 @@ -150,7 +150,7 @@
352  #ifdef CONFIG_NET_CLS_ROUTE
353                     nh->nh_tclassid != onh->nh_tclassid ||
354  #endif
355 -                   ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD))
356 +                   ((nh->nh_flags^onh->nh_flags)&~RTNH_F_BADSTATE))
357                         return -1;
358                 onh++;
359         } endfor_nexthops(fi);
360 @@ -166,7 +166,7 @@
361                     nfi->fib_prefsrc == fi->fib_prefsrc &&
362                     nfi->fib_priority == fi->fib_priority &&
363                     memcmp(nfi->fib_metrics, fi->fib_metrics, sizeof(fi->fib_metrics)) == 0 &&
364 -                   ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 &&
365 +                   ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_BADSTATE) == 0 &&
366                     (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0))
367                         return fi;
368         } endfor_fib_info();
369 @@ -953,24 +953,42 @@
370  void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
371  {
372         struct fib_info *fi = res->fi;
373 -       int w;
374 +       int w, alive;
375  
376         spin_lock_bh(&fib_multipath_lock);
377 +       if (flp->oif) {
378 +               int sel = -1;
379 +               w = -1;
380 +               change_nexthops(fi) {
381 +                       if (flp->oif != nh->nh_oif)
382 +                               continue;
383 +                       if (!(nh->nh_flags&RTNH_F_BADSTATE)) {
384 +                               if (nh->nh_power > w) {
385 +                                       w = nh->nh_power;
386 +                                       sel = nhsel;
387 +                               }
388 +                       }
389 +               } endfor_nexthops(fi);
390 +               if (sel >= 0) {
391 +                       spin_unlock_bh(&fib_multipath_lock);
392 +                       res->nh_sel = sel;
393 +                       return;
394 +               }
395 +               goto last_resort;
396 +       }
397 +
398 +repeat:
399         if (fi->fib_power <= 0) {
400                 int power = 0;
401                 change_nexthops(fi) {
402 -                       if (!(nh->nh_flags&RTNH_F_DEAD)) {
403 +                       if (!(nh->nh_flags&RTNH_F_BADSTATE)) {
404                                 power += nh->nh_weight;
405                                 nh->nh_power = nh->nh_weight;
406                         }
407                 } endfor_nexthops(fi);
408                 fi->fib_power = power;
409 -               if (power <= 0) {
410 -                       spin_unlock_bh(&fib_multipath_lock);
411 -                       /* Race condition: route has just become dead. */
412 -                       res->nh_sel = 0;
413 -                       return;
414 -               }
415 +               if (power <= 0)
416 +                       goto last_resort;
417         }
418  
419  
420 @@ -980,20 +998,37 @@
421  
422         w = jiffies % fi->fib_power;
423  
424 +       alive = 0;
425         change_nexthops(fi) {
426 -               if (!(nh->nh_flags&RTNH_F_DEAD) && nh->nh_power) {
427 +               if (!(nh->nh_flags&RTNH_F_BADSTATE) && nh->nh_power) {
428                         if ((w -= nh->nh_power) <= 0) {
429                                 nh->nh_power--;
430                                 fi->fib_power--;
431 +                               spin_unlock_bh(&fib_multipath_lock);
432                                 res->nh_sel = nhsel;
433 +                               return;
434 +                       }
435 +                       alive = 1;
436 +               }
437 +       } endfor_nexthops(fi);
438 +       if (alive) {
439 +               fi->fib_power = 0;
440 +               goto repeat;
441 +       }
442 +
443 +last_resort:
444 +
445 +       for_nexthops(fi) {
446 +               if (!(nh->nh_flags&RTNH_F_DEAD)) {
447 +                       if (!flp->oif || flp->oif == nh->nh_oif) {
448                                 spin_unlock_bh(&fib_multipath_lock);
449 +                               res->nh_sel = nhsel;
450                                 return;
451                         }
452                 }
453         } endfor_nexthops(fi);
454  
455         /* Race condition: route has just become dead. */
456 -       res->nh_sel = 0;
457         spin_unlock_bh(&fib_multipath_lock);
458  }
459  #endif
460 diff -ur v2.5.50/linux/net/ipv4/route.c linux/net/ipv4/route.c
461 --- v2.5.50/linux/net/ipv4/route.c      Mon Nov 11 23:43:59 2002
462 +++ linux/net/ipv4/route.c      Sun Dec  1 17:04:46 2002
463 @@ -1433,8 +1433,9 @@
464         if (res.type != RTN_UNICAST)
465                 goto martian_destination;
466  
467 +       fib_select_default(&fl, &res);
468  #ifdef CONFIG_IP_ROUTE_MULTIPATH
469 -       if (res.fi->fib_nhs > 1 && fl.oif == 0)
470 +       if (res.fi->fib_nhs > 1)
471                 fib_select_multipath(&fl, &res);
472  #endif
473         out_dev = in_dev_get(FIB_RES_DEV(res));
474 @@ -1823,7 +1824,7 @@
475  
476         if (fib_lookup(&fl, &res)) {
477                 res.fi = NULL;
478 -               if (oldflp->oif) {
479 +               if (oldflp->oif && dev_out->flags&IFF_UP) {
480                         /* Apparently, routing tables are wrong. Assume,
481                            that the destination is on link.
482  
483 @@ -1873,13 +1874,12 @@
484                 goto make_route;
485         }
486  
487 +       if (res.type == RTN_UNICAST)
488 +               fib_select_default(&fl, &res);
489  #ifdef CONFIG_IP_ROUTE_MULTIPATH
490 -       if (res.fi->fib_nhs > 1 && fl.oif == 0)
491 +       if (res.fi->fib_nhs > 1)
492                 fib_select_multipath(&fl, &res);
493 -       else
494  #endif
495 -       if (!res.prefixlen && res.type == RTN_UNICAST && !fl.oif)
496 -               fib_select_default(&fl, &res);
497  
498         if (!fl.fl4_src)
499                 fl.fl4_src = FIB_RES_PREFSRC(res);
This page took 0.56469 seconds and 3 git commands to generate.