~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to net/ipv4/fib_semantics.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
#include <linux/proc_fs.h>
33
33
#include <linux/skbuff.h>
34
34
#include <linux/init.h>
 
35
#include <linux/slab.h>
35
36
 
36
37
#include <net/arp.h>
37
38
#include <net/ip.h>
59
60
 
60
61
static DEFINE_SPINLOCK(fib_multipath_lock);
61
62
 
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;                                     \
 
67
             nh++, nhsel++)
64
68
 
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++)
67
74
 
68
75
#else /* CONFIG_IP_ROUTE_MULTIPATH */
69
76
 
70
77
/* Hope, that gcc will optimize it to get rid of dummy loop */
71
78
 
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++)
74
82
 
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) {                                           \
 
84
        int nhsel;                                                      \
 
85
        struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh);    \
 
86
        for (nhsel = 0; nhsel < 1; nhsel++)
77
87
 
78
88
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
79
89
 
85
95
        int     error;
86
96
        u8      scope;
87
97
} fib_props[RTN_MAX + 1] = {
88
 
        {
 
98
        [RTN_UNSPEC] = {
89
99
                .error  = 0,
90
100
                .scope  = RT_SCOPE_NOWHERE,
91
 
        },      /* RTN_UNSPEC */
92
 
        {
 
101
        },
 
102
        [RTN_UNICAST] = {
93
103
                .error  = 0,
94
104
                .scope  = RT_SCOPE_UNIVERSE,
95
 
        },      /* RTN_UNICAST */
96
 
        {
 
105
        },
 
106
        [RTN_LOCAL] = {
97
107
                .error  = 0,
98
108
                .scope  = RT_SCOPE_HOST,
99
 
        },      /* RTN_LOCAL */
100
 
        {
101
 
                .error  = 0,
102
 
                .scope  = RT_SCOPE_LINK,
103
 
        },      /* RTN_BROADCAST */
104
 
        {
105
 
                .error  = 0,
106
 
                .scope  = RT_SCOPE_LINK,
107
 
        },      /* RTN_ANYCAST */
108
 
        {
 
109
        },
 
110
        [RTN_BROADCAST] = {
 
111
                .error  = 0,
 
112
                .scope  = RT_SCOPE_LINK,
 
113
        },
 
114
        [RTN_ANYCAST] = {
 
115
                .error  = 0,
 
116
                .scope  = RT_SCOPE_LINK,
 
117
        },
 
118
        [RTN_MULTICAST] = {
109
119
                .error  = 0,
110
120
                .scope  = RT_SCOPE_UNIVERSE,
111
 
        },      /* RTN_MULTICAST */
112
 
        {
 
121
        },
 
122
        [RTN_BLACKHOLE] = {
113
123
                .error  = -EINVAL,
114
124
                .scope  = RT_SCOPE_UNIVERSE,
115
 
        },      /* RTN_BLACKHOLE */
116
 
        {
 
125
        },
 
126
        [RTN_UNREACHABLE] = {
117
127
                .error  = -EHOSTUNREACH,
118
128
                .scope  = RT_SCOPE_UNIVERSE,
119
 
        },      /* RTN_UNREACHABLE */
120
 
        {
 
129
        },
 
130
        [RTN_PROHIBIT] = {
121
131
                .error  = -EACCES,
122
132
                .scope  = RT_SCOPE_UNIVERSE,
123
 
        },      /* RTN_PROHIBIT */
124
 
        {
 
133
        },
 
134
        [RTN_THROW] = {
125
135
                .error  = -EAGAIN,
126
136
                .scope  = RT_SCOPE_UNIVERSE,
127
 
        },      /* RTN_THROW */
128
 
        {
129
 
                .error  = -EINVAL,
130
 
                .scope  = RT_SCOPE_NOWHERE,
131
 
        },      /* RTN_NAT */
132
 
        {
133
 
                .error  = -EINVAL,
134
 
                .scope  = RT_SCOPE_NOWHERE,
135
 
        },      /* RTN_XRESOLVE */
 
137
        },
 
138
        [RTN_NAT] = {
 
139
                .error  = -EINVAL,
 
140
                .scope  = RT_SCOPE_NOWHERE,
 
141
        },
 
142
        [RTN_XRESOLVE] = {
 
143
                .error  = -EINVAL,
 
144
                .scope  = RT_SCOPE_NOWHERE,
 
145
        },
136
146
};
137
147
 
