3535#include <linux/seq_file.h>
3636#include <linux/export.h>
3737#include <linux/etherdevice.h>
38+ #include <linux/refcount.h>
3839
3940int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME ;
4041int sysctl_aarp_tick_time = AARP_TICK_TIME ;
@@ -44,6 +45,7 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME;
4445/* Lists of aarp entries */
4546/**
4647 * struct aarp_entry - AARP entry
48+ * @refcnt: Reference count
4749 * @last_sent: Last time we xmitted the aarp request
4850 * @packet_queue: Queue of frames wait for resolution
4951 * @status: Used for proxy AARP
@@ -55,6 +57,7 @@ int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME;
5557 * @next: Next entry in chain
5658 */
5759struct aarp_entry {
60+ refcount_t refcnt ;
5861 /* These first two are only used for unresolved entries */
5962 unsigned long last_sent ;
6063 struct sk_buff_head packet_queue ;
@@ -79,6 +82,17 @@ static DEFINE_RWLOCK(aarp_lock);
7982/* Used to walk the list and purge/kick entries. */
8083static struct timer_list aarp_timer ;
8184
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+
8296/*
8397 * Delete an aarp queue
8498 *
@@ -87,7 +101,7 @@ static struct timer_list aarp_timer;
87101static void __aarp_expire (struct aarp_entry * a )
88102{
89103 skb_queue_purge (& a -> packet_queue );
90- kfree (a );
104+ aarp_entry_put (a );
91105}
92106
93107/*
@@ -380,9 +394,11 @@ static void aarp_purge(void)
380394static struct aarp_entry * aarp_alloc (void )
381395{
382396 struct aarp_entry * a = kmalloc (sizeof (* a ), GFP_ATOMIC );
397+ if (!a )
398+ return NULL ;
383399
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 );
386402 return a ;
387403}
388404
@@ -508,6 +524,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa)
508524 entry -> dev = atif -> dev ;
509525
510526 write_lock_bh (& aarp_lock );
527+ aarp_entry_get (entry );
511528
512529 hash = sa -> s_node % (AARP_HASH_SIZE - 1 );
513530 entry -> next = proxies [hash ];
@@ -533,6 +550,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct atalk_addr *sa)
533550 retval = 1 ;
534551 }
535552
553+ aarp_entry_put (entry );
536554 write_unlock_bh (& aarp_lock );
537555out :
538556 return retval ;
0 commit comments