60
61
static DEFINE_SPINLOCK(fib_multipath_lock);
62
#define for_nexthops(fi) { int nhsel; const struct fib_nh * nh; \
63
for (nhsel=0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
63
#define for_nexthops(fi) { \
64
int nhsel; const struct fib_nh *nh; \
65
for (nhsel = 0, nh = (fi)->fib_nh; \
66
nhsel < (fi)->fib_nhs; \
65
#define change_nexthops(fi) { int nhsel; struct fib_nh * nh; \
66
for (nhsel=0, nh = (struct fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nh++, nhsel++)
69
#define change_nexthops(fi) { \
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
75
#else /* CONFIG_IP_ROUTE_MULTIPATH */
70
77
/* Hope, that gcc will optimize it to get rid of dummy loop */
72
#define for_nexthops(fi) { int nhsel = 0; const struct fib_nh * nh = (fi)->fib_nh; \
73
for (nhsel=0; nhsel < 1; nhsel++)
79
#define for_nexthops(fi) { \
80
int nhsel; const struct fib_nh *nh = (fi)->fib_nh; \
81
for (nhsel = 0; nhsel < 1; nhsel++)
75
#define change_nexthops(fi) { int nhsel = 0; struct fib_nh * nh = (struct fib_nh *)((fi)->fib_nh); \
76
for (nhsel=0; nhsel < 1; nhsel++)
83
#define change_nexthops(fi) { \
85
struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \
86
for (nhsel = 0; nhsel < 1; nhsel++)
78
88
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
87
97
} fib_props[RTN_MAX + 1] = {
90
100
.scope = RT_SCOPE_NOWHERE,
94
104
.scope = RT_SCOPE_UNIVERSE,
98
108
.scope = RT_SCOPE_HOST,
102
.scope = RT_SCOPE_LINK,
103
}, /* RTN_BROADCAST */
106
.scope = RT_SCOPE_LINK,
112
.scope = RT_SCOPE_LINK,
116
.scope = RT_SCOPE_LINK,
110
120
.scope = RT_SCOPE_UNIVERSE,
111
}, /* RTN_MULTICAST */
113
123
.error = -EINVAL,
114
124
.scope = RT_SCOPE_UNIVERSE,
115
}, /* RTN_BLACKHOLE */
126
[RTN_UNREACHABLE] = {
117
127
.error = -EHOSTUNREACH,
118
128
.scope = RT_SCOPE_UNIVERSE,
119
}, /* RTN_UNREACHABLE */
121
131
.error = -EACCES,
122
132
.scope = RT_SCOPE_UNIVERSE,
123
}, /* RTN_PROHIBIT */
125
135
.error = -EAGAIN,
126
136
.scope = RT_SCOPE_UNIVERSE,
130
.scope = RT_SCOPE_NOWHERE,
134
.scope = RT_SCOPE_NOWHERE,
135
}, /* RTN_XRESOLVE */
140
.scope = RT_SCOPE_NOWHERE,
144
.scope = RT_SCOPE_NOWHERE,
139
149
/* Release a nexthop info record */
151
static void free_fib_info_rcu(struct rcu_head *head)
153
struct fib_info *fi = container_of(head, struct fib_info, rcu);
141
158
void free_fib_info(struct fib_info *fi)
143
160
if (fi->fib_dead == 0) {
144
printk(KERN_WARNING "Freeing alive fib_info %p\n", fi);
161
pr_warning("Freeing alive fib_info %p\n", fi);
147
164
change_nexthops(fi) {
165
if (nexthop_nh->nh_dev)
166
dev_put(nexthop_nh->nh_dev);
167
nexthop_nh->nh_dev = NULL;
151
168
} endfor_nexthops(fi);
153
170
release_net(fi->fib_net);
171
call_rcu(&fi->rcu, free_fib_info_rcu);
157
174
void fib_release_info(struct fib_info *fi)
480
Semantics of nexthop is very messy by historical reasons.
481
We have to take into account, that:
482
a) gateway can be actually local interface address,
483
so that gatewayed route is direct.
484
b) gateway must be on-link address, possibly
485
described not by an ifaddr, but also by a direct route.
486
c) If both gateway and interface are specified, they should not
488
d) If we use tunnel routes, gateway could be not on-link.
490
Attempt to reconcile all of these (alas, self-contradictory) conditions
491
results in pretty ugly and hairy code with obscure logic.
493
I chose to generalized it instead, so that the size
494
of code does not increase practically, but it becomes
496
Every prefix is assigned a "scope" value: "host" is local address,
497
"link" is direct route,
498
[ ... "site" ... "interior" ... ]
499
and "universe" is true gateway route with global meaning.
501
Every prefix refers to a set of "nexthop"s (gw, oif),
502
where gw must have narrower scope. This recursion stops
503
when gw has LOCAL scope or if "nexthop" is declared ONLINK,
504
which means that gw is forced to be on link.
506
Code is still hairy, but now it is apparently logically
507
consistent and very flexible. F.e. as by-product it allows
508
to co-exists in peace independent exterior and interior
511
Normally it looks as following.
513
{universe prefix} -> (gw, oif) [scope link]
515
|-> {link prefix} -> (gw, oif) [scope local]
517
|-> {local prefix} (terminal node)
497
* Semantics of nexthop is very messy by historical reasons.
498
* We have to take into account, that:
499
* a) gateway can be actually local interface address,
500
* so that gatewayed route is direct.
501
* b) gateway must be on-link address, possibly
502
* described not by an ifaddr, but also by a direct route.
503
* c) If both gateway and interface are specified, they should not
505
* d) If we use tunnel routes, gateway could be not on-link.
507
* Attempt to reconcile all of these (alas, self-contradictory) conditions
508
* results in pretty ugly and hairy code with obscure logic.
510
* I chose to generalized it instead, so that the size
511
* of code does not increase practically, but it becomes
513
* Every prefix is assigned a "scope" value: "host" is local address,
514
* "link" is direct route,
515
* [ ... "site" ... "interior" ... ]
516
* and "universe" is true gateway route with global meaning.
518
* Every prefix refers to a set of "nexthop"s (gw, oif),
519
* where gw must have narrower scope. This recursion stops
520
* when gw has LOCAL scope or if "nexthop" is declared ONLINK,
521
* which means that gw is forced to be on link.
523
* Code is still hairy, but now it is apparently logically
524
* consistent and very flexible. F.e. as by-product it allows
525
* to co-exists in peace independent exterior and interior
528
* Normally it looks as following.
530
* {universe prefix} -> (gw, oif) [scope link]
532
* |-> {link prefix} -> (gw, oif) [scope local]
534
* |-> {local prefix} (terminal node)
520
536
static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
521
537
struct fib_nh *nh)
541
struct net_device *dev;
526
543
net = cfg->fc_nlinfo.nl_net;
528
545
struct fib_result res;
530
#ifdef CONFIG_IP_ROUTE_PERVASIVE
531
if (nh->nh_flags&RTNH_F_PERVASIVE)
534
if (nh->nh_flags&RTNH_F_ONLINK) {
535
struct net_device *dev;
547
if (nh->nh_flags & RTNH_F_ONLINK) {
537
549
if (cfg->fc_scope >= RT_SCOPE_LINK)
539
551
if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST)
541
if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL)
553
dev = __dev_get_by_index(net, nh->nh_oif);
543
if (!(dev->flags&IFF_UP))
556
if (!(dev->flags & IFF_UP))
544
557
return -ENETDOWN;
545
558
nh->nh_dev = dev;
547
560
nh->nh_scope = RT_SCOPE_LINK;
551
565
struct flowi fl = {
555
.scope = cfg->fc_scope + 1,
566
.fl4_dst = nh->nh_gw,
567
.fl4_scope = cfg->fc_scope + 1,
558
568
.oif = nh->nh_oif,
561
571
/* It is not necessary, but requires a bit of thinking */
562
572
if (fl.fl4_scope < RT_SCOPE_LINK)
563
573
fl.fl4_scope = RT_SCOPE_LINK;
564
if ((err = fib_lookup(net, &fl, &res)) != 0)
574
err = fib_lookup(net, &fl, &res);
568
581
if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
570
583
nh->nh_scope = res.scope;
571
584
nh->nh_oif = FIB_RES_OIF(res);
572
if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL)
574
dev_hold(nh->nh_dev);
576
if (!(nh->nh_dev->flags & IFF_UP))
585
nh->nh_dev = dev = FIB_RES_DEV(res);
589
err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN;
583
591
struct in_device *in_dev;
585
if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
593
if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK))
588
598
in_dev = inetdev_by_index(net, nh->nh_oif);
589
599
if (in_dev == NULL)
591
if (!(in_dev->dev->flags&IFF_UP)) {
602
if (!(in_dev->dev->flags & IFF_UP))
595
604
nh->nh_dev = in_dev->dev;
596
605
dev_hold(nh->nh_dev);
597
606
nh->nh_scope = RT_SCOPE_HOST;
603
614
static inline unsigned int fib_laddr_hashfn(__be32 val)
605
616
unsigned int mask = (fib_hash_size - 1);
607
return ((__force u32)val ^ ((__force u32)val >> 7) ^ ((__force u32)val >> 14)) & mask;
618
return ((__force u32)val ^
619
((__force u32)val >> 7) ^
620
((__force u32)val >> 14)) & mask;
610
623
static struct hlist_head *fib_hash_alloc(int bytes)