138
148
 
139
149
/* Release a nexthop info record */
140
150
 
 
151
static void free_fib_info_rcu(struct rcu_head *head)
 
152
{
 
153
        struct fib_info *fi = container_of(head, struct fib_info, rcu);
 
154
 
 
155
        kfree(fi);
 
156
}
 
157
 
141
158
void free_fib_info(struct fib_info *fi)
142
159
{
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);
145
162
                return;
146
163
        }
147
164
        change_nexthops(fi) {
148
 
                if (nh->nh_dev)
149
 
                        dev_put(nh->nh_dev);
150
 
                nh->nh_dev = NULL;
 
165
                if (nexthop_nh->nh_dev)
 
166
                        dev_put(nexthop_nh->nh_dev);
 
167
                nexthop_nh->nh_dev = NULL;
151
168
        } endfor_nexthops(fi);
152
169
        fib_info_cnt--;
153
170
        release_net(fi->fib_net);
154
 
        kfree(fi);
 
171
        call_rcu(&fi->rcu, free_fib_info_rcu);
155
172
}
156
173
 
157
174
void fib_release_info(struct fib_info *fi)
162
179
                if (fi->fib_prefsrc)
163
180
                        hlist_del(&fi->fib_lhash);
164
181
                change_nexthops(fi) {
165
 
                        if (!nh->nh_dev)
 
182
                        if (!nexthop_nh->nh_dev)
166
183
                                continue;
167
 
                        hlist_del(&nh->nh_hash);
 
184
                        hlist_del(&nexthop_nh->nh_hash);
168
185
                } endfor_nexthops(fi)
169
186
                fi->fib_dead = 1;
170
187
                fib_info_put(fi);
172
189
        spin_unlock_bh(&fib_info_lock);
173
190
}
174
191
 
175
 
static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi)
 
192
static inline int nh_comp(const struct fib_info *fi, const struct fib_info *ofi)
176
193
{
177
194
        const struct fib_nh *onh = ofi->fib_nh;
178
195
 
186
203
#ifdef CONFIG_NET_CLS_ROUTE
187
204
                    nh->nh_tclassid != onh->nh_tclassid ||
188
205
#endif
189
 
                    ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD))
 
206
                    ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD))
190
207
                        return -1;
191
208
                onh++;
192
209
        } endfor_nexthops(fi);
228
245
        head = &fib_info_hash[hash];
229
246
 
230
247
        hlist_for_each_entry(fi, node, head, fib_hash) {
231
 
                if (fi->fib_net != nfi->fib_net)
 
248
                if (!net_eq(fi->fib_net, nfi->fib_net))
232
249
                        continue;
233
250
                if (fi->fib_nhs != nfi->fib_nhs)
234
251
                        continue;
237
254
                    nfi->fib_priority == fi->fib_priority &&
238
255
                    memcmp(nfi->fib_metrics, fi->fib_metrics,
239
256
                           sizeof(fi->fib_metrics)) == 0 &&
240
 
                    ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 &&
 
257
                    ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 &&
241
258
                    (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0))
242
259
                        return fi;
243
260
        }
246
263
}
247
264
 
248
265
/* Check, that the gateway is already configured.
249
 
   Used only by redirect accept routine.
 
266
 * Used only by redirect accept routine.
250
267
 */
