Skip to contentSkip to conversation

Introduce struct ax25_sock.

PATCH In review Ralf Baechle 3 participants 6 messages Jul 21, 2006 – Jul 23, 2006

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 Introduce struct ax25_sock.

Upto now AX.25 was using two separate structures for it's sockets. One, ax25_cb described the entire actual AX.25 connection. The other was the standard struct sock.

This patch combines both into struct ax25_sock which is more in line with current practice. An AX.25 speciality was that a ax25_cb could exist without a struct sock referencing it. Keep that alive for now by keeping the old struct sock *sk member of ax25_cb in struct ax25_sock. This now just has become a struct-internal pointer.

Aside of wanrouter AX.25 has also been the last member of struct sock.sk_protinfo. With net/wanrouter being considered hopeless code and an application-level solution being prefered these days this means we now can delete sk_protinfo.

 include/net/ax25.h        |  144 +++++++++++++++++---------------------
 include/net/netrom.h      |    6 -
 include/net/rose.h        |    6 -
 net/ax25/af_ax25.c        |  173 ++++++++++++++++++++--------------------------
 net/ax25/ax25_ds_in.c     |    8 +-
 net/ax25/ax25_ds_subr.c   |   14 +--
 net/ax25/ax25_ds_timer.c  |   10 +-
 net/ax25/ax25_iface.c     |   16 ++--
 net/ax25/ax25_in.c        |   15 ++-
 net/ax25/ax25_ip.c        |    4 -
 net/ax25/ax25_out.c       |   19 ++---
 net/ax25/ax25_route.c     |    2 
 net/ax25/ax25_std_in.c    |   10 +-
 net/ax25/ax25_std_subr.c  |   10 +-
 net/ax25/ax25_std_timer.c |   10 +-
 net/ax25/ax25_subr.c      |   18 ++--
 net/ax25/ax25_timer.c     |   32 ++++----
 net/netrom/nr_route.c     |   14 +--
 net/rose/rose_route.c     |    4 -
 19 files changed, 243 insertions(+), 272 deletions(-)
include/net/ax25.h +67 -77
Index: linux-net/include/net/ax25.h
===================================================================
@@ -10,6 +10,7 @@
 #include <linux/spinlock.h>
 #include <linux/timer.h>
 #include <linux/list.h>
+#include <net/sock.h>
 #include <asm/atomic.h>
 
 #define	AX25_T1CLAMPLO  		1
@@ -221,8 +222,9 @@ typedef struct ax25_dev {
 #endif
 } ax25_dev;
 
-typedef struct ax25_cb {
-	struct hlist_node	ax25_node;
+struct ax25_sock {
+	/* Struct sock has to be the first member of ax25_sock */
+	struct sock		sock;
 	ax25_address		source_addr, dest_addr;
 	ax25_digi		*digipeat;
 	ax25_dev		*ax25_dev;
@@ -241,24 +243,12 @@ typedef struct ax25_cb {
 	unsigned char		window;
 	struct timer_list	timer, dtimer;
 	struct sock		*sk;		/* Backlink to socket */
-	atomic_t		refcount;
-} ax25_cb;
-
-#define ax25_sk(__sk) ((ax25_cb *)(__sk)->sk_protinfo)
-
-#define ax25_for_each(__ax25, node, list) \
-	hlist_for_each_entry(__ax25, node, list, ax25_node)
+};
 
-#define ax25_cb_hold(__ax25) \
-	atomic_inc(&((__ax25)->refcount))
+#define ax25_sk(sk) ((struct ax25_sock *)(sk))
 
-static __inline__ void ax25_cb_put(ax25_cb *ax25)
-{
-	if (atomic_dec_and_test(&ax25->refcount)) {
-		kfree(ax25->digipeat);
-		kfree(ax25);
-	}
-}
+#define ax25_for_each(ax25, node, list) \
+	hlist_for_each_entry(ax25, node, list, sock.sk_node)
 
 static inline __be16 ax25_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
@@ -271,14 +261,14 @@ static inline __be16 ax25_type_trans(str
 /* af_ax25.c */
 extern struct hlist_head ax25_list;
 extern spinlock_t ax25_list_lock;
-extern void ax25_cb_add(ax25_cb *);
+extern void ax25_cb_add(struct ax25_sock *);
 struct sock *ax25_find_listener(ax25_address *, int, struct net_device *, int);
 struct sock *ax25_get_socket(ax25_address *, ax25_address *, int);
-extern ax25_cb *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *, struct net_device *);
+extern struct ax25_sock *ax25_find_cb(ax25_address *, ax25_address *, ax25_digi *, struct net_device *);
 extern void ax25_send_to_raw(ax25_address *, struct sk_buff *, int);
-extern void ax25_destroy_socket(ax25_cb *);
-extern ax25_cb *ax25_create_cb(void);
-extern void ax25_fillin_cb(ax25_cb *, ax25_dev *);
+extern void ax25_destroy_socket(struct ax25_sock *);
+extern struct ax25_sock *ax25_alloc_sock(struct socket *sock);
+extern void ax25_fillin_cb(struct ax25_sock *, ax25_dev *);
 extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
 
 /* ax25_addr.c */
@@ -309,39 +299,39 @@ extern struct net_device *ax25_fwd_dev(s
 extern void ax25_dev_free(void);
 
 /* ax25_ds_in.c */
-extern int  ax25_ds_frame_in(ax25_cb *, struct sk_buff *, int);
+extern int  ax25_ds_frame_in(struct ax25_sock *, struct sk_buff *, int);
 
 /* ax25_ds_subr.c */
-extern void ax25_ds_nr_error_recovery(ax25_cb *);
-extern void ax25_ds_enquiry_response(ax25_cb *);
-extern void ax25_ds_establish_data_link(ax25_cb *);
+extern void ax25_ds_nr_error_recovery(struct ax25_sock *);
+extern void ax25_ds_enquiry_response(struct ax25_sock *);
+extern void ax25_ds_establish_data_link(struct ax25_sock *);
 extern void ax25_dev_dama_off(ax25_dev *);
-extern void ax25_dama_on(ax25_cb *);
-extern void ax25_dama_off(ax25_cb *);
+extern void ax25_dama_on(struct ax25_sock *);
+extern void ax25_dama_off(struct ax25_sock *);
 
 /* ax25_ds_timer.c */
 extern void ax25_ds_set_timer(ax25_dev *);
 extern void ax25_ds_del_timer(ax25_dev *);
-extern void ax25_ds_timer(ax25_cb *);
-extern void ax25_ds_t1_timeout(ax25_cb *);
-extern void ax25_ds_heartbeat_expiry(ax25_cb *);
-extern void ax25_ds_t3timer_expiry(ax25_cb *);
-extern void ax25_ds_idletimer_expiry(ax25_cb *);
+extern void ax25_ds_timer(struct ax25_sock *);
+extern void ax25_ds_t1_timeout(struct ax25_sock *);
+extern void ax25_ds_heartbeat_expiry(struct ax25_sock *);
+extern void ax25_ds_t3timer_expiry(struct ax25_sock *);
+extern void ax25_ds_idletimer_expiry(struct ax25_sock *);
 
 /* ax25_iface.c */
-extern int  ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, ax25_cb *));
+extern int  ax25_protocol_register(unsigned int, int (*)(struct sk_buff *, struct ax25_sock *));
 extern void ax25_protocol_release(unsigned int);
-extern int  ax25_linkfail_register(void (*)(ax25_cb *, int));
-extern void ax25_linkfail_release(void (*)(ax25_cb *, int));
+extern int  ax25_linkfail_register(void (*)(struct ax25_sock *, int));
+extern void ax25_linkfail_release(void (*)(struct ax25_sock *, int));
 extern int  ax25_listen_register(ax25_address *, struct net_device *);
 extern void ax25_listen_release(ax25_address *, struct net_device *);
-extern int  (*ax25_protocol_function(unsigned int))(struct sk_buff *, ax25_cb *);
+extern int  (*ax25_protocol_function(unsigned int))(struct sk_buff *, struct ax25_sock *);
 extern int  ax25_listen_mine(ax25_address *, struct net_device *);
