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 hlist_node *node;
302 struct fib_info *fi;
303 unsigned int hash;
304
305 hash = fib_info_hashfn(nfi);
306 head = &fib_info_hash[hash];
307
308 hlist_for_each_entry(fi, node, head, fib_hash) {
309 if (!net_eq(fi->fib_net, nfi->fib_net))
310 continue;
311 if (fi->fib_nhs != nfi->fib_nhs)
312 continue;
313 if (nfi->fib_protocol == fi->fib_protocol &&
314 nfi->fib_scope == fi->fib_scope &&
315 nfi->fib_prefsrc == fi->fib_prefsrc &&
316 nfi->fib_priority == fi->fib_priority &&
317 nfi->fib_type == fi->fib_type &&
318 memcmp(nfi->fib_metrics, fi->fib_metrics,
319 sizeof(u32) * RTAX_MAX) == 0 &&
320 ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 &&
321 (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0))
322 return fi;
323 }
324
325 return NULL;
326}
327
328
329
330
331int ip_fib_check_default(__be32 gw, struct net_device *dev)
332{
333 struct hlist_head *head;
334 struct hlist_node *node;
335 struct fib_nh *nh;
336 unsigned int hash;
337
338 spin_lock(&fib_info_lock);
339
340 hash = fib_devindex_hashfn(dev->ifindex);
341 head = &fib_info_devhash[hash];
342 hlist_for_each_entry(nh, node, head, nh_hash) {
343 if (nh->nh_dev == dev &&
344 nh->nh_gw == gw &&
345 !(nh->nh_flags & RTNH_F_DEAD)) {
346 spin_unlock(&fib_info_lock);
347 return 0;
348 }
349 }
350
351 spin_unlock(&fib_info_lock);
352
353 return -1;
354}
355
356static inline size_t fib_nlmsg_size(struct fib_info *fi)
357{
358 size_t payload = NLMSG_ALIGN(sizeof(struct rtmsg))
359 + nla_total_size(4)
360 + nla_total_size(4)
361 + nla_total_size(4)
362 + nla_total_size(4);
363
364
365 payload += nla_total_size((RTAX_MAX * nla_total_size(4)));
366
367 if (fi->fib_nhs) {
368
369
370
371 size_t nhsize = nla_total_size(sizeof(struct rtnexthop));
372
373
374 nhsize += 2 * nla_total_size(4);
375
376
377 payload += nla_total_size(fi->fib_nhs * nhsize);
378 }
379
380 return payload;
381}
382
383void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
384 int dst_len, u32 tb_id, struct nl_info *info,
385 unsigned int nlm_flags)
386{
387 struct sk_buff *skb;
388 u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0;
389 int err = -ENOBUFS;
390
391 skb = nlmsg_new(fib_nlmsg_size(fa->fa_info), GFP_KERNEL);
392 if (skb == NULL)
393 goto errout;
394
395 err = fib_dump_info(skb, info->pid, seq, event, tb_id,
396 fa->fa_type, key, dst_len,
397 fa->fa_tos, fa->fa_info, nlm_flags);
398 if (err < 0) {
399
400 WARN_ON(err == -EMSGSIZE);
401 kfree_skb(skb);
402 goto errout;
403 }
404 rtnl_notify(skb, info->nl_net, info->pid, RTNLGRP_IPV4_ROUTE,
405 info->nlh, GFP_KERNEL);
406 return;
407errout:
408 if (err < 0)
409 rtnl_set_sk_err(info->nl_net, RTNLGRP_IPV4_ROUTE, err);
410}
411
412
413
414
415struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio)
416{
417 if (fah) {
418 struct fib_alias *fa;
419 list_for_each_entry(fa, fah, fa_list) {
420 if (fa->fa_tos > tos)
421 continue;
422 if (fa->fa_info->fib_priority >= prio ||
423 fa->fa_tos < tos)
424 return fa;
425 }
426 }
427 return NULL;
428}
429
430int fib_detect_death(struct fib_info *fi, int order,
431 struct fib_info **last_resort, int *last_idx, int dflt)
432{
433 struct neighbour *n;
434 int state = NUD_NONE;
435
436 n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev);
437 if (n) {
438 state = n->nud_state;
439 neigh_release(n);
440 }
441 if (state == NUD_REACHABLE)
442 return 0;
443 if ((state & NUD_VALID) && order != dflt)
444 return 0;
445 if ((state & NUD_VALID) ||
446 (*last_idx < 0 && order > dflt)) {
447 *last_resort = fi;
448 *last_idx = order;
449 }
450 return 1;
451}
452
453#ifdef CONFIG_IP_ROUTE_MULTIPATH
454
455static int fib_count_nexthops(struct rtnexthop *rtnh, int remaining)
456{
457 int nhs = 0;
458
459 while (rtnh_ok(rtnh, remaining)) {
460 nhs++;
461 rtnh = rtnh_next(rtnh, &remaining);
462 }
463
464
465 return remaining > 0 ? 0 : nhs;
466}
467
468static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
469 int remaining, struct fib_config *cfg)
470{
471 change_nexthops(fi) {
472 int attrlen;
473
474 if (!rtnh_ok(rtnh, remaining))
475 return -EINVAL;
476
477 nexthop_nh->nh_flags =
478 (cfg->fc_flags & ~0xFF) | rtnh->rtnh_flags;
479 nexthop_nh->nh_oif = rtnh->rtnh_ifindex;
480 nexthop_nh->nh_weight = rtnh->rtnh_hops + 1;
481
482 attrlen = rtnh_attrlen(rtnh);
483 if (attrlen > 0) {
484 struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
485
486 nla = nla_find(attrs, attrlen, RTA_GATEWAY);
487 nexthop_nh->nh_gw = nla ? nla_get_be32(nla) : 0;
488#ifdef CONFIG_IP_ROUTE_CLASSID
489 nla = nla_find(attrs, attrlen, RTA_FLOW);
490 nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0;
491 if (nexthop_nh->nh_tclassid)
492 fi->fib_net->ipv4.fib_num_tclassid_users++;
493#endif
494 }
495
496 rtnh = rtnh_next(rtnh, &remaining);
497 } endfor_nexthops(fi);
498
499 return 0;
500}
501
502#endif
503
504int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
505{
506#ifdef CONFIG_IP_ROUTE_MULTIPATH
507 struct rtnexthop *rtnh;
508 int remaining;
509#endif
510
511 if (cfg->fc_priority && cfg->fc_priority != fi->fib_priority)
512 return 1;
513
514 if (cfg->fc_oif || cfg->fc_gw) {
515 if ((!cfg->fc_oif || cfg->fc_oif == fi->fib_nh->nh_oif) &&
516 (!cfg->fc_gw || cfg->fc_gw == fi->fib_nh->nh_gw))
517 return 0;
518 return 1;
519 }
520
521#ifdef CONFIG_IP_ROUTE_MULTIPATH
522 if (cfg->fc_mp == NULL)
523 return 0;
524
525 rtnh = cfg->fc_mp;
526 remaining = cfg->fc_mp_len;
527
528 for_nexthops(fi) {
529 int attrlen;
530
531 if (!rtnh_ok(rtnh, remaining))
532 return -EINVAL;
533
534 if (rtnh->rtnh_ifindex && rtnh->rtnh_ifindex != nh->nh_oif)
535 return 1;
536
537 attrlen = rtnh_attrlen(rtnh);
538 if (attrlen < 0) {
539 struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
540
541 nla = nla_find(attrs, attrlen, RTA_GATEWAY);
542 if (nla && nla_get_be32(nla) != nh->nh_gw)
543 return 1;
544#ifdef CONFIG_IP_ROUTE_CLASSID
545 nla = nla_find(attrs, attrlen, RTA_FLOW);
546 if (nla && nla_get_u32(nla) != nh->nh_tclassid)
547 return 1;
548#endif
549 }
550
551 rtnh = rtnh_next(rtnh, &remaining);
552 } endfor_nexthops(fi);
553#endif
554 return 0;
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
599
600
601static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
602 struct fib_nh *nh)
603{
604 int err;
605 struct net *net;
606 struct net_device *dev;
607
608 net = cfg->fc_nlinfo.nl_net;
609 if (nh->nh_gw) {
610 struct fib_result res;
611
612 if (nh->nh_flags & RTNH_F_ONLINK) {
613
614 if (cfg->fc_scope >= RT_SCOPE_LINK)
615 return -EINVAL;
616 if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST)
617 return -EINVAL;
618 dev = __dev_get_by_index(net, nh->nh_oif);
619 if (!dev)
620 return -ENODEV;
621 if (!(dev->flags & IFF_UP))
622 return -ENETDOWN;
623 nh->nh_dev = dev;
624 dev_hold(dev);
625 nh->nh_scope = RT_SCOPE_LINK;
626 return 0;
627 }
628 rcu_read_lock();
629 {
630 struct flowi4 fl4 = {
631 .daddr = nh->nh_gw,
632 .flowi4_scope = cfg->fc_scope + 1,
633 .flowi4_oif = nh->nh_oif,
634 };
635
636
637 if (fl4.flowi4_scope < RT_SCOPE_LINK)
638 fl4.flowi4_scope = RT_SCOPE_LINK;
639 err = fib_lookup(net, &fl4, &res);
640 if (err) {
641 rcu_read_unlock();
642 return err;
643 }
644 }
645 err = -EINVAL;
646 if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
647 goto out;
648 nh->nh_scope = res.scope;
649 nh->nh_oif = FIB_RES_OIF(res);
650 nh->nh_dev = dev = FIB_RES_DEV(res);
651 if (!dev)
652 goto out;
653 dev_hold(dev);
654 err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN;
655 } else {
656 struct in_device *in_dev;
657
658 if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK))
659 return -EINVAL;
660
661 rcu_read_lock();
662 err = -ENODEV;
663 in_dev = inetdev_by_index(net, nh->nh_oif);
664 if (in_dev == NULL)
665 goto out;
666 err = -ENETDOWN;
667 if (!(in_dev->dev->flags & IFF_UP))
668 goto out;
669 nh->nh_dev = in_dev->dev;
670 dev_hold(nh->nh_dev);
671 nh->nh_scope = RT_SCOPE_HOST;
672 err = 0;
673 }
674out:
675 rcu_read_unlock();
676 return err;
677}
678
679static inline unsigned int fib_laddr_hashfn(__be32 val)
680{
681 unsigned int mask = (fib_info_hash_size - 1);
682
683 return ((__force u32)val ^
684 ((__force u32)val >> 7) ^
685 ((__force u32)val >> 14)) & mask;
686}
687
688static struct hlist_head *fib_info_hash_alloc(int bytes)
689{
690 if (bytes <= PAGE_SIZE)
691 return kzalloc(bytes, GFP_KERNEL);
692 else
693 return (struct hlist_head *)
694 __get_free_pages(GFP_KERNEL | __GFP_ZERO,
695 get_order(bytes));
696}
697
698static void fib_info_hash_free(struct hlist_head *hash, int bytes)
699{
700 if (!hash)
701 return;
702
703 if (bytes <= PAGE_SIZE)
704 kfree(hash);
705 else
706 free_pages((unsigned long) hash, get_order(bytes));
707}
708
709static void fib_info_hash_move(struct hlist_head *new_info_hash,
710 struct hlist_head *new_laddrhash,
711 unsigned int new_size)
712{
713 struct hlist_head *old_info_hash, *old_laddrhash;
714 unsigned int old_size = fib_info_hash_size;
715 unsigned int i, bytes;
716
717 spin_lock_bh(&fib_info_lock);
718 old_info_hash = fib_info_hash;
719 old_laddrhash = fib_info_laddrhash;
720 fib_info_hash_size = new_size;
721
722 for (i = 0; i < old_size; i++) {
723 struct hlist_head *head = &fib_info_hash[i];
724 struct hlist_node *node, *n;
725 struct fib_info *fi;
726
727 hlist_for_each_entry_safe(fi, node, n, head, fib_hash) {
728 struct hlist_head *dest;
729 unsigned int new_hash;
730
731 hlist_del(&fi->fib_hash);
732
733 new_hash = fib_info_hashfn(fi);
734 dest = &new_info_hash[new_hash];
735 hlist_add_head(&fi->fib_hash, dest);
736 }
737 }
738 fib_info_hash = new_info_hash;
739
740 for (i = 0; i < old_size; i++) {
741 struct hlist_head *lhead = &fib_info_laddrhash[i];
742 struct hlist_node *node, *n;
743 struct fib_info *fi;
744
745 hlist_for_each_entry_safe(fi, node, n, lhead, fib_lhash) {
746 struct hlist_head *ldest;
747 unsigned int new_hash;
748
749 hlist_del(&fi->fib_lhash);
750
751 new_hash = fib_laddr_hashfn(fi->fib_prefsrc);
752 ldest = &new_laddrhash[new_hash];
753 hlist_add_head(&fi->fib_lhash, ldest);
754 }
755 }
756 fib_info_laddrhash = new_laddrhash;
757
758 spin_unlock_bh(&fib_info_lock);
759
760 bytes = old_size * sizeof(struct hlist_head *);
761 fib_info_hash_free(old_info_hash, bytes);
762 fib_info_hash_free(old_laddrhash, bytes);
763}
764
765__be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh)
766{
767 nh->nh_saddr = inet_select_addr(nh->nh_dev,
768 nh->nh_gw,
769 nh->nh_parent->fib_scope);
770 nh->nh_saddr_genid = atomic_read(&net->ipv4.dev_addr_genid);
771
772 return nh->nh_saddr;
773}
774
775struct fib_info *fib_create_info(struct fib_config *cfg)
776{
777 int err;
778 struct fib_info *fi = NULL;
779 struct fib_info *ofi;
780 int nhs = 1;
781 struct net *net = cfg->fc_nlinfo.nl_net;
782
783 if (cfg->fc_type > RTN_MAX)
784 goto err_inval;
785
786
787 if (fib_props[cfg->fc_type].scope > cfg->fc_scope)
788 goto err_inval;
789
790#ifdef CONFIG_IP_ROUTE_MULTIPATH
791 if (cfg->fc_mp) {
792 nhs = fib_count_nexthops(cfg->fc_mp, cfg->fc_mp_len);
793 if (nhs == 0)
794 goto err_inval;
795 }
796#endif
797
798 err = -ENOBUFS;
799 if (fib_info_cnt >= fib_info_hash_size) {
800 unsigned int new_size = fib_info_hash_size << 1;
801 struct hlist_head *new_info_hash;
802 struct hlist_head *new_laddrhash;
803 unsigned int bytes;
804
805 if (!new_size)
806 new_size = 1;
807 bytes = new_size * sizeof(struct hlist_head *);
808 new_info_hash = fib_info_hash_alloc(bytes);
809 new_laddrhash = fib_info_hash_alloc(bytes);
810 if (!new_info_hash || !new_laddrhash) {
811 fib_info_hash_free(new_info_hash, bytes);
812 fib_info_hash_free(new_laddrhash, bytes);
813 } else
814 fib_info_hash_move(new_info_hash, new_laddrhash, new_size);
815
816 if (!fib_info_hash_size)
817 goto failure;
818 }
819
820 fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
821 if (fi == NULL)
822 goto failure;
823 if (cfg->fc_mx) {
824 fi->fib_metrics = kzalloc(sizeof(u32) * RTAX_MAX, GFP_KERNEL);
825 if (!fi->fib_metrics)
826 goto failure;
827 } else
828 fi->fib_metrics = (u32 *) dst_default_metrics;
829 fib_info_cnt++;
830
831 fi->fib_net = hold_net(net);
832 fi->fib_protocol = cfg->fc_protocol;
833 fi->fib_scope = cfg->fc_scope;
834 fi->fib_flags = cfg->fc_flags;
835 fi->fib_priority = cfg->fc_priority;
836 fi->fib_prefsrc = cfg->fc_prefsrc;
837 fi->fib_type = cfg->fc_type;
838
839 fi->fib_nhs = nhs;
840 change_nexthops(fi) {
841 nexthop_nh->nh_parent = fi;
842 nexthop_nh->nh_pcpu_rth_output = alloc_percpu(struct rtable __rcu *);
843 if (!nexthop_nh->nh_pcpu_rth_output)
844 goto failure;
845 } endfor_nexthops(fi)
846
847 if (cfg->fc_mx) {
848 struct nlattr *nla;
849 int remaining;
850
851 nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) {
852 int type = nla_type(nla);
853
854 if (type) {
855 u32 val;
856
857 if (type > RTAX_MAX)
858 goto err_inval;
859 val = nla_get_u32(nla);
860 if (type == RTAX_ADVMSS && val > 65535 - 40)
861 val = 65535 - 40;
862 if (type == RTAX_MTU && val > 65535 - 15)
863 val = 65535 - 15;
864 fi->fib_metrics[type - 1] = val;
865 }
866 }
867 }
868
869 if (cfg->fc_mp) {
870#ifdef CONFIG_IP_ROUTE_MULTIPATH
871 err = fib_get_nhs(fi, cfg->fc_mp, cfg->fc_mp_len, cfg);
872 if (err != 0)
873 goto failure;
874 if (cfg->fc_oif && fi->fib_nh->nh_oif != cfg->fc_oif)
875 goto err_inval;
876 if (cfg->fc_gw && fi->fib_nh->nh_gw != cfg->fc_gw)
877 goto err_inval;
878#ifdef CONFIG_IP_ROUTE_CLASSID
879 if (cfg->fc_flow && fi->fib_nh->nh_tclassid != cfg->fc_flow)
880 goto err_inval;
881#endif
882#else
883 goto err_inval;
884#endif
885 } else {
886 struct fib_nh *nh = fi->fib_nh;
887
888 nh->nh_oif = cfg->fc_oif;
889 nh->nh_gw = cfg->fc_gw;
890 nh->nh_flags = cfg->fc_flags;
891#ifdef CONFIG_IP_ROUTE_CLASSID
892 nh->nh_tclassid = cfg->fc_flow;
893 if (nh->nh_tclassid)
894 fi->fib_net->ipv4.fib_num_tclassid_users++;
895#endif
896#ifdef CONFIG_IP_ROUTE_MULTIPATH
897 nh->nh_weight = 1;
898#endif
899 }
900
901 if (fib_props[cfg->fc_type].error) {
902 if (cfg->fc_gw || cfg->fc_oif || cfg->fc_mp)
903 goto err_inval;
904 goto link_it;
905 } else {
906 switch (cfg->fc_type) {
907 case RTN_UNICAST:
908 case RTN_LOCAL:
909 case RTN_BROADCAST:
910 case RTN_ANYCAST:
911 case RTN_MULTICAST:
912 break;
913 default:
914 goto err_inval;
915 }
916 }
917
918 if (cfg->fc_scope > RT_SCOPE_HOST)
919 goto err_inval;
920
921 if (cfg->fc_scope == RT_SCOPE_HOST) {
922 struct fib_nh *nh = fi->fib_nh;
923
924
925 if (nhs != 1 || nh->nh_gw)
926 goto err_inval;
927 nh->nh_scope = RT_SCOPE_NOWHERE;
928 nh->nh_dev = dev_get_by_index(net, fi->fib_nh->nh_oif);
929 err = -ENODEV;
930 if (nh->nh_dev == NULL)
931 goto failure;
932 } else {
933 change_nexthops(fi) {
934 err = fib_check_nh(cfg, fi, nexthop_nh);
935 if (err != 0)
936 goto failure;
937 } endfor_nexthops(fi)
938 }
939
940 if (fi->fib_prefsrc) {
941 if (cfg->fc_type != RTN_LOCAL || !cfg->fc_dst ||
942 fi->fib_prefsrc != cfg->fc_dst)
943 if (inet_addr_type(net, fi->fib_prefsrc) != RTN_LOCAL)
944 goto err_inval;
945 }
946
947 change_nexthops(fi) {
948 fib_info_update_nh_saddr(net, nexthop_nh);
949 } endfor_nexthops(fi)
950
951link_it:
952 ofi = fib_find_info(fi);
953 if (ofi) {
954 fi->fib_dead = 1;
955 free_fib_info(fi);
956 ofi->fib_treeref++;
957 return ofi;
958 }
959
960 fi->fib_treeref++;
961 atomic_inc(&fi->fib_clntref);
962 spin_lock_bh(&fib_info_lock);
963 hlist_add_head(&fi->fib_hash,
964 &fib_info_hash[fib_info_hashfn(fi)]);
965 if (fi->fib_prefsrc) {
966 struct hlist_head *head;
967
968 head = &fib_info_laddrhash[fib_laddr_hashfn(fi->fib_prefsrc)];
969 hlist_add_head(&fi->fib_lhash, head);
970 }
971 change_nexthops(fi) {
972 struct hlist_head *head;
973 unsigned int hash;
974
975 if (!nexthop_nh->nh_dev)
976 continue;
977 hash = fib_devindex_hashfn(nexthop_nh->nh_dev->ifindex);
978 head = &fib_info_devhash[hash];
979 hlist_add_head(&nexthop_nh->nh_hash, head);
980 } endfor_nexthops(fi)
981 spin_unlock_bh(&fib_info_lock);
982 return fi;
983
984err_inval:
985 err = -EINVAL;
986
987failure:
988 if (fi) {
989 fi->fib_dead = 1;
990 free_fib_info(fi);
991 }
992
993 return ERR_PTR(err);
994}
995
996int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
997 u32 tb_id, u8 type, __be32 dst, int dst_len, u8 tos,
998 struct fib_info *fi, unsigned int flags)
999{
1000 struct nlmsghdr *nlh;
1001 struct rtmsg *rtm;
1002
1003 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*rtm), flags);
1004 if (nlh == NULL)
1005 return -EMSGSIZE;
1006
1007 rtm = nlmsg_data(nlh);
1008 rtm->rtm_family = AF_INET;
1009 rtm->rtm_dst_len = dst_len;
1010 rtm->rtm_src_len = 0;
1011 rtm->rtm_tos = tos;
1012 if (tb_id < 256)
1013 rtm->rtm_table = tb_id;
1014 else
1015 rtm->rtm_table = RT_TABLE_COMPAT;
1016 if (nla_put_u32(skb, RTA_TABLE, tb_id))
1017 goto nla_put_failure;
1018 rtm->rtm_type = type;
1019 rtm->rtm_flags = fi->fib_flags;
1020 rtm->rtm_scope = fi->fib_scope;
1021 rtm->rtm_protocol = fi->fib_protocol;
1022
1023 if (rtm->rtm_dst_len &&
1024 nla_put_be32(skb, RTA_DST, dst))
1025 goto nla_put_failure;
1026 if (fi->fib_priority &&
1027 nla_put_u32(skb, RTA_PRIORITY, fi->fib_priority))
1028 goto nla_put_failure;
1029 if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
1030 goto nla_put_failure;
1031
1032 if (fi->fib_prefsrc &&
1033 nla_put_be32(skb, RTA_PREFSRC, fi->fib_prefsrc))
1034 goto nla_put_failure;
1035 if (fi->fib_nhs == 1) {
1036 if (fi->fib_nh->nh_gw &&
1037 nla_put_be32(skb, RTA_GATEWAY, fi->fib_nh->nh_gw))
1038 goto nla_put_failure;
1039 if (fi->fib_nh->nh_oif &&
1040 nla_put_u32(skb, RTA_OIF, fi->fib_nh->nh_oif))
1041 goto nla_put_failure;
1042#ifdef CONFIG_IP_ROUTE_CLASSID
1043 if (fi->fib_nh[0].nh_tclassid &&
1044 nla_put_u32(skb, RTA_FLOW, fi->fib_nh[0].nh_tclassid))
1045 goto nla_put_failure;
1046#endif
1047 }
1048#ifdef CONFIG_IP_ROUTE_MULTIPATH
1049 if (fi->fib_nhs > 1) {
1050 struct rtnexthop *rtnh;
1051 struct nlattr *mp;
1052
1053 mp = nla_nest_start(skb, RTA_MULTIPATH);
1054 if (mp == NULL)
1055 goto nla_put_failure;
1056
1057 for_nexthops(fi) {
1058 rtnh = nla_reserve_nohdr(skb, sizeof(*rtnh));
1059 if (rtnh == NULL)
1060 goto nla_put_failure;
1061
1062 rtnh->rtnh_flags = nh->nh_flags & 0xFF;
1063 rtnh->rtnh_hops = nh->nh_weight - 1;
1064 rtnh->rtnh_ifindex = nh->nh_oif;
1065
1066 if (nh->nh_gw &&
1067 nla_put_be32(skb, RTA_GATEWAY, nh->nh_gw))
1068 goto nla_put_failure;
1069#ifdef CONFIG_IP_ROUTE_CLASSID
1070 if (nh->nh_tclassid &&
1071 nla_put_u32(skb, RTA_FLOW, nh->nh_tclassid))
1072 goto nla_put_failure;
1073#endif
1074
1075 rtnh->rtnh_len = nlmsg_get_pos(skb) - (void *) rtnh;
1076 } endfor_nexthops(fi);
1077
1078 nla_nest_end(skb, mp);
1079 }
1080#endif
1081 return nlmsg_end(skb, nlh);
1082
1083nla_put_failure:
1084 nlmsg_cancel(skb, nlh);
1085 return -EMSGSIZE;
1086}
1087
1088
1089
1090
1091
1092
1093
1094int fib_sync_down_addr(struct net *net, __be32 local)
1095{
1096 int ret = 0;
1097 unsigned int hash = fib_laddr_hashfn(local);
1098 struct hlist_head *head = &fib_info_laddrhash[hash];
1099 struct hlist_node *node;
1100 struct fib_info *fi;
1101
1102 if (fib_info_laddrhash == NULL || local == 0)
1103 return 0;
1104
1105 hlist_for_each_entry(fi, node, head, fib_lhash) {
1106 if (!net_eq(fi->fib_net, net))
1107 continue;
1108 if (fi->fib_prefsrc == local) {
1109 fi->fib_flags |= RTNH_F_DEAD;
1110 ret++;
1111 }
1112 }
1113 return ret;
1114}
1115
1116int fib_sync_down_dev(struct net_device *dev, int force)
1117{
1118 int ret = 0;
1119 int scope = RT_SCOPE_NOWHERE;
1120 struct fib_info *prev_fi = NULL;
1121 unsigned int hash = fib_devindex_hashfn(dev->ifindex);
1122 struct hlist_head *head = &fib_info_devhash[hash];
1123 struct hlist_node *node;
1124 struct fib_nh *nh;
1125
1126 if (force)
1127 scope = -1;
1128
1129 hlist_for_each_entry(nh, node, head, nh_hash) {
1130 struct fib_info *fi = nh->nh_parent;
1131 int dead;
1132
1133 BUG_ON(!fi->fib_nhs);
1134 if (nh->nh_dev != dev || fi == prev_fi)
1135 continue;
1136 prev_fi = fi;
1137 dead = 0;
1138 change_nexthops(fi) {
1139 if (nexthop_nh->nh_flags & RTNH_F_DEAD)
1140 dead++;
1141 else if (nexthop_nh->nh_dev == dev &&
1142 nexthop_nh->nh_scope != scope) {
1143 nexthop_nh->nh_flags |= RTNH_F_DEAD;
1144#ifdef CONFIG_IP_ROUTE_MULTIPATH
1145 spin_lock_bh(&fib_multipath_lock);
1146 fi->fib_power -= nexthop_nh->nh_power;
1147 nexthop_nh->nh_power = 0;
1148 spin_unlock_bh(&fib_multipath_lock);
1149#endif
1150 dead++;
1151 }
1152#ifdef CONFIG_IP_ROUTE_MULTIPATH
1153 if (force > 1 && nexthop_nh->nh_dev == dev) {
1154 dead = fi->fib_nhs;
1155 break;
1156 }
1157#endif
1158 } endfor_nexthops(fi)
1159 if (dead == fi->fib_nhs) {
1160 fi->fib_flags |= RTNH_F_DEAD;
1161 ret++;
1162 }
1163 }
1164
1165 return ret;
1166}
1167
1168
1169void fib_select_default(struct fib_result *res)
1170{
1171 struct fib_info *fi = NULL, *last_resort = NULL;
1172 struct list_head *fa_head = res->fa_head;
1173 struct fib_table *tb = res->table;
1174 int order = -1, last_idx = -1;
1175 struct fib_alias *fa;
1176
1177 list_for_each_entry_rcu(fa, fa_head, fa_list) {
1178 struct fib_info *next_fi = fa->fa_info;
1179
1180 if (next_fi->fib_scope != res->scope ||
1181 fa->fa_type != RTN_UNICAST)
1182 continue;
1183
1184 if (next_fi->fib_priority > res->fi->fib_priority)
1185 break;
1186 if (!next_fi->fib_nh[0].nh_gw ||
1187 next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
1188 continue;
1189
1190 fib_alias_accessed(fa);
1191
1192 if (fi == NULL) {
1193 if (next_fi != res->fi)
1194 break;
1195 } else if (!fib_detect_death(fi, order, &last_resort,
1196 &last_idx, tb->tb_default)) {
1197 fib_result_assign(res, fi);
1198 tb->tb_default = order;
1199 goto out;
1200 }
1201 fi = next_fi;
1202 order++;
1203 }
1204
1205 if (order <= 0 || fi == NULL) {
1206 tb->tb_default = -1;
1207 goto out;
1208 }
1209
1210 if (!fib_detect_death(fi, order, &last_resort, &last_idx,
1211 tb->tb_default)) {
1212 fib_result_assign(res, fi);
1213 tb->tb_default = order;
1214 goto out;
1215 }
1216
1217 if (last_idx >= 0)
1218 fib_result_assign(res, last_resort);
1219 tb->tb_default = last_idx;
1220out:
1221 return;
1222}
1223
1224#ifdef CONFIG_IP_ROUTE_MULTIPATH
1225
1226
1227
1228
1229
1230int fib_sync_up(struct net_device *dev)
1231{
1232 struct fib_info *prev_fi;
1233 unsigned int hash;
1234 struct hlist_head *head;
1235 struct hlist_node *node;
1236 struct fib_nh *nh;
1237 int ret;
1238
1239 if (!(dev->flags & IFF_UP))
1240 return 0;
1241
1242 prev_fi = NULL;
1243 hash = fib_devindex_hashfn(dev->ifindex);
1244 head = &fib_info_devhash[hash];
1245 ret = 0;
1246
1247 hlist_for_each_entry(nh, node, head, nh_hash) {
1248 struct fib_info *fi = nh->nh_parent;
1249 int alive;
1250
1251 BUG_ON(!fi->fib_nhs);
1252 if (nh->nh_dev != dev || fi == prev_fi)
1253 continue;
1254
1255 prev_fi = fi;
1256 alive = 0;
1257 change_nexthops(fi) {
1258 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
1259 alive++;
1260 continue;
1261 }
1262 if (nexthop_nh->nh_dev == NULL ||
1263 !(nexthop_nh->nh_dev->flags & IFF_UP))
1264 continue;
1265 if (nexthop_nh->nh_dev != dev ||
1266 !__in_dev_get_rtnl(dev))
1267 continue;
1268 alive++;
1269 spin_lock_bh(&fib_multipath_lock);
1270 nexthop_nh->nh_power = 0;
1271 nexthop_nh->nh_flags &= ~RTNH_F_DEAD;
1272 spin_unlock_bh(&fib_multipath_lock);
1273 } endfor_nexthops(fi)
1274
1275 if (alive > 0) {
1276 fi->fib_flags &= ~RTNH_F_DEAD;
1277 ret++;
1278 }
1279 }
1280
1281 return ret;
1282}
1283
1284
1285
1286
1287
1288void fib_select_multipath(struct fib_result *res)
1289{
1290 struct fib_info *fi = res->fi;
1291 int w;
1292
1293 spin_lock_bh(&fib_multipath_lock);
1294 if (fi->fib_power <= 0) {
1295 int power = 0;
1296 change_nexthops(fi) {
1297 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
1298 power += nexthop_nh->nh_weight;
1299 nexthop_nh->nh_power = nexthop_nh->nh_weight;
1300 }
1301 } endfor_nexthops(fi);
1302 fi->fib_power = power;
1303 if (power <= 0) {
1304 spin_unlock_bh(&fib_multipath_lock);
1305
1306 res->nh_sel = 0;
1307 return;
1308 }
1309 }
1310
1311
1312
1313
1314
1315
1316 w = jiffies % fi->fib_power;
1317
1318 change_nexthops(fi) {
1319 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD) &&
1320 nexthop_nh->nh_power) {
1321 w -= nexthop_nh->nh_power;
1322 if (w <= 0) {
1323 nexthop_nh->nh_power--;
1324 fi->fib_power--;
1325 res->nh_sel = nhsel;
1326 spin_unlock_bh(&fib_multipath_lock);
1327 return;
1328 }
1329 }
1330 } endfor_nexthops(fi);
1331
1332
1333 res->nh_sel = 0;
1334 spin_unlock_bh(&fib_multipath_lock);
1335}
1336#endif
1337