35
35
#include <linux/seq_file.h>
36
36
#include <linux/export.h>
37
37
#include <linux/etherdevice.h>
38
+ #include <linux/refcount.h>
38
39
39
40
int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME ;
40
41
int sysctl_aarp_tick_time = AARP_TICK_TIME ;
@@ -44,6 +45,7 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME;
44
45
/* Lists of aarp entries */
45
46
/**
46
47
* struct aarp_entry - AARP entry
48
+ * @refcnt: Reference count
47
49
* @last_sent: Last time we xmitted the aarp request
48
50
* @packet_queue: Queue of frames wait for resolution
49
51
* @status: Used for proxy AARP
@@ -55,6 +57,7 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME;
55
57
* @next: Next entry in chain
56
58
*/
57
59
struct aarp_entry {
60
+ refcount_t refcnt ;
58
61
/* These first two are only used for unresolved entries */
59
62
unsigned long last_sent ;
60
63
struct sk_buff_head packet_queue ;
@@ -79,6 +82,17 @@ static DEFINE_RWLOCK(aarp_lock);
79
82
/* Used to walk the list and purge/kick entries. */
80
83
static struct timer_list aarp_timer ;
81
84
85
+ static inline void aarp_entry_get (struct aarp_entry * a )
86
+ {
87
+ refcount_inc (& a -> refcnt );
88
+ }
89
+
90
+ static inline void aarp_entry_put (struct aarp_entry * a )
91
+ {
92
+ if (refcount_dec_and_test (& a -> refcnt ))
93
+ kfree (a );
94
+ }
95
+
82
96
/*
83
97
* Delete an aarp queue
84
98
*
@@ -87,7 +101,7 @@ static struct timer_list aarp_timer;
87
101
static void __aarp_expire (struct aarp_entry * a )
88
102
{
89
103
skb_queue_purge (& a -> packet_queue );
90
- kfree (a );
104
+ aarp_entry_put (a );
91
105
}
92
106
93
107
/*
@@ -380,9 +394,11 @@ static void aarp_purge(void)
380
394
static struct aarp_entry * aarp_alloc (void )
381
395
{
382
396
struct aarp_entry * a = kmalloc (sizeof (* a ), GFP_ATOMIC );
397
+ if (!a )
398
+ return NULL ;
383
399
384
- if ( a )
385
- skb_queue_head_init (& a -> packet_queue );
400
+ refcount_set ( & a -> refcnt , 1 );
401
+ skb_queue_head_init (& a -> packet_queue );
386
402
return a ;
387
403
}
388
404
@@ -477,6 +493,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa)
477
493
entry -> dev = atif -> dev ;
478
494
479
495
write_lock_bh (& aarp_lock );
496
+ aarp_entry_get (entry );
480
497
481
498
hash = sa -> s_node % (AARP_HASH_SIZE - 1 );
482
499
entry -> next = proxies [hash ];
@@ -502,6 +519,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa)
502
519
retval = 1 ;
503
520
}
504
521
522
+ aarp_entry_put (entry );
505
523
write_unlock_bh (& aarp_lock );
506
524
out :
507
525
return retval ;
0 commit comments