-extern void ax25_link_failed(ax25_cb *, int);
+extern void ax25_link_failed(struct ax25_sock *, int);
 extern int  ax25_protocol_is_registered(unsigned int);
 
 /* ax25_in.c */
-extern int  ax25_rx_iframe(ax25_cb *, struct sk_buff *);
+extern int  ax25_rx_iframe(struct ax25_sock *, struct sk_buff *);
 extern int  ax25_kiss_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
 
 /* ax25_ip.c */
@@ -349,63 +339,63 @@ extern int  ax25_hard_header(struct sk_b
 extern int  ax25_rebuild_header(struct sk_buff *);
 
 /* ax25_out.c */
-extern ax25_cb *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, ax25_digi *, struct net_device *);
-extern void ax25_output(ax25_cb *, int, struct sk_buff *);
-extern void ax25_kick(ax25_cb *);
-extern void ax25_transmit_buffer(ax25_cb *, struct sk_buff *, int);
+extern struct ax25_sock *ax25_send_frame(struct sk_buff *, int, ax25_address *, ax25_address *, ax25_digi *, struct net_device *);
+extern void ax25_output(struct ax25_sock *, int, struct sk_buff *);
+extern void ax25_kick(struct ax25_sock *);
+extern void ax25_transmit_buffer(struct ax25_sock *, struct sk_buff *, int);
 extern void ax25_queue_xmit(struct sk_buff *skb, struct net_device *dev);
-extern int  ax25_check_iframes_acked(ax25_cb *, unsigned short);
+extern int  ax25_check_iframes_acked(struct ax25_sock *, unsigned short);
 
 /* ax25_route.c */
 extern void ax25_rt_device_down(struct net_device *);
 extern int  ax25_rt_ioctl(unsigned int, void __user *);
 extern struct file_operations ax25_route_fops;
 extern ax25_route *ax25_get_route(ax25_address *addr, struct net_device *dev);
-extern int  ax25_rt_autobind(ax25_cb *, ax25_address *);
+extern int  ax25_rt_autobind(struct ax25_sock *, ax25_address *);
 extern struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *);
 extern void ax25_rt_free(void);
 
 /* ax25_std_in.c */
-extern int  ax25_std_frame_in(ax25_cb *, struct sk_buff *, int);
+extern int  ax25_std_frame_in(struct ax25_sock *, struct sk_buff *, int);
 
 /* ax25_std_subr.c */
-extern void ax25_std_nr_error_recovery(ax25_cb *);
-extern void ax25_std_establish_data_link(ax25_cb *);
-extern void ax25_std_transmit_enquiry(ax25_cb *);
-extern void ax25_std_enquiry_response(ax25_cb *);
-extern void ax25_std_timeout_response(ax25_cb *);
+extern void ax25_std_nr_error_recovery(struct ax25_sock *);
+extern void ax25_std_establish_data_link(struct ax25_sock *);
+extern void ax25_std_transmit_enquiry(struct ax25_sock *);
+extern void ax25_std_enquiry_response(struct ax25_sock *);
+extern void ax25_std_timeout_response(struct ax25_sock *);
 
 /* ax25_std_timer.c */
-extern void ax25_std_heartbeat_expiry(ax25_cb *);
-extern void ax25_std_t1timer_expiry(ax25_cb *);
-extern void ax25_std_t2timer_expiry(ax25_cb *);
-extern void ax25_std_t3timer_expiry(ax25_cb *);
-extern void ax25_std_idletimer_expiry(ax25_cb *);
+extern void ax25_std_heartbeat_expiry(struct ax25_sock *);
+extern void ax25_std_t1timer_expiry(struct ax25_sock *);
+extern void ax25_std_t2timer_expiry(struct ax25_sock *);
+extern void ax25_std_t3timer_expiry(struct ax25_sock *);
+extern void ax25_std_idletimer_expiry(struct ax25_sock *);
 
 /* ax25_subr.c */
-extern void ax25_clear_queues(ax25_cb *);
-extern void ax25_frames_acked(ax25_cb *, unsigned short);
-extern void ax25_requeue_frames(ax25_cb *);
-extern int  ax25_validate_nr(ax25_cb *, unsigned short);
-extern int  ax25_decode(ax25_cb *, struct sk_buff *, int *, int *, int *);
-extern void ax25_send_control(ax25_cb *, int, int, int);
+extern void ax25_clear_queues(struct ax25_sock *);
+extern void ax25_frames_acked(struct ax25_sock *, unsigned short);
+extern void ax25_requeue_frames(struct ax25_sock *);
+extern int  ax25_validate_nr(struct ax25_sock *, unsigned short);
+extern int  ax25_decode(struct ax25_sock *, struct sk_buff *, int *, int *, int *);
+extern void ax25_send_control(struct ax25_sock *, int, int, int);
 extern void ax25_return_dm(struct net_device *, ax25_address *, ax25_address *, ax25_digi *);
-extern void ax25_calculate_t1(ax25_cb *);
-extern void ax25_calculate_rtt(ax25_cb *);
-extern void ax25_disconnect(ax25_cb *, int);
+extern void ax25_calculate_t1(struct ax25_sock *);
+extern void ax25_calculate_rtt(struct ax25_sock *);
+extern void ax25_disconnect(struct ax25_sock *, int);
 
 /* ax25_timer.c */
-extern void ax25_start_heartbeat(ax25_cb *);
-extern void ax25_start_t1timer(ax25_cb *);
-extern void ax25_start_t2timer(ax25_cb *);
-extern void ax25_start_t3timer(ax25_cb *);
-extern void ax25_start_idletimer(ax25_cb *);
-extern void ax25_stop_heartbeat(ax25_cb *);
-extern void ax25_stop_t1timer(ax25_cb *);
-extern void ax25_stop_t2timer(ax25_cb *);
-extern void ax25_stop_t3timer(ax25_cb *);
-extern void ax25_stop_idletimer(ax25_cb *);
-extern int  ax25_t1timer_running(ax25_cb *);
+extern void ax25_start_heartbeat(struct ax25_sock *);
+extern void ax25_start_t1timer(struct ax25_sock *);
+extern void ax25_start_t2timer(struct ax25_sock *);
+extern void ax25_start_t3timer(struct ax25_sock *);
+extern void ax25_start_idletimer(struct ax25_sock *);
+extern void ax25_stop_heartbeat(struct ax25_sock *);
+extern void ax25_stop_t1timer(struct ax25_sock *);
+extern void ax25_stop_t2timer(struct ax25_sock *);
+extern void ax25_stop_t3timer(struct ax25_sock *);
+extern void ax25_stop_idletimer(struct ax25_sock *);
+extern int  ax25_t1timer_running(struct ax25_sock *);
 extern unsigned long ax25_display_timer(struct timer_list *);
 
 /* ax25_uid.c */