251
 
 
252
268
int ip_fib_check_default(__be32 gw, struct net_device *dev)
253
269
{
254
270
        struct hlist_head *head;
263
279
        hlist_for_each_entry(nh, node, head, nh_hash) {
264
280
                if (nh->nh_dev == dev &&
265
281
                    nh->nh_gw == gw &&
266
 
                    !(nh->nh_flags&RTNH_F_DEAD)) {
 
282
                    !(nh->nh_flags & RTNH_F_DEAD)) {
267
283
                        spin_unlock(&fib_info_lock);
268
284
                        return 0;
269
285
                }
361
377
        }
362
378
        if (state == NUD_REACHABLE)
363
379
                return 0;
364
 
        if ((state&NUD_VALID) && order != dflt)
 
380
        if ((state & NUD_VALID) && order != dflt)
365
381
                return 0;
366
 
        if ((state&NUD_VALID) ||
367
 
            (*last_idx<0 && order > dflt)) {
 
382
        if ((state & NUD_VALID) ||
 
383
            (*last_idx < 0 && order > dflt)) {
368
384
                *last_resort = fi;
369
385
                *last_idx = order;
370
386
        }
395
411
                if (!rtnh_ok(rtnh, remaining))
396
412
                        return -EINVAL;
397
413
 
398
 
                nh->nh_flags = (cfg->fc_flags & ~0xFF) | rtnh->rtnh_flags;
399
 
                nh->nh_oif = rtnh->rtnh_ifindex;
400
 
                nh->nh_weight = rtnh->rtnh_hops + 1;
 
414
                nexthop_nh->nh_flags =
 
415
                        (cfg->fc_flags & ~0xFF) | rtnh->rtnh_flags;
 
416
                nexthop_nh->nh_oif = rtnh->rtnh_ifindex;
 
417
                nexthop_nh->nh_weight = rtnh->rtnh_hops + 1;
401
418
 
402
419
                attrlen = rtnh_attrlen(rtnh);
403
420
                if (attrlen > 0) {
404
421
                        struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
405
422
 
406
423
                        nla = nla_find(attrs, attrlen, RTA_GATEWAY);
407
 
                        nh->nh_gw = nla ? nla_get_be32(nla) : 0;
 
424
                        nexthop_nh->nh_gw = nla ? nla_get_be32(nla) : 0;
408
425
#ifdef CONFIG_NET_CLS_ROUTE
409
426
                        nla = nla_find(attrs, attrlen, RTA_FLOW);
410
 
                        nh->nh_tclassid = nla ? nla_get_u32(nla) : 0;
 
427
                        nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0;
411
428
#endif
412
429
                }
413
430
 
474
491
 
475
492
 
476
493
/*
477
 
   Picture
478
 
   -------
479
 
 
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
487
 
      contradict.
488
 
   d) If we use tunnel routes, gateway could be not on-link.
489
 
 
490
 
   Attempt to reconcile all of these (alas, self-contradictory) conditions
491
 
   results in pretty ugly and hairy code with obscure logic.
492
 
 
493
 
   I chose to generalized it instead, so that the size
494
 
   of code does not increase practically, but it becomes
495
 
   much more general.
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.
500
 
 
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.
505
 
 
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
509
 
   routing processes.
510
 
 
511
 
   Normally it looks as following.
512
 
 
513
 
   {universe prefix}  -> (gw, oif) [scope link]
514
 
                          |
515
 
                          |-> {link prefix} -> (gw, oif) [scope local]
516
 
                                                |
517
 
                                                |-> {local prefix} (terminal node)
 
494
 * Picture
 
495
 * -------
 
496
 *
 
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
 
504
 *    contradict.
 
505
 * d) If we use tunnel routes, gateway could be not on-link.
 
506
 *
 
507
 * Attempt to reconcile all of these (alas, self-contradictory) conditions
 
508
 * results in pretty ugly and hairy code with obscure logic.
 
509
 *
 
510
 * I chose to generalized it instead, so that the size
 
511
 * of code does not increase practically, but it becomes
 
512
 * much more general.
 
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.
 
517
 *
 
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.
 
522
 *
 
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
 
526
 * routing processes.
 
527
 *
 
528
 * Normally it looks as following.
 
529
 *
 
530
 * {universe prefix}  -> (gw, oif) [scope link]
 
531
 *                |
 
532
 *                |-> {link prefix} -> (gw, oif) [scope local]
 
533
 *                                      |
 
534
 *                                      |-> {local prefix} (terminal node)
518
535
 */
519
 
 
520
536
static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
521
537
                        struct fib_nh *nh)
522
538
{
523
539
        int err;
524
540
        struct net *net;
 
541
        struct net_device *dev;
525
542
 
526
543
        net = cfg->fc_nlinfo.nl_net;
527
544
        if (nh->nh_gw) {
528
545
                struct fib_result res;
529
546
 
530
 
#ifdef CONFIG_IP_ROUTE_PERVASIVE
531
 
                if (nh->nh_flags&RTNH_F_PERVASIVE)
532
 
                        return 0;
533
 
#endif
534
 
                if (nh->nh_flags&RTNH_F_ONLINK) {
535
 
                        struct net_device *dev;
 
547
                if (nh->nh_flags & RTNH_F_ONLINK) {
536
548
 
537
549
                        if (cfg->fc_scope >= RT_SCOPE_LINK)
538
550
                                return -EINVAL;
539
551
                        if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST)
540
552
                                return -EINVAL;
541
 
                        if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL)
 
553
                        dev = __dev_get_by_index(net, nh->nh_oif);
 
554
                        if (!dev)
542
555
                                return -ENODEV;
543
 
                        if (!(dev->flags&IFF_UP))
 
556
                        if (!(dev->flags & IFF_UP))
544
557
                                return -ENETDOWN;
545
558
                        nh->nh_dev = dev;
546
559
                        dev_hold(dev);
547
560
                        nh->nh_scope = RT_SCOPE_LINK;
548
561
                        return 0;
549
562
                }
 
563
                rcu_read_lock();
550
564
                {
551
565
                        struct flowi fl = {
552
 
                                .nl_u = {
553
 
                                        .ip4_u = {
554
 
                                                .daddr = nh->nh_gw,
555
 
                                                .scope = cfg->fc_scope + 1,
556
 
                                        },
557
 
                                },
 
566
                                .fl4_dst = nh->nh_gw,
 
567
                                .fl4_scope = cfg->fc_scope + 1,
558
568
                                .oif = nh->nh_oif,
559
569
                        };
560
570
 
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);
 
575
                        if (err) {
 
576
                                rcu_read_unlock();
565
577
                                return err;
 
578
                        }
566
579
                }
567
580
                err = -EINVAL;
568
581
                if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
569
582
                        goto out;
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)
573
 
                        goto out;
