aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r--net/ipv4/fib_semantics.c531
1 files changed, 275 insertions, 256 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 20f09c5b31e8..33e2c35b74b7 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -49,7 +49,7 @@
49static DEFINE_SPINLOCK(fib_info_lock); 49static DEFINE_SPINLOCK(fib_info_lock);
50static struct hlist_head *fib_info_hash; 50static struct hlist_head *fib_info_hash;
51static struct hlist_head *fib_info_laddrhash; 51static struct hlist_head *fib_info_laddrhash;
52static unsigned int fib_hash_size; 52static unsigned int fib_info_hash_size;
53static unsigned int fib_info_cnt; 53static unsigned int fib_info_cnt;
54 54
55#define DEVINDEX_HASHBITS 8 55#define DEVINDEX_HASHBITS 8
@@ -60,89 +60,93 @@ static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE];
60 60
61static DEFINE_SPINLOCK(fib_multipath_lock); 61static DEFINE_SPINLOCK(fib_multipath_lock);
62 62
63#define for_nexthops(fi) { int nhsel; const struct fib_nh * nh; \ 63#define for_nexthops(fi) { \
64for (nhsel=0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++) 64 int nhsel; const struct fib_nh *nh; \
65 for (nhsel = 0, nh = (fi)->fib_nh; \
66 nhsel < (fi)->fib_nhs; \
67 nh++, nhsel++)
65 68
66#define change_nexthops(fi) { int nhsel; struct fib_nh *nexthop_nh; \ 69#define change_nexthops(fi) { \
67for (nhsel=0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nexthop_nh++, nhsel++) 70 int nhsel; struct fib_nh *nexthop_nh; \
71 for (nhsel = 0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \
72 nhsel < (fi)->fib_nhs; \
73 nexthop_nh++, nhsel++)
68 74
69#else /* CONFIG_IP_ROUTE_MULTIPATH */ 75#else /* CONFIG_IP_ROUTE_MULTIPATH */
70 76
71/* Hope, that gcc will optimize it to get rid of dummy loop */ 77/* Hope, that gcc will optimize it to get rid of dummy loop */
72 78
73#define for_nexthops(fi) { int nhsel = 0; const struct fib_nh * nh = (fi)->fib_nh; \ 79#define for_nexthops(fi) { \
74for (nhsel=0; nhsel < 1; nhsel++) 80 int nhsel; const struct fib_nh *nh = (fi)->fib_nh; \
81 for (nhsel = 0; nhsel < 1; nhsel++)
75 82
76#define change_nexthops(fi) { int nhsel = 0; struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \ 83#define change_nexthops(fi) { \
77for (nhsel=0; nhsel < 1; nhsel++) 84 int nhsel; \
85 struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \
86 for (nhsel = 0; nhsel < 1; nhsel++)
78 87
79#endif /* CONFIG_IP_ROUTE_MULTIPATH */ 88#endif /* CONFIG_IP_ROUTE_MULTIPATH */
80 89
81#define endfor_nexthops(fi) } 90#define endfor_nexthops(fi) }
82 91
83 92
84static const struct 93const struct fib_prop fib_props[RTN_MAX + 1] = {
85{ 94 [RTN_UNSPEC] = {
86 int error;
87 u8 scope;
88} fib_props[RTN_MAX + 1] = {
89 {
90 .error = 0, 95 .error = 0,
91 .scope = RT_SCOPE_NOWHERE, 96 .scope = RT_SCOPE_NOWHERE,
92 }, /* RTN_UNSPEC */ 97 },
93 { 98 [RTN_UNICAST] = {
94 .error = 0, 99 .error = 0,
95 .scope = RT_SCOPE_UNIVERSE, 100 .scope = RT_SCOPE_UNIVERSE,
96 }, /* RTN_UNICAST */ 101 },
97 { 102 [RTN_LOCAL] = {
98 .error = 0, 103 .error = 0,
99 .scope = RT_SCOPE_HOST, 104 .scope = RT_SCOPE_HOST,
100 }, /* RTN_LOCAL */ 105 },
101 { 106 [RTN_BROADCAST] = {
102 .error = 0, 107 .error = 0,
103 .scope = RT_SCOPE_LINK, 108 .scope = RT_SCOPE_LINK,
104 }, /* RTN_BROADCAST */ 109 },
105 { 110 [RTN_ANYCAST] = {
106 .error = 0, 111 .error = 0,
107 .scope = RT_SCOPE_LINK, 112 .scope = RT_SCOPE_LINK,
108 }, /* RTN_ANYCAST */ 113 },
109 { 114 [RTN_MULTICAST] = {
110 .error = 0, 115 .error = 0,
111 .scope = RT_SCOPE_UNIVERSE, 116 .scope = RT_SCOPE_UNIVERSE,
112 }, /* RTN_MULTICAST */ 117 },
113 { 118 [RTN_BLACKHOLE] = {
114 .error = -EINVAL, 119 .error = -EINVAL,
115 .scope = RT_SCOPE_UNIVERSE, 120 .scope = RT_SCOPE_UNIVERSE,
116 }, /* RTN_BLACKHOLE */ 121 },
117 { 122 [RTN_UNREACHABLE] = {
118 .error = -EHOSTUNREACH, 123 .error = -EHOSTUNREACH,
119 .scope = RT_SCOPE_UNIVERSE, 124 .scope = RT_SCOPE_UNIVERSE,
120 }, /* RTN_UNREACHABLE */ 125 },
121 { 126 [RTN_PROHIBIT] = {
122 .error = -EACCES, 127 .error = -EACCES,
123 .scope = RT_SCOPE_UNIVERSE, 128 .scope = RT_SCOPE_UNIVERSE,
124 }, /* RTN_PROHIBIT */ 129 },
125 { 130 [RTN_THROW] = {
126 .error = -EAGAIN, 131 .error = -EAGAIN,
127 .scope = RT_SCOPE_UNIVERSE, 132 .scope = RT_SCOPE_UNIVERSE,
128 }, /* RTN_THROW */ 133 },
129 { 134 [RTN_NAT] = {
130 .error = -EINVAL, 135 .error = -EINVAL,
131 .scope = RT_SCOPE_NOWHERE, 136 .scope = RT_SCOPE_NOWHERE,
132 }, /* RTN_NAT */ 137 },
133 { 138 [RTN_XRESOLVE] = {
134 .error = -EINVAL, 139 .error = -EINVAL,
135 .scope = RT_SCOPE_NOWHERE, 140 .scope = RT_SCOPE_NOWHERE,
136 }, /* RTN_XRESOLVE */ 141 },
137}; 142};
138 143
139
140/* Release a nexthop info record */ 144/* Release a nexthop info record */
141 145
142void free_fib_info(struct fib_info *fi) 146void free_fib_info(struct fib_info *fi)
143{ 147{
144 if (fi->fib_dead == 0) { 148 if (fi->fib_dead == 0) {
145 printk(KERN_WARNING "Freeing alive fib_info %p\n", fi); 149 pr_warning("Freeing alive fib_info %p\n", fi);
146 return; 150 return;
147 } 151 }
148 change_nexthops(fi) { 152 change_nexthops(fi) {
@@ -152,7 +156,7 @@ void free_fib_info(struct fib_info *fi)
152 } endfor_nexthops(fi); 156 } endfor_nexthops(fi);
153 fib_info_cnt--; 157 fib_info_cnt--;
154 release_net(fi->fib_net); 158 release_net(fi->fib_net);
155 kfree(fi); 159 kfree_rcu(fi, rcu);
156} 160}
157 161
158void fib_release_info(struct fib_info *fi) 162void fib_release_info(struct fib_info *fi)
@@ -173,7 +177,7 @@ void fib_release_info(struct fib_info *fi)
173 spin_unlock_bh(&fib_info_lock); 177 spin_unlock_bh(&fib_info_lock);
174} 178}
175 179
176static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) 180static inline int nh_comp(const struct fib_info *fi, const struct fib_info *ofi)
177{ 181{
178 const struct fib_nh *onh = ofi->fib_nh; 182 const struct fib_nh *onh = ofi->fib_nh;
179 183
@@ -184,10 +188,10 @@ static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *
184#ifdef CONFIG_IP_ROUTE_MULTIPATH 188#ifdef CONFIG_IP_ROUTE_MULTIPATH
185 nh->nh_weight != onh->nh_weight || 189 nh->nh_weight != onh->nh_weight ||
186#endif 190#endif
187#ifdef CONFIG_NET_CLS_ROUTE 191#ifdef CONFIG_IP_ROUTE_CLASSID
188 nh->nh_tclassid != onh->nh_tclassid || 192 nh->nh_tclassid != onh->nh_tclassid ||
189#endif 193#endif
190 ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD)) 194 ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD))
191 return -1; 195 return -1;
192 onh++; 196 onh++;
193 } endfor_nexthops(fi); 197 } endfor_nexthops(fi);
@@ -205,10 +209,10 @@ static inline unsigned int fib_devindex_hashfn(unsigned int val)
205 209
206static inline unsigned int fib_info_hashfn(const struct fib_info *fi) 210static inline unsigned int fib_info_hashfn(const struct fib_info *fi)
207{ 211{
208 unsigned int mask = (fib_hash_size - 1); 212 unsigned int mask = (fib_info_hash_size - 1);
209 unsigned int val = fi->fib_nhs; 213 unsigned int val = fi->fib_nhs;
210 214
211 val ^= fi->fib_protocol; 215 val ^= (fi->fib_protocol << 8) | fi->fib_scope;
212 val ^= (__force u32)fi->fib_prefsrc; 216 val ^= (__force u32)fi->fib_prefsrc;
213 val ^= fi->fib_priority; 217 val ^= fi->fib_priority;
214 for_nexthops(fi) { 218 for_nexthops(fi) {
@@ -234,11 +238,12 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi)
234 if (fi->fib_nhs != nfi->fib_nhs) 238 if (fi->fib_nhs != nfi->fib_nhs)
235 continue; 239 continue;
236 if (nfi->fib_protocol == fi->fib_protocol && 240 if (nfi->fib_protocol == fi->fib_protocol &&
241 nfi->fib_scope == fi->fib_scope &&
237 nfi->fib_prefsrc == fi->fib_prefsrc && 242 nfi->fib_prefsrc == fi->fib_prefsrc &&
238 nfi->fib_priority == fi->fib_priority && 243 nfi->fib_priority == fi->fib_priority &&
239 memcmp(nfi->fib_metrics, fi->fib_metrics, 244 memcmp(nfi->fib_metrics, fi->fib_metrics,
240 sizeof(fi->fib_metrics)) == 0 && 245 sizeof(u32) * RTAX_MAX) == 0 &&
241 ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 && 246 ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 &&
242 (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0)) 247 (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0))
243 return fi; 248 return fi;
244 } 249 }
@@ -247,9 +252,8 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi)
247} 252}
248 253
249/* Check, that the gateway is already configured. 254/* Check, that the gateway is already configured.
250 Used only by redirect accept routine. 255 * Used only by redirect accept routine.
251 */ 256 */
252
253int ip_fib_check_default(__be32 gw, struct net_device *dev) 257int ip_fib_check_default(__be32 gw, struct net_device *dev)
254{ 258{
255 struct hlist_head *head; 259 struct hlist_head *head;
@@ -264,7 +268,7 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev)
264 hlist_for_each_entry(nh, node, head, nh_hash) { 268 hlist_for_each_entry(nh, node, head, nh_hash) {
265 if (nh->nh_dev == dev && 269 if (nh->nh_dev == dev &&
266 nh->nh_gw == gw && 270 nh->nh_gw == gw &&
267 !(nh->nh_flags&RTNH_F_DEAD)) { 271 !(nh->nh_flags & RTNH_F_DEAD)) {
268 spin_unlock(&fib_info_lock); 272 spin_unlock(&fib_info_lock);
269 return 0; 273 return 0;
270 } 274 }
@@ -315,7 +319,7 @@ void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
315 goto errout; 319 goto errout;
316 320
317 err = fib_dump_info(skb, info->pid, seq, event, tb_id, 321 err = fib_dump_info(skb, info->pid, seq, event, tb_id,
318 fa->fa_type, fa->fa_scope, key, dst_len, 322 fa->fa_type, key, dst_len,
319 fa->fa_tos, fa->fa_info, nlm_flags); 323 fa->fa_tos, fa->fa_info, nlm_flags);
320 if (err < 0) { 324 if (err < 0) {
321 /* -EMSGSIZE implies BUG in fib_nlmsg_size() */ 325 /* -EMSGSIZE implies BUG in fib_nlmsg_size() */
@@ -362,10 +366,10 @@ int fib_detect_death(struct fib_info *fi, int order,
362 } 366 }
363 if (state == NUD_REACHABLE) 367 if (state == NUD_REACHABLE)
364 return 0; 368 return 0;
365 if ((state&NUD_VALID) && order != dflt) 369 if ((state & NUD_VALID) && order != dflt)
366 return 0; 370 return 0;
367 if ((state&NUD_VALID) || 371 if ((state & NUD_VALID) ||
368 (*last_idx<0 && order > dflt)) { 372 (*last_idx < 0 && order > dflt)) {
369 *last_resort = fi; 373 *last_resort = fi;
370 *last_idx = order; 374 *last_idx = order;
371 } 375 }
@@ -407,7 +411,7 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
407 411
408 nla = nla_find(attrs, attrlen, RTA_GATEWAY); 412 nla = nla_find(attrs, attrlen, RTA_GATEWAY);
409 nexthop_nh->nh_gw = nla ? nla_get_be32(nla) : 0; 413 nexthop_nh->nh_gw = nla ? nla_get_be32(nla) : 0;
410#ifdef CONFIG_NET_CLS_ROUTE 414#ifdef CONFIG_IP_ROUTE_CLASSID
411 nla = nla_find(attrs, attrlen, RTA_FLOW); 415 nla = nla_find(attrs, attrlen, RTA_FLOW);
412 nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0; 416 nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0;
413#endif 417#endif
@@ -461,7 +465,7 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
461 nla = nla_find(attrs, attrlen, RTA_GATEWAY); 465 nla = nla_find(attrs, attrlen, RTA_GATEWAY);
462 if (nla && nla_get_be32(nla) != nh->nh_gw) 466 if (nla && nla_get_be32(nla) != nh->nh_gw)
463 return 1; 467 return 1;
464#ifdef CONFIG_NET_CLS_ROUTE 468#ifdef CONFIG_IP_ROUTE_CLASSID
465 nla = nla_find(attrs, attrlen, RTA_FLOW); 469 nla = nla_find(attrs, attrlen, RTA_FLOW);
466 if (nla && nla_get_u32(nla) != nh->nh_tclassid) 470 if (nla && nla_get_u32(nla) != nh->nh_tclassid)
467 return 1; 471 return 1;
@@ -476,145 +480,146 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
476 480
477 481
478/* 482/*
479 Picture 483 * Picture
480 ------- 484 * -------
481 485 *
482 Semantics of nexthop is very messy by historical reasons. 486 * Semantics of nexthop is very messy by historical reasons.
483 We have to take into account, that: 487 * We have to take into account, that:
484 a) gateway can be actually local interface address, 488 * a) gateway can be actually local interface address,
485 so that gatewayed route is direct. 489 * so that gatewayed route is direct.
486 b) gateway must be on-link address, possibly 490 * b) gateway must be on-link address, possibly
487 described not by an ifaddr, but also by a direct route. 491 * described not by an ifaddr, but also by a direct route.
488 c) If both gateway and interface are specified, they should not 492 * c) If both gateway and interface are specified, they should not
489 contradict. 493 * contradict.
490 d) If we use tunnel routes, gateway could be not on-link. 494 * d) If we use tunnel routes, gateway could be not on-link.
491 495 *
492 Attempt to reconcile all of these (alas, self-contradictory) conditions 496 * Attempt to reconcile all of these (alas, self-contradictory) conditions
493 results in pretty ugly and hairy code with obscure logic. 497 * results in pretty ugly and hairy code with obscure logic.
494 498 *
495 I chose to generalized it instead, so that the size 499 * I chose to generalized it instead, so that the size
496 of code does not increase practically, but it becomes 500 * of code does not increase practically, but it becomes
497 much more general. 501 * much more general.
498 Every prefix is assigned a "scope" value: "host" is local address, 502 * Every prefix is assigned a "scope" value: "host" is local address,
499 "link" is direct route, 503 * "link" is direct route,
500 [ ... "site" ... "interior" ... ] 504 * [ ... "site" ... "interior" ... ]
501 and "universe" is true gateway route with global meaning. 505 * and "universe" is true gateway route with global meaning.
502 506 *
503 Every prefix refers to a set of "nexthop"s (gw, oif), 507 * Every prefix refers to a set of "nexthop"s (gw, oif),
504 where gw must have narrower scope. This recursion stops 508 * where gw must have narrower scope. This recursion stops
505 when gw has LOCAL scope or if "nexthop" is declared ONLINK, 509 * when gw has LOCAL scope or if "nexthop" is declared ONLINK,
506 which means that gw is forced to be on link. 510 * which means that gw is forced to be on link.
507 511 *
508 Code is still hairy, but now it is apparently logically 512 * Code is still hairy, but now it is apparently logically
509 consistent and very flexible. F.e. as by-product it allows 513 * consistent and very flexible. F.e. as by-product it allows
510 to co-exists in peace independent exterior and interior 514 * to co-exists in peace independent exterior and interior
511 routing processes. 515 * routing processes.
512 516 *
513 Normally it looks as following. 517 * Normally it looks as following.
514 518 *
515 {universe prefix} -> (gw, oif) [scope link] 519 * {universe prefix} -> (gw, oif) [scope link]
516 | 520 * |
517 |-> {link prefix} -> (gw, oif) [scope local] 521 * |-> {link prefix} -> (gw, oif) [scope local]
518 | 522 * |
519 |-> {local prefix} (terminal node) 523 * |-> {local prefix} (terminal node)
520 */ 524 */
521
522static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, 525static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
523 struct fib_nh *nh) 526 struct fib_nh *nh)
524{ 527{
525 int err; 528 int err;
526 struct net *net; 529 struct net *net;
530 struct net_device *dev;
527 531
528 net = cfg->fc_nlinfo.nl_net; 532 net = cfg->fc_nlinfo.nl_net;
529 if (nh->nh_gw) { 533 if (nh->nh_gw) {
530 struct fib_result res; 534 struct fib_result res;
531 535
532 if (nh->nh_flags&RTNH_F_ONLINK) { 536 if (nh->nh_flags & RTNH_F_ONLINK) {
533 struct net_device *dev;
534 537
535 if (cfg->fc_scope >= RT_SCOPE_LINK) 538 if (cfg->fc_scope >= RT_SCOPE_LINK)
536 return -EINVAL; 539 return -EINVAL;
537 if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST) 540 if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST)
538 return -EINVAL; 541 return -EINVAL;
539 if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL) 542 dev = __dev_get_by_index(net, nh->nh_oif);
543 if (!dev)
540 return -ENODEV; 544 return -ENODEV;
541 if (!(dev->flags&IFF_UP)) 545 if (!(dev->flags & IFF_UP))
542 return -ENETDOWN; 546 return -ENETDOWN;
543 nh->nh_dev = dev; 547 nh->nh_dev = dev;
544 dev_hold(dev); 548 dev_hold(dev);
545 nh->nh_scope = RT_SCOPE_LINK; 549 nh->nh_scope = RT_SCOPE_LINK;
546 return 0; 550 return 0;
547 } 551 }
552 rcu_read_lock();
548 { 553 {
549 struct flowi fl = { 554 struct flowi4 fl4 = {
550 .nl_u = { 555 .daddr = nh->nh_gw,
551 .ip4_u = { 556 .flowi4_scope = cfg->fc_scope + 1,
552 .daddr = nh->nh_gw, 557 .flowi4_oif = nh->nh_oif,
553 .scope = cfg->fc_scope + 1,
554 },
555 },
556 .oif = nh->nh_oif,
557 }; 558 };
558 559
559 /* It is not necessary, but requires a bit of thinking */ 560 /* It is not necessary, but requires a bit of thinking */
560 if (fl.fl4_scope < RT_SCOPE_LINK) 561 if (fl4.flowi4_scope < RT_SCOPE_LINK)
561 fl.fl4_scope = RT_SCOPE_LINK; 562 fl4.flowi4_scope = RT_SCOPE_LINK;
562 if ((err = fib_lookup(net, &fl, &res)) != 0) 563 err = fib_lookup(net, &fl4, &res);
564 if (err) {
565 rcu_read_unlock();
563 return err; 566 return err;
567 }
564 } 568 }
565 err = -EINVAL; 569 err = -EINVAL;
566 if (res.type != RTN_UNICAST && res.type != RTN_LOCAL) 570 if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
567 goto out; 571 goto out;
568 nh->nh_scope = res.scope; 572 nh->nh_scope = res.scope;
569 nh->nh_oif = FIB_RES_OIF(res); 573 nh->nh_oif = FIB_RES_OIF(res);
570 if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL) 574 nh->nh_dev = dev = FIB_RES_DEV(res);
575 if (!dev)
571 goto out; 576 goto out;
572 dev_hold(nh->nh_dev); 577 dev_hold(dev);
573 err = -ENETDOWN; 578 err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN;
574 if (!(nh->nh_dev->flags & IFF_UP))
575 goto out;
576 err = 0;
577out:
578 fib_res_put(&res);
579 return err;
580 } else { 579 } else {
581 struct in_device *in_dev; 580 struct in_device *in_dev;
582 581
583 if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK)) 582 if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK))
584 return -EINVAL; 583 return -EINVAL;
585 584
585 rcu_read_lock();
586 err = -ENODEV;
586 in_dev = inetdev_by_index(net, nh->nh_oif); 587 in_dev = inetdev_by_index(net, nh->nh_oif);
587 if (in_dev == NULL) 588 if (in_dev == NULL)
588 return -ENODEV; 589 goto out;
589 if (!(in_dev->dev->flags&IFF_UP)) { 590 err = -ENETDOWN;
590 in_dev_put(in_dev); 591 if (!(in_dev->dev->flags & IFF_UP))
591 return -ENETDOWN; 592 goto out;
592 }
593 nh->nh_dev = in_dev->dev; 593 nh->nh_dev = in_dev->dev;
594 dev_hold(nh->nh_dev); 594 dev_hold(nh->nh_dev);
595 nh->nh_scope = RT_SCOPE_HOST; 595 nh->nh_scope = RT_SCOPE_HOST;
596 in_dev_put(in_dev); 596 err = 0;
597 } 597 }
598 return 0; 598out:
599 rcu_read_unlock();
600 return err;
599} 601}
600 602
601static inline unsigned int fib_laddr_hashfn(__be32 val) 603static inline unsigned int fib_laddr_hashfn(__be32 val)
602{ 604{
603 unsigned int mask = (fib_hash_size - 1); 605 unsigned int mask = (fib_info_hash_size - 1);
604 606
605 return ((__force u32)val ^ ((__force u32)val >> 7) ^ ((__force u32)val >> 14)) & mask; 607 return ((__force u32)val ^
608 ((__force u32)val >> 7) ^
609 ((__force u32)val >> 14)) & mask;
606} 610}
607 611
608static struct hlist_head *fib_hash_alloc(int bytes) 612static struct hlist_head *fib_info_hash_alloc(int bytes)
609{ 613{
610 if (bytes <= PAGE_SIZE) 614 if (bytes <= PAGE_SIZE)
611 return kzalloc(bytes, GFP_KERNEL); 615 return kzalloc(bytes, GFP_KERNEL);
612 else 616 else
613 return (struct hlist_head *) 617 return (struct hlist_head *)
614 __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(bytes)); 618 __get_free_pages(GFP_KERNEL | __GFP_ZERO,
619 get_order(bytes));
615} 620}
616 621
617static void fib_hash_free(struct hlist_head *hash, int bytes) 622static void fib_info_hash_free(struct hlist_head *hash, int bytes)
618{ 623{
619 if (!hash) 624 if (!hash)
620 return; 625 return;
@@ -625,18 +630,18 @@ static void fib_hash_free(struct hlist_head *hash, int bytes)
625 free_pages((unsigned long) hash, get_order(bytes)); 630 free_pages((unsigned long) hash, get_order(bytes));
626} 631}
627 632
628static void fib_hash_move(struct hlist_head *new_info_hash, 633static void fib_info_hash_move(struct hlist_head *new_info_hash,
629 struct hlist_head *new_laddrhash, 634 struct hlist_head *new_laddrhash,
630 unsigned int new_size) 635 unsigned int new_size)
631{ 636{
632 struct hlist_head *old_info_hash, *old_laddrhash; 637 struct hlist_head *old_info_hash, *old_laddrhash;
633 unsigned int old_size = fib_hash_size; 638 unsigned int old_size = fib_info_hash_size;
634 unsigned int i, bytes; 639 unsigned int i, bytes;
635 640
636 spin_lock_bh(&fib_info_lock); 641 spin_lock_bh(&fib_info_lock);
637 old_info_hash = fib_info_hash; 642 old_info_hash = fib_info_hash;
638 old_laddrhash = fib_info_laddrhash; 643 old_laddrhash = fib_info_laddrhash;
639 fib_hash_size = new_size; 644 fib_info_hash_size = new_size;
640 645
641 for (i = 0; i < old_size; i++) { 646 for (i = 0; i < old_size; i++) {
642 struct hlist_head *head = &fib_info_hash[i]; 647 struct hlist_head *head = &fib_info_hash[i];
@@ -677,8 +682,18 @@ static void fib_hash_move(struct hlist_head *new_info_hash,
677 spin_unlock_bh(&fib_info_lock); 682 spin_unlock_bh(&fib_info_lock);
678 683
679 bytes = old_size * sizeof(struct hlist_head *); 684 bytes = old_size * sizeof(struct hlist_head *);
680 fib_hash_free(old_info_hash, bytes); 685 fib_info_hash_free(old_info_hash, bytes);
681 fib_hash_free(old_laddrhash, bytes); 686 fib_info_hash_free(old_laddrhash, bytes);
687}
688
689__be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh)
690{
691 nh->nh_saddr = inet_select_addr(nh->nh_dev,
692 nh->nh_gw,
693 nh->nh_parent->fib_scope);
694 nh->nh_saddr_genid = atomic_read(&net->ipv4.dev_addr_genid);
695
696 return nh->nh_saddr;
682} 697}
683 698
684struct fib_info *fib_create_info(struct fib_config *cfg) 699struct fib_info *fib_create_info(struct fib_config *cfg)
@@ -689,6 +704,9 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
689 int nhs = 1; 704 int nhs = 1;
690 struct net *net = cfg->fc_nlinfo.nl_net; 705 struct net *net = cfg->fc_nlinfo.nl_net;
691 706
707 if (cfg->fc_type > RTN_MAX)
708 goto err_inval;
709
692 /* Fast check to catch the most weird cases */ 710 /* Fast check to catch the most weird cases */
693 if (fib_props[cfg->fc_type].scope > cfg->fc_scope) 711 if (fib_props[cfg->fc_type].scope > cfg->fc_scope)
694 goto err_inval; 712 goto err_inval;
@@ -702,8 +720,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
702#endif 720#endif
703 721
704 err = -ENOBUFS; 722 err = -ENOBUFS;
705 if (fib_info_cnt >= fib_hash_size) { 723 if (fib_info_cnt >= fib_info_hash_size) {
706 unsigned int new_size = fib_hash_size << 1; 724 unsigned int new_size = fib_info_hash_size << 1;
707 struct hlist_head *new_info_hash; 725 struct hlist_head *new_info_hash;
708 struct hlist_head *new_laddrhash; 726 struct hlist_head *new_laddrhash;
709 unsigned int bytes; 727 unsigned int bytes;
@@ -711,25 +729,32 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
711 if (!new_size) 729 if (!new_size)
712 new_size = 1; 730 new_size = 1;
713 bytes = new_size * sizeof(struct hlist_head *); 731 bytes = new_size * sizeof(struct hlist_head *);
714 new_info_hash = fib_hash_alloc(bytes); 732 new_info_hash = fib_info_hash_alloc(bytes);
715 new_laddrhash = fib_hash_alloc(bytes); 733 new_laddrhash = fib_info_hash_alloc(bytes);
716 if (!new_info_hash || !new_laddrhash) { 734 if (!new_info_hash || !new_laddrhash) {
717 fib_hash_free(new_info_hash, bytes); 735 fib_info_hash_free(new_info_hash, bytes);
718 fib_hash_free(new_laddrhash, bytes); 736 fib_info_hash_free(new_laddrhash, bytes);
719 } else 737 } else
720 fib_hash_move(new_info_hash, new_laddrhash, new_size); 738 fib_info_hash_move(new_info_hash, new_laddrhash, new_size);
721 739
722 if (!fib_hash_size) 740 if (!fib_info_hash_size)
723 goto failure; 741 goto failure;
724 } 742 }
725 743
726 fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL); 744 fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
727 if (fi == NULL) 745 if (fi == NULL)
728 goto failure; 746 goto failure;
747 if (cfg->fc_mx) {
748 fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL);
749 if (!fi->fib_metrics)
750 goto failure;
751 } else
752 fi->fib_metrics = (u32 *) dst_default_metrics;
729 fib_info_cnt++; 753 fib_info_cnt++;
730 754
731 fi->fib_net = hold_net(net); 755 fi->fib_net = hold_net(net);
732 fi->fib_protocol = cfg->fc_protocol; 756 fi->fib_protocol = cfg->fc_protocol;
757 fi->fib_scope = cfg->fc_scope;
733 fi->fib_flags = cfg->fc_flags; 758 fi->fib_flags = cfg->fc_flags;
734 fi->fib_priority = cfg->fc_priority; 759 fi->fib_priority = cfg->fc_priority;
735 fi->fib_prefsrc = cfg->fc_prefsrc; 760 fi->fib_prefsrc = cfg->fc_prefsrc;
@@ -763,7 +788,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
763 goto err_inval; 788 goto err_inval;
764 if (cfg->fc_gw && fi->fib_nh->nh_gw != cfg->fc_gw) 789 if (cfg->fc_gw && fi->fib_nh->nh_gw != cfg->fc_gw)
765 goto err_inval; 790 goto err_inval;
766#ifdef CONFIG_NET_CLS_ROUTE 791#ifdef CONFIG_IP_ROUTE_CLASSID
767 if (cfg->fc_flow && fi->fib_nh->nh_tclassid != cfg->fc_flow) 792 if (cfg->fc_flow && fi->fib_nh->nh_tclassid != cfg->fc_flow)
768 goto err_inval; 793 goto err_inval;
769#endif 794#endif
@@ -776,7 +801,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
776 nh->nh_oif = cfg->fc_oif; 801 nh->nh_oif = cfg->fc_oif;
777 nh->nh_gw = cfg->fc_gw; 802 nh->nh_gw = cfg->fc_gw;
778 nh->nh_flags = cfg->fc_flags; 803 nh->nh_flags = cfg->fc_flags;
779#ifdef CONFIG_NET_CLS_ROUTE 804#ifdef CONFIG_IP_ROUTE_CLASSID
780 nh->nh_tclassid = cfg->fc_flow; 805 nh->nh_tclassid = cfg->fc_flow;
781#endif 806#endif
782#ifdef CONFIG_IP_ROUTE_MULTIPATH 807#ifdef CONFIG_IP_ROUTE_MULTIPATH
@@ -788,6 +813,17 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
788 if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp) 813 if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp)
789 goto err_inval; 814 goto err_inval;
790 goto link_it; 815 goto link_it;
816 } else {
817 switch (cfg->fc_type) {
818 case RTN_UNICAST:
819 case RTN_LOCAL:
820 case RTN_BROADCAST:
821 case RTN_ANYCAST:
822 case RTN_MULTICAST:
823 break;
824 default:
825 goto err_inval;
826 }
791 } 827 }
792 828
793 if (cfg->fc_scope > RT_SCOPE_HOST) 829 if (cfg->fc_scope > RT_SCOPE_HOST)
@@ -806,7 +842,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
806 goto failure; 842 goto failure;
807 } else { 843 } else {
808 change_nexthops(fi) { 844 change_nexthops(fi) {
809 if ((err = fib_check_nh(cfg, fi, nexthop_nh)) != 0) 845 err = fib_check_nh(cfg, fi, nexthop_nh);
846 if (err != 0)
810 goto failure; 847 goto failure;
811 } endfor_nexthops(fi) 848 } endfor_nexthops(fi)
812 } 849 }
@@ -818,8 +855,13 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
818 goto err_inval; 855 goto err_inval;
819 } 856 }
820 857
858 change_nexthops(fi) {
859 fib_info_update_nh_saddr(net, nexthop_nh);
860 } endfor_nexthops(fi)
861
821link_it: 862link_it:
822 if ((ofi = fib_find_info(fi)) != NULL) { 863 ofi = fib_find_info(fi);
864 if (ofi) {
823 fi->fib_dead = 1; 865 fi->fib_dead = 1;
824 free_fib_info(fi); 866 free_fib_info(fi);
825 ofi->fib_treeref++; 867 ofi->fib_treeref++;
@@ -862,86 +904,8 @@ failure:
862 return ERR_PTR(err); 904 return ERR_PTR(err);
863} 905}
864 906
865/* Note! fib_semantic_match intentionally uses RCU list functions. */
866int fib_semantic_match(struct list_head *head, const struct flowi *flp,
867 struct fib_result *res, int prefixlen)
868{
869 struct fib_alias *fa;
870 int nh_sel = 0;
871
872 list_for_each_entry_rcu(fa, head, fa_list) {
873 int err;
874
875 if (fa->fa_tos &&
876 fa->fa_tos != flp->fl4_tos)
877 continue;
878
879 if (fa->fa_scope < flp->fl4_scope)
880 continue;
881
882 fa->fa_state |= FA_S_ACCESSED;
883
884 err = fib_props[fa->fa_type].error;
885 if (err == 0) {
886 struct fib_info *fi = fa->fa_info;
887
888 if (fi->fib_flags & RTNH_F_DEAD)
889 continue;
890
891 switch (fa->fa_type) {
892 case RTN_UNICAST:
893 case RTN_LOCAL:
894 case RTN_BROADCAST:
895 case RTN_ANYCAST:
896 case RTN_MULTICAST:
897 for_nexthops(fi) {
898 if (nh->nh_flags&RTNH_F_DEAD)
899 continue;
900 if (!flp->oif || flp->oif == nh->nh_oif)
901 break;
902 }
903#ifdef CONFIG_IP_ROUTE_MULTIPATH
904 if (nhsel < fi->fib_nhs) {
905 nh_sel = nhsel;
906 goto out_fill_res;
907 }
908#else
909 if (nhsel < 1) {
910 goto out_fill_res;
911 }
912#endif
913 endfor_nexthops(fi);
914 continue;
915
916 default:
917 printk(KERN_WARNING "fib_semantic_match bad type %#x\n",
918 fa->fa_type);
919 return -EINVAL;
920 }
921 }
922 return err;
923 }
924 return 1;
925
926out_fill_res:
927 res->prefixlen = prefixlen;
928 res->nh_sel = nh_sel;
929 res->type = fa->fa_type;
930 res->scope = fa->fa_scope;
931 res->fi = fa->fa_info;
932 atomic_inc(&res->fi->fib_clntref);
933 return 0;
934}
935
936/* Find appropriate source address to this destination */
937
938__be32 __fib_res_prefsrc(struct fib_result *res)
939{
940 return inet_select_addr(FIB_RES_DEV(*res), FIB_RES_GW(*res), res->scope);
941}
942
943int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, 907int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
944 u32 tb_id, u8 type, u8 scope, __be32 dst, int dst_len, u8 tos, 908 u32 tb_id, u8 type, __be32 dst, int dst_len, u8 tos,
945 struct fib_info *fi, unsigned int flags) 909 struct fib_info *fi, unsigned int flags)
946{ 910{
947 struct nlmsghdr *nlh; 911 struct nlmsghdr *nlh;
@@ -963,7 +927,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
963 NLA_PUT_U32(skb, RTA_TABLE, tb_id); 927 NLA_PUT_U32(skb, RTA_TABLE, tb_id);
964 rtm->rtm_type = type; 928 rtm->rtm_type = type;
965 rtm->rtm_flags = fi->fib_flags; 929 rtm->rtm_flags = fi->fib_flags;
966 rtm->rtm_scope = scope; 930 rtm->rtm_scope = fi->fib_scope;
967 rtm->rtm_protocol = fi->fib_protocol; 931 rtm->rtm_protocol = fi->fib_protocol;
968 932
969 if (rtm->rtm_dst_len) 933 if (rtm->rtm_dst_len)
@@ -984,7 +948,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
984 948
985 if (fi->fib_nh->nh_oif) 949 if (fi->fib_nh->nh_oif)
986 NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif); 950 NLA_PUT_U32(skb, RTA_OIF, fi->fib_nh->nh_oif);
987#ifdef CONFIG_NET_CLS_ROUTE 951#ifdef CONFIG_IP_ROUTE_CLASSID
988 if (fi->fib_nh[0].nh_tclassid) 952 if (fi->fib_nh[0].nh_tclassid)
989 NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid); 953 NLA_PUT_U32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid);
990#endif 954#endif
@@ -1009,7 +973,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
1009 973
1010 if (nh->nh_gw) 974 if (nh->nh_gw)
1011 NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw); 975 NLA_PUT_BE32(skb, RTA_GATEWAY, nh->nh_gw);
1012#ifdef CONFIG_NET_CLS_ROUTE 976#ifdef CONFIG_IP_ROUTE_CLASSID
1013 if (nh->nh_tclassid) 977 if (nh->nh_tclassid)
1014 NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid); 978 NLA_PUT_U32(skb, RTA_FLOW, nh->nh_tclassid);
1015#endif 979#endif
@@ -1028,10 +992,10 @@ nla_put_failure:
1028} 992}
1029 993
1030/* 994/*
1031 Update FIB if: 995 * Update FIB if:
1032 - local address disappeared -> we must delete all the entries 996 * - local address disappeared -> we must delete all the entries
1033 referring to it. 997 * referring to it.
1034 - device went down -> we must shutdown all nexthops going via it. 998 * - device went down -> we must shutdown all nexthops going via it.
1035 */ 999 */
1036int fib_sync_down_addr(struct net *net, __be32 local) 1000int fib_sync_down_addr(struct net *net, __be32 local)
1037{ 1001{
@@ -1078,7 +1042,7 @@ int fib_sync_down_dev(struct net_device *dev, int force)
1078 prev_fi = fi; 1042 prev_fi = fi;
1079 dead = 0; 1043 dead = 0;
1080 change_nexthops(fi) { 1044 change_nexthops(fi) {
1081 if (nexthop_nh->nh_flags&RTNH_F_DEAD) 1045 if (nexthop_nh->nh_flags & RTNH_F_DEAD)
1082 dead++; 1046 dead++;
1083 else if (nexthop_nh->nh_dev == dev && 1047 else if (nexthop_nh->nh_dev == dev &&
1084 nexthop_nh->nh_scope != scope) { 1048 nexthop_nh->nh_scope != scope) {
@@ -1107,13 +1071,68 @@ int fib_sync_down_dev(struct net_device *dev, int force)
1107 return ret; 1071 return ret;
1108} 1072}
1109 1073
1074/* Must be invoked inside of an RCU protected region. */
1075void fib_select_default(struct fib_result *res)
1076{
1077 struct fib_info *fi = NULL, *last_resort = NULL;
1078 struct list_head *fa_head = res->fa_head;
1079 struct fib_table *tb = res->table;
1080 int order = -1, last_idx = -1;
1081 struct fib_alias *fa;
1082
1083 list_for_each_entry_rcu(fa, fa_head, fa_list) {
1084 struct fib_info *next_fi = fa->fa_info;
1085
1086 if (next_fi->fib_scope != res->scope ||
1087 fa->fa_type != RTN_UNICAST)
1088 continue;
1089
1090 if (next_fi->fib_priority > res->fi->fib_priority)
1091 break;
1092 if (!next_fi->fib_nh[0].nh_gw ||
1093 next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
1094 continue;
1095
1096 fib_alias_accessed(fa);
1097
1098 if (fi == NULL) {
1099 if (next_fi != res->fi)
1100 break;
1101 } else if (!fib_detect_death(fi, order, &last_resort,
1102 &last_idx, tb->tb_default)) {
1103 fib_result_assign(res, fi);
1104 tb->tb_default = order;
1105 goto out;
1106 }
1107 fi = next_fi;
1108 order++;
1109 }
1110
1111 if (order <= 0 || fi == NULL) {
1112 tb->tb_default = -1;
1113 goto out;
1114 }
1115
1116 if (!fib_detect_death(fi, order, &last_resort, &last_idx,
1117 tb->tb_default)) {
1118 fib_result_assign(res, fi);
1119 tb->tb_default = order;
1120 goto out;
1121 }
1122
1123 if (last_idx >= 0)
1124 fib_result_assign(res, last_resort);
1125 tb->tb_default = last_idx;
1126out:
1127 return;
1128}
1129
1110#ifdef CONFIG_IP_ROUTE_MULTIPATH 1130#ifdef CONFIG_IP_ROUTE_MULTIPATH
1111 1131
1112/* 1132/*
1113 Dead device goes up. We wake up dead nexthops. 1133 * Dead device goes up. We wake up dead nexthops.
1114 It takes sense only on multipath routes. 1134 * It takes sense only on multipath routes.
1115 */ 1135 */
1116
1117int fib_sync_up(struct net_device *dev) 1136int fib_sync_up(struct net_device *dev)
1118{ 1137{
1119 struct fib_info *prev_fi; 1138 struct fib_info *prev_fi;
@@ -1123,7 +1142,7 @@ int fib_sync_up(struct net_device *dev)
1123 struct fib_nh *nh; 1142 struct fib_nh *nh;
1124 int ret; 1143 int ret;
1125 1144
1126 if (!(dev->flags&IFF_UP)) 1145 if (!(dev->flags & IFF_UP))
1127 return 0; 1146 return 0;
1128 1147
1129 prev_fi = NULL; 1148 prev_fi = NULL;
@@ -1142,12 +1161,12 @@ int fib_sync_up(struct net_device *dev)
1142 prev_fi = fi; 1161 prev_fi = fi;
1143 alive = 0; 1162 alive = 0;
1144 change_nexthops(fi) { 1163 change_nexthops(fi) {
1145 if (!(nexthop_nh->nh_flags&RTNH_F_DEAD)) { 1164 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
1146 alive++; 1165 alive++;
1147 continue; 1166 continue;
1148 } 1167 }
1149 if (nexthop_nh->nh_dev == NULL || 1168 if (nexthop_nh->nh_dev == NULL ||
1150 !(nexthop_nh->nh_dev->flags&IFF_UP)) 1169 !(nexthop_nh->nh_dev->flags & IFF_UP))
1151 continue; 1170 continue;
1152 if (nexthop_nh->nh_dev != dev || 1171 if (nexthop_nh->nh_dev != dev ||
1153 !__in_dev_get_rtnl(dev)) 1172 !__in_dev_get_rtnl(dev))
@@ -1169,11 +1188,10 @@ int fib_sync_up(struct net_device *dev)
1169} 1188}
1170 1189
1171/* 1190/*
1172 The algorithm is suboptimal, but it provides really 1191 * The algorithm is suboptimal, but it provides really
1173 fair weighted route distribution. 1192 * fair weighted route distribution.
1174 */ 1193 */
1175 1194void fib_select_multipath(struct fib_result *res)
1176void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
1177{ 1195{
1178 struct fib_info *fi = res->fi; 1196 struct fib_info *fi = res->fi;
1179 int w; 1197 int w;
@@ -1182,7 +1200,7 @@ void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
1182 if (fi->fib_power <= 0) { 1200 if (fi->fib_power <= 0) {
1183 int power = 0; 1201 int power = 0;
1184 change_nexthops(fi) { 1202 change_nexthops(fi) {
1185 if (!(nexthop_nh->nh_flags&RTNH_F_DEAD)) { 1203 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
1186 power += nexthop_nh->nh_weight; 1204 power += nexthop_nh->nh_weight;
1187 nexthop_nh->nh_power = nexthop_nh->nh_weight; 1205 nexthop_nh->nh_power = nexthop_nh->nh_weight;
1188 } 1206 }
@@ -1198,15 +1216,16 @@ void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
1198 1216
1199 1217
1200 /* w should be random number [0..fi->fib_power-1], 1218 /* w should be random number [0..fi->fib_power-1],
1201 it is pretty bad approximation. 1219 * it is pretty bad approximation.
1202 */ 1220 */
1203 1221
1204 w = jiffies % fi->fib_power; 1222 w = jiffies % fi->fib_power;
1205 1223
1206 change_nexthops(fi) { 1224 change_nexthops(fi) {
1207 if (!(nexthop_nh->nh_flags&RTNH_F_DEAD) && 1225 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD) &&
1208 nexthop_nh->nh_power) { 1226 nexthop_nh->nh_power) {
1209 if ((w -= nexthop_nh->nh_power) <= 0) { 1227 w -= nexthop_nh->nh_power;
1228 if (w <= 0) {
1210 nexthop_nh->nh_power--; 1229 nexthop_nh->nh_power--;
1211 fi->fib_power--; 1230 fi->fib_power--;
1212 res->nh_sel = nhsel; 1231 res->nh_sel = nhsel;