]> git.pld-linux.org Git - packages/kernel.git/blame - 00_static_routes-2.6.0-test1-8.diff
- obsolete (new driver name sym53c8xx_2 doesn't conflict now)
[packages/kernel.git] / 00_static_routes-2.6.0-test1-8.diff
CommitLineData
e7b0439e 1diff -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 */
11diff -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:
34diff -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 1.428592 seconds and 4 git commands to generate.