aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2010-04-13 01:03:21 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-13 17:49:33 -0400
commit862465f2e7e90975e7bf0ecfbb171dd3adedd950 (patch)
tree281c43f90130cc23eb581c702afaf4ab226dbff5
parentd658f8a0e63b6476148162aa7a3ffffc58dcad52 (diff)
ipv4: ipmr: convert struct mfc_cache to struct list_head
Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/mroute.h2
-rw-r--r--include/net/netns/ipv4.h4
-rw-r--r--net/ipv4/ipmr.c125
3 files changed, 64 insertions, 67 deletions
diff --git a/include/linux/mroute.h b/include/linux/mroute.h
index de7780a6dd32..7ff6c77d6008 100644
--- a/include/linux/mroute.h
+++ b/include/linux/mroute.h
@@ -191,7 +191,7 @@ struct vif_device {
191#define VIFF_STATIC 0x8000 191#define VIFF_STATIC 0x8000
192 192
193struct mfc_cache { 193struct mfc_cache {
194 struct mfc_cache *next; /* Next entry on cache line */ 194 struct list_head list;
195 __be32 mfc_mcastgrp; /* Group the entry belongs to */ 195 __be32 mfc_mcastgrp; /* Group the entry belongs to */
196 __be32 mfc_origin; /* Source of packet */ 196 __be32 mfc_origin; /* Source of packet */
197 vifi_t mfc_parent; /* Source interface */ 197 vifi_t mfc_parent; /* Source interface */
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index b15e518f952a..5d06429968d5 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -61,8 +61,8 @@ struct netns_ipv4 {
61#ifdef CONFIG_IP_MROUTE 61#ifdef CONFIG_IP_MROUTE
62 struct sock *mroute_sk; 62 struct sock *mroute_sk;
63 struct timer_list ipmr_expire_timer; 63 struct timer_list ipmr_expire_timer;
64 struct mfc_cache *mfc_unres_queue; 64 struct list_head mfc_unres_queue;
65 struct mfc_cache **mfc_cache_array; 65 struct list_head *mfc_cache_array;
66 struct vif_device *vif_table; 66 struct vif_device *vif_table;
67 int maxvif; 67 int maxvif;
68 atomic_t cache_resolve_queue_len; 68 atomic_t cache_resolve_queue_len;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index f8e25c8ba070..21b5edc2f343 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -367,35 +367,32 @@ static void ipmr_expire_process(unsigned long arg)
367 struct net *net = (struct net *)arg; 367 struct net *net = (struct net *)arg;
368 unsigned long now; 368 unsigned long now;
369 unsigned long expires; 369 unsigned long expires;
370 struct mfc_cache *c, **cp; 370 struct mfc_cache *c, *next;
371 371
372 if (!spin_trylock(&mfc_unres_lock)) { 372 if (!spin_trylock(&mfc_unres_lock)) {
373 mod_timer(&net->ipv4.ipmr_expire_timer, jiffies+HZ/10); 373 mod_timer(&net->ipv4.ipmr_expire_timer, jiffies+HZ/10);
374 return; 374 return;
375 } 375 }
376 376
377 if (net->ipv4.mfc_unres_queue == NULL) 377 if (list_empty(&net->ipv4.mfc_unres_queue))
378 goto out; 378 goto out;
379 379
380 now = jiffies; 380 now = jiffies;
381 expires = 10*HZ; 381 expires = 10*HZ;
382 cp = &net->ipv4.mfc_unres_queue;
383 382
384 while ((c=*cp) != NULL) { 383 list_for_each_entry_safe(c, next, &net->ipv4.mfc_unres_queue, list) {
385 if (time_after(c->mfc_un.unres.expires, now)) { 384 if (time_after(c->mfc_un.unres.expires, now)) {
386 unsigned long interval = c->mfc_un.unres.expires - now; 385 unsigned long interval = c->mfc_un.unres.expires - now;
387 if (interval < expires) 386 if (interval < expires)
388 expires = interval; 387 expires = interval;
389 cp = &c->next;
390 continue; 388 continue;
391 } 389 }
392 390
393 *cp = c->next; 391 list_del(&c->list);
394
395 ipmr_destroy_unres(net, c); 392 ipmr_destroy_unres(net, c);
396 } 393 }
397 394
398 if (net->ipv4.mfc_unres_queue != NULL) 395 if (!list_empty(&net->ipv4.mfc_unres_queue))
399 mod_timer(&net->ipv4.ipmr_expire_timer, jiffies + expires); 396 mod_timer(&net->ipv4.ipmr_expire_timer, jiffies + expires);
400 397
401out: 398out:
@@ -537,11 +534,11 @@ static struct mfc_cache *ipmr_cache_find(struct net *net,
537 int line = MFC_HASH(mcastgrp, origin); 534 int line = MFC_HASH(mcastgrp, origin);
538 struct mfc_cache *c; 535 struct mfc_cache *c;
539 536
540 for (c = net->ipv4.mfc_cache_array[line]; c; c = c->next) { 537 list_for_each_entry(c, &net->ipv4.mfc_cache_array[line], list) {
541 if (c->mfc_origin==origin && c->mfc_mcastgrp==mcastgrp) 538 if (c->mfc_origin == origin && c->mfc_mcastgrp == mcastgrp)
542 break; 539 return c;
543 } 540 }
544 return c; 541 return NULL;
545} 542}
546 543
547/* 544/*
@@ -699,18 +696,21 @@ static int ipmr_cache_report(struct net *net,
699static int 696static int
700ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb) 697ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb)
701{ 698{
699 bool found = false;
702 int err; 700 int err;
703 struct mfc_cache *c; 701 struct mfc_cache *c;
704 const struct iphdr *iph = ip_hdr(skb); 702 const struct iphdr *iph = ip_hdr(skb);
705 703
706 spin_lock_bh(&mfc_unres_lock); 704 spin_lock_bh(&mfc_unres_lock);
707 for (c=net->ipv4.mfc_unres_queue; c; c=c->next) { 705 list_for_each_entry(c, &net->ipv4.mfc_unres_queue, list) {
708 if (c->mfc_mcastgrp == iph->daddr && 706 if (c->mfc_mcastgrp == iph->daddr &&
709 c->mfc_origin == iph->saddr) 707 c->mfc_origin == iph->saddr) {
708 found = true;
710 break; 709 break;
710 }
711 } 711 }
712 712
713 if (c == NULL) { 713 if (!found) {
714 /* 714 /*
715 * Create a new entry if allowable 715 * Create a new entry if allowable
716 */ 716 */
@@ -746,8 +746,7 @@ ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb)
746 } 746 }
747 747
748 atomic_inc(&net->ipv4.cache_resolve_queue_len); 748 atomic_inc(&net->ipv4.cache_resolve_queue_len);
749 c->next = net->ipv4.mfc_unres_queue; 749 list_add(&c->list, &net->ipv4.mfc_unres_queue);
750 net->ipv4.mfc_unres_queue = c;
751 750
752 mod_timer(&net->ipv4.ipmr_expire_timer, c->mfc_un.unres.expires); 751 mod_timer(&net->ipv4.ipmr_expire_timer, c->mfc_un.unres.expires);
753 } 752 }
@@ -774,16 +773,15 @@ ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb)
774static int ipmr_mfc_delete(struct net *net, struct mfcctl *mfc) 773static int ipmr_mfc_delete(struct net *net, struct mfcctl *mfc)
775{ 774{
776 int line; 775 int line;
777 struct mfc_cache *c, **cp; 776 struct mfc_cache *c, *next;
778 777
779 line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); 778 line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
780 779
781 for (cp = &net->ipv4.mfc_cache_array[line]; 780 list_for_each_entry_safe(c, next, &net->ipv4.mfc_cache_array[line], list) {
782 (c = *cp) != NULL; cp = &c->next) {
783 if (c->mfc_origin == mfc->mfcc_origin.s_addr && 781 if (c->mfc_origin == mfc->mfcc_origin.s_addr &&
784 c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) { 782 c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr) {
785 write_lock_bh(&mrt_lock); 783 write_lock_bh(&mrt_lock);
786 *cp = c->next; 784 list_del(&c->list);
787 write_unlock_bh(&mrt_lock); 785 write_unlock_bh(&mrt_lock);
788 786
789 ipmr_cache_free(c); 787 ipmr_cache_free(c);
@@ -795,22 +793,24 @@ static int ipmr_mfc_delete(struct net *net, struct mfcctl *mfc)
795 793
796static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock) 794static int ipmr_mfc_add(struct net *net, struct mfcctl *mfc, int mrtsock)
797{ 795{
796 bool found = false;
798 int line; 797 int line;
799 struct mfc_cache *uc, *c, **cp; 798 struct mfc_cache *uc, *c;
800 799
801 if (mfc->mfcc_parent >= MAXVIFS) 800 if (mfc->mfcc_parent >= MAXVIFS)
802 return -ENFILE; 801 return -ENFILE;
803 802
804 line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr); 803 line = MFC_HASH(mfc->mfcc_mcastgrp.s_addr, mfc->mfcc_origin.s_addr);
805 804
806 for (cp = &net->ipv4.mfc_cache_array[line]; 805 list_for_each_entry(c, &net->ipv4.mfc_cache_array[line], list) {
807 (c = *cp) != NULL; cp = &c->next) {
808 if (c->mfc_origin == mfc->mfcc_origin.s_addr && 806 if (c->mfc_origin == mfc->mfcc_origin.s_addr &&
809 c->mfc_mcastgrp == mfc->mfcc_mcastgrp.s_addr)