diff options
author | Ralf Baechle DL5RB <ralf@linux-mips.org> | 2006-07-03 22:30:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-07-03 22:30:18 -0400 |
commit | 006f68b84fe19fc5015a8cf838a10d75f91f0218 (patch) | |
tree | 2c9377778e4e09bb8d10084341207ba1352f600a /include/net | |
parent | 8dc22d2b642f8a6f14ef8878777a05311e5d1d7e (diff) |
[AX.25]: Reference counting for AX.25 routes.
In the past routes could be freed even though the were possibly in use ...
Signed-off-by: Ralf Baechle DL5RB <ralf@linux-mips.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/ax25.h | 24 |
1 files changed, 15 insertions, 9 deletions
diff --git a/include/net/ax25.h b/include/net/ax25.h index 7cd528e9d668..69374cd1a857 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h | |||
@@ -182,14 +182,26 @@ typedef struct { | |||
182 | 182 | ||
183 | typedef struct ax25_route { | 183 | typedef struct ax25_route { |
184 | struct ax25_route *next; | 184 | struct ax25_route *next; |
185 | atomic_t ref; | 185 | atomic_t refcount; |
186 | ax25_address callsign; | 186 | ax25_address callsign; |
187 | struct net_device *dev; | 187 | struct net_device *dev; |
188 | ax25_digi *digipeat; | 188 | ax25_digi *digipeat; |
189 | char ip_mode; | 189 | char ip_mode; |
190 | struct timer_list timer; | ||
191 | } ax25_route; | 190 | } ax25_route; |
192 | 191 | ||
192 | static inline void ax25_hold_route(ax25_route *ax25_rt) | ||
193 | { | ||
194 | atomic_inc(&ax25_rt->refcount); | ||
195 | } | ||
196 | |||
197 | extern void __ax25_put_route(ax25_route *ax25_rt); | ||
198 | |||
199 | static inline void ax25_put_route(ax25_route *ax25_rt) | ||
200 | { | ||
201 | if (atomic_dec_and_test(&ax25_rt->refcount)) | ||
202 | __ax25_put_route(ax25_rt); | ||
203 | } | ||
204 | |||
193 | typedef struct { | 205 | typedef struct { |
194 | char slave; /* slave_mode? */ | 206 | char slave; /* slave_mode? */ |
195 | struct timer_list slave_timer; /* timeout timer */ | 207 | struct timer_list slave_timer; /* timeout timer */ |
@@ -348,17 +360,11 @@ extern int ax25_check_iframes_acked(ax25_cb *, unsigned short); | |||
348 | extern void ax25_rt_device_down(struct net_device *); | 360 | extern void ax25_rt_device_down(struct net_device *); |
349 | extern int ax25_rt_ioctl(unsigned int, void __user *); | 361 | extern int ax25_rt_ioctl(unsigned int, void __user *); |
350 | extern struct file_operations ax25_route_fops; | 362 | extern struct file_operations ax25_route_fops; |
363 | extern ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev); | ||
351 | extern int ax25_rt_autobind(ax25_cb *, ax25_address *); | 364 | extern int ax25_rt_autobind(ax25_cb *, ax25_address *); |
352 | extern ax25_route *ax25_rt_find_route(ax25_route *, ax25_address *, | ||
353 | struct net_device *); | ||
354 | extern struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *); | 365 | extern struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *); |
355 | extern void ax25_rt_free(void); | 366 | extern void ax25_rt_free(void); |
356 | 367 | ||
357 | static inline void ax25_put_route(ax25_route *ax25_rt) | ||
358 | { | ||
359 | atomic_dec(&ax25_rt->ref); | ||
360 | } | ||
361 | |||
362 | /* ax25_std_in.c */ | 368 | /* ax25_std_in.c */ |
363 | extern int ax25_std_frame_in(ax25_cb *, struct sk_buff *, int); | 369 | extern int ax25_std_frame_in(ax25_cb *, struct sk_buff *, int); |
364 | 370 | ||