1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <asm/uaccess.h>
17#include <linux/bitops.h>
18#include <linux/types.h>
19#include <linux/kernel.h>
20#include <linux/jiffies.h>
21#include <linux/mm.h>
22#include <linux/string.h>
23#include <linux/socket.h>
24#include <linux/sockios.h>
25#include <linux/errno.h>
26#include <linux/in.h>
27#include <linux/inet.h>
28#include <linux/inetdevice.h>
29#include <linux/netdevice.h>
30#include <linux/if_arp.h>
31#include <linux/proc_fs.h>
32#include <linux/skbuff.h>
33#include <linux/init.h>
34#include <linux/slab.h>
35
36#include <net/arp.h>
37#include <net/ip.h>
38#include <net/protocol.h>
39#include <net/route.h>
40#include <net/tcp.h>
41#include <net/sock.h>
42#include <net/ip_fib.h>
43#include <net/netlink.h>
44#include <net/nexthop.h>
45
46#include "fib_lookup.h"
47
48static DEFINE_SPINLOCK(fib_info_lock);
49static struct hlist_head *fib_info_hash;
50static struct hlist_head *fib_info_laddrhash;
51static unsigned int fib_info_hash_size;
52static unsigned int fib_info_cnt;
53
54#define DEVINDEX_HASHBITS 8
55#define DEVINDEX_HASHSIZE (1U << DEVINDEX_HASHBITS)
56static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE];
57
58#ifdef CONFIG_IP_ROUTE_MULTIPATH
59
60static DEFINE_SPINLOCK(fib_multipath_lock);
61
62#define for_nexthops(fi) { \
63 int nhsel; const struct fib_nh *nh; \
64 for (nhsel = 0, nh = (fi)->fib_nh; \
65 nhsel < (fi)->fib_nhs; \
66 nh++, nhsel++)
67
68#define change_nexthops(fi) { \
69 int nhsel; struct fib_nh *nexthop_nh; \
70 for (nhsel = 0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \
71 nhsel < (fi)->fib_nhs; \
72 nexthop_nh++, nhsel++)
73
74#else
75
76
77
78#define for_nexthops(fi) { \
79 int nhsel; const struct fib_nh *nh = (fi)->fib_nh; \
80 for (nhsel = 0; nhsel < 1; nhsel++)
81
82#define change_nexthops(fi) { \
83 int nhsel; \
84 struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \
85 for (nhsel = 0; nhsel < 1; nhsel++)
86
87#endif
88
89#define endfor_nexthops(fi) }
90
91
92const struct fib_prop fib_props[RTN_MAX + 1] = {
93 [RTN_UNSPEC] = {
94 .error = 0,
95 .scope = RT_SCOPE_NOWHERE,
96 },
97 [RTN_UNICAST] = {
98 .error = 0,
99 .scope = RT_SCOPE_UNIVERSE,
100 },
101 [RTN_LOCAL] = {
102 .error = 0,
103 .scope = RT_SCOPE_HOST,
104 },
105 [RTN_BROADCAST] = {
106 .error = 0,
107 .scope = RT_SCOPE_LINK,
108 },
109 [RTN_ANYCAST] = {
110 .error = 0,
111 .scope = RT_SCOPE_LINK,
112 },
113 [RTN_MULTICAST] = {
114 .error = 0,
115 .scope = RT_SCOPE_UNIVERSE,
116 },
117 [RTN_BLACKHOLE] = {
118 .error = -EINVAL,
119 .scope = RT_SCOPE_UNIVERSE,
120 },
121 [RTN_UNREACHABLE] = {
122 .error = -EHOSTUNREACH,
123 .scope = RT_SCOPE_UNIVERSE,
124 },
125 [RTN_PROHIBIT] = {
126 .error = -EACCES,
127 .scope = RT_SCOPE_UNIVERSE,
128 },
129 [RTN_THROW] = {
130 .error = -EAGAIN,
131 .scope = RT_SCOPE_UNIVERSE,
132 },
133 [RTN_NAT] = {
134 .error = -EINVAL,
135 .scope = RT_SCOPE_NOWHERE,
136 },
137 [RTN_XRESOLVE] = {
138 .error = -EINVAL,
139 .scope = RT_SCOPE_NOWHERE,
140 },
141};
142
143static void rt_fibinfo_free(struct rtable __rcu **rtp)
144{
145 struct rtable *rt = rcu_dereference_protected(*rtp, 1);
146
147 if (!rt)
148 return;
149
150
151
152
153
154
155 dst_free(&rt->dst);
156}
157
158static void free_nh_exceptions(struct fib_nh *nh)
159{
160 struct fnhe_hash_bucket *hash = nh->nh_exceptions;
161 int i;
162
163 for (i = 0; i < FNHE_HASH_SIZE; i++) {
164 struct fib_nh_exception *fnhe;
165
166 fnhe = rcu_dereference_protected(hash[i].chain, 1);
167 while (fnhe) {
168 struct fib_nh_exception *next;
169
170 next = rcu_dereference_protected(fnhe->fnhe_next, 1);
171
172 rt_fibinfo_free(&fnhe->fnhe_rth);
173
174 kfree(fnhe);
175
176 fnhe = next;
177 }
178 }
179 kfree(hash);
180}
181
182static void rt_fibinfo_free_cpus(struct rtable __rcu * __percpu *rtp)
183{
184 int cpu;
185
186 if (!rtp)
187 return;
188
189 for_each_possible_cpu(cpu) {
190 struct rtable *rt;
191
192 rt = rcu_dereference_protected(*per_cpu_ptr(rtp, cpu), 1);
193 if (rt)
194 dst_free(&rt->dst);
195 }
196 free_percpu(rtp);
197}
198
199
200static void free_fib_info_rcu(struct rcu_head *head)
201{
202 struct fib_info *fi = container_of(head, struct fib_info, rcu);
203
204 change_nexthops(fi) {
205 if (nexthop_nh->nh_dev)
206 dev_put(nexthop_nh->nh_dev);
207 if (nexthop_nh->nh_exceptions)
208 free_nh_exceptions(nexthop_nh);
209 rt_fibinfo_free_cpus(nexthop_nh->nh_pcpu_rth_output);
210 rt_fibinfo_free(&nexthop_nh->nh_rth_input);
211 } endfor_nexthops(fi);
212
213 release_net(fi->fib_net);
214 if (fi->fib_metrics != (u32 *) dst_default_metrics)
215 kfree(fi->fib_metrics);
216 kfree(fi);
217}
218
219void free_fib_info(struct fib_info *fi)
220{
221 if (fi->fib_dead == 0) {
222 pr_warn("Freeing alive fib_info %p\n", fi);
223 return;
224 }
225 fib_info_cnt--;
226#ifdef CONFIG_IP_ROUTE_CLASSID
227 change_nexthops(fi) {
228 if (nexthop_nh->nh_tclassid)
229 fi->fib_net->ipv4.fib_num_tclassid_users--;
230 } endfor_nexthops(fi);
231#endif
232 call_rcu(&fi->rcu, free_fib_info_rcu);
233}
234
235void fib_release_info(struct fib_info *fi)
236{
237 spin_lock_bh(&fib_info_lock);
238 if (fi && --fi->fib_treeref == 0) {
239 hlist_del(&fi->fib_hash);
240 if (fi->fib_prefsrc)
241 hlist_del(&fi->fib_lhash);
242 change_nexthops(fi) {
243 if (!nexthop_nh->nh_dev)
244 continue;
245 hlist_del(&nexthop_nh->nh_hash);
246 } endfor_nexthops(fi)
247 fi->fib_dead = 1;
248 fib_info_put(fi);
249 }
250 spin_unlock_bh(&fib_info_lock);
251}
252
253static inline int nh_comp(const struct fib_info *fi, const struct fib_info *ofi)
254{
255 const struct fib_nh *onh = ofi->fib_nh;
256
257 for_nexthops(fi) {
258 if (nh->nh_oif != onh->nh_oif ||
259 nh->nh_gw != onh->nh_gw ||
260 nh->nh_scope != onh->nh_scope ||
261#ifdef CONFIG_IP_ROUTE_MULTIPATH
262 nh->nh_weight != onh->nh_weight ||
263#endif
264#ifdef CONFIG_IP_ROUTE_CLASSID
265 nh->nh_tclassid != onh->nh_tclassid ||
266#endif
267 ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD))
268 return -1;
269 onh++;
270 } endfor_nexthops(fi);
271 return 0;
272}
273
274static inline unsigned int fib_devindex_hashfn(unsigned int val)
275{
276 unsigned int mask = DEVINDEX_HASHSIZE - 1;
277
278 return (val ^
279 (val >> DEVINDEX_HASHBITS) ^
280 (val >> (DEVINDEX_HASHBITS * 2))) & mask;
281}
282
283static inline unsigned int fib_info_hashfn(const struct fib_info *fi)
284{
285 unsigned int mask = (fib_info_hash_size - 1);
286 unsigned int val = fi->fib_nhs;
287
288 val ^= (fi->fib_protocol << 8) | fi->fib_scope;
289 val ^= (__force u32)fi->fib_prefsrc;
290 val ^= fi->fib_priority;
291 for_nexthops(fi) {
292 val ^= fib_devindex_hashfn(nh->nh_oif);
293 } endfor_nexthops(fi)
294
295 return (val ^ (val >> 7) ^ (val >> 12)) & mask;
296}
297
298static struct fib_info *fib_find_info(const struct fib_info *nfi)
299{
300 struct hlist_head *head;
301 struct fib_info *fi;
302 unsigned int hash;
303
304 hash = fib_info_hashfn(nfi);
305 head = &fib_info_hash[hash];
306
307 hlist_for_each_entry(fi, head, fib_hash) {
308 if (!net_eq(fi->fib_net, nfi->fib_net))
309 continue;
310 if (fi->fib_nhs != nfi->fib_nhs)
311 continue;
312 if (nfi->fib_protocol == fi->fib_protocol &&
313 nfi->fib_scope == fi->fib_scope &&
314 nfi->fib_prefsrc == fi->fib_prefsrc &&
315 nfi->fib_priority == fi->fib_priority &&
316 nfi->fib_type == fi->fib_type &&
317 memcmp(nfi->fib_metrics, fi->fib_metrics,
318 sizeof(u32) * RTAX_MAX) == 0 &&
319 ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 &&
320 (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0))
321 return fi;
322 }
323
324 return NULL;
325}
326
327
328
329
330int ip_fib_check_default(__be32 gw, struct net_device *dev)
331{
332 struct hlist_head *head;
333 struct fib_nh *nh;
334 unsigned int hash;
335
336 spin_lock(&fib_info_lock);
337
338 hash = fib_devindex_hashfn(dev->ifindex);
339 head = &fib_info_devhash[hash];
340 hlist_for_each_entry(nh, head, nh_hash) {
341 if (nh->nh_dev == dev &&
342 nh->nh_gw == gw &&
343 !(nh->nh_flags & RTNH_F_DEAD)) {
344 spin_unlock(&fib_info_lock);
345 return 0;
346 }
347 }
348
349 spin_unlock(&fib_info_lock);
350
351 return -1;
352}
353
354static inline size_t fib_nlmsg_size(struct fib_info *fi)
355{
356 size_t payload = NLMSG_ALIGN(sizeof(struct rtmsg))
357 + nla_total_size(4)
358 + nla_total_size(4)
359 + nla_total_size(4)
360 + nla_total_size(4);
361
362
363 payload += nla_total_size((RTAX_MAX * nla_total_size(4)));
364
365 if (fi->fib_nhs) {
366
367
368
369 size_t nhsize = nla_total_size(sizeof(struct rtnexthop));
370
371
372 nhsize += 2 * nla_total_size(4);
373
374
375 payload += nla_total_size(fi->fib_nhs * nhsize);
376 }
377
378 return payload;
379}
380
381void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
382 int dst_len, u32 tb_id, struct nl_info *info,
383 unsigned int nlm_flags)
384{
385 struct sk_buff *skb;
386 u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0;
387 int err = -ENOBUFS;
388
389 skb = nlmsg_new(fib_nlmsg_size(fa->fa_info), GFP_KERNEL);
390 if (skb == NULL)
391 goto errout;
392
393 err = fib_dump_info(skb, info->portid, seq, event, tb_id,
394 fa->fa_type, key, dst_len,
395 fa->fa_tos, fa->fa_info, nlm_flags);
396 if (err < 0) {
397
398 WARN_ON(err == -EMSGSIZE);
399 kfree_skb(skb);
400 goto errout;
401 }
402 rtnl_notify(skb, info->nl_net, info->portid, RTNLGRP_IPV4_ROUTE,
403 info->nlh, GFP_KERNEL);
404 return;
405errout:
406 if (err < 0)
407 rtnl_set_sk_err(info->nl_net, RTNLGRP_IPV4_ROUTE, err);
408}
409
410
411
412
413struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio)
414{
415 if (fah) {
416 struct fib_alias *fa;
417 list_for_each_entry(fa, fah, fa_list) {
418 if (fa->fa_tos > tos)
419 continue;
420 if (fa->fa_info->fib_priority >= prio ||
421 fa->fa_tos < tos)
422 return fa;
423 }
424 }
425 return NULL;
426}
427
428int fib_detect_death(struct fib_info *fi, int order,
429 struct fib_info **last_resort, int *last_idx, int dflt)
430{
431 struct neighbour *n;
432 int state = NUD_NONE;
433
434 n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev);
435 if (n) {
436 state = n->nud_state;
437 neigh_release(n);
438 }
439 if (state == NUD_REACHABLE)
440 return 0;
441 if ((state & NUD_VALID) && order != dflt)
442 return 0;
443 if ((state & NUD_VALID) ||
444 (*last_idx < 0 && order > dflt)) {
445 *last_resort = fi;
446 *last_idx = order;
447 }
448 return 1;
449}
450
451#ifdef CONFIG_IP_ROUTE_MULTIPATH
452
453static int fib_count_nexthops(struct rtnexthop *rtnh, int remaining)
454{
455 int nhs = 0;
456
457 while (rtnh_ok(rtnh, remaining)) {
458 nhs++;
459 rtnh = rtnh_next(rtnh, &remaining);
460 }
461
462
463 return remaining > 0 ? 0 : nhs;
464}
465
466static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
467 int remaining, struct fib_config *cfg)
468{
469 change_nexthops(fi) {
470 int attrlen;
471
472 if (!rtnh_ok(rtnh, remaining))
473 return -EINVAL;
474
475 nexthop_nh->nh_flags =
476 (cfg->fc_flags & ~0xFF) | rtnh->rtnh_flags;
477 nexthop_nh->nh_oif = rtnh->rtnh_ifindex;
478 nexthop_nh->nh_weight = rtnh->rtnh_hops + 1;
479
480 attrlen = rtnh_attrlen(rtnh);
481 if (attrlen > 0) {
482 struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
483
484 nla = nla_find(attrs, attrlen, RTA_GATEWAY);
485 nexthop_nh->nh_gw = nla ? nla_get_be32(nla) : 0;
486#ifdef CONFIG_IP_ROUTE_CLASSID
487 nla = nla_find(attrs, attrlen, RTA_FLOW);
488 nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0;
489 if (nexthop_nh->nh_tclassid)
490 fi->fib_net->ipv4.fib_num_tclassid_users++;
491#endif
492 }
493
494 rtnh = rtnh_next(rtnh, &remaining);
495 } endfor_nexthops(fi);
496
497 return 0;
498}
499
500#endif
501
502int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
503{
504#ifdef CONFIG_IP_ROUTE_MULTIPATH
505 struct rtnexthop *rtnh;
506 int remaining;
507#endif
508
509 if (cfg->fc_priority && cfg->fc_priority != fi->fib_priority)
510 return 1;
511
512 if (cfg->fc_oif || cfg->fc_gw) {
513 if ((!cfg->fc_oif || cfg->fc_oif == fi->fib_nh->nh_oif) &&
514 (!cfg->fc_gw || cfg->fc_gw == fi->fib_nh->nh_gw))
515 return 0;
516 return 1;
517 }
518
519#ifdef CONFIG_IP_ROUTE_MULTIPATH
520 if (cfg->fc_mp == NULL)
521 return 0;
522
523 rtnh = cfg->fc_mp;
524 remaining = cfg->fc_mp_len;
525
526 for_nexthops(fi) {
527 int attrlen;
528
529 if (!rtnh_ok(rtnh, remaining))
530 return -EINVAL;
531
532 if (rtnh->rtnh_ifindex && rtnh->rtnh_ifindex != nh->nh_oif)
533 return 1;
534
535 attrlen = rtnh_attrlen(rtnh);
536 if (attrlen < 0) {
537 struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
538
539 nla = nla_find(attrs, attrlen, RTA_GATEWAY);
540 if (nla && nla_get_be32(nla) != nh->nh_gw)
541 return 1;
542#ifdef CONFIG_IP_ROUTE_CLASSID
543 nla = nla_find(attrs, attrlen, RTA_FLOW);
544 if (nla && nla_get_u32(nla) != nh->nh_tclassid)
545 return 1;
546#endif
547 }
548
549 rtnh = rtnh_next(rtnh, &remaining);
550 } endfor_nexthops(fi);
551#endif
552 return 0;
553}
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
600 struct fib_nh *nh)
601{
602 int err;
603 struct net *net;
604 struct net_device *dev;
605
606 net = cfg->fc_nlinfo.nl_net;
607 if (nh->nh_gw) {
608 struct fib_result res;
609
610 if (nh->nh_flags & RTNH_F_ONLINK) {
611
612 if (cfg->fc_scope >= RT_SCOPE_LINK)
613 return -EINVAL;
614 if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST)
615 return -EINVAL;
616 dev = __dev_get_by_index(net, nh->nh_oif);
617 if (!dev)
618 return -ENODEV;
619 if (!(dev->flags & IFF_UP))
620 return -ENETDOWN;
621 nh->nh_dev = dev;
622 dev_hold(dev);
623 nh->nh_scope = RT_SCOPE_LINK;
624 return 0;
625 }
626 rcu_read_lock();
627 {
628 struct flowi4 fl4 = {
629 .daddr = nh->nh_gw,
630 .flowi4_scope = cfg->fc_scope + 1,
631 .flowi4_oif = nh->nh_oif,
632 };
633
634
635 if (fl4.flowi4_scope < RT_SCOPE_LINK)
636 fl4.flowi4_scope = RT_SCOPE_LINK;
637 err = fib_lookup(net, &fl4, &res);
638 if (err) {
639 rcu_read_unlock();
640 return err;
641 }
642 }
643 err = -EINVAL;
644 if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
645 goto out;
646 nh->nh_scope = res.scope;
647 nh->nh_oif = FIB_RES_OIF(res);
648 nh->nh_dev = dev = FIB_RES_DEV(res);
649 if (!dev)
650 goto out;
651 dev_hold(dev);
652 err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN;
653 } else {
654 struct in_device *in_dev;
655
656 if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK))
657 return -EINVAL;
658
659 rcu_read_lock();
660 err = -ENODEV;
661 in_dev = inetdev_by_index(net, nh->nh_oif);
662 if (in_dev == NULL)
663 goto out;
664 err = -ENETDOWN;
665 if (!(in_dev->dev->flags & IFF_UP))
666 goto out;
667 nh->nh_dev = in_dev->dev;
668 dev_hold(nh->nh_dev);
669 nh->nh_scope = RT_SCOPE_HOST;
670 err = 0;
671 }
672out:
673 rcu_read_unlock();
674 return err;
675}
676
677static inline unsigned int fib_laddr_hashfn(__be32 val)
678{
679 unsigned int mask = (fib_info_hash_size - 1);
680
681 return ((__force u32)val ^
682 ((__force u32)val >> 7) ^
683 ((__force u32)val >> 14)) & mask;
684}
685
686static struct hlist_head *fib_info_hash_alloc(int bytes)
687{
688 if (bytes <= PAGE_SIZE)
689 return kzalloc(bytes, GFP_KERNEL);
690 else
691 return (struct hlist_head *)
692 __get_free_pages(GFP_KERNEL | __GFP_ZERO,
693 get_order(bytes));
694}
695
696static void fib_info_hash_free(struct hlist_head *hash, int bytes)
697{
698 if (!hash)
699 return;
700
701 if (bytes <= PAGE_SIZE)
702 kfree(hash);
703 else
704 free_pages((unsigned long) hash, get_order(bytes));
705}
706
707static void fib_info_hash_move(struct hlist_head *new_info_hash,
708 struct hlist_head *new_laddrhash,
709 unsigned int new_size)
710{
711 struct hlist_head *old_info_hash, *old_laddrhash;
712 unsigned int old_size = fib_info_hash_size;
713 unsigned int i, bytes;
714
715 spin_lock_bh(&fib_info_lock);
716 old_info_hash = fib_info_hash;
717 old_laddrhash = fib_info_laddrhash;
718 fib_info_hash_size = new_size;
719
720 for (i = 0; i < old_size; i++) {
721 struct hlist_head *head = &fib_info_hash[i];
722 struct hlist_node *n;
723 struct fib_info *fi;
724
725 hlist_for_each_entry_safe(fi, n, head, fib_hash) {
726 struct hlist_head *dest;
727 unsigned int new_hash;
728
729 hlist_del(&fi->fib_hash);
730
731 new_hash = fib_info_hashfn(fi);
732 dest = &new_info_hash[new_hash];
733 hlist_add_head(&fi->fib_hash, dest);
734 }
735 }
736 fib_info_hash = new_info_hash;
737
738 for (i = 0; i < old_size; i++) {
739 struct hlist_head *lhead = &fib_info_laddrhash[i];
740 struct hlist_node *n;
741 struct fib_info *fi;
742
743 hlist_for_each_entry_safe(fi, n, lhead, fib_lhash) {
744 struct hlist_head *ldest;
745 unsigned int new_hash;
746
747 hlist_del(&fi->fib_lhash);
748
749 new_hash = fib_laddr_hashfn(fi->fib_prefsrc);
750 ldest = &new_laddrhash[new_hash];
751 hlist_add_head(&fi->fib_lhash, ldest);
752 }
753 }
754 fib_info_laddrhash = new_laddrhash;
755
756 spin_unlock_bh(&fib_info_lock);
757
758 bytes = old_size * sizeof(struct hlist_head *);
759 fib_info_hash_free(old_info_hash, bytes);
760 fib_info_hash_free(old_laddrhash, bytes);
761}
762
763__be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh)
764{
765 nh->nh_saddr = inet_select_addr(nh->nh_dev,
766 nh->nh_gw,
767 nh->nh_parent->fib_scope);
768 nh->nh_saddr_genid = atomic_read(&net->ipv4.dev_addr_genid);
769
770 return nh->nh_saddr;
771}
772
773struct fib_info *fib_create_info(struct fib_config *cfg)
774{
775 int err;
776 struct fib_info *fi = NULL;
777 struct fib_info *ofi;
778 int nhs = 1;
779 struct net *net = cfg->fc_nlinfo.nl_net;
780
781 if (cfg->fc_type > RTN_MAX)
782 goto err_inval;
783
784
785 if (fib_props[cfg->fc_type].scope > cfg->fc_scope)
786 goto err_inval;
787
788#ifdef CONFIG_IP_ROUTE_MULTIPATH
789 if (cfg->fc_mp) {
790 nhs = fib_count_nexthops(cfg->fc_mp, cfg->fc_mp_len);
791 if (nhs == 0)
792 goto err_inval;
793 }
794#endif
795
796 err = -ENOBUFS;
797 if (fib_info_cnt >= fib_info_hash_size) {
798 unsigned int new_size = fib_info_hash_size << 1;
799 struct hlist_head *new_info_hash;
800 struct hlist_head *new_laddrhash;
801 unsigned int bytes;
802
803 if (!new_size)
804 new_size = 16;
805 bytes = new_size * sizeof(struct hlist_head *);
806 new_info_hash = fib_info_hash_alloc(bytes);
807 new_laddrhash = fib_info_hash_alloc(bytes);
808 if (!new_info_hash || !new_laddrhash) {
809 fib_info_hash_free(new_info_hash, bytes);
810 fib_info_hash_free(new_laddrhash, bytes);
811 } else
812 fib_info_hash_move(new_info_hash, new_laddrhash, new_size);
813
814 if (!fib_info_hash_size)
815 goto failure;
816 }
817
818 fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
819 if (fi == NULL)
820 goto failure;
821 if (cfg->fc_mx) {
822 fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL);
823 if (!fi->fib_metrics)
824 goto failure;
825 } else
826 fi->fib_metrics = (u32 *) dst_default_metrics;
827 fib_info_cnt++;
828
829 fi->fib_net = hold_net(net);
830 fi->fib_protocol = cfg->fc_protocol;
831 fi->fib_scope = cfg->fc_scope;
832 fi->fib_flags = cfg->fc_flags;
833 fi->fib_priority = cfg->fc_priority;
834 fi->fib_prefsrc = cfg->fc_prefsrc;
835 fi->fib_type = cfg->fc_type;
836
837 fi->fib_nhs = nhs;
838 change_nexthops(fi) {
839 nexthop_nh->nh_parent = fi;
840 nexthop_nh->nh_pcpu_rth_output = alloc_percpu(struct rtable __rcu *);
841 if (!nexthop_nh->nh_pcpu_rth_output)
842 goto failure;
843 } endfor_nexthops(fi)
844
845 if (cfg->fc_mx) {
846 struct nlattr *nla;
847 int remaining;
848
849 nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) {
850 int type = nla_type(nla);
851
852 if (type) {
853 u32 val;
854
855 if (type > RTAX_MAX)
856 goto err_inval;
857 val = nla_get_u32(nla);
858 if (type == RTAX_ADVMSS && val > 65535 - 40)
859 val = 65535 - 40;
860 if (type == RTAX_MTU && val > 65535 - 15)
861 val = 65535 - 15;
862 fi->fib_metrics[type - 1] = val;
863 }
864 }
865 }
866
867 if (cfg->fc_mp) {
868#ifdef CONFIG_IP_ROUTE_MULTIPATH
869 err = fib_get_nhs(fi, cfg->fc_mp, cfg->fc_mp_len, cfg);
870 if (err != 0)
871 goto failure;
872 if (cfg->fc_oif && fi->fib_nh->nh_oif != cfg->fc_oif)
873 goto err_inval;
874 if (cfg->fc_gw && fi->fib_nh->nh_gw != cfg->fc_gw)
875 goto err_inval;
876#ifdef CONFIG_IP_ROUTE_CLASSID
877 if (cfg->fc_flow && fi->fib_nh->nh_tclassid != cfg->fc_flow)
878 goto err_inval;
879#endif
880#else
881 goto err_inval;
882#endif
883 } else {
884 struct fib_nh *nh = fi->fib_nh;
885
886 nh->nh_oif = cfg->fc_oif;
887 nh->nh_gw = cfg->fc_gw;
888 nh->nh_flags = cfg->fc_flags;
889#ifdef CONFIG_IP_ROUTE_CLASSID
890 nh->nh_tclassid = cfg->fc_flow;
891 if (nh->nh_tclassid)
892 fi->fib_net->ipv4.fib_num_tclassid_users++;
893#endif
894#ifdef CONFIG_IP_ROUTE_MULTIPATH
895 nh->nh_weight = 1;
896#endif
897 }
898
899 if (fib_props[cfg->fc_type].error) {
900 if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp)
901 goto err_inval;
902 goto link_it;
903 } else {
904 switch (cfg->fc_type) {
905 case RTN_UNICAST:
906 case RTN_LOCAL:
907 case RTN_BROADCAST:
908 case RTN_ANYCAST:
909 case RTN_MULTICAST:
910 break;
911 default:
912 goto err_inval;
913 }
914 }
915
916 if (cfg->fc_scope > RT_SCOPE_HOST)
917 goto err_inval;
918
919 if (cfg->fc_scope == RT_SCOPE_HOST) {
920 struct fib_nh *nh = fi->fib_nh;
921
922
923 if (nhs != 1 || nh->nh_gw)
924 goto err_inval;
925 nh->nh_scope = RT_SCOPE_NOWHERE;
926 nh->nh_dev = dev_get_by_index(net, fi->fib_nh->nh_oif);
927 err = -ENODEV;
928 if (nh->nh_dev == NULL)
929 goto failure;
930 } else {
931 change_nexthops(fi) {
932 err = fib_check_nh(cfg, fi, nexthop_nh);
933 if (err != 0)
934 goto failure;
935 } endfor_nexthops(fi)
936 }
937
938 if (fi->fib_prefsrc) {
939 if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
940 fi->fib_prefsrc != cfg->fc_dst)
941 if (inet_addr_type(net, fi->fib_prefsrc) != RTN_LOCAL)
942 goto err_inval;
943 }
944
945 change_nexthops(fi) {
946 fib_info_update_nh_saddr(net, nexthop_nh);
947 } endfor_nexthops(fi)
948
949link_it:
950 ofi = fib_find_info(fi);
951 if (ofi) {
952 fi->fib_dead = 1;
953 free_fib_info(fi);
954 ofi->fib_treeref++;
955 return ofi;
956 }
957
958 fi->fib_treeref++;
959 atomic_inc(&fi->fib_clntref);
960 spin_lock_bh(&fib_info_lock);
961 hlist_add_head(&fi->fib_hash,
962 &fib_info_hash[fib_info_hashfn(fi)]);
963 if (fi->fib_prefsrc) {
964 struct hlist_head *head;
965
966 head = &fib_info_laddrhash[fib_laddr_hashfn(fi->fib_prefsrc)];
967 hlist_add_head(&fi->fib_lhash, head);
968 }
969 change_nexthops(fi) {
970 struct hlist_head *head;
971 unsigned int hash;
972
973 if (!nexthop_nh->nh_dev)
974 continue;
975 hash = fib_devindex_hashfn(nexthop_nh->nh_dev->ifindex);
976 head = &fib_info_devhash[hash];
977 hlist_add_head(&nexthop_nh->nh_hash, head);
978 } endfor_nexthops(fi)
979 spin_unlock_bh(&fib_info_lock);
980 return fi;
981
982err_inval:
983 err = -EINVAL;
984
985failure:
986 if (fi) {
987 fi->fib_dead = 1;
988 free_fib_info(fi);
989 }
990
991 return ERR_PTR(err);
992}
993
994int fib_dump_info(struct sk_buff *skb, u32 portid, u32 seq, int event,
995 u32 tb_id, u8 type, __be32 dst, int dst_len, u8 tos,
996 struct fib_info *fi, unsigned int flags)
997{
998 struct nlmsghdr *nlh;
999 struct rtmsg *rtm;
1000
1001 nlh = nlmsg_put(skb, portid, seq, event, sizeof(*rtm), flags);
1002 if (nlh == NULL)
1003 return -EMSGSIZE;
1004
1005 rtm = nlmsg_data(nlh);
1006 rtm->rtm_family = AF_INET;
1007 rtm->rtm_dst_len = dst_len;
1008 rtm->rtm_src_len = 0;
1009 rtm->rtm_tos = tos;
1010 if (tb_id < 256)
1011 rtm->rtm_table = tb_id;
1012 else
1013 rtm->rtm_table = RT_TABLE_COMPAT;
1014 if (nla_put_u32(skb, RTA_TABLE, tb_id))
1015 goto nla_put_failure;
1016 rtm->rtm_type = type;
1017 rtm->rtm_flags = fi->fib_flags;
1018 rtm->rtm_scope = fi->fib_scope;
1019 rtm->rtm_protocol = fi->fib_protocol;
1020
1021 if (rtm->rtm_dst_len &&
1022 nla_put_be32(skb, RTA_DST, dst))
1023 goto nla_put_failure;
1024 if (fi->fib_priority &&
1025 nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority))
1026 goto nla_put_failure;
1027 if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
1028 goto nla_put_failure;
1029
1030 if (fi->fib_prefsrc &&
1031 nla_put_be32(skb, RTA_PREFSRC, fi->fib_prefsrc))
1032 goto nla_put_failure;
1033 if (fi->fib_nhs == 1) {
1034 if (fi->fib_nh->nh_gw &&
1035 nla_put_be32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw))
1036 goto nla_put_failure;
1037 if (fi->fib_nh->nh_oif &&
1038 nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif))
1039 goto nla_put_failure;
1040#ifdef CONFIG_IP_ROUTE_CLASSID
1041 if (fi->fib_nh[0].nh_tclassid &&
1042 nla_put_u32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid))
1043 goto nla_put_failure;
1044#endif
1045 }
1046#ifdef CONFIG_IP_ROUTE_MULTIPATH
1047 if (fi->fib_nhs > 1) {
1048 struct rtnexthop *rtnh;
1049 struct nlattr *mp;
1050
1051 mp = nla_nest_start(skb, RTA_MULTIPATH);
1052 if (mp == NULL)
1053 goto nla_put_failure;
1054
1055 for_nexthops(fi) {
1056 rtnh = nla_reserve_nohdr(skb, sizeof(*rtnh));
1057 if (rtnh == NULL)
1058 goto nla_put_failure;
1059
1060 rtnh->rtnh_flags = nh->nh_flags & 0xFF;
1061 rtnh->rtnh_hops = nh->nh_weight - 1;
1062 rtnh->rtnh_ifindex = nh->nh_oif;
1063
1064 if (nh->nh_gw &&
1065 nla_put_be32(skb, RTA_GATEWAY, nh->nh_gw))
1066 goto nla_put_failure;
1067#ifdef CONFIG_IP_ROUTE_CLASSID
1068 if (nh->nh_tclassid &&
1069 nla_put_u32(skb, RTA_FLOW, nh->nh_tclassid))
1070 goto nla_put_failure;
1071#endif
1072
1073 rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *) rtnh;
1074 } endfor_nexthops(fi);
1075
1076 nla_nest_end(skb, mp);
1077 }
1078#endif
1079 return nlmsg_end(skb, nlh);
1080
1081nla_put_failure:
1082 nlmsg_cancel(skb, nlh);
1083 return -EMSGSIZE;
1084}
1085
1086
1087
1088
1089
1090
1091
1092int fib_sync_down_addr(struct net *net, __be32 local)
1093{
1094 int ret = 0;
1095 unsigned int hash = fib_laddr_hashfn(local);
1096 struct hlist_head *head = &fib_info_laddrhash[hash];
1097 struct fib_info *fi;
1098
1099 if (fib_info_laddrhash == NULL || local == 0)
1100 return 0;
1101
1102 hlist_for_each_entry(fi, head, fib_lhash) {
1103 if (!net_eq(fi->fib_net, net))
1104 continue;
1105 if (fi->fib_prefsrc == local) {
1106 fi->fib_flags |= RTNH_F_DEAD;
1107 ret++;
1108 }
1109 }
1110 return ret;
1111}
1112
1113int fib_sync_down_dev(struct net_device *dev, int force)
1114{
1115 int ret = 0;
1116 int scope = RT_SCOPE_NOWHERE;
1117 struct fib_info *prev_fi = NULL;
1118 unsigned int hash = fib_devindex_hashfn(dev->ifindex);
1119 struct hlist_head *head = &fib_info_devhash[hash];
1120 struct fib_nh *nh;
1121
1122 if (force)
1123 scope = -1;
1124
1125 hlist_for_each_entry(nh, head, nh_hash) {
1126 struct fib_info *fi = nh->nh_parent;
1127 int dead;
1128
1129 BUG_ON(!fi->fib_nhs);
1130 if (nh->nh_dev != dev || fi == prev_fi)
1131 continue;
1132 prev_fi = fi;
1133 dead = 0;
1134 change_nexthops(fi) {
1135 if (nexthop_nh->nh_flags & RTNH_F_DEAD)
1136 dead++;
1137 else if (nexthop_nh->nh_dev == dev &&
1138 nexthop_nh->nh_scope != scope) {
1139 nexthop_nh->nh_flags |= RTNH_F_DEAD;
1140#ifdef CONFIG_IP_ROUTE_MULTIPATH
1141 spin_lock_bh(&fib_multipath_lock);
1142 fi->fib_power -= nexthop_nh->nh_power;
1143 nexthop_nh->nh_power = 0;
1144 spin_unlock_bh(&fib_multipath_lock);
1145#endif
1146 dead++;
1147 }
1148#ifdef CONFIG_IP_ROUTE_MULTIPATH
1149 if (force > 1 && nexthop_nh->nh_dev == dev) {
1150 dead = fi->fib_nhs;
1151 break;
1152 }
1153#endif
1154 } endfor_nexthops(fi)
1155 if (dead == fi->fib_nhs) {
1156 fi->fib_flags |= RTNH_F_DEAD;
1157 ret++;
1158 }
1159 }
1160
1161 return ret;
1162}
1163
1164
1165void fib_select_default(struct fib_result *res)
1166{
1167 struct fib_info *fi = NULL, *last_resort = NULL;
1168 struct list_head *fa_head = res->fa_head;
1169 struct fib_table *tb = res->table;
1170 int order = -1, last_idx = -1;
1171 struct fib_alias *fa;
1172
1173 list_for_each_entry_rcu(fa, fa_head, fa_list) {
1174 struct fib_info *next_fi = fa->fa_info;
1175
1176 if (next_fi->fib_scope != res->scope ||
1177 fa->fa_type != RTN_UNICAST)
1178 continue;
1179
1180 if (next_fi->fib_priority > res->fi->fib_priority)
1181 break;
1182 if (!next_fi->fib_nh[0].nh_gw ||
1183 next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
1184 continue;
1185
1186 fib_alias_accessed(fa);
1187
1188 if (fi == NULL) {
1189 if (next_fi != res->fi)
1190 break;
1191 } else if (!fib_detect_death(fi, order, &last_resort,
1192 &last_idx, tb->tb_default)) {
1193 fib_result_assign(res, fi);
1194 tb->tb_default = order;
1195 goto out;
1196 }
1197 fi = next_fi;
1198 order++;
1199 }
1200
1201 if (order <= 0 || fi == NULL) {
1202 tb->tb_default = -1;
1203 goto out;
1204 }
1205
1206 if (!fib_detect_death(fi, order, &last_resort, &last_idx,
1207 tb->tb_default)) {
1208 fib_result_assign(res, fi);
1209 tb->tb_default = order;
1210 goto out;
1211 }
1212
1213 if (last_idx >= 0)
1214 fib_result_assign(res, last_resort);
1215 tb->tb_default = last_idx;
1216out:
1217 return;
1218}
1219
1220#ifdef CONFIG_IP_ROUTE_MULTIPATH
1221
1222
1223
1224
1225
1226int fib_sync_up(struct net_device *dev)
1227{
1228 struct fib_info *prev_fi;
1229 unsigned int hash;
1230 struct hlist_head *head;
1231 struct fib_nh *nh;
1232 int ret;
1233
1234 if (!(dev->flags & IFF_UP))
1235 return 0;
1236
1237 prev_fi = NULL;
1238 hash = fib_devindex_hashfn(dev->ifindex);
1239 head = &fib_info_devhash[hash];
1240 ret = 0;
1241
1242 hlist_for_each_entry(nh, head, nh_hash) {
1243 struct fib_info *fi = nh->nh_parent;
1244 int alive;
1245
1246 BUG_ON(!fi->fib_nhs);
1247 if (nh->nh_dev != dev || fi == prev_fi)
1248 continue;
1249
1250 prev_fi = fi;
1251 alive = 0;
1252 change_nexthops(fi) {
1253 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
1254 alive++;
1255 continue;
1256 }
1257 if (nexthop_nh->nh_dev == NULL ||
1258 !(nexthop_nh->nh_dev->flags & IFF_UP))
1259 continue;
1260 if (nexthop_nh->nh_dev != dev ||
1261 !__in_dev_get_rtnl(dev))
1262 continue;
1263 alive++;
1264 spin_lock_bh(&fib_multipath_lock);
1265 nexthop_nh->nh_power = 0;
1266 nexthop_nh->nh_flags &= ~RTNH_F_DEAD;
1267 spin_unlock_bh(&fib_multipath_lock);
1268 } endfor_nexthops(fi)
1269
1270 if (alive > 0) {
1271 fi->fib_flags &= ~RTNH_F_DEAD;
1272 ret++;
1273 }
1274 }
1275
1276 return ret;
1277}
1278
1279
1280
1281
1282
1283void fib_select_multipath(struct fib_result *res)
1284{
1285 struct fib_info *fi = res->fi;
1286 int w;
1287
1288 spin_lock_bh(&fib_multipath_lock);
1289 if (fi->fib_power <= 0) {
1290 int power = 0;
1291 change_nexthops(fi) {
1292 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
1293 power += nexthop_nh->nh_weight;
1294 nexthop_nh->nh_power = nexthop_nh->nh_weight;
1295 }
1296 } endfor_nexthops(fi);
1297 fi->fib_power = power;
1298 if (power <= 0) {
1299 spin_unlock_bh(&fib_multipath_lock);
1300
1301 res->nh_sel = 0;
1302 return;
1303 }
1304 }
1305
1306
1307
1308
1309
1310
1311 w = jiffies % fi->fib_power;
1312
1313 change_nexthops(fi) {
1314 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD) &&
1315 nexthop_nh->nh_power) {
1316 w -= nexthop_nh->nh_power;
1317 if (w <= 0) {
1318 nexthop_nh->nh_power--;
1319 fi->fib_power--;
1320 res->nh_sel = nhsel;
1321 spin_unlock_bh(&fib_multipath_lock);
1322 return;
1323 }
1324 }
1325 } endfor_nexthops(fi);
1326
1327
1328 res->nh_sel = 0;
1329 spin_unlock_bh(&fib_multipath_lock);
1330}
1331#endif
1332