aboutsummaryrefslogtreecommitdiffstats
path: root/net/decnet/dn_table.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/decnet/dn_table.c')
-rw-r--r--net/decnet/dn_table.c251
1 files changed, 126 insertions, 125 deletions
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index 13b2421991ba..780a141f8342 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -60,7 +60,7 @@ struct dn_hash
60#define dz_prefix(key,dz) ((key).datum) 60#define dz_prefix(key,dz) ((key).datum)
61 61
62#define for_nexthops(fi) { int nhsel; const struct dn_fib_nh *nh;\ 62#define for_nexthops(fi) { int nhsel; const struct dn_fib_nh *nh;\
63 for(nhsel = 0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++) 63 for(nhsel = 0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
64 64
65#define endfor_nexthops(fi) } 65#define endfor_nexthops(fi) }
66 66
@@ -290,94 +290,97 @@ static inline size_t dn_fib_nlmsg_size(struct dn_fib_info *fi)
290} 290}
291 291
292static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, 292static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
293 u32 tb_id, u8 type, u8 scope, void *dst, int dst_len, 293 u32 tb_id, u8 type, u8 scope, void *dst, int dst_len,
294 struct dn_fib_info *fi, unsigned int flags) 294 struct dn_fib_info *fi, unsigned int flags)
295{ 295{
296 struct rtmsg *rtm; 296 struct rtmsg *rtm;
297 struct nlmsghdr *nlh; 297 struct nlmsghdr *nlh;
298 unsigned char *b = skb->tail; 298 unsigned char *b = skb->tail;
299 299
300 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags); 300 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*rtm), flags);
301 rtm = NLMSG_DATA(nlh); 301 rtm = NLMSG_DATA(nlh);
302 rtm->rtm_family = AF_DECnet; 302 rtm->rtm_family = AF_DECnet;
303 rtm->rtm_dst_len = dst_len; 303 rtm->rtm_dst_len = dst_len;
304 rtm->rtm_src_len = 0; 304 rtm->rtm_src_len = 0;
305 rtm->rtm_tos = 0; 305 rtm->rtm_tos = 0;
306 rtm->rtm_table = tb_id; 306 rtm->rtm_table = tb_id;
307 RTA_PUT_U32(skb, RTA_TABLE, tb_id); 307 RTA_PUT_U32(skb, RTA_TABLE, tb_id);
308 rtm->rtm_flags = fi->fib_flags; 308 rtm->rtm_flags = fi->fib_flags;
309 rtm->rtm_scope = scope; 309 rtm->rtm_scope = scope;
310 rtm->rtm_type = type; 310 rtm->rtm_type = type;
311 if (rtm->rtm_dst_len) 311 if (rtm->rtm_dst_len)
312 RTA_PUT(skb, RTA_DST, 2, dst); 312 RTA_PUT(skb, RTA_DST, 2, dst);
313 rtm->rtm_protocol = fi->fib_protocol; 313 rtm->rtm_protocol = fi->fib_protocol;
314 if (fi->fib_priority) 314 if (fi->fib_priority)
315 RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority); 315 RTA_PUT(skb, RTA_PRIORITY, 4, &fi->fib_priority);
316 if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0) 316 if (rtnetlink_put_metrics(skb, fi->fib_metrics) < 0)
317 goto rtattr_failure; 317 goto rtattr_failure;
318 if (fi->fib_nhs == 1) { 318 if (fi->fib_nhs == 1) {
319 if (fi->fib_nh->nh_gw) 319 if (fi->fib_nh->nh_gw)
320 RTA_PUT(skb, RTA_GATEWAY, 2, &fi->fib_nh->nh_gw); 320 RTA_PUT(skb, RTA_GATEWAY, 2, &fi->fib_nh->nh_gw);
321 if (fi->fib_nh->nh_oif) 321 if (fi->fib_nh->nh_oif)
322 RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif); 322 RTA_PUT(skb, RTA_OIF, sizeof(int), &fi->fib_nh->nh_oif);
323 } 323 }
324 if (fi->fib_nhs > 1) { 324 if (fi->fib_nhs > 1) {
325 struct rtnexthop *nhp; 325 struct rtnexthop *nhp;
326 struct rtattr *mp_head; 326 struct rtattr *mp_head;
327 if (skb_tailroom(skb) <= RTA_SPACE(0)) 327 if (skb_tailroom(skb) <= RTA_SPACE(0))
328 goto rtattr_failure; 328 goto rtattr_failure;
329 mp_head = (struct rtattr *)skb_put(skb, RTA_SPACE(0)); 329 mp_head = (struct rtattr *)skb_put(skb, RTA_SPACE(0));
330 330
331 for_nexthops(fi) { 331 for_nexthops(fi) {
332 if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) 332 if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4))
333 goto rtattr_failure; 333 goto rtattr_failure;
334 nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); 334 nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
335 nhp->rtnh_flags = nh->nh_flags & 0xFF; 335 nhp->rtnh_flags = nh->nh_flags & 0xFF;
336 nhp->rtnh_hops = nh->nh_weight - 1; 336 nhp->rtnh_hops = nh->nh_weight - 1;
337 nhp->rtnh_ifindex = nh->nh_oif; 337 nhp->rtnh_ifindex = nh->nh_oif;
338 if (nh->nh_gw) 338 if (nh->nh_gw)
339 RTA_PUT(skb, RTA_GATEWAY, 2, &nh->nh_gw); 339 RTA_PUT(skb, RTA_GATEWAY, 2, &nh->nh_gw);
340 nhp->rtnh_len = skb->tail - (unsigned char *)nhp; 340 nhp->rtnh_len = skb->tail - (unsigned char *)nhp;
341 } endfor_nexthops(fi); 341 } endfor_nexthops(fi);
342 mp_head->rta_type = RTA_MULTIPATH; 342 mp_head->rta_type = RTA_MULTIPATH;
343 mp_head->rta_len = skb->tail - (u8*)mp_head; 343 mp_head->rta_len = skb->tail - (u8*)mp_head;
344 } 344 }
345 345
346 nlh->nlmsg_len = skb->tail - b; 346 nlh->nlmsg_len = skb->tail - b;
347 return skb->len; 347 return skb->len;
348 348
349 349
350nlmsg_failure: 350nlmsg_failure:
351rtattr_failure: 351rtattr_failure:
352 skb_trim(skb, b - skb->data); 352 skb_trim(skb, b - skb->data);
353 return -1; 353 return -EMSGSIZE;
354} 354}
355 355
356 356
357static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id, 357static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id,
358 struct nlmsghdr *nlh, struct netlink_skb_parms *req) 358 struct nlmsghdr *nlh, struct netlink_skb_parms *req)
359{ 359{
360 struct sk_buff *skb; 360 struct sk_buff *skb;
361 u32 pid = req ? req->pid : 0; 361 u32 pid = req ? req->pid : 0;
362 int err = -ENOBUFS; 362 int err = -ENOBUFS;
363 363
364 skb = nlmsg_new(dn_fib_nlmsg_size(DN_FIB_INFO(f)), GFP_KERNEL); 364 skb = nlmsg_new(dn_fib_nlmsg_size(DN_FIB_INFO(f)), GFP_KERNEL);
365 if (skb == NULL) 365 if (skb == NULL)
366 goto errout; 366 goto errout;
367 367
368 err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, 368 err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id,
369 f->fn_type, f->fn_scope, &f->fn_key, z, 369 f->fn_type, f->fn_scope, &f->fn_key, z,
370 DN_FIB_INFO(f), 0); 370 DN_FIB_INFO(f), 0);
371 /* failure implies BUG in dn_fib_nlmsg_size() */ 371 if (err < 0) {
372 BUG_ON(err < 0); 372 /* -EMSGSIZE implies BUG in dn_fib_nlmsg_size() */
373 373 WARN_ON(err == -EMSGSIZE);
374 kfree_skb(skb);
375 goto errout;
376 }
374 err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL); 377 err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
375errout: 378errout:
376 if (err < 0) 379 if (err < 0)
377 rtnl_set_sk_err(RTNLGRP_DECnet_ROUTE, err); 380 rtnl_set_sk_err(RTNLGRP_DECnet_ROUTE, err);
378} 381}
379 382
380static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb, 383static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb,
381 struct netlink_callback *cb, 384 struct netlink_callback *cb,
382 struct dn_fib_table *tb, 385 struct dn_fib_table *tb,
383 struct dn_zone *dz, 386 struct dn_zone *dz,
@@ -391,12 +394,12 @@ static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb,
391 continue; 394 continue;
392 if (f->fn_state & DN_S_ZOMBIE) 395 if (f->fn_state & DN_S_ZOMBIE)
393 continue; 396 continue;
394 if (dn_fib_dump_info(skb, NETLINK_CB(cb->skb).pid, 397 if (dn_fib_dump_info(skb, NETLINK_CB(cb->skb).pid,
395 cb->nlh->nlmsg_seq, 398 cb->nlh->nlmsg_seq,
396 RTM_NEWROUTE, 399 RTM_NEWROUTE,
397 tb->n, 400 tb->n,
398 (f->fn_state & DN_S_ZOMBIE) ? 0 : f->fn_type, 401 (f->fn_state & DN_S_ZOMBIE) ? 0 : f->fn_type,
399 f->fn_scope, &f->fn_key, dz->dz_order, 402 f->fn_scope, &f->fn_key, dz->dz_order,
400 f->fn_info, NLM_F_MULTI) < 0) { 403 f->fn_info, NLM_F_MULTI) < 0) {
401 cb->args[4] = i; 404 cb->args[4] = i;
402 return -1; 405 return -1;
@@ -406,7 +409,7 @@ static __inline__ int dn_hash_dump_bucket(struct sk_buff *skb,
406 return skb->len; 409 return skb->len;
407} 410}
408 411
409static __inline__ int dn_hash_dump_zone(struct sk_buff *skb, 412static __inline__ int dn_hash_dump_zone(struct sk_buff *skb,
410 struct netlink_callback *cb, 413 struct netlink_callback *cb,
411 struct dn_fib_table *tb, 414 struct dn_fib_table *tb,
412 struct dn_zone *dz) 415 struct dn_zone *dz)
@@ -430,10 +433,10 @@ static __inline__ int dn_hash_dump_zone(struct sk_buff *skb,
430 return skb->len; 433 return skb->len;
431} 434}
432 435
433static int dn_fib_table_dump(struct dn_fib_table *tb, struct sk_buff *skb, 436static int dn_fib_table_dump(struct dn_fib_table *tb, struct sk_buff *skb,
434 struct netlink_callback *cb) 437 struct netlink_callback *cb)
435{ 438{
436 int m, s_m; 439 int m, s_m;
437 struct dn_zone *dz; 440 struct dn_zone *dz;
438 struct dn_hash *table = (struct dn_hash *)tb->data; 441 struct dn_hash *table = (struct dn_hash *)tb->data;
439 442
@@ -454,7 +457,7 @@ static int dn_fib_table_dump(struct dn_fib_table *tb, struct sk_buff *skb,
454 read_unlock(&dn_fib_tables_lock); 457 read_unlock(&dn_fib_tables_lock);
455 cb->args[2] = m; 458 cb->args[2] = m;
456 459
457 return skb->len; 460 return skb->len;
458} 461}
459 462
460int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb) 463int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb)
@@ -479,7 +482,7 @@ int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb)
479 goto next; 482 goto next;
480 if (dumped) 483 if (dumped)
481 memset(&cb->args[2], 0, sizeof(cb->args) - 484 memset(&cb->args[2], 0, sizeof(cb->args) -
482 2 * sizeof(cb->args[0])); 485 2 * sizeof(cb->args[0]));
483 if (tb->dump(tb, skb, cb) < 0) 486 if (tb->dump(tb, skb, cb) < 0)
484 goto out; 487 goto out;
485 dumped = 1; 488 dumped = 1;
@@ -500,13 +503,13 @@ static int dn_fib_table_insert(struct dn_fib_table *tb, struct rtmsg *r, struct
500 struct dn_fib_node *new_f, *f, **fp, **del_fp; 503 struct dn_fib_node *new_f, *f, **fp, **del_fp;
501 struct dn_zone *dz; 504 struct dn_zone *dz;
502 struct dn_fib_info *fi; 505 struct dn_fib_info *fi;
503 int z = r->rtm_dst_len; 506 int z = r->rtm_dst_len;
504 int type = r->rtm_type; 507 int type = r->rtm_type;
505 dn_fib_key_t key; 508 dn_fib_key_t key;
506 int err; 509 int err;
507 510
508 if (z > 16) 511 if (z > 16)
509 return -EINVAL; 512 return -EINVAL;
510 513
511 dz = table->dh_zones[z]; 514 dz = table->dh_zones[z];
512 if (!dz && !(dz = dn_new_zone(table, z))) 515 if (!dz && !(dz = dn_new_zone(table, z)))
@@ -521,8 +524,8 @@ static int dn_fib_table_insert(struct dn_fib_table *tb, struct rtmsg *r, struct
521 key = dz_key(dst, dz); 524 key = dz_key(dst, dz);
522 } 525 }
523 526
524 if ((fi = dn_fib_create_info(r, rta, n, &err)) == NULL) 527 if ((fi = dn_fib_create_info(r, rta, n, &err)) == NULL)
525 return err; 528 return err;
526 529
527 if (dz->dz_nent > (dz->dz_divisor << 2) && 530 if (dz->dz_nent > (dz->dz_divisor << 2) &&
528 dz->dz_divisor > DN_MAX_DIVISOR && 531 dz->dz_divisor > DN_MAX_DIVISOR &&
@@ -590,12 +593,10 @@ create:
590 593
591replace: 594replace:
592 err = -ENOBUFS; 595 err = -ENOBUFS;
593 new_f = kmem_cache_alloc(dn_hash_kmem, GFP_KERNEL); 596 new_f = kmem_cache_zalloc(dn_hash_kmem, GFP_KERNEL);
594 if (new_f == NULL) 597 if (new_f == NULL)
595 goto out; 598 goto out;
596 599
597 memset(new_f, 0, sizeof(struct dn_fib_node));
598
599 new_f->fn_key = key; 600 new_f->fn_key = key;
600 new_f->fn_type = type; 601 new_f->fn_type = type;
601 new_f->fn_scope = r->rtm_scope; 602 new_f->fn_scope = r->rtm_scope;
@@ -623,9 +624,9 @@ replace:
623 dn_rt_cache_flush(-1); 624 dn_rt_cache_flush(-1);
624 } 625 }
625 626
626 dn_rtmsg_fib(RTM_NEWROUTE, new_f, z, tb->n, n, req); 627 dn_rtmsg_fib(RTM_NEWROUTE, new_f, z, tb->n, n, req);
627 628
628 return 0; 629 return 0;
629out: 630out:
630 dn_fib_release_info(fi); 631 dn_fib_release_info(fi);
631 return err; 632 return err;
@@ -636,14 +637,14 @@ static int dn_fib_table_delete(struct dn_fib_table *tb, struct rtmsg *r, struct
636{ 637{
637 struct dn_hash *table = (struct dn_hash*)tb->data; 638 struct dn_hash *table = (struct dn_hash*)tb->data;
638 struct dn_fib_node **fp, **del_fp, *f; 639 struct dn_fib_node **fp, **del_fp, *f;
639 int z = r->rtm_dst_len; 640 int z = r->rtm_dst_len;
640 struct dn_zone *dz; 641 struct dn_zone *dz;
641 dn_fib_key_t key; 642 dn_fib_key_t key;
642 int matched; 643 int matched;
643 644
644 645
645 if (z > 16) 646 if (z > 16)
646 return -EINVAL; 647 return -EINVAL;
647 648
648 if ((dz = table->dh_zones[z]) == NULL) 649 if ((dz = table->dh_zones[z]) == NULL)
649 return -ESRCH; 650 return -ESRCH;
@@ -679,7 +680,7 @@ static int dn_fib_table_delete(struct dn_fib_table *tb, struct rtmsg *r, struct
679 if (del_fp == NULL && 680 if (del_fp == NULL &&
680 (!r->rtm_type || f->fn_type == r->rtm_type) && 681 (!r->rtm_type || f->fn_type == r->rtm_type) &&
681 (r->rtm_scope == RT_SCOPE_NOWHERE || f->fn_scope == r->rtm_scope) && 682 (r->rtm_scope == RT_SCOPE_NOWHERE || f->fn_scope == r->rtm_scope) &&
682 (!r->rtm_protocol || 683 (!r->rtm_protocol ||
683 fi->fib_protocol == r->rtm_protocol) && 684 fi->fib_protocol == r->rtm_protocol) &&
684 dn_fib_nh_match(r, n, rta, fi) == 0) 685 dn_fib_nh_match(r, n, rta, fi) == 0)
685 del_fp = fp; 686 del_fp = fp;
@@ -687,7 +688,7 @@ static int dn_fib_table_delete(struct dn_fib_table *tb, struct rtmsg *r, struct
687 688
688 if (del_fp) { 689 if (del_fp) {
689 f = *del_fp; 690 f = *del_fp;
690 dn_rtmsg_fib(RTM_DELROUTE, f, z, tb->n, n, req); 691 dn_rtmsg_fib(RTM_DELROUTE, f, z, tb->n, n, req);
691 692
692 if (matched != 1) { 693 if (matched != 1) {
693 write_lock_bh(&dn_fib_tables_lock); 694 write_lock_bh(&dn_fib_tables_lock);
@@ -711,7 +712,7 @@ static int dn_fib_table_delete(struct dn_fib_table *tb, struct rtmsg *r, struct
711 return 0; 712 return 0;
712 } 713 }
713 714
714 return -ESRCH; 715 return -ESRCH;
715} 716}
716 717
717static inline int dn_flush_list(struct dn_fib_node **fp, int z, struct dn_hash *table) 718static inline int dn_flush_list(struct dn_fib_node **fp, int z, struct dn_hash *table)
@@ -758,7 +759,7 @@ static int dn_fib_table_flush(struct dn_fib_table *tb)
758 759
759static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowi *flp, struct dn_fib_res *res) 760static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowi *flp, struct dn_fib_res *res)
760{ 761{
761 int err; 762 int err;
762 struct dn_zone *dz; 763 struct dn_zone *dz;
763 struct dn_hash *t = (struct dn_hash *)tb->data; 764 struct dn_hash *t = (struct dn_hash *)tb->data;
764 765
@@ -787,7 +788,7 @@ static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowi *flp,
787 788
788 if (err == 0) { 789 if (err == 0) {
789 res->type = f->fn_type; 790 res->type = f->fn_type;
790 res->scope = f->fn_scope; 791 res->scope = f->fn_scope;
791 res->prefixlen = dz->dz_order; 792 res->prefixlen = dz->dz_order;
792 goto out; 793 goto out;
793 } 794 }
@@ -798,21 +799,21 @@ static int dn_fib_table_lookup(struct dn_fib_table *tb, const struct flowi *flp,
798 err = 1; 799 err = 1;
799out: 800out:
800 read_unlock(&dn_fib_tables_lock); 801 read_unlock(&dn_fib_tables_lock);
801 return err; 802 return err;
802} 803}
803 804
804 805
805struct dn_fib_table *dn_fib_get_table(u32 n, int create) 806struct dn_fib_table *dn_fib_get_table(u32 n, int create)
806{ 807{
807 struct dn_fib_table *t; 808 struct dn_fib_table *t;
808 struct hlist_node *node; 809 struct hlist_node *node;
809 unsigned int h; 810 unsigned int h;
810 811
811 if (n < RT_TABLE_MIN) 812 if (n < RT_TABLE_MIN)
812 return NULL; 813 return NULL;
813 814
814 if (n > RT_TABLE_MAX) 815 if (n > RT_TABLE_MAX)
815 return NULL; 816 return NULL;
816 817
817 h = n & (DN_FIB_TABLE_HASHSZ - 1); 818 h = n & (DN_FIB_TABLE_HASHSZ - 1);
818 rcu_read_lock(); 819 rcu_read_lock();
@@ -824,54 +825,54 @@ struct dn_fib_table *dn_fib_get_table(u32 n, int create)
824 } 825 }
825 rcu_read_unlock(); 826 rcu_read_unlock();
826 827
827 if (!create) 828 if (!create)
828 return NULL; 829 return NULL;
829 830
830 if (in_interrupt() && net_ratelimit()) { 831 if (in_interrupt() && net_ratelimit()) {
831 printk(KERN_DEBUG "DECnet: BUG! Attempt to create routing table from interrupt\n"); 832 printk(KERN_DEBUG "DECnet: BUG! Attempt to create routing table from interrupt\n");
832 return NULL; 833 return NULL;
833 } 834 }
834 835
835 t = kzalloc(sizeof(struct dn_fib_table) + sizeof(struct dn_hash), 836 t = kzalloc(sizeof(struct dn_fib_table) + sizeof(struct dn_hash),
836 GFP_KERNEL); 837 GFP_KERNEL);
837 if (t == NULL) 838 if (t == NULL)
838 return NULL; 839 return NULL;
839 840
840 t->n = n; 841 t->n = n;
841 t->insert = dn_fib_table_insert; 842 t->insert = dn_fib_table_insert;
842 t->delete = dn_fib_table_delete; 843 t->delete = dn_fib_table_delete;
843 t->lookup = dn_fib_table_lookup; 844 t->lookup = dn_fib_table_lookup;
844 t->flush = dn_fib_table_flush; 845 t->flush = dn_fib_table_flush;
845 t->dump = dn_fib_table_dump; 846 t->dump = dn_fib_table_dump;
846 hlist_add_head_rcu(&t->hlist, &dn_fib_table_hash[h]); 847 hlist_add_head_rcu(&t->hlist, &dn_fib_table_hash[h]);
847 848
848 return t; 849 return t;
849} 850}
850 851
851struct dn_fib_table *dn_fib_empty_table(void) 852struct dn_fib_table *dn_fib_empty_table(void)
852{ 853{
853 u32 id; 854 u32 id;
854 855
855 for(id = RT_TABLE_MIN; id <= RT_TABLE_MAX; id++) 856 for(id = RT_TABLE_MIN; id <= RT_TABLE_MAX; id++)
856 if (dn_fib_get_table(id, 0) == NULL) 857 if (dn_fib_get_table(id, 0) == NULL)
857 return dn_fib_get_table(id, 1); 858 return dn_fib_get_table(id, 1);
858 return NULL; 859 return NULL;
859} 860}
860 861
861void dn_fib_flush(void) 862void dn_fib_flush(void)
862{ 863{
863 int flushed = 0; 864 int flushed = 0;
864 struct dn_fib_table *tb; 865 struct dn_fib_table *tb;
865 struct hlist_node *node; 866 struct hlist_node *node;
866 unsigned int h; 867 unsigned int h;
867 868
868 for (h = 0; h < DN_FIB_TABLE_HASHSZ; h++) { 869 for (h = 0; h < DN_FIB_TABLE_HASHSZ; h++) {
869 hlist_for_each_entry(tb, node, &dn_fib_table_hash[h], hlist) 870 hlist_for_each_entry(tb, node, &dn_fib_table_hash[h], hlist)
870 flushed += tb->flush(tb); 871 flushed += tb->flush(tb);
871 } 872 }
872 873
873 if (flushed) 874 if (flushed)
874 dn_rt_cache_flush(-1); 875 dn_rt_cache_flush(-1);
875} 876}
876 877
877void __init dn_fib_table_init(void) 878void __init dn_fib_table_init(void)
@@ -891,7 +892,7 @@ void __exit dn_fib_table_cleanup(void)
891 write_lock(&dn_fib_tables_lock); 892 write_lock(&dn_fib_tables_lock);
892 for (h = 0; h < DN_FIB_TABLE_HASHSZ; h++) { 893 for (h = 0; h < DN_FIB_TABLE_HASHSZ; h++) {
893 hlist_for_each_entry_safe(t, node, next, &dn_fib_table_hash[h], 894 hlist_for_each_entry_safe(t, node, next, &dn_fib_table_hash[h],
894 hlist) { 895 hlist) {
895 hlist_del(&t->hlist); 896 hlist_del(&t->hlist);
896 kfree(t); 897 kfree(t);
897 } 898 }