574
 
                dev_hold(nh->nh_dev);
575
 
                err = -ENETDOWN;
576
 
                if (!(nh->nh_dev->flags & IFF_UP))
577
 
                        goto out;
578
 
                err = 0;
579
 
out:
580
 
                fib_res_put(&res);
581
 
                return err;
 
585
                nh->nh_dev = dev = FIB_RES_DEV(res);
 
586
                if (!dev)
 
587
                        goto out;
 
588
                dev_hold(dev);
 
589
                err = (dev->flags & IFF_UP) ? 0 : -ENETDOWN;
582
590
        } else {
583
591
                struct in_device *in_dev;
584
592
 
585
 
                if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK))
 
593
                if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK))
586
594
                        return -EINVAL;
587
595
 
 
596
                rcu_read_lock();
 
597
                err = -ENODEV;
588
598
                in_dev = inetdev_by_index(net, nh->nh_oif);
589
599
                if (in_dev == NULL)
590
 
                        return -ENODEV;
591
 
                if (!(in_dev->dev->flags&IFF_UP)) {
592
 
                        in_dev_put(in_dev);
593
 
                        return -ENETDOWN;
594
 
                }
 
600
                        goto out;
 
601
                err = -ENETDOWN;
 
602
                if (!(in_dev->dev->flags & IFF_UP))
 
603
                        goto out;
595
604
                nh->nh_dev = in_dev->dev;
596
605
                dev_hold(nh->nh_dev);
597
606
                nh->nh_scope = RT_SCOPE_HOST;