include/net/netrom.h +3 -3
Index: linux-net/include/net/netrom.h
===================================================================
@@ -89,7 +89,7 @@ struct nr_neigh {
 	struct hlist_node	neigh_node;
 	ax25_address		callsign;
 	ax25_digi		*digipeat;
-	ax25_cb			*ax25;
+	struct ax25_sock			*ax25;
 	struct net_device	*dev;
 	unsigned char		quality;
 	unsigned char		locked;
@@ -213,8 +213,8 @@ extern void nr_rt_device_down(struct net
 extern struct net_device *nr_dev_first(void);
 extern struct net_device *nr_dev_get(ax25_address *);
 extern int  nr_rt_ioctl(unsigned int, void __user *);
-extern void nr_link_failed(ax25_cb *, int);
-extern int  nr_route_frame(struct sk_buff *, ax25_cb *);
+extern void nr_link_failed(struct ax25_sock *, int);
+extern int  nr_route_frame(struct sk_buff *, struct ax25_sock *);
 extern struct file_operations nr_nodes_fops;
 extern struct file_operations nr_neigh_fops;
 extern void nr_rt_free(void);
include/net/rose.h +3 -3
Index: linux-net/include/net/rose.h
===================================================================
@@ -85,7 +85,7 @@ struct rose_neigh {
 	struct rose_neigh	*next;
 	ax25_address		callsign;
 	ax25_digi		*digipeat;
-	ax25_cb			*ax25;
+	struct ax25_sock			*ax25;
 	struct net_device		*dev;
 	unsigned short		count;
 	unsigned short		use;
@@ -203,8 +203,8 @@ extern struct net_device *rose_dev_get(r
 extern struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *);
 extern struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *, unsigned char *);
 extern int  rose_rt_ioctl(unsigned int, void __user *);
-extern void rose_link_failed(ax25_cb *, int);
-extern int  rose_route_frame(struct sk_buff *, ax25_cb *);
+extern void rose_link_failed(struct ax25_sock *, int);
+extern int  rose_route_frame(struct sk_buff *, struct ax25_sock *);
 extern void rose_rt_free(void);
 
 /* rose_subr.c */
net/ax25/af_ax25.c +76 -97

421 lines not on this page · raw message

net/ax25/ax25_ds_in.c +4 -4
Index: linux-net/net/ax25/ax25_ds_in.c
===================================================================
@@ -34,7 +34,7 @@
  *	The handling of the timer(s) is in file ax25_ds_timer.c.
  *	Handling of state 0 and connection release is in ax25.c.
  */
-static int ax25_ds_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
+static int ax25_ds_state1_machine(struct ax25_sock *ax25, struct sk_buff *skb, int frametype, int pf, int type)
 {
 	switch (frametype) {
 	case AX25_SABM:
@@ -102,7 +102,7 @@ static int ax25_ds_state1_machine(ax25_c
  *	The handling of the timer(s) is in file ax25_ds_timer.c
  *	Handling of state 0 and connection release is in ax25.c.
  */
-static int ax25_ds_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
+static int ax25_ds_state2_machine(struct ax25_sock *ax25, struct sk_buff *skb, int frametype, int pf, int type)
 {
 	switch (frametype) {
 	case AX25_SABM:
@@ -147,7 +147,7 @@ static int ax25_ds_state2_machine(ax25_c
  *	The handling of the timer(s) is in file ax25_timer.c
  *	Handling of state 0 and connection release is in ax25.c.
  */
-static int ax25_ds_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
+static int ax25_ds_state3_machine(struct ax25_sock *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
 {
 	int queued = 0;
 
@@ -281,7 +281,7 @@ static int ax25_ds_state3_machine(ax25_c
 /*
  *	Higher level upcall for a LAPB frame
  */
-int ax25_ds_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type)
+int ax25_ds_frame_in(struct ax25_sock *ax25, struct sk_buff *skb, int type)
 {
 	int queued = 0, frametype, ns, nr, pf;
 
net/ax25/ax25_ds_subr.c +7 -7
Index: linux-net/net/ax25/ax25_ds_subr.c
===================================================================
@@ -29,7 +29,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 
-void ax25_ds_nr_error_recovery(ax25_cb *ax25)
+void ax25_ds_nr_error_recovery(struct ax25_sock *ax25)
 {
 	ax25_ds_establish_data_link(ax25);
 }
@@ -37,9 +37,9 @@ void ax25_ds_nr_error_recovery(ax25_cb *
 /*
  *	dl1bke 960114: transmit I frames on DAMA poll
  */
-void ax25_ds_enquiry_response(ax25_cb *ax25)
+void ax25_ds_enquiry_response(struct ax25_sock *ax25)
 {
-	ax25_cb *ax25o;
+	struct ax25_sock *ax25o;
 	struct hlist_node *node;
 
 	/* Please note that neither DK4EG´s nor DG2FEF´s
@@ -109,7 +109,7 @@ void ax25_ds_enquiry_response(ax25_cb *a
 	spin_unlock(&ax25_list_lock);
 }
 
-void ax25_ds_establish_data_link(ax25_cb *ax25)
+void ax25_ds_establish_data_link(struct ax25_sock *ax25)
 {
 	ax25->condition &= AX25_COND_DAMA_MODE;
 	ax25->n2count    = 0;
@@ -158,7 +158,7 @@ static void ax25_kiss_cmd(ax25_dev *ax25
  */
 static int ax25_check_dama_slave(ax25_dev *ax25_dev)
 {
-	ax25_cb *ax25;
+	struct ax25_sock *ax25;
 	int res = 0;
 	struct hlist_node *node;
 
@@ -197,13 +197,13 @@ void ax25_dev_dama_off(ax25_dev *ax25_de
 	}
 }
 
-void ax25_dama_on(ax25_cb *ax25)
+void ax25_dama_on(struct ax25_sock *ax25)
 {
 	ax25_dev_dama_on(ax25->ax25_dev);
 	ax25->condition |= AX25_COND_DAMA_MODE;
 }
 
-void ax25_dama_off(ax25_cb *ax25)
+void ax25_dama_off(struct ax25_sock *ax25)
 {
 	ax25->condition &= ~AX25_COND_DAMA_MODE;
 	ax25_dev_dama_off(ax25->ax25_dev);
net/ax25/ax25_ds_timer.c +5 -5
Index: linux-net/net/ax25/ax25_ds_timer.c
===================================================================
@@ -74,7 +74,7 @@ void ax25_ds_set_timer(ax25_dev *ax25_de
 static void ax25_ds_timeout(unsigned long arg)
 {
 	ax25_dev *ax25_dev = (struct ax25_dev *) arg;
-	ax25_cb *ax25;
+	struct ax25_sock *ax25;
 	struct hlist_node *node;
 
 	if (ax25_dev == NULL || !ax25_dev->dama.slave)
@@ -98,7 +98,7 @@ static void ax25_ds_timeout(unsigned lon
 	ax25_dev_dama_off(ax25_dev);
 }
 
-void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
+void ax25_ds_heartbeat_expiry(struct ax25_sock *ax25)
 {
 	struct sock *sk=ax25->sk;
 
@@ -150,7 +150,7 @@ void ax25_ds_heartbeat_expiry(ax25_cb *a
  *                gets reloaded with every frame for this
  *		  connection.
  */
-void ax25_ds_t3timer_expiry(ax25_cb *ax25)
+void ax25_ds_t3timer_expiry(struct ax25_sock *ax25)
 {
 	ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
 	ax25_dama_off(ax25);
@@ -161,7 +161,7 @@ void ax25_ds_t3timer_expiry(ax25_cb *ax2
  *		  unlike T3 this timer gets reloaded only on
  *		  I frames.
  */
-void ax25_ds_idletimer_expiry(ax25_cb *ax25)
+void ax25_ds_idletimer_expiry(struct ax25_sock *ax25)
 {
 	ax25_clear_queues(ax25);
 
@@ -193,7 +193,7 @@ void ax25_ds_idletimer_expiry(ax25_cb *a
  *                Thus we'll have to do parts of our T1 handling in
  *                ax25_enquiry_response().
  */
-void ax25_ds_t1_timeout(ax25_cb *ax25)
+void ax25_ds_t1_timeout(struct ax25_sock *ax25)
 {
 	switch (ax25->state) {
 	case AX25_STATE_1:
net/ax25/ax25_iface.c +8 -8
Index: linux-net/net/ax25/ax25_iface.c
===================================================================
@@ -32,13 +32,13 @@
 static struct protocol_struct {
 	struct protocol_struct *next;
 	unsigned int pid;
-	int (*func)(struct sk_buff *, ax25_cb *);
+	int (*func)(struct sk_buff *, struct ax25_sock *);
 } *protocol_list = NULL;
 static DEFINE_RWLOCK(protocol_list_lock);
 
 static struct linkfail_struct {
 	struct linkfail_struct *next;
-	void (*func)(ax25_cb *, int);
+	void (*func)(struct ax25_sock *, int);
 } *linkfail_list = NULL;
 static DEFINE_SPINLOCK(linkfail_lock);
 
@@ -50,7 +50,7 @@ static struct listen_struct {
 static DEFINE_SPINLOCK(listen_lock);
 
 int ax25_protocol_register(unsigned int pid,
-	int (*func)(struct sk_buff *, ax25_cb *))
+	int (*func)(struct sk_buff *, struct ax25_sock *))
 {
 	struct protocol_struct *protocol;
 
@@ -110,7 +110,7 @@ void ax25_protocol_release(unsigned int 
 
 EXPORT_SYMBOL(ax25_protocol_release);
 
-int ax25_linkfail_register(void (*func)(ax25_cb *, int))
+int ax25_linkfail_register(void (*func)(struct ax25_sock *, int))
 {
 	struct linkfail_struct *linkfail;
 
@@ -129,7 +129,7 @@ int ax25_linkfail_register(void (*func)(
 
 EXPORT_SYMBOL(ax25_linkfail_register);
 
-void ax25_linkfail_release(void (*func)(ax25_cb *, int))
+void ax25_linkfail_release(void (*func)(struct ax25_sock *, int))
 {
 	struct linkfail_struct *s, *linkfail;
 
@@ -220,9 +220,9 @@ void ax25_listen_release(ax25_address *c
 
 EXPORT_SYMBOL(ax25_listen_release);
 
-int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
+int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, struct ax25_sock *)
 {
-	int (*res)(struct sk_buff *, ax25_cb *) = NULL;
+	int (*res)(struct sk_buff *, struct ax25_sock *) = NULL;
 	struct protocol_struct *protocol;
 
 	read_lock(&protocol_list_lock);
@@ -251,7 +251,7 @@ int ax25_listen_mine(ax25_address *calls
 	return 0;
 }
 
-void ax25_link_failed(ax25_cb *ax25, int reason)
+void ax25_link_failed(struct ax25_sock *ax25, int reason)
 {
 	struct linkfail_struct *linkfail;
 
net/ax25/ax25_in.c +8 -7
Index: linux-net/net/ax25/ax25_in.c
===================================================================
@@ -36,7 +36,7 @@
  *	Given a fragment, queue it on the fragment queue and if the fragment
  *	is complete, send it back to ax25_rx_iframe.
  */
-static int ax25_rx_fragment(ax25_cb *ax25, struct sk_buff *skb)
+static int ax25_rx_fragment(struct ax25_sock *ax25, struct sk_buff *skb)
 {
 	struct sk_buff *skbn, *skbo;
 
@@ -99,9 +99,9 @@ static int ax25_rx_fragment(ax25_cb *ax2
  *	This is where all valid I frames are sent to, to be dispatched to
  *	whichever protocol requires them.
  */
-int ax25_rx_iframe(ax25_cb *ax25, struct sk_buff *skb)
+int ax25_rx_iframe(struct ax25_sock *ax25, struct sk_buff *skb)
 {
-	int (*func)(struct sk_buff *, ax25_cb *);
+	int (*func)(struct sk_buff *, struct ax25_sock *);
 	unsigned char pid;
 	int queued = 0;
 
@@ -157,7 +157,7 @@ int ax25_rx_iframe(ax25_cb *ax25, struct
 /*
  *	Higher level upcall for a LAPB frame
  */
-static int ax25_process_rx_frame(ax25_cb *ax25, struct sk_buff *skb, int type, int dama)
+static int ax25_process_rx_frame(struct ax25_sock *ax25, struct sk_buff *skb, int type, int dama)
 {
 	int queued = 0;
 
@@ -190,7 +190,7 @@ static int ax25_rcv(struct sk_buff *skb,
 	int type = 0, mine = 0, dama;
 	struct sock *make, *sk;
 	ax25_digi dp, reverse_dp;
-	ax25_cb *ax25;
+	struct ax25_sock *ax25;
 	ax25_dev *ax25_dev;
 
 	/*
@@ -321,7 +321,7 @@ static int ax25_rcv(struct sk_buff *skb,
 		if (ax25_process_rx_frame(ax25, skb, type, dama) == 0)
 			kfree_skb(skb);
 
-		ax25_cb_put(ax25);
+		sock_put(&ax25->sock);
 		return 0;
 	}
 
@@ -376,7 +376,8 @@ static int ax25_rcv(struct sk_buff *skb,
 			return 0;
 		}
 
-		if ((ax25 = ax25_create_cb()) == NULL) {
+		ax25 = ax25_alloc_sock(NULL);
+		if (!ax25) {
 			ax25_return_dm(dev, &src, &dest, &dp);
 			kfree_skb(skb);
 			return 0;
net/ax25/ax25_ip.c +2 -2
Index: linux-net/net/ax25/ax25_ip.c
===================================================================
@@ -108,7 +108,7 @@ int ax25_rebuild_header(struct sk_buff *
 	ax25_address *src, *dst;
 	ax25_digi *digipeat = NULL;
 	ax25_dev *ax25_dev;
-	ax25_cb *ax25;
+	struct ax25_sock *ax25;
 	char ip_mode = ' ';
 
 	dst = (ax25_address *)(bp + 1);
@@ -180,7 +180,7 @@ int ax25_rebuild_header(struct sk_buff *
 			    &src_c,
 			    &dst_c, digipeat, dev);
 			if (ax25) {
-				ax25_cb_put(ax25);
+				sock_put(&ax25->sock);
 			}
 			goto put;
 		}
net/ax25/ax25_out.c +10 -9
Index: linux-net/net/ax25/ax25_out.c
===================================================================
@@ -34,10 +34,10 @@
 
 static DEFINE_SPINLOCK(ax25_frag_lock);
 
-ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax25_address *dest, ax25_digi *digi, struct net_device *dev)
+struct ax25_sock *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax25_address *dest, ax25_digi *digi, struct net_device *dev)
 {
 	ax25_dev *ax25_dev;
-	ax25_cb *ax25;
+	struct ax25_sock *ax25;
 
 	/*
 	 * Take the default packet length for the device if zero is
@@ -61,7 +61,8 @@ ax25_cb *ax25_send_frame(struct sk_buff 
 	if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
 		return NULL;
 
-	if ((ax25 = ax25_create_cb()) == NULL)
+	ax25 = ax25_alloc_sock(NULL);
+	if (!ax25)
 		return NULL;
 
 	ax25_fillin_cb(ax25, ax25_dev);
@@ -71,7 +72,7 @@ ax25_cb *ax25_send_frame(struct sk_buff 
 
 	if (digi != NULL) {
 		if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) {
-			ax25_cb_put(ax25);
+			sock_put(&ax25->sock);
 			return NULL;
 		}
 		memcpy(ax25->digipeat, digi, sizeof(ax25_digi));
@@ -112,7 +113,7 @@ EXPORT_SYMBOL(ax25_send_frame);
  *	zero then we are not allowed to do fragmentation, even if the frame
  *	is too large.
  */
-void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
+void ax25_output(struct ax25_sock *ax25, int paclen, struct sk_buff *skb)
 {
 	struct sk_buff *skbn;
 	unsigned char *p;
@@ -199,7 +200,7 @@ void ax25_output(ax25_cb *ax25, int pacl
  *  This procedure is passed a buffer descriptor for an iframe. It builds
  *  the rest of the control part of the frame and then writes it out.
  */
-static void ax25_send_iframe(ax25_cb *ax25, struct sk_buff *skb, int poll_bit)
+static void ax25_send_iframe(struct ax25_sock *ax25, struct sk_buff *skb, int poll_bit)
 {
 	unsigned char *frame;
 
@@ -229,7 +230,7 @@ static void ax25_send_iframe(ax25_cb *ax
 	ax25_transmit_buffer(ax25, skb, AX25_COMMAND);
 }
 
-void ax25_kick(ax25_cb *ax25)
+void ax25_kick(struct ax25_sock *ax25)
 {
 	struct sk_buff *skb, *skbn;
 	int last = 1;
@@ -311,7 +312,7 @@ void ax25_kick(ax25_cb *ax25)
 	}
 }
 
-void ax25_transmit_buffer(ax25_cb *ax25, struct sk_buff *skb, int type)
+void ax25_transmit_buffer(struct ax25_sock *ax25, struct sk_buff *skb, int type)
 {
 	struct sk_buff *skbn;
 	unsigned char *ptr;
@@ -361,7 +362,7 @@ void ax25_queue_xmit(struct sk_buff *skb
 	dev_queue_xmit(skb);
 }
 
-int ax25_check_iframes_acked(ax25_cb *ax25, unsigned short nr)
+int ax25_check_iframes_acked(struct ax25_sock *ax25, unsigned short nr)
 {
 	if (ax25->vs == nr) {
 		ax25_frames_acked(ax25, nr);
net/ax25/ax25_route.c +1 -1
Index: linux-net/net/ax25/ax25_route.c
===================================================================
@@ -405,7 +405,7 @@ static inline void ax25_adjust_path(ax25
 /*
  *	Find which interface to use.
  */
-int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
+int ax25_rt_autobind(struct ax25_sock *ax25, ax25_address *addr)
 {
 	ax25_uid_assoc *user;
 	ax25_route *ax25_rt;
net/ax25/ax25_std_in.c +5 -5
Index: linux-net/net/ax25/ax25_std_in.c
===================================================================
@@ -41,7 +41,7 @@
  *	The handling of the timer(s) is in file ax25_std_timer.c.
  *	Handling of state 0 and connection release is in ax25.c.
  */
-static int ax25_std_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
+static int ax25_std_state1_machine(struct ax25_sock *ax25, struct sk_buff *skb, int frametype, int pf, int type)
 {
 	switch (frametype) {
 	case AX25_SABM:
@@ -105,7 +105,7 @@ static int ax25_std_state1_machine(ax25_
  *	The handling of the timer(s) is in file ax25_std_timer.c
  *	Handling of state 0 and connection release is in ax25.c.
  */
-static int ax25_std_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int pf, int type)
+static int ax25_std_state2_machine(struct ax25_sock *ax25, struct sk_buff *skb, int frametype, int pf, int type)
 {
 	switch (frametype) {
 	case AX25_SABM:
@@ -143,7 +143,7 @@ static int ax25_std_state2_machine(ax25_
  *	The handling of the timer(s) is in file ax25_std_timer.c
  *	Handling of state 0 and connection release is in ax25.c.
  */
-static int ax25_std_state3_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
+static int ax25_std_state3_machine(struct ax25_sock *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
 {
 	int queued = 0;
 
@@ -268,7 +268,7 @@ static int ax25_std_state3_machine(ax25_
  *	The handling of the timer(s) is in file ax25_std_timer.c
  *	Handling of state 0 and connection release is in ax25.c.
  */
-static int ax25_std_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
+static int ax25_std_state4_machine(struct ax25_sock *ax25, struct sk_buff *skb, int frametype, int ns, int nr, int pf, int type)
 {
 	int queued = 0;
 
@@ -421,7 +421,7 @@ static int ax25_std_state4_machine(ax25_
 /*
  *	Higher level upcall for a LAPB frame
  */
-int ax25_std_frame_in(ax25_cb *ax25, struct sk_buff *skb, int type)
+int ax25_std_frame_in(struct ax25_sock *ax25, struct sk_buff *skb, int type)
 {
 	int queued = 0, frametype, ns, nr, pf;
 
net/ax25/ax25_std_subr.c +5 -5
Index: linux-net/net/ax25/ax25_std_subr.c
===================================================================
@@ -32,12 +32,12 @@
  * Networking Conference paper, as is the whole state machine.
  */
 
-void ax25_std_nr_error_recovery(ax25_cb *ax25)
+void ax25_std_nr_error_recovery(struct ax25_sock *ax25)
 {
 	ax25_std_establish_data_link(ax25);
 }
 
-void ax25_std_establish_data_link(ax25_cb *ax25)
+void ax25_std_establish_data_link(struct ax25_sock *ax25)
 {
 	ax25->condition = 0x00;
 	ax25->n2count   = 0;
@@ -54,7 +54,7 @@ void ax25_std_establish_data_link(ax25_c
 	ax25_start_t1timer(ax25);
 }
 
-void ax25_std_transmit_enquiry(ax25_cb *ax25)
+void ax25_std_transmit_enquiry(struct ax25_sock *ax25)
 {
 	if (ax25->condition & AX25_COND_OWN_RX_BUSY)
 		ax25_send_control(ax25, AX25_RNR, AX25_POLLON, AX25_COMMAND);
@@ -67,7 +67,7 @@ void ax25_std_transmit_enquiry(ax25_cb *
 	ax25_start_t1timer(ax25);
 }
 
-void ax25_std_enquiry_response(ax25_cb *ax25)
+void ax25_std_enquiry_response(struct ax25_sock *ax25)
 {
 	if (ax25->condition & AX25_COND_OWN_RX_BUSY)
 		ax25_send_control(ax25, AX25_RNR, AX25_POLLON, AX25_RESPONSE);
@@ -77,7 +77,7 @@ void ax25_std_enquiry_response(ax25_cb *
 	ax25->condition &= ~AX25_COND_ACK_PENDING;
 }
 
-void ax25_std_timeout_response(ax25_cb *ax25)
+void ax25_std_timeout_response(struct ax25_sock *ax25)
 {
 	if (ax25->condition & AX25_COND_OWN_RX_BUSY)
 		ax25_send_control(ax25, AX25_RNR, AX25_POLLOFF, AX25_RESPONSE);
net/ax25/ax25_std_timer.c +5 -5
Index: linux-net/net/ax25/ax25_std_timer.c
===================================================================
@@ -31,7 +31,7 @@
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 
-void ax25_std_heartbeat_expiry(ax25_cb *ax25)
+void ax25_std_heartbeat_expiry(struct ax25_sock *ax25)
 {
 	struct sock *sk=ax25->sk;
 	
@@ -79,7 +79,7 @@ void ax25_std_heartbeat_expiry(ax25_cb *
 	ax25_start_heartbeat(ax25);
 }
 
-void ax25_std_t2timer_expiry(ax25_cb *ax25)
+void ax25_std_t2timer_expiry(struct ax25_sock *ax25)
 {
 	if (ax25->condition & AX25_COND_ACK_PENDING) {
 		ax25->condition &= ~AX25_COND_ACK_PENDING;
@@ -87,14 +87,14 @@ void ax25_std_t2timer_expiry(ax25_cb *ax
 	}
 }
 
-void ax25_std_t3timer_expiry(ax25_cb *ax25)
+void ax25_std_t3timer_expiry(struct ax25_sock *ax25)
 {
 	ax25->n2count = 0;
 	ax25_std_transmit_enquiry(ax25);
 	ax25->state   = AX25_STATE_4;
 }
 
-void ax25_std_idletimer_expiry(ax25_cb *ax25)
+void ax25_std_idletimer_expiry(struct ax25_sock *ax25)
 {
 	ax25_clear_queues(ax25);
 
@@ -120,7 +120,7 @@ void ax25_std_idletimer_expiry(ax25_cb *
 	}
 }
 
-void ax25_std_t1timer_expiry(ax25_cb *ax25)
+void ax25_std_t1timer_expiry(struct ax25_sock *ax25)
 {
 	switch (ax25->state) {
 	case AX25_STATE_1:
net/ax25/ax25_subr.c +9 -9
Index: linux-net/net/ax25/ax25_subr.c
===================================================================
@@ -34,7 +34,7 @@
 /*
  *	This routine purges all the queues of frames.
  */
-void ax25_clear_queues(ax25_cb *ax25)
+void ax25_clear_queues(struct ax25_sock *ax25)
 {
 	skb_queue_purge(&ax25->write_queue);
 	skb_queue_purge(&ax25->ack_queue);
@@ -47,7 +47,7 @@ void ax25_clear_queues(ax25_cb *ax25)
  * acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the
  * SDL diagram.
  */
-void ax25_frames_acked(ax25_cb *ax25, unsigned short nr)
+void ax25_frames_acked(struct ax25_sock *ax25, unsigned short nr)
 {
 	struct sk_buff *skb;
 
@@ -63,7 +63,7 @@ void ax25_frames_acked(ax25_cb *ax25, un
 	}
 }
 
-void ax25_requeue_frames(ax25_cb *ax25)
+void ax25_requeue_frames(struct ax25_sock *ax25)
 {
         struct sk_buff *skb, *skb_prev = NULL;
 
@@ -85,7 +85,7 @@ void ax25_requeue_frames(ax25_cb *ax25)
  *	Validate that the value of nr is between va and vs. Return true or
  *	false for testing.
  */
-int ax25_validate_nr(ax25_cb *ax25, unsigned short nr)
+int ax25_validate_nr(struct ax25_sock *ax25, unsigned short nr)
 {
 	unsigned short vc = ax25->va;
 
@@ -103,7 +103,7 @@ int ax25_validate_nr(ax25_cb *ax25, unsi
  *	This routine is the centralised routine for parsing the control
  *	information for the different frame formats.
  */
-int ax25_decode(ax25_cb *ax25, struct sk_buff *skb, int *ns, int *nr, int *pf)
+int ax25_decode(struct ax25_sock *ax25, struct sk_buff *skb, int *ns, int *nr, int *pf)
 {
 	unsigned char *frame;
 	int frametype = AX25_ILLEGAL;
@@ -153,7 +153,7 @@ int ax25_decode(ax25_cb *ax25, struct sk
  *	command or  response  for  the remote machine ( eg. RR, UA etc. ).
  *	Only supervisory or unnumbered frames are processed.
  */
-void ax25_send_control(ax25_cb *ax25, int frametype, int poll_bit, int type)
+void ax25_send_control(struct ax25_sock *ax25, int frametype, int poll_bit, int type)
 {
 	struct sk_buff *skb;
 	unsigned char  *dptr;
@@ -226,7 +226,7 @@ void ax25_return_dm(struct net_device *d
 /*
  *	Exponential backoff for AX.25
  */
-void ax25_calculate_t1(ax25_cb *ax25)
+void ax25_calculate_t1(struct ax25_sock *ax25)
 {
 	int n, t = 2;
 
@@ -251,7 +251,7 @@ void ax25_calculate_t1(ax25_cb *ax25)
 /*
  *	Calculate the Round Trip Time
  */
-void ax25_calculate_rtt(ax25_cb *ax25)
+void ax25_calculate_rtt(struct ax25_sock *ax25)
 {
 	if (ax25->backoff == 0)
 		return;
@@ -266,7 +266,7 @@ void ax25_calculate_rtt(ax25_cb *ax25)
 		ax25->rtt = AX25_T1CLAMPHI;
 }
 
-void ax25_disconnect(ax25_cb *ax25, int reason)
+void ax25_disconnect(struct ax25_sock *ax25, int reason)
 {
 	ax25_clear_queues(ax25);
 
net/ax25/ax25_timer.c +16 -16
Index: linux-net/net/ax25/ax25_timer.c
===================================================================
@@ -40,7 +40,7 @@ static void ax25_t2timer_expiry(unsigned
 static void ax25_t3timer_expiry(unsigned long);
 static void ax25_idletimer_expiry(unsigned long);
 
-void ax25_start_heartbeat(ax25_cb *ax25)
+void ax25_start_heartbeat(struct ax25_sock *ax25)
 {
 	del_timer(&ax25->timer);
 
@@ -51,7 +51,7 @@ void ax25_start_heartbeat(ax25_cb *ax25)
 	add_timer(&ax25->timer);
 }
 
-void ax25_start_t1timer(ax25_cb *ax25)
+void ax25_start_t1timer(struct ax25_sock *ax25)
 {
 	del_timer(&ax25->t1timer);
 
@@ -62,7 +62,7 @@ void ax25_start_t1timer(ax25_cb *ax25)
 	add_timer(&ax25->t1timer);
 }
 
-void ax25_start_t2timer(ax25_cb *ax25)
+void ax25_start_t2timer(struct ax25_sock *ax25)
 {
 	del_timer(&ax25->t2timer);
 
@@ -73,7 +73,7 @@ void ax25_start_t2timer(ax25_cb *ax25)
 	add_timer(&ax25->t2timer);
 }
 
-void ax25_start_t3timer(ax25_cb *ax25)
+void ax25_start_t3timer(struct ax25_sock *ax25)
 {
 	del_timer(&ax25->t3timer);
 
@@ -86,7 +86,7 @@ void ax25_start_t3timer(ax25_cb *ax25)
 	}
 }
 
-void ax25_start_idletimer(ax25_cb *ax25)
+void ax25_start_idletimer(struct ax25_sock *ax25)
 {
 	del_timer(&ax25->idletimer);
 
@@ -99,32 +99,32 @@ void ax25_start_idletimer(ax25_cb *ax25)
 	}
 }
 
-void ax25_stop_heartbeat(ax25_cb *ax25)
+void ax25_stop_heartbeat(struct ax25_sock *ax25)
 {
 	del_timer(&ax25->timer);
 }
 
-void ax25_stop_t1timer(ax25_cb *ax25)
+void ax25_stop_t1timer(struct ax25_sock *ax25)
 {
 	del_timer(&ax25->t1timer);
 }
 
-void ax25_stop_t2timer(ax25_cb *ax25)
+void ax25_stop_t2timer(struct ax25_sock *ax25)
 {
 	del_timer(&ax25->t2timer);
 }
 
-void ax25_stop_t3timer(ax25_cb *ax25)
+void ax25_stop_t3timer(struct ax25_sock *ax25)
 {
 	del_timer(&ax25->t3timer);
 }
 
-void ax25_stop_idletimer(ax25_cb *ax25)
+void ax25_stop_idletimer(struct ax25_sock *ax25)
 {
 	del_timer(&ax25->idletimer);
 }
 
-int ax25_t1timer_running(ax25_cb *ax25)
+int ax25_t1timer_running(struct ax25_sock *ax25)
 {
 	return timer_pending(&ax25->t1timer);
 }
@@ -142,7 +142,7 @@ EXPORT_SYMBOL(ax25_display_timer);
 static void ax25_heartbeat_expiry(unsigned long param)
 {
 	int proto = AX25_PROTO_STD_SIMPLEX;
-	ax25_cb *ax25 = (ax25_cb *)param;
+	struct ax25_sock *ax25 = (struct ax25_sock *)param;
 
 	if (ax25->ax25_dev)
 		proto = ax25->ax25_dev->values[AX25_VALUES_PROTOCOL];
@@ -166,7 +166,7 @@ static void ax25_heartbeat_expiry(unsign
 
 static void ax25_t1timer_expiry(unsigned long param)
 {
-	ax25_cb *ax25 = (ax25_cb *)param;
+	struct ax25_sock *ax25 = (struct ax25_sock *)param;
 
 	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
 	case AX25_PROTO_STD_SIMPLEX:
@@ -185,7 +185,7 @@ static void ax25_t1timer_expiry(unsigned
 
 static void ax25_t2timer_expiry(unsigned long param)
 {
-	ax25_cb *ax25 = (ax25_cb *)param;
+	struct ax25_sock *ax25 = (struct ax25_sock *)param;
 
 	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
 	case AX25_PROTO_STD_SIMPLEX:
@@ -204,7 +204,7 @@ static void ax25_t2timer_expiry(unsigned
 
 static void ax25_t3timer_expiry(unsigned long param)
 {
-	ax25_cb *ax25 = (ax25_cb *)param;
+	struct ax25_sock *ax25 = (struct ax25_sock *)param;
 
 	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
 	case AX25_PROTO_STD_SIMPLEX:
@@ -225,7 +225,7 @@ static void ax25_t3timer_expiry(unsigned
 
 static void ax25_idletimer_expiry(unsigned long param)
 {
-	ax25_cb *ax25 = (ax25_cb *)param;
+	struct ax25_sock *ax25 = (struct ax25_sock *)param;
 
 	switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
 	case AX25_PROTO_STD_SIMPLEX:
net/netrom/nr_route.c +7 -7
Index: linux-net/net/netrom/nr_route.c
===================================================================
@@ -718,7 +718,7 @@ int nr_rt_ioctl(unsigned int cmd, void _
  * 	A level 2 link has timed out, therefore it appears to be a poor link,
  *	then don't use that neighbour until it is reset.
  */
-void nr_link_failed(ax25_cb *ax25, int reason)
+void nr_link_failed(struct ax25_sock *ax25, int reason)
 {
 	struct nr_neigh *s, *nr_neigh = NULL;
 	struct hlist_node *node;
@@ -738,7 +738,7 @@ void nr_link_failed(ax25_cb *ax25, int r
 		return;
 
 	nr_neigh->ax25 = NULL;
-	ax25_cb_put(ax25);
+	sock_put(&ax25->sock);
 
 	if (++nr_neigh->failed < sysctl_netrom_link_fails_count) {
 		nr_neigh_put(nr_neigh);
@@ -757,17 +757,17 @@ void nr_link_failed(ax25_cb *ax25, int r
 }
 
 /*
- *	Route a frame to an appropriate AX.25 connection. A NULL ax25_cb
+ *	Route a frame to an appropriate AX.25 connection. A NULL struct ax25_sock
  *	indicates an internally generated frame.
  */
-int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+int nr_route_frame(struct sk_buff *skb, struct ax25_sock *ax25)
 {
 	ax25_address *nr_src, *nr_dest;
 	struct nr_neigh *nr_neigh;
 	struct nr_node  *nr_node;
 	struct net_device *dev;
 	unsigned char *dptr;
-	ax25_cb *ax25s;
+	struct ax25_sock *ax25s;
 	int ret;
 	struct sk_buff *skbn;
 
@@ -833,8 +833,8 @@ int nr_route_frame(struct sk_buff *skb, 
 
 	ax25s = ax25_send_frame(skb, 256, (ax25_address *)dev->dev_addr, &nr_neigh->callsign, nr_neigh->digipeat, nr_neigh->dev);
 	if (nr_neigh->ax25 && ax25s) {
-		/* We were already holding this ax25_cb */
-		ax25_cb_put(ax25s);
+		/* We were already holding this struct ax25_sock */
+		sock_put(&ax25s->sock);
 	}
 	nr_neigh->ax25 = ax25s;
 
net/rose/rose_route.c +2 -2
Index: linux-net/net/rose/rose_route.c
===================================================================
@@ -790,7 +790,7 @@ static void rose_del_route_by_neigh(stru
  *	then don't use that neighbour until it is reset. Blow away all through
  *	routes and connections using this route.
  */
-void rose_link_failed(ax25_cb *ax25, int reason)
+void rose_link_failed(struct ax25_sock *ax25, int reason)
 {
 	struct rose_neigh *rose_neigh;
 
@@ -830,7 +830,7 @@ void rose_link_device_down(struct net_de
 /*
  *	Route a frame to an appropriate AX.25 connection.
  */
-int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
+int rose_route_frame(struct sk_buff *skb, struct ax25_sock *ax25)
 {
 	struct rose_neigh *rose_neigh, *new_neigh;
 	struct rose_route *rose_route;
#1 lore raw

PATCH 2/2 Fix reference counting by socket timers

With struct sock and ax25_cb in a unified data structure it now is possible to fix the reference counting by using the sk_reset_timer and sk_stop_timer helper function - the previous implementation was based simply on "principle hope".

 include/net/ax25.h    |    5 +++
 include/net/rose.h    |    1 
 net/ax25/af_ax25.c    |   55 ++++++++++++++++++---------------
 net/ax25/ax25_timer.c |   82 ++++++++++++++++++++------------------------------
 net/netrom/nr_timer.c |   29 +++++++++--------
 net/rose/af_rose.c    |    6 +--
 net/rose/rose_timer.c |   79 +++++++++++++++++++-----------------------------
 7 files changed, 120 insertions(+), 137 deletions(-)
net/ax25/af_ax25.c +30 -25
Index: linux-net/net/ax25/af_ax25.c
===================================================================
@@ -49,8 +49,6 @@
 #include <net/ip.h>
 #include <net/arp.h>
 
-
-
 HLIST_HEAD(ax25_list);
 DEFINE_SPINLOCK(ax25_list_lock);
 
@@ -261,13 +259,10 @@ void ax25_destroy_socket(struct ax25_soc
  */
 static void ax25_destroy_timer(unsigned long data)
 {
-	struct ax25_sock *ax25 = (struct ax25_sock *)data;
-	struct sock *sk;
-	
-	sk=ax25->sk;
-	
+	struct ax25_sock *ax25 = (struct ax25_sock *) data;
+	struct sock *sk = ax25->sk;
+
 	bh_lock_sock(sk);
-	sock_hold(sk);
 	ax25_destroy_socket(ax25);
 	bh_unlock_sock(sk);
 	sock_put(sk);
@@ -281,6 +276,7 @@ static void ax25_destroy_timer(unsigned 
  */
 void ax25_destroy_socket(struct ax25_sock *ax25)
 {
+	struct sock *sk = ax25->sk;
 	struct sk_buff *skb;
 
 	ax25_cb_del(ax25);
@@ -293,9 +289,9 @@ void ax25_destroy_socket(struct ax25_soc
 
 	ax25_clear_queues(ax25);	/* Flush the queues */
 
-	if (ax25->sk != NULL) {
+	if (sk) {
 		while ((skb = skb_dequeue(&ax25->sk->sk_receive_queue)) != NULL) {
-			if (skb->sk != ax25->sk) {
+			if (skb->sk != sk) {
 				/* A pending connection */
 				struct ax25_sock *sax25 = ax25_sk(skb->sk);
 
@@ -308,23 +304,14 @@ void ax25_destroy_socket(struct ax25_soc
 
 			kfree_skb(skb);
 		}
-		skb_queue_purge(&ax25->sk->sk_write_queue);
-	}
+		skb_queue_purge(&sk->sk_write_queue);
 
-	if (ax25->sk != NULL) {
-		if (atomic_read(&ax25->sk->sk_wmem_alloc) ||
-		    atomic_read(&ax25->sk->sk_rmem_alloc)) {
+		if (atomic_read(&sk->sk_wmem_alloc) ||
+		    atomic_read(&sk->sk_rmem_alloc)) {
 			/* Defer: outstanding buffers */
-			init_timer(&ax25->dtimer);
-			ax25->dtimer.expires  = jiffies + 2 * HZ;
-			ax25->dtimer.function = ax25_destroy_timer;
-			ax25->dtimer.data     = (unsigned long)ax25;
-			add_timer(&ax25->dtimer);
-		} else {
-			struct sock *sk=ax25->sk;
-			ax25->sk=NULL;
+			sk_reset_timer(sk, &ax25->dtimer, jiffies + 2 * HZ);
+		} else
 			sock_put(sk);
-		}
 	} else {
 		sock_put(&ax25->sock);
 	}
@@ -497,11 +484,29 @@ struct ax25_sock *ax25_alloc_sock(struct
 	skb_queue_head_init(&ax25->ack_queue);
 	skb_queue_head_init(&ax25->reseq_queue);
 
-	init_timer(&ax25->timer);
 	init_timer(&ax25->t1timer);
+	ax25->t1timer.function	= &ax25_t1timer_expiry;
+	ax25->t1timer.data	= (unsigned long) ax25;
+
 	init_timer(&ax25->t2timer);
+	ax25->t2timer.function	= &ax25_t2timer_expiry;
+	ax25->t2timer.data	= (unsigned long) ax25;
+
 	init_timer(&ax25->t3timer);
+	ax25->t3timer.function	= &ax25_t3timer_expiry;
+	ax25->t3timer.data	= (unsigned long) ax25;
+
 	init_timer(&ax25->idletimer);
+	ax25->idletimer.function= &ax25_idletimer_expiry;
+	ax25->idletimer.data	= (unsigned long) ax25;
+
+	init_timer(&ax25->timer);
+	ax25->timer.function	= &ax25_heartbeat_expiry;
+	ax25->timer.data	= (unsigned long) ax25;
+
+	init_timer(&ax25->dtimer);
+	ax25->dtimer.function	= ax25_destroy_timer;
+	ax25->dtimer.data	= (unsigned long)ax25;
 
 	ax25_fillin_cb(ax25, NULL);
 
net/ax25/ax25_timer.c +34 -48

175 lines not on this page · raw message

include/net/ax25.h +5 -0
Index: linux-net/include/net/ax25.h
===================================================================
@@ -395,6 +395,11 @@ extern void ax25_stop_t1timer(struct ax2
 extern void ax25_stop_t2timer(struct ax25_sock *);
 extern void ax25_stop_t3timer(struct ax25_sock *);
 extern void ax25_stop_idletimer(struct ax25_sock *);
+extern void ax25_heartbeat_expiry(unsigned long);
+extern void ax25_t1timer_expiry(unsigned long);
+extern void ax25_t2timer_expiry(unsigned long);
+extern void ax25_t3timer_expiry(unsigned long);
+extern void ax25_idletimer_expiry(unsigned long);
 extern int  ax25_t1timer_running(struct ax25_sock *);
 extern unsigned long ax25_display_timer(struct timer_list *);
 
net/netrom/nr_timer.c +16 -13
Index: linux-net/net/netrom/nr_timer.c
===================================================================
@@ -65,21 +65,21 @@ void nr_start_t1timer(struct sock *sk)
 {
 	struct nr_sock *nr = nr_sk(sk);
 
-	mod_timer(&nr->t1timer, jiffies + nr->t1);
+	sk_reset_timer(sk, &nr->t1timer, jiffies + nr->t1);
 }
 
 void nr_start_t2timer(struct sock *sk)
 {
 	struct nr_sock *nr = nr_sk(sk);
 
-	mod_timer(&nr->t2timer, jiffies + nr->t2);
+	sk_reset_timer(sk, &nr->t2timer, jiffies + nr->t2);
 }
 
 void nr_start_t4timer(struct sock *sk)
 {
 	struct nr_sock *nr = nr_sk(sk);
 
-	mod_timer(&nr->t4timer, jiffies + nr->t4);
+	sk_reset_timer(sk, &nr->t4timer, jiffies + nr->t4);
 }
 
 void nr_start_idletimer(struct sock *sk)
@@ -87,37 +87,37 @@ void nr_start_idletimer(struct sock *sk)
 	struct nr_sock *nr = nr_sk(sk);
 
 	if (nr->idle > 0)
-		mod_timer(&nr->idletimer, jiffies + nr->idle);
+		sk_reset_timer(sk, &nr->idletimer, jiffies + nr->idle);
 }
 
 void nr_start_heartbeat(struct sock *sk)
 {
-	mod_timer(&sk->sk_timer, jiffies + 5 * HZ);
+	sk_reset_timer(sk, &sk->sk_timer, jiffies + 5 * HZ);
 }
 
 void nr_stop_t1timer(struct sock *sk)
 {
-	del_timer(&nr_sk(sk)->t1timer);
+	sk_stop_timer(sk, &nr_sk(sk)->t1timer);
 }
 
 void nr_stop_t2timer(struct sock *sk)
 {
-	del_timer(&nr_sk(sk)->t2timer);
+	sk_stop_timer(sk, &nr_sk(sk)->t2timer);
 }
 
 void nr_stop_t4timer(struct sock *sk)
 {
-	del_timer(&nr_sk(sk)->t4timer);
+	sk_stop_timer(sk, &nr_sk(sk)->t4timer);
 }
 
 void nr_stop_idletimer(struct sock *sk)
 {
-	del_timer(&nr_sk(sk)->idletimer);
+	sk_stop_timer(sk, &nr_sk(sk)->idletimer);
 }
 
 void nr_stop_heartbeat(struct sock *sk)
 {
-	del_timer(&sk->sk_timer);
+	sk_stop_timer(sk, &sk->sk_timer);
 }
 
 int nr_t1timer_running(struct sock *sk)
@@ -137,10 +137,7 @@ static void nr_heartbeat_expiry(unsigned
 		   is accepted() it isn't 'dead' so doesn't get removed. */
 		if (sock_flag(sk, SOCK_DESTROY) ||
 		    (sk->sk_state == TCP_LISTEN && sock_flag(sk, SOCK_DEAD))) {
-			sock_hold(sk);
-			bh_unlock_sock(sk);
 			nr_destroy_socket(sk);
-			sock_put(sk);
 			return;
 		}
 		break;
@@ -161,7 +158,9 @@ static void nr_heartbeat_expiry(unsigned
 	}
 
 	nr_start_heartbeat(sk);
+
 	bh_unlock_sock(sk);
+	sock_put(sk);
 }
 
 static void nr_t2timer_expiry(unsigned long param)
@@ -175,6 +174,7 @@ static void nr_t2timer_expiry(unsigned l
 		nr_enquiry_response(sk);
 	}
 	bh_unlock_sock(sk);
+	sock_put(sk);
 }
 
 static void nr_t4timer_expiry(unsigned long param)
@@ -184,6 +184,7 @@ static void nr_t4timer_expiry(unsigned l
 	bh_lock_sock(sk);
 	nr_sk(sk)->condition &= ~NR_COND_PEER_RX_BUSY;
 	bh_unlock_sock(sk);
+	sock_put(sk);
 }
 
 static void nr_idletimer_expiry(unsigned long param)
@@ -212,6 +213,7 @@ static void nr_idletimer_expiry(unsigned
 		sock_set_flag(sk, SOCK_DEAD);
 	}
 	bh_unlock_sock(sk);
+	sock_put(sk);
 }
 
 static void nr_t1timer_expiry(unsigned long param)
@@ -257,4 +259,5 @@ static void nr_t1timer_expiry(unsigned l
 
 	nr_start_t1timer(sk);
 	bh_unlock_sock(sk);
+	sock_put(sk);
 }
include/net/rose.h +1 -0
Index: linux-net/include/net/rose.h
===================================================================
@@ -218,6 +218,7 @@ extern int  rose_parse_facilities(unsign
 extern void rose_disconnect(struct sock *, int, int, int);
 
 /* rose_timer.c */
+extern void rose_init_timers(struct sock *sk);
 extern void rose_start_heartbeat(struct sock *);
 extern void rose_start_t1timer(struct sock *);
 extern void rose_start_t2timer(struct sock *);
net/rose/af_rose.c +2 -4
Index: linux-net/net/rose/af_rose.c
===================================================================
@@ -522,8 +522,7 @@ static int rose_create(struct socket *so
 	sock->ops    = &rose_proto_ops;
 	sk->sk_protocol = protocol;
 
-	init_timer(&rose->timer);
-	init_timer(&rose->idletimer);
+	rose_init_timers(sk);
 
 	rose->t1   = msecs_to_jiffies(sysctl_rose_call_request_timeout);
 	rose->t2   = msecs_to_jiffies(sysctl_rose_reset_request_timeout);
@@ -567,8 +566,7 @@ static struct sock *rose_make_new(struct
 	sk->sk_sleep    = osk->sk_sleep;
 	sock_copy_flags(sk, osk);
 
-	init_timer(&rose->timer);
-	init_timer(&rose->idletimer);
+	rose_init_timers(sk);
 
 	orose		= rose_sk(osk);
 	rose->t1	= orose->t1;
net/rose/rose_timer.c +32 -47

162 lines not on this page · raw message

#2 lore raw
In reply to Ralf Baechle
Quoted 4 lines · Ralf Baechle

Aside of wanrouter AX.25 has also been the last member of struct sock.sk_protinfo. With net/wanrouter being considered hopeless code and an application-level solution being prefered these days this means we now can delete sk_protinfo.

/me sheds a tear... ;) Yay, hasta la vista sk_protinfo, it has been a long way 8)

- Arnaldo

maintainer
#3 lore raw
In reply to Ralf Baechle

From: Ralf Baechle <[email protected]>
Date: Fri, 21 Jul 2006 11:29:46 -0400

Quoted 10 lines

Upto now AX.25 was using two separate structures for it's sockets. One, ax25_cb described the entire actual AX.25 connection. The other was the standard struct sock.

This patch combines both into struct ax25_sock which is more in line with current practice. An AX.25 speciality was that a ax25_cb could exist without a struct sock referencing it. Keep that alive for now by keeping the old struct sock *sk member of ax25_cb in struct ax25_sock. This now just has become a struct-internal pointer.

Quoted 6 lines

Aside of wanrouter AX.25 has also been the last member of struct sock.sk_protinfo. With net/wanrouter being considered hopeless code and an application-level solution being prefered these days this means we now can delete sk_protinfo.

This is very nice work Ralf, but I think it's 2.6.19 material. :-)

#4 lore raw
Quoted 4 lines · David Miller
Quoted 1 line

This is very nice work Ralf, but I think it's 2.6.19 material. :-)

While this patch itself is more of a cleanup it's a prerequisite for being able the use the sk_*_timer functions to fix the reference counts in AX.25 timers ...

I have no problem to wait with deleting sk_protinfo :-)

Ralf

maintainer
#5 lore raw

From: Ralf Baechle <[email protected]>
Date: Sat, 22 Jul 2006 08:13:43 -0400

Quoted 3 lines

While this patch itself is more of a cleanup it's a prerequisite for being able the use the sk_*_timer functions to fix the reference counts in AX.25 timers ...

When you have those timer refcount fixes as part of your patch set, I can then justify putting the change into 2.6.18. Feel free to resubmit once you have it all ready.