ad4c14f968a132b98804687decfba81ed6516cb0
[pandora-kernel.git] / net / ipv4 / fib_frontend.c
1 /*
2  * INET         An implementation of the TCP/IP protocol suite for the LINUX
3  *              operating system.  INET is implemented using the  BSD Socket
4  *              interface as the means of communication with the user level.
5  *
6  *              IPv4 Forwarding Information Base: FIB frontend.
7  *
8  * Version:     $Id: fib_frontend.c,v 1.26 2001/10/31 21:55:54 davem Exp $
9  *
10  * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
11  *
12  *              This program is free software; you can redistribute it and/or
13  *              modify it under the terms of the GNU General Public License
14  *              as published by the Free Software Foundation; either version
15  *              2 of the License, or (at your option) any later version.
16  */
17
18 #include <linux/module.h>
19 #include <asm/uaccess.h>
20 #include <asm/system.h>
21 #include <linux/bitops.h>
22 #include <linux/capability.h>
23 #include <linux/types.h>
24 #include <linux/kernel.h>
25 #include <linux/sched.h>
26 #include <linux/mm.h>
27 #include <linux/string.h>
28 #include <linux/socket.h>
29 #include <linux/sockios.h>
30 #include <linux/errno.h>
31 #include <linux/in.h>
32 #include <linux/inet.h>
33 #include <linux/inetdevice.h>
34 #include <linux/netdevice.h>
35 #include <linux/if_addr.h>
36 #include <linux/if_arp.h>
37 #include <linux/skbuff.h>
38 #include <linux/netlink.h>
39 #include <linux/init.h>
40 #include <linux/list.h>
41
42 #include <net/ip.h>
43 #include <net/protocol.h>
44 #include <net/route.h>
45 #include <net/tcp.h>
46 #include <net/sock.h>
47 #include <net/icmp.h>
48 #include <net/arp.h>
49 #include <net/ip_fib.h>
50
51 #define FFprint(a...) printk(KERN_DEBUG a)
52
53 #ifndef CONFIG_IP_MULTIPLE_TABLES
54
55 struct fib_table *ip_fib_local_table;
56 struct fib_table *ip_fib_main_table;
57
58 #define FIB_TABLE_HASHSZ 1
59 static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
60
61 #else
62
63 #define FIB_TABLE_HASHSZ 256
64 static struct hlist_head fib_table_hash[FIB_TABLE_HASHSZ];
65
66 struct fib_table *fib_new_table(u32 id)
67 {
68         struct fib_table *tb;
69         unsigned int h;
70
71         if (id == 0)
72                 id = RT_TABLE_MAIN;
73         tb = fib_get_table(id);
74         if (tb)
75                 return tb;
76         tb = fib_hash_init(id);
77         if (!tb)
78                 return NULL;
79         h = id & (FIB_TABLE_HASHSZ - 1);
80         hlist_add_head_rcu(&tb->tb_hlist, &fib_table_hash[h]);
81         return tb;
82 }
83
84 struct fib_table *fib_get_table(u32 id)
85 {
86         struct fib_table *tb;
87         struct hlist_node *node;
88         unsigned int h;
89
90         if (id == 0)
91                 id = RT_TABLE_MAIN;
92         h = id & (FIB_TABLE_HASHSZ - 1);
93         rcu_read_lock();
94         hlist_for_each_entry_rcu(tb, node, &fib_table_hash[h], tb_hlist) {
95                 if (tb->tb_id == id) {
96                         rcu_read_unlock();
97                         return tb;
98                 }
99         }
100         rcu_read_unlock();
101         return NULL;
102 }
103 #endif /* CONFIG_IP_MULTIPLE_TABLES */
104
105 static void fib_flush(void)
106 {
107         int flushed = 0;
108         struct fib_table *tb;
109         struct hlist_node *node;
110         unsigned int h;
111
112         for (h = 0; h < FIB_TABLE_HASHSZ; h++) {
113                 hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist)
114                         flushed += tb->tb_flush(tb);
115         }
116
117         if (flushed)
118                 rt_cache_flush(-1);
119 }
120
121 /*
122  *      Find the first device with a given source address.
123  */
124
125 struct net_device * ip_dev_find(u32 addr)
126 {
127         struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
128         struct fib_result res;
129         struct net_device *dev = NULL;
130
131 #ifdef CONFIG_IP_MULTIPLE_TABLES
132         res.r = NULL;
133 #endif
134
135         if (!ip_fib_local_table ||
136             ip_fib_local_table->tb_lookup(ip_fib_local_table, &fl, &res))
137                 return NULL;
138         if (res.type != RTN_LOCAL)
139                 goto out;
140         dev = FIB_RES_DEV(res);
141
142         if (dev)
143                 dev_hold(dev);
144 out:
145         fib_res_put(&res);
146         return dev;
147 }
148
149 unsigned inet_addr_type(u32 addr)
150 {
151         struct flowi            fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
152         struct fib_result       res;
153         unsigned ret = RTN_BROADCAST;
154
155         if (ZERONET(addr) || BADCLASS(addr))
156                 return RTN_BROADCAST;
157         if (MULTICAST(addr))
158                 return RTN_MULTICAST;
159
160 #ifdef CONFIG_IP_MULTIPLE_TABLES
161         res.r = NULL;
162 #endif
163         
164         if (ip_fib_local_table) {
165                 ret = RTN_UNICAST;
166                 if (!ip_fib_local_table->tb_lookup(ip_fib_local_table,
167                                                    &fl, &res)) {
168                         ret = res.type;
169                         fib_res_put(&res);
170                 }
171         }
172         return ret;
173 }
174
175 /* Given (packet source, input interface) and optional (dst, oif, tos):
176    - (main) check, that source is valid i.e. not broadcast or our local
177      address.
178    - figure out what "logical" interface this packet arrived
179      and calculate "specific destination" address.
180    - check, that packet arrived from expected physical interface.
181  */
182
183 int fib_validate_source(u32 src, u32 dst, u8 tos, int oif,
184                         struct net_device *dev, u32 *spec_dst, u32 *itag)
185 {
186         struct in_device *in_dev;
187         struct flowi fl = { .nl_u = { .ip4_u =
188                                       { .daddr = src,
189                                         .saddr = dst,
190                                         .tos = tos } },
191                             .iif = oif };
192         struct fib_result res;
193         int no_addr, rpf;
194         int ret;
195
196         no_addr = rpf = 0;
197         rcu_read_lock();
198         in_dev = __in_dev_get_rcu(dev);
199         if (in_dev) {
200                 no_addr = in_dev->ifa_list == NULL;
201                 rpf = IN_DEV_RPFILTER(in_dev);
202         }
203         rcu_read_unlock();
204
205         if (in_dev == NULL)
206                 goto e_inval;
207
208         if (fib_lookup(&fl, &res))
209                 goto last_resort;
210         if (res.type != RTN_UNICAST)
211                 goto e_inval_res;
212         *spec_dst = FIB_RES_PREFSRC(res);
213         fib_combine_itag(itag, &res);
214 #ifdef CONFIG_IP_ROUTE_MULTIPATH
215         if (FIB_RES_DEV(res) == dev || res.fi->fib_nhs > 1)
216 #else
217         if (FIB_RES_DEV(res) == dev)
218 #endif
219         {
220                 ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
221                 fib_res_put(&res);
222                 return ret;
223         }
224         fib_res_put(&res);
225         if (no_addr)
226                 goto last_resort;
227         if (rpf)
228                 goto e_inval;
229         fl.oif = dev->ifindex;
230
231         ret = 0;
232         if (fib_lookup(&fl, &res) == 0) {
233                 if (res.type == RTN_UNICAST) {
234                         *spec_dst = FIB_RES_PREFSRC(res);
235                         ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
236                 }
237                 fib_res_put(&res);
238         }
239         return ret;
240
241 last_resort:
242         if (rpf)
243                 goto e_inval;
244         *spec_dst = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE);
245         *itag = 0;
246         return 0;
247
248 e_inval_res:
249         fib_res_put(&res);
250 e_inval:
251         return -EINVAL;
252 }
253
254 #ifndef CONFIG_IP_NOSIOCRT
255
256 /*
257  *      Handle IP routing ioctl calls. These are used to manipulate the routing tables
258  */
259  
260 int ip_rt_ioctl(unsigned int cmd, void __user *arg)
261 {
262         int err;
263         struct kern_rta rta;
264         struct rtentry  r;
265         struct {
266                 struct nlmsghdr nlh;
267                 struct rtmsg    rtm;
268         } req;
269
270         switch (cmd) {
271         case SIOCADDRT:         /* Add a route */
272         case SIOCDELRT:         /* Delete a route */
273                 if (!capable(CAP_NET_ADMIN))
274                         return -EPERM;
275                 if (copy_from_user(&r, arg, sizeof(struct rtentry)))
276                         return -EFAULT;
277                 rtnl_lock();
278                 err = fib_convert_rtentry(cmd, &req.nlh, &req.rtm, &rta, &r);
279                 if (err == 0) {
280                         if (cmd == SIOCDELRT) {
281                                 struct fib_table *tb = fib_get_table(req.rtm.rtm_table);
282                                 err = -ESRCH;
283                                 if (tb)
284                                         err = tb->tb_delete(tb, &req.rtm, &rta, &req.nlh, NULL);
285                         } else {
286                                 struct fib_table *tb = fib_new_table(req.rtm.rtm_table);
287                                 err = -ENOBUFS;
288                                 if (tb)
289                                         err = tb->tb_insert(tb, &req.rtm, &rta, &req.nlh, NULL);
290                         }
291                         kfree(rta.rta_mx);
292                 }
293                 rtnl_unlock();
294                 return err;
295         }
296         return -EINVAL;
297 }
298
299 #else
300
301 int ip_rt_ioctl(unsigned int cmd, void *arg)
302 {
303         return -EINVAL;
304 }
305
306 #endif
307
308 static int inet_check_attr(struct rtmsg *r, struct rtattr **rta)
309 {
310         int i;
311
312         for (i=1; i<=RTA_MAX; i++, rta++) {
313                 struct rtattr *attr = *rta;
314                 if (attr) {
315                         if (RTA_PAYLOAD(attr) < 4)
316                                 return -EINVAL;
317                         if (i != RTA_MULTIPATH && i != RTA_METRICS &&
318                             i != RTA_TABLE)
319                                 *rta = (struct rtattr*)RTA_DATA(attr);
320                 }
321         }
322         return 0;
323 }
324
325 int inet_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
326 {
327         struct fib_table * tb;
328         struct rtattr **rta = arg;
329         struct rtmsg *r = NLMSG_DATA(nlh);
330
331         if (inet_check_attr(r, rta))
332                 return -EINVAL;
333
334         tb = fib_get_table(rtm_get_table(rta, r->rtm_table));
335         if (tb)
336                 return tb->tb_delete(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb));
337         return -ESRCH;
338 }
339
340 int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
341 {
342         struct fib_table * tb;
343         struct rtattr **rta = arg;
344         struct rtmsg *r = NLMSG_DATA(nlh);
345
346         if (inet_check_attr(r, rta))
347                 return -EINVAL;
348
349         tb = fib_new_table(rtm_get_table(rta, r->rtm_table));
350         if (tb)
351                 return tb->tb_insert(tb, r, (struct kern_rta*)rta, nlh, &NETLINK_CB(skb));
352         return -ENOBUFS;
353 }
354
355 int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
356 {
357         unsigned int h, s_h;
358         unsigned int e = 0, s_e;
359         struct fib_table *tb;
360         struct hlist_node *node;
361         int dumped = 0;
362
363         if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&
364             ((struct rtmsg*)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)
365                 return ip_rt_dump(skb, cb);
366
367         s_h = cb->args[0];
368         s_e = cb->args[1];
369
370         for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
371                 e = 0;
372                 hlist_for_each_entry(tb, node, &fib_table_hash[h], tb_hlist) {
373                         if (e < s_e)
374                                 goto next;
375                         if (dumped)
376                                 memset(&cb->args[2], 0, sizeof(cb->args) -
377                                                  2 * sizeof(cb->args[0]));
378                         if (tb->tb_dump(tb, skb, cb) < 0)
379                                 goto out;
380                         dumped = 1;
381 next:
382                         e++;
383                 }
384         }
385 out:
386         cb->args[1] = e;
387         cb->args[0] = h;
388
389         return skb->len;
390 }
391
392 /* Prepare and feed intra-kernel routing request.
393    Really, it should be netlink message, but :-( netlink
394    can be not configured, so that we feed it directly
395    to fib engine. It is legal, because all events occur
396    only when netlink is already locked.
397  */
398
399 static void fib_magic(int cmd, int type, u32 dst, int dst_len, struct in_ifaddr *ifa)
400 {
401         struct fib_table * tb;
402         struct {
403                 struct nlmsghdr nlh;
404                 struct rtmsg    rtm;
405         } req;
406         struct kern_rta rta;
407
408         memset(&req.rtm, 0, sizeof(req.rtm));
409         memset(&rta, 0, sizeof(rta));
410
411         if (type == RTN_UNICAST)
412                 tb = fib_new_table(RT_TABLE_MAIN);
413         else
414                 tb = fib_new_table(RT_TABLE_LOCAL);
415
416         if (tb == NULL)
417                 return;
418
419         req.nlh.nlmsg_len = sizeof(req);
420         req.nlh.nlmsg_type = cmd;
421         req.nlh.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_APPEND;
422         req.nlh.nlmsg_pid = 0;
423         req.nlh.nlmsg_seq = 0;
424
425         req.rtm.rtm_dst_len = dst_len;
426         req.rtm.rtm_table = tb->tb_id;
427         req.rtm.rtm_protocol = RTPROT_KERNEL;
428         req.rtm.rtm_scope = (type != RTN_LOCAL ? RT_SCOPE_LINK : RT_SCOPE_HOST);
429         req.rtm.rtm_type = type;
430
431         rta.rta_dst = &dst;
432         rta.rta_prefsrc = &ifa->ifa_local;
433         rta.rta_oif = &ifa->ifa_dev->dev->ifindex;
434
435         if (cmd == RTM_NEWROUTE)
436                 tb->tb_insert(tb, &req.rtm, &rta, &req.nlh, NULL);
437         else
438                 tb->tb_delete(tb, &req.rtm, &rta, &req.nlh, NULL);
439 }
440
441 void fib_add_ifaddr(struct in_ifaddr *ifa)
442 {
443         struct in_device *in_dev = ifa->ifa_dev;
444         struct net_device *dev = in_dev->dev;
445         struct in_ifaddr *prim = ifa;
446         u32 mask = ifa->ifa_mask;
447         u32 addr = ifa->ifa_local;
448         u32 prefix = ifa->ifa_address&mask;
449
450         if (ifa->ifa_flags&IFA_F_SECONDARY) {
451                 prim = inet_ifa_byprefix(in_dev, prefix, mask);
452                 if (prim == NULL) {
453                         printk(KERN_DEBUG "fib_add_ifaddr: bug: prim == NULL\n");
454                         return;
455                 }
456         }
457
458         fib_magic(RTM_NEWROUTE, RTN_LOCAL, addr, 32, prim);
459
460         if (!(dev->flags&IFF_UP))
461                 return;
462
463         /* Add broadcast address, if it is explicitly assigned. */
464         if (ifa->ifa_broadcast && ifa->ifa_broadcast != 0xFFFFFFFF)
465                 fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
466
467         if (!ZERONET(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) &&
468             (prefix != addr || ifa->ifa_prefixlen < 32)) {
469                 fib_magic(RTM_NEWROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL :
470                           RTN_UNICAST, prefix, ifa->ifa_prefixlen, prim);
471
472                 /* Add network specific broadcasts, when it takes a sense */
473                 if (ifa->ifa_prefixlen < 31) {
474                         fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix, 32, prim);
475                         fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix|~mask, 32, prim);
476                 }
477         }
478 }
479
480 static void fib_del_ifaddr(struct in_ifaddr *ifa)
481 {
482         struct in_device *in_dev = ifa->ifa_dev;
483         struct net_device *dev = in_dev->dev;
484         struct in_ifaddr *ifa1;
485         struct in_ifaddr *prim = ifa;
486         u32 brd = ifa->ifa_address|~ifa->ifa_mask;
487         u32 any = ifa->ifa_address&ifa->ifa_mask;
488 #define LOCAL_OK        1
489 #define BRD_OK          2
490 #define BRD0_OK         4
491 #define BRD1_OK         8
492         unsigned ok = 0;
493
494         if (!(ifa->ifa_flags&IFA_F_SECONDARY))
495                 fib_magic(RTM_DELROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL :
496                           RTN_UNICAST, any, ifa->ifa_prefixlen, prim);
497         else {
498                 prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask);
499                 if (prim == NULL) {
500                         printk(KERN_DEBUG "fib_del_ifaddr: bug: prim == NULL\n");
501                         return;
502                 }
503         }
504
505         /* Deletion is more complicated than add.
506            We should take care of not to delete too much :-)
507
508            Scan address list to be sure that addresses are really gone.
509          */
510
511         for (ifa1 = in_dev->ifa_list; ifa1; ifa1 = ifa1->ifa_next) {
512                 if (ifa->ifa_local == ifa1->ifa_local)
513                         ok |= LOCAL_OK;
514                 if (ifa->ifa_broadcast == ifa1->ifa_broadcast)
515                         ok |= BRD_OK;
516                 if (brd == ifa1->ifa_broadcast)
517                         ok |= BRD1_OK;
518                 if (any == ifa1->ifa_broadcast)
519                         ok |= BRD0_OK;
520         }
521
522         if (!(ok&BRD_OK))
523                 fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
524         if (!(ok&BRD1_OK))
525                 fib_magic(RTM_DELROUTE, RTN_BROADCAST, brd, 32, prim);
526         if (!(ok&BRD0_OK))
527                 fib_magic(RTM_DELROUTE, RTN_BROADCAST, any, 32, prim);
528         if (!(ok&LOCAL_OK)) {
529                 fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim);
530
531                 /* Check, that this local address finally disappeared. */
532                 if (inet_addr_type(ifa->ifa_local) != RTN_LOCAL) {
533                         /* And the last, but not the least thing.
534                            We must flush stray FIB entries.
535
536                            First of all, we scan fib_info list searching
537                            for stray nexthop entries, then ignite fib_flush.
538                         */
539                         if (fib_sync_down(ifa->ifa_local, NULL, 0))
540                                 fib_flush();
541                 }
542         }
543 #undef LOCAL_OK
544 #undef BRD_OK
545 #undef BRD0_OK
546 #undef BRD1_OK
547 }
548
549 static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
550 {
551         
552         struct fib_result       res;
553         struct flowi            fl = { .nl_u = { .ip4_u = { .daddr = frn->fl_addr, 
554                                                             .fwmark = frn->fl_fwmark,
555                                                             .tos = frn->fl_tos,
556                                                             .scope = frn->fl_scope } } };
557         if (tb) {
558                 local_bh_disable();
559
560                 frn->tb_id = tb->tb_id;
561                 frn->err = tb->tb_lookup(tb, &fl, &res);
562
563                 if (!frn->err) {
564                         frn->prefixlen = res.prefixlen;
565                         frn->nh_sel = res.nh_sel;
566                         frn->type = res.type;
567                         frn->scope = res.scope;
568                 }
569                 local_bh_enable();
570         }
571 }
572
573 static void nl_fib_input(struct sock *sk, int len)
574 {
575         struct sk_buff *skb = NULL;
576         struct nlmsghdr *nlh = NULL;
577         struct fib_result_nl *frn;
578         u32 pid;     
579         struct fib_table *tb;
580         
581         skb = skb_dequeue(&sk->sk_receive_queue);
582         nlh = (struct nlmsghdr *)skb->data;
583         if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len ||
584             nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) {
585                 kfree_skb(skb);
586                 return;
587         }
588         
589         frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
590         tb = fib_get_table(frn->tb_id_in);
591
592         nl_fib_lookup(frn, tb);
593         
594         pid = nlh->nlmsg_pid;           /*pid of sending process */
595         NETLINK_CB(skb).pid = 0;         /* from kernel */
596         NETLINK_CB(skb).dst_pid = pid;
597         NETLINK_CB(skb).dst_group = 0;  /* unicast */
598         netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
599 }    
600
601 static void nl_fib_lookup_init(void)
602 {
603       netlink_kernel_create(NETLINK_FIB_LOOKUP, 0, nl_fib_input, THIS_MODULE);
604 }
605
606 static void fib_disable_ip(struct net_device *dev, int force)
607 {
608         if (fib_sync_down(0, dev, force))
609                 fib_flush();
610         rt_cache_flush(0);
611         arp_ifdown(dev);
612 }
613
614 static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, void *ptr)
615 {
616         struct in_ifaddr *ifa = (struct in_ifaddr*)ptr;
617
618         switch (event) {
619         case NETDEV_UP:
620                 fib_add_ifaddr(ifa);
621 #ifdef CONFIG_IP_ROUTE_MULTIPATH
622                 fib_sync_up(ifa->ifa_dev->dev);
623 #endif
624                 rt_cache_flush(-1);
625                 break;
626         case NETDEV_DOWN:
627                 fib_del_ifaddr(ifa);
628                 if (ifa->ifa_dev->ifa_list == NULL) {
629                         /* Last address was deleted from this interface.
630                            Disable IP.
631                          */
632                         fib_disable_ip(ifa->ifa_dev->dev, 1);
633                 } else {
634                         rt_cache_flush(-1);
635                 }
636                 break;
637         }
638         return NOTIFY_DONE;
639 }
640
641 static int fib_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
642 {
643         struct net_device *dev = ptr;
644         struct in_device *in_dev = __in_dev_get_rtnl(dev);
645
646         if (event == NETDEV_UNREGISTER) {
647                 fib_disable_ip(dev, 2);
648                 return NOTIFY_DONE;
649         }
650
651         if (!in_dev)
652                 return NOTIFY_DONE;
653
654         switch (event) {
655         case NETDEV_UP:
656                 for_ifa(in_dev) {
657                         fib_add_ifaddr(ifa);
658                 } endfor_ifa(in_dev);
659 #ifdef CONFIG_IP_ROUTE_MULTIPATH
660                 fib_sync_up(dev);
661 #endif
662                 rt_cache_flush(-1);
663                 break;
664         case NETDEV_DOWN:
665                 fib_disable_ip(dev, 0);
666                 break;
667         case NETDEV_CHANGEMTU:
668         case NETDEV_CHANGE:
669                 rt_cache_flush(0);
670                 break;
671         }
672         return NOTIFY_DONE;
673 }
674
675 static struct notifier_block fib_inetaddr_notifier = {
676         .notifier_call =fib_inetaddr_event,
677 };
678
679 static struct notifier_block fib_netdev_notifier = {
680         .notifier_call =fib_netdev_event,
681 };
682
683 void __init ip_fib_init(void)
684 {
685         unsigned int i;
686
687         for (i = 0; i < FIB_TABLE_HASHSZ; i++)
688                 INIT_HLIST_HEAD(&fib_table_hash[i]);
689 #ifndef CONFIG_IP_MULTIPLE_TABLES
690         ip_fib_local_table = fib_hash_init(RT_TABLE_LOCAL);
691         hlist_add_head_rcu(&ip_fib_local_table->tb_hlist, &fib_table_hash[0]);
692         ip_fib_main_table  = fib_hash_init(RT_TABLE_MAIN);
693         hlist_add_head_rcu(&ip_fib_main_table->tb_hlist, &fib_table_hash[0]);
694 #else
695         fib4_rules_init();
696 #endif
697
698         register_netdevice_notifier(&fib_netdev_notifier);
699         register_inetaddr_notifier(&fib_inetaddr_notifier);
700         nl_fib_lookup_init();
701 }
702
703 EXPORT_SYMBOL(inet_addr_type);
704 EXPORT_SYMBOL(ip_dev_find);