598
 
                in_dev_put(in_dev);
 
607
                err = 0;
599
608
        }
600
 
        return 0;
 
609
out:
 
610
        rcu_read_unlock();
 
611
        return err;
601
612
}
602
613
 
603
614
static inline unsigned int fib_laddr_hashfn(__be32 val)
604
615
{
605
616
        unsigned int mask = (fib_hash_size - 1);
606
617
 
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;
608
621
}
609
622
 
610
623
static struct hlist_head *fib_hash_alloc(int bytes)
613
626
                return kzalloc(bytes, GFP_KERNEL);
614
627
        else
615
628
                return (struct hlist_head *)
616
 
                        __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(bytes));
 
629
                        __get_free_pages(GFP_KERNEL | __GFP_ZERO,
 
630
                                         get_order(bytes));
617
631
}
618
632
 
619
633
static void fib_hash_free(struct hlist_head *hash, int bytes)
738
752
 
739
753
        fi->fib_nhs = nhs;
740
754
        change_nexthops(fi) {
741
 
                nh->nh_parent = fi;
 
755
                nexthop_nh->nh_parent = fi;
742
756
        } endfor_nexthops(fi)
743
757
 
744
758
        if (cfg->fc_mx) {
808
822
                        goto failure;
809
823
        } else {
810
824
                change_nexthops(fi) {
811
 
                        if ((err = fib_check_nh(cfg, fi, nh)) != 0)
 
825
                        err = fib_check_nh(cfg, fi, nexthop_nh);
 
826
                        if (err != 0)
812
827
                                goto failure;
813
828
                } endfor_nexthops(fi)
814
829
        }
821
836
        }
822
837
 
823
838
link_it:
824
 
        if ((ofi = fib_find_info(fi)) != NULL) {
 
839
        ofi = fib_find_info(fi);
 
840
        if (ofi) {
825
841
                fi->fib_dead = 1;
826
842
                free_fib_info(fi);
827
843
                ofi->fib_treeref++;
843
859
                struct hlist_head *head;
844
860
                unsigned int hash;
845
861
 
846
 
                if (!nh->nh_dev)
 
862
                if (!nexthop_nh->nh_dev)
847
863
                        continue;
848
 
                hash = fib_devindex_hashfn(nh->nh_dev->ifindex);
 
864
                hash = fib_devindex_hashfn(nexthop_nh->nh_dev->ifindex);
849
865
                head = &fib_info_devhash[hash];
850
 
                hlist_add_head(&nh->nh_hash, head);
 
866
                hlist_add_head(&nexthop_nh->nh_hash, head);
851
867
        } endfor_nexthops(fi)
852
868
        spin_unlock_bh(&fib_info_lock);
853
869
        return fi;
866
882
 
867
883
/* Note! fib_semantic_match intentionally uses  RCU list functions. */
868
884
int fib_semantic_match(struct list_head *head, const struct flowi *flp,
869
 
                       struct fib_result *res, int prefixlen)
 
885
                       struct fib_result *res, int prefixlen, int fib_flags)
870
886
{
871
887
        struct fib_alias *fa;
872
888
        int nh_sel = 0;
881
897
                if (fa->fa_scope < flp->fl4_scope)
882
898
                        continue;
883
899
 
884
 
                fa->fa_state |= FA_S_ACCESSED;
 
900
                fib_alias_accessed(fa);
885
901
 
886
902
                err = fib_props[fa->fa_type].error;
887
903
                if (err == 0) {
897
913
                        case RTN_ANYCAST:
898
914
                        case RTN_MULTICAST:
899
915
                                for_nexthops(fi) {
900
 
                                        if (nh->nh_flags&RTNH_F_DEAD)
 
916
                                        if (nh->nh_flags & RTNH_F_DEAD)
901
917
                                                continue;
902
918
                                        if (!flp->oif || flp->oif == nh->nh_oif)
903
919
                                                break;
908
924
                                        goto out_fill_res;
909
925
                                }
910
926
#else
911
 
                                if (nhsel < 1) {
 
927
                                if (nhsel < 1)
912
928
                                        goto out_fill_res;
913
 
                                }
914
929
#endif
915
930
                                endfor_nexthops(fi);
916
931
                                continue;
917
932
 
918
933
                        default:
919
 
                                printk(KERN_WARNING "fib_semantic_match bad type %#x\n",
920
 
                                        fa->fa_type);
 
934
                                pr_warning("fib_semantic_match bad type %#x\n",
 
935
                                           fa->fa_type);
921
936
                                return -EINVAL;
922
937
                        }
923
938
                }
