]> git.pld-linux.org Git - packages/kernel.git/blob - 00_static_routes-2.6.0-test1-8.diff
- CSZ scheduler removed from kernel tree.
[packages/kernel.git] / 00_static_routes-2.6.0-test1-8.diff
1 diff -ur v2.6.0-test1/linux/include/net/ip_fib.h linux/include/net/ip_fib.h
2 --- v2.6.0-test1/linux/include/net/ip_fib.h     Sat Jul 26 16:38:32 2003
3 +++ linux/include/net/ip_fib.h  Sun Jul 27 14:23:10 2003
4 @@ -280,4 +280,6 @@
5  #endif
6  }
7  
8 +extern rwlock_t fib_nhflags_lock;
9 +
10  #endif  /* _NET_FIB_H */
11 diff -ur v2.6.0-test1/linux/net/ipv4/fib_frontend.c linux/net/ipv4/fib_frontend.c
12 --- v2.6.0-test1/linux/net/ipv4/fib_frontend.c  Sat Jul 26 16:38:42 2003
13 +++ linux/net/ipv4/fib_frontend.c       Sun Jul 27 14:23:10 2003
14 @@ -530,9 +530,7 @@
15         switch (event) {
16         case NETDEV_UP:
17                 fib_add_ifaddr(ifa);
18 -#ifdef CONFIG_IP_ROUTE_MULTIPATH
19                 fib_sync_up(ifa->ifa_dev->dev);
20 -#endif
21                 rt_cache_flush(-1);
22                 break;
23         case NETDEV_DOWN:
24 @@ -568,9 +566,7 @@
25                 for_ifa(in_dev) {
26                         fib_add_ifaddr(ifa);
27                 } endfor_ifa(in_dev);
28 -#ifdef CONFIG_IP_ROUTE_MULTIPATH
29                 fib_sync_up(dev);
30 -#endif
31                 rt_cache_flush(-1);
32                 break;
33         case NETDEV_DOWN:
34 diff -ur v2.6.0-test1/linux/net/ipv4/fib_semantics.c linux/net/ipv4/fib_semantics.c
35 --- v2.6.0-test1/linux/net/ipv4/fib_semantics.c Sat Jul 26 16:38:42 2003
36 +++ linux/net/ipv4/fib_semantics.c      Sun Jul 27 14:23:10 2003
37 @@ -48,6 +48,7 @@
38  static struct fib_info         *fib_info_list;
39  static rwlock_t fib_info_lock = RW_LOCK_UNLOCKED;
40  int fib_info_cnt;
41 +rwlock_t fib_nhflags_lock = RW_LOCK_UNLOCKED;
42  
43  #define for_fib_info() { struct fib_info *fi; \
44         for (fi = fib_info_list; fi; fi = fi->fib_next)
45 @@ -403,8 +404,11 @@
46                                 return -EINVAL;
47                         if ((dev = __dev_get_by_index(nh->nh_oif)) == NULL)
48                                 return -ENODEV;
49 -                       if (!(dev->flags&IFF_UP))
50 -                               return -ENETDOWN;
51 +                       if (!(dev->flags&IFF_UP)) {
52 +                               if (fi->fib_protocol != RTPROT_STATIC)
53 +                                       return -ENETDOWN;
54 +                               nh->nh_flags |= RTNH_F_DEAD;
55 +                       }
56                         nh->nh_dev = dev;
57                         dev_hold(dev);
58                         nh->nh_scope = RT_SCOPE_LINK;
59 @@ -419,24 +423,48 @@
60                         /* It is not necessary, but requires a bit of thinking */
61                         if (fl.fl4_scope < RT_SCOPE_LINK)
62                                 fl.fl4_scope = RT_SCOPE_LINK;
63 -                       if ((err = fib_lookup(&fl, &res)) != 0)
64 -                               return err;
65 +                       err = fib_lookup(&fl, &res);
66                 }
67 -               err = -EINVAL;
68 -               if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
69 -                       goto out;
70 -               nh->nh_scope = res.scope;
71 -               nh->nh_oif = FIB_RES_OIF(res);
72 -               if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL)
73 -                       goto out;
74 -               dev_hold(nh->nh_dev);
75 -               err = -ENETDOWN;
76 -               if (!(nh->nh_dev->flags & IFF_UP))
77 -                       goto out;
78 -               err = 0;
79 +               if (err) {
80 +                       struct in_device *in_dev;
81 +
82 +                       if (err != -ENETUNREACH ||
83 +                           fi->fib_protocol != RTPROT_STATIC)
84 +                               return err;
85 +
86 +                       in_dev = inetdev_by_index(nh->nh_oif);
87 +                       if (in_dev == NULL ||
88 +                           in_dev->dev->flags & IFF_UP) {
89 +                               if (in_dev)
90 +                                       in_dev_put(in_dev);
91 +                               return err;
92 +                       }
93 +                       nh->nh_flags |= RTNH_F_DEAD;
94 +                       nh->nh_scope = RT_SCOPE_LINK;
95 +                       nh->nh_dev = in_dev->dev;
96 +                       dev_hold(nh->nh_dev);
97 +                       in_dev_put(in_dev);
98 +               } else {
99 +                       err = -EINVAL;
100 +                       if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
101 +                               goto out;
102 +                       nh->nh_scope = res.scope;
103 +                       nh->nh_oif = FIB_RES_OIF(res);
104 +                       if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL)
105 +                               goto out;
106 +                       dev_hold(nh->nh_dev);
107 +                       if (!(nh->nh_dev->flags & IFF_UP)) {
108 +                               if (fi->fib_protocol != RTPROT_STATIC) {
109 +                                       err = -ENETDOWN;
110 +                                       goto out;
111 +                               }
112 +                               nh->nh_flags |= RTNH_F_DEAD;
113 +                       }
114 +                       err = 0;
115  out:
116 -               fib_res_put(&res);
117 -               return err;
118 +                       fib_res_put(&res);
119 +                       return err;
120 +               }
121         } else {
122                 struct in_device *in_dev;
123  
124 @@ -447,8 +475,11 @@
125                 if (in_dev == NULL)
126                         return -ENODEV;
127                 if (!(in_dev->dev->flags&IFF_UP)) {
128 -                       in_dev_put(in_dev);
129 -                       return -ENETDOWN;
130 +                       if (fi->fib_protocol != RTPROT_STATIC) {
131 +                               in_dev_put(in_dev);
132 +                               return -ENETDOWN;
133 +                       }
134 +                       nh->nh_flags |= RTNH_F_DEAD;
135                 }
136                 nh->nh_dev = in_dev->dev;
137                 dev_hold(nh->nh_dev);
138 @@ -910,22 +941,35 @@
139                 if (local && fi->fib_prefsrc == local) {
140                         fi->fib_flags |= RTNH_F_DEAD;
141                         ret++;
142 -               } else if (dev && fi->fib_nhs) {
143 +               } else if (fi->fib_nhs) {
144                         int dead = 0;
145  
146                         change_nexthops(fi) {
147 -                               if (nh->nh_flags&RTNH_F_DEAD)
148 -                                       dead++;
149 -                               else if (nh->nh_dev == dev &&
150 -                                        nh->nh_scope != scope) {
151 -                                       nh->nh_flags |= RTNH_F_DEAD;
152 +                               if (nh->nh_flags&RTNH_F_DEAD) {
153 +                                       if (fi->fib_protocol!=RTPROT_STATIC ||
154 +                                           nh->nh_dev == NULL ||
155 +                                           !__in_dev_get(nh->nh_dev) ||
156 +                                           nh->nh_dev->flags&IFF_UP)
157 +                                               dead++;
158 +                               } else if ((nh->nh_dev == dev && dev &&
159 +                                           nh->nh_scope != scope) ||
160 +                                           (local == nh->nh_gw && local &&
161 +                                            nh->nh_oif)) {
162 +                                       write_lock_bh(&fib_nhflags_lock);
163  #ifdef CONFIG_IP_ROUTE_MULTIPATH
164 -                                       spin_lock_bh(&fib_multipath_lock);
165 +                                       spin_lock(&fib_multipath_lock);
166 +                                       nh->nh_flags |= RTNH_F_DEAD;
167                                         fi->fib_power -= nh->nh_power;
168                                         nh->nh_power = 0;
169 -                                       spin_unlock_bh(&fib_multipath_lock);
170 +                                       spin_unlock(&fib_multipath_lock);
171 +#else
172 +                                       nh->nh_flags |= RTNH_F_DEAD;
173  #endif
174 -                                       dead++;
175 +                                       write_unlock_bh(&fib_nhflags_lock);
176 +                                       if (fi->fib_protocol!=RTPROT_STATIC ||
177 +                                           force ||
178 +                                           (dev && __in_dev_get(dev) == NULL))
179 +                                               dead++;
180                                 }
181  #ifdef CONFIG_IP_ROUTE_MULTIPATH
182                                 if (force > 1 && nh->nh_dev == dev) {
183 @@ -943,37 +987,56 @@
184         return ret;
185  }
186  
187 -#ifdef CONFIG_IP_ROUTE_MULTIPATH
188 -
189  /*
190 -   Dead device goes up. We wake up dead nexthops.
191 -   It takes sense only on multipath routes.
192 +   Dead device goes up or new address is added. We wake up dead nexthops.
193   */
194  
195  int fib_sync_up(struct net_device *dev)
196  {
197 -       int ret = 0;
198 +       struct fib_result res;
199 +       int ret, rep;
200  
201 +repeat:
202         if (!(dev->flags&IFF_UP))
203                 return 0;
204  
205 +       ret = 0;
206 +       rep = 0;
207         for_fib_info() {
208                 int alive = 0;
209  
210                 change_nexthops(fi) {
211 -                       if (!(nh->nh_flags&RTNH_F_DEAD)) {
212 -                               alive++;
213 +                       if (!(nh->nh_flags&RTNH_F_DEAD))
214                                 continue;
215 -                       }
216                         if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP))
217                                 continue;
218                         if (nh->nh_dev != dev || __in_dev_get(dev) == NULL)
219                                 continue;
220 +                       if (nh->nh_gw && fi->fib_protocol == RTPROT_STATIC) {
221 +                               struct flowi fl = {
222 +                                       .nl_u = { .ip4_u =
223 +                                                 { .daddr = nh->nh_gw,
224 +                                                   .scope = nh->nh_scope } },
225 +                                       .oif =  nh->nh_oif,
226 +                               };
227 +                               if (fib_lookup(&fl, &res) != 0)
228 +                                       continue;
229 +                               if (res.type != RTN_UNICAST &&
230 +                                   res.type != RTN_LOCAL) {
231 +                                       fib_res_put(&res);
232 +                                       continue;
233 +                               }
234 +                               nh->nh_scope = res.scope;
235 +                               fib_res_put(&res);
236 +                               rep = 1;
237 +                       }
238                         alive++;
239 +#ifdef CONFIG_IP_ROUTE_MULTIPATH
240                         spin_lock_bh(&fib_multipath_lock);
241                         nh->nh_power = 0;
242                         nh->nh_flags &= ~RTNH_F_DEAD;
243                         spin_unlock_bh(&fib_multipath_lock);
244 +#endif
245                 } endfor_nexthops(fi)
246  
247                 if (alive > 0) {
248 @@ -981,8 +1044,12 @@
249                         ret++;
250                 }
251         } endfor_fib_info();
252 +       if (rep)
253 +               goto repeat;
254         return ret;
255  }
256 +
257 +#ifdef CONFIG_IP_ROUTE_MULTIPATH
258  
259  /*
260     The algorithm is suboptimal, but it provides really
This page took 0.110023 seconds and 3 git commands to generate.