931
946
        res->type = fa->fa_type;
932
947
        res->scope = fa->fa_scope;
933
948
        res->fi = fa->fa_info;
934
 
        atomic_inc(&res->fi->fib_clntref);
 
949
        if (!(fib_flags & FIB_LOOKUP_NOREF))
 
950
                atomic_inc(&res->fi->fib_clntref);
935
951
        return 0;
936
952
}
937
953
 
1030
1046
}
1031
1047
 
1032
1048
/*
1033
 
   Update FIB if:
1034
 
   - local address disappeared -> we must delete all the entries
1035
 
     referring to it.
1036
 
   - device went down -> we must shutdown all nexthops going via it.
 
1049
 * Update FIB if:
 
1050
 * - local address disappeared -> we must delete all the entries
 
1051
 *   referring to it.
 
1052
 * - device went down -> we must shutdown all nexthops going via it.
1037
1053
 */
1038
1054
int fib_sync_down_addr(struct net *net, __be32 local)
1039
1055
{
1047
1063
                return 0;
1048
1064
 
1049
1065
        hlist_for_each_entry(fi, node, head, fib_lhash) {
1050
 
                if (fi->fib_net != net)
 
1066
                if (!net_eq(fi->fib_net, net))
1051
1067
                        continue;
1052
1068
                if (fi->fib_prefsrc == local) {
1053
1069
                        fi->fib_flags |= RTNH_F_DEAD;
1080
1096
                prev_fi = fi;
1081
1097
                dead = 0;
1082
1098
                change_nexthops(fi) {
1083
 
                        if (nh->nh_flags&RTNH_F_DEAD)
 
1099
                        if (nexthop_nh->nh_flags & RTNH_F_DEAD)
1084
1100
                                dead++;
1085
 
                        else if (nh->nh_dev == dev &&
1086
 
                                        nh->nh_scope != scope) {
1087
 
                                nh->nh_flags |= RTNH_F_DEAD;
 
1101
                        else if (nexthop_nh->nh_dev == dev &&
 
1102
                                 nexthop_nh->nh_scope != scope) {
 
1103
                                nexthop_nh->nh_flags |= RTNH_F_DEAD;
1088
1104
#ifdef CONFIG_IP_ROUTE_MULTIPATH
1089
1105
                                spin_lock_bh(&fib_multipath_lock);
1090
 
                                fi->fib_power -= nh->nh_power;
1091
 
                                nh->nh_power = 0;
 
1106
                                fi->fib_power -= nexthop_nh->nh_power;
 
1107
                                nexthop_nh->nh_power = 0;
1092
1108
                                spin_unlock_bh(&fib_multipath_lock);
1093
1109
#endif
1094
1110
                                dead++;
1095
1111
                        }
1096
1112
#ifdef CONFIG_IP_ROUTE_MULTIPATH
1097
 
                        if (force > 1 && nh->nh_dev == dev) {
 
1113
                        if (force > 1 && nexthop_nh->nh_dev == dev) {
1098
1114
                                dead = fi->fib_nhs;
1099
1115
                                break;
1100
1116
                        }
1112
1128
#ifdef CONFIG_IP_ROUTE_MULTIPATH
1113
1129
 
1114
1130
/*
1115
 
   Dead device goes up. We wake up dead nexthops.
1116
 
   It takes sense only on multipath routes.
 
1131
 * Dead device goes up. We wake up dead nexthops.
 
1132
 * It takes sense only on multipath routes.
1117
1133
 */
1118
 
 
1119
1134
int fib_sync_up(struct net_device *dev)
1120
1135
{
1121
1136
        struct fib_info *prev_fi;
1125
1140
        struct fib_nh *nh;
1126
1141
        int ret;
1127
1142
 
1128
 
        if (!(dev->flags&IFF_UP))
 
1143
        if (!(dev->flags & IFF_UP))
1129
1144
                return 0;
1130
1145
 
1131
1146
        prev_fi = NULL;
1144
1159
                prev_fi = fi;
1145
1160
                alive = 0;
1146
1161
                change_nexthops(fi) {
1147
 
                        if (!(nh->nh_flags&RTNH_F_DEAD)) {
 
1162
                        if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
1148
1163
                                alive++;
1149
1164
                                continue;
1150
1165
                        }
1151
 
                        if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP))
 
1166
                        if (nexthop_nh->nh_dev == NULL ||
 
1167
                            !(nexthop_nh->nh_dev->flags & IFF_UP))
1152
1168
                                continue;
1153
 
                        if (nh->nh_dev != dev || !__in_dev_get_rtnl(dev))
 
1169
                        if (nexthop_nh->nh_dev != dev ||
 
1170
                            !__in_dev_get_rtnl(dev))
1154
1171
                                continue;
1155
1172
                        alive++;
1156
1173
                        spin_lock_bh(&fib_multipath_lock);
1157
 
                        nh->nh_power = 0;
1158
 
                        nh->nh_flags &= ~RTNH_F_DEAD;
 
1174
                        nexthop_nh->nh_power = 0;
 
1175
                        nexthop_nh->nh_flags &= ~RTNH_F_DEAD;
1159
1176
                        spin_unlock_bh(&fib_multipath_lock);
1160
1177
                } endfor_nexthops(fi)
1161
1178
 
1169
1186
}
1170
1187
 
1171
1188
/*
1172
 
   The algorithm is suboptimal, but it provides really
1173
 
   fair weighted route distribution.
 
1189
 * The algorithm is suboptimal, but it provides really
 
1190
 * fair weighted route distribution.
1174
1191
 */
1175
 
 
1176
1192
void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
1177
1193
{
1178
1194
        struct fib_info *fi = res->fi;
1182
1198
        if (fi->fib_power <= 0) {
1183
1199
                int power = 0;
1184
1200
                change_nexthops(fi) {
1185
 
                        if (!(nh->nh_flags&RTNH_F_DEAD)) {
1186
 
                                power += nh->nh_weight;
1187
 
                                nh->nh_power = nh->nh_weight;
 
1201
                        if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
 
1202
                                power += nexthop_nh->nh_weight;
 
1203
                                nexthop_nh->nh_power = nexthop_nh->nh_weight;
1188
1204
                        }
1189
1205
                } endfor_nexthops(fi);
1190
1206
                fi->fib_power = power;
1198
1214
 
1199
1215
 
1200
1216
        /* w should be random number [0..fi->fib_power-1],
1201
 
           it is pretty bad approximation.
 
1217
         * it is pretty bad approximation.
1202
1218
         */
1203
1219
 
1204
1220
        w = jiffies % fi->fib_power;
1205
1221
 
1206
1222
        change_nexthops(fi) {
1207
 
                if (!(nh->nh_flags&RTNH_F_DEAD) && nh->nh_power) {
1208
 
                        if ((w -= nh->nh_power) <= 0) {
1209
 
                                nh->nh_power--;
 
1223
                if (!(nexthop_nh->nh_flags & RTNH_F_DEAD) &&
 
1224
                    nexthop_nh->nh_power) {
 
1225
                        w -= nexthop_nh->nh_power;
 
1226
                        if (w <= 0) {
 
1227
                                nexthop_nh->nh_power--;
1210
1228
                                fi->fib_power--;
1211
1229
                                res->nh_sel = nhsel;
1212
1230
                                spin_unlock_bh(&fib_multipath_lock);