Commit 5c0fbae1 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo

Merge hera.kernel.org:/home/acme/BK/x25-2.5.old

into hera.kernel.org:/home/acme/BK/x25-2.5
parents 536ce362 004ffedc
This diff is collapsed.
...@@ -39,16 +39,16 @@ ...@@ -39,16 +39,16 @@
* An X.121 address, it is held as ASCII text, null terminated, up to 15 * An X.121 address, it is held as ASCII text, null terminated, up to 15
* digits and a null terminator. * digits and a null terminator.
*/ */
typedef struct { struct x25_address {
char x25_addr[16]; char x25_addr[16];
} x25_address; };
/* /*
* Linux X.25 Address structure, used for bind, and connect mostly. * Linux X.25 Address structure, used for bind, and connect mostly.
*/ */
struct sockaddr_x25 { struct sockaddr_x25 {
sa_family_t sx25_family; /* Must be AF_X25 */ sa_family_t sx25_family; /* Must be AF_X25 */
x25_address sx25_addr; /* X.121 Address */ struct x25_address sx25_addr; /* X.121 Address */
}; };
/* /*
...@@ -78,9 +78,9 @@ struct x25_subscrip_struct { ...@@ -78,9 +78,9 @@ struct x25_subscrip_struct {
* Routing table control structure. * Routing table control structure.
*/ */
struct x25_route_struct { struct x25_route_struct {
x25_address address; struct x25_address address;
unsigned int sigdigits; unsigned int sigdigits;
char device[200]; char device[200];
}; };
/* /*
......
...@@ -78,8 +78,8 @@ struct lapb_frame { ...@@ -78,8 +78,8 @@ struct lapb_frame {
/* /*
* The per LAPB connection control structure. * The per LAPB connection control structure.
*/ */
typedef struct lapb_cb { struct lapb_cb {
struct lapb_cb *next; struct list_head node;
void *token; void *token;
/* Link status fields */ /* Link status fields */
...@@ -100,43 +100,45 @@ typedef struct lapb_cb { ...@@ -100,43 +100,45 @@ typedef struct lapb_cb {
/* FRMR control information */ /* FRMR control information */
struct lapb_frame frmr_data; struct lapb_frame frmr_data;
unsigned char frmr_type; unsigned char frmr_type;
} lapb_cb;
atomic_t refcnt;
};
/* lapb_iface.c */ /* lapb_iface.c */
extern void lapb_connect_confirmation(lapb_cb *, int); extern void lapb_connect_confirmation(struct lapb_cb *lapb, int);
extern void lapb_connect_indication(lapb_cb *, int); extern void lapb_connect_indication(struct lapb_cb *lapb, int);
extern void lapb_disconnect_confirmation(lapb_cb *, int); extern void lapb_disconnect_confirmation(struct lapb_cb *lapb, int);
extern void lapb_disconnect_indication(lapb_cb *, int); extern void lapb_disconnect_indication(struct lapb_cb *lapb, int);
extern int lapb_data_indication(lapb_cb *, struct sk_buff *); extern int lapb_data_indication(struct lapb_cb *lapb, struct sk_buff *);
extern int lapb_data_transmit(lapb_cb *, struct sk_buff *); extern int lapb_data_transmit(struct lapb_cb *lapb, struct sk_buff *);
/* lapb_in.c */ /* lapb_in.c */
extern void lapb_data_input(lapb_cb *, struct sk_buff *); extern void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *);
/* lapb_out.c */ /* lapb_out.c */
extern void lapb_kick(lapb_cb *); extern void lapb_kick(struct lapb_cb *lapb);
extern void lapb_transmit_buffer(lapb_cb *, struct sk_buff *, int); extern void lapb_transmit_buffer(struct lapb_cb *lapb, struct sk_buff *, int);
extern void lapb_establish_data_link(lapb_cb *); extern void lapb_establish_data_link(struct lapb_cb *lapb);
extern void lapb_enquiry_response(lapb_cb *); extern void lapb_enquiry_response(struct lapb_cb *lapb);
extern void lapb_timeout_response(lapb_cb *); extern void lapb_timeout_response(struct lapb_cb *lapb);
extern void lapb_check_iframes_acked(lapb_cb *, unsigned short); extern void lapb_check_iframes_acked(struct lapb_cb *lapb, unsigned short);
extern void lapb_check_need_response(lapb_cb *, int, int); extern void lapb_check_need_response(struct lapb_cb *lapb, int, int);
/* lapb_subr.c */ /* lapb_subr.c */
extern void lapb_clear_queues(lapb_cb *); extern void lapb_clear_queues(struct lapb_cb *lapb);
extern void lapb_frames_acked(lapb_cb *, unsigned short); extern void lapb_frames_acked(struct lapb_cb *lapb, unsigned short);
extern void lapb_requeue_frames(lapb_cb *); extern void lapb_requeue_frames(struct lapb_cb *lapb);
extern int lapb_validate_nr(lapb_cb *, unsigned short); extern int lapb_validate_nr(struct lapb_cb *lapb, unsigned short);
extern void lapb_decode(lapb_cb *, struct sk_buff *, struct lapb_frame *); extern void lapb_decode(struct lapb_cb *lapb, struct sk_buff *, struct lapb_frame *);
extern void lapb_send_control(lapb_cb *, int, int, int); extern void lapb_send_control(struct lapb_cb *lapb, int, int, int);
extern void lapb_transmit_frmr(lapb_cb *); extern void lapb_transmit_frmr(struct lapb_cb *lapb);
/* lapb_timer.c */ /* lapb_timer.c */
extern void lapb_start_t1timer(lapb_cb *); extern void lapb_start_t1timer(struct lapb_cb *lapb);
extern void lapb_start_t2timer(lapb_cb *); extern void lapb_start_t2timer(struct lapb_cb *lapb);
extern void lapb_stop_t1timer(lapb_cb *); extern void lapb_stop_t1timer(struct lapb_cb *lapb);
extern void lapb_stop_t2timer(lapb_cb *); extern void lapb_stop_t2timer(struct lapb_cb *lapb);
extern int lapb_t1timer_running(lapb_cb *); extern int lapb_t1timer_running(struct lapb_cb *lapb);
/* /*
* Debug levels. * Debug levels.
......
...@@ -101,26 +101,36 @@ enum { ...@@ -101,26 +101,36 @@ enum {
#define X25_MAX_FAC_LEN 20 /* Plenty to spare */ #define X25_MAX_FAC_LEN 20 /* Plenty to spare */
#define X25_MAX_CUD_LEN 128 #define X25_MAX_CUD_LEN 128
/**
* struct x25_route - x25 routing entry
* @node - entry in x25_list_lock
* @address - Start of address range
* @sigdigits - Number of sig digits
* @dev - More than one for MLP
* @refcnt - reference counter
*/
struct x25_route { struct x25_route {
struct x25_route *next; struct list_head node;
x25_address address; /* Start of address range */ struct x25_address address;
unsigned int sigdigits; /* Number of sig digits */ unsigned int sigdigits;
struct net_device *dev; /* More than one for MLP */ struct net_device *dev;
atomic_t refcnt;
}; };
struct x25_neigh { struct x25_neigh {
struct x25_neigh *next; struct list_head node;
struct net_device *dev; struct net_device *dev;
unsigned int state; unsigned int state;
unsigned int extended; unsigned int extended;
struct sk_buff_head queue; struct sk_buff_head queue;
unsigned long t20; unsigned long t20;
struct timer_list t20timer; struct timer_list t20timer;
unsigned long global_facil_mask; unsigned long global_facil_mask;
atomic_t refcnt;
}; };
typedef struct { struct x25_opt {
x25_address source_addr, dest_addr; struct x25_address source_addr, dest_addr;
struct x25_neigh *neighbour; struct x25_neigh *neighbour;
unsigned int lci; unsigned int lci;
unsigned char state, condition, qbitincl, intflag; unsigned char state, condition, qbitincl, intflag;
...@@ -137,9 +147,9 @@ typedef struct { ...@@ -137,9 +147,9 @@ typedef struct {
struct x25_facilities facilities; struct x25_facilities facilities;
struct x25_calluserdata calluserdata; struct x25_calluserdata calluserdata;
unsigned long vc_facil_mask; /* inc_call facilities mask */ unsigned long vc_facil_mask; /* inc_call facilities mask */
} x25_cb; };
#define x25_sk(__sk) ((x25_cb *)(__sk)->protinfo) #define x25_sk(__sk) ((struct x25_opt *)(__sk)->protinfo)
/* af_x25.c */ /* af_x25.c */
extern int sysctl_x25_restart_request_timeout; extern int sysctl_x25_restart_request_timeout;
...@@ -148,8 +158,10 @@ extern int sysctl_x25_reset_request_timeout; ...@@ -148,8 +158,10 @@ extern int sysctl_x25_reset_request_timeout;
extern int sysctl_x25_clear_request_timeout; extern int sysctl_x25_clear_request_timeout;
extern int sysctl_x25_ack_holdback_timeout; extern int sysctl_x25_ack_holdback_timeout;
extern int x25_addr_ntoa(unsigned char *, x25_address *, x25_address *); extern int x25_addr_ntoa(unsigned char *, struct x25_address *,
extern int x25_addr_aton(unsigned char *, x25_address *, x25_address *); struct x25_address *);
extern int x25_addr_aton(unsigned char *, struct x25_address *,
struct x25_address *);
extern unsigned int x25_new_lci(struct x25_neigh *); extern unsigned int x25_new_lci(struct x25_neigh *);
extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *); extern struct sock *x25_find_socket(unsigned int, struct x25_neigh *);
extern void x25_destroy_socket(struct sock *); extern void x25_destroy_socket(struct sock *);
...@@ -188,19 +200,42 @@ extern int x25_subscr_ioctl(unsigned int, void *); ...@@ -188,19 +200,42 @@ extern int x25_subscr_ioctl(unsigned int, void *);
extern struct x25_neigh *x25_get_neigh(struct net_device *); extern struct x25_neigh *x25_get_neigh(struct net_device *);
extern void x25_link_free(void); extern void x25_link_free(void);
/* x25_neigh.c */
static __inline__ void x25_neigh_hold(struct x25_neigh *nb)
{
atomic_inc(&nb->refcnt);
}
static __inline__ void x25_neigh_put(struct x25_neigh *nb)
{
if (atomic_dec_and_test(&nb->refcnt))
kfree(nb);
}
/* x25_out.c */ /* x25_out.c */
extern int x25_output(struct sock *, struct sk_buff *); extern int x25_output(struct sock *, struct sk_buff *);
extern void x25_kick(struct sock *); extern void x25_kick(struct sock *);
extern void x25_enquiry_response(struct sock *); extern void x25_enquiry_response(struct sock *);
/* x25_route.c */ /* x25_route.c */
extern struct net_device *x25_get_route(x25_address *); extern struct x25_route *x25_get_route(struct x25_address *addr);
extern struct net_device *x25_dev_get(char *); extern struct net_device *x25_dev_get(char *);
extern void x25_route_device_down(struct net_device *); extern void x25_route_device_down(struct net_device *);
extern int x25_route_ioctl(unsigned int, void *); extern int x25_route_ioctl(unsigned int, void *);
extern int x25_routes_get_info(char *, char **, off_t, int); extern int x25_routes_get_info(char *, char **, off_t, int);
extern void x25_route_free(void); extern void x25_route_free(void);
static __inline__ void x25_route_hold(struct x25_route *rt)
{
atomic_inc(&rt->refcnt);
}
static __inline__ void x25_route_put(struct x25_route *rt)
{
if (atomic_dec_and_test(&rt->refcnt))
kfree(rt);
}
/* x25_subr.c */ /* x25_subr.c */
extern void x25_clear_queues(struct sock *); extern void x25_clear_queues(struct sock *);
extern void x25_frames_acked(struct sock *, unsigned short); extern void x25_frames_acked(struct sock *, unsigned short);
......
This diff is collapsed.
This diff is collapsed.
...@@ -38,56 +38,54 @@ ...@@ -38,56 +38,54 @@
* This procedure is passed a buffer descriptor for an iframe. It builds * 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. * the rest of the control part of the frame and then writes it out.
*/ */
static void lapb_send_iframe(lapb_cb *lapb, struct sk_buff *skb, int poll_bit) static void lapb_send_iframe(struct lapb_cb *lapb, struct sk_buff *skb, int poll_bit)
{ {
unsigned char *frame; unsigned char *frame;
if (skb == NULL) if (!skb)
return; return;
if (lapb->mode & LAPB_EXTENDED) { if (lapb->mode & LAPB_EXTENDED) {
frame = skb_push(skb, 2); frame = skb_push(skb, 2);
frame[0] = LAPB_I; frame[0] = LAPB_I;
frame[0] |= (lapb->vs << 1); frame[0] |= lapb->vs << 1;
frame[1] = (poll_bit) ? LAPB_EPF : 0; frame[1] = poll_bit ? LAPB_EPF : 0;
frame[1] |= (lapb->vr << 1); frame[1] |= lapb->vr << 1;
} else { } else {
frame = skb_push(skb, 1); frame = skb_push(skb, 1);
*frame = LAPB_I; *frame = LAPB_I;
*frame |= (poll_bit) ? LAPB_SPF : 0; *frame |= poll_bit ? LAPB_SPF : 0;
*frame |= (lapb->vr << 5); *frame |= lapb->vr << 5;
*frame |= (lapb->vs << 1); *frame |= lapb->vs << 1;
} }
#if LAPB_DEBUG > 1 #if LAPB_DEBUG > 1
printk(KERN_DEBUG "lapb: (%p) S%d TX I(%d) S%d R%d\n", lapb->token, lapb->state, poll_bit, lapb->vs, lapb->vr); printk(KERN_DEBUG "lapb: (%p) S%d TX I(%d) S%d R%d\n",
lapb->token, lapb->state, poll_bit, lapb->vs, lapb->vr);
#endif #endif
lapb_transmit_buffer(lapb, skb, LAPB_COMMAND); lapb_transmit_buffer(lapb, skb, LAPB_COMMAND);
} }
void lapb_kick(lapb_cb *lapb) void lapb_kick(struct lapb_cb *lapb)
{ {
struct sk_buff *skb, *skbn; struct sk_buff *skb, *skbn;
unsigned short modulus, start, end; unsigned short modulus, start, end;
modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS; modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS;
start = !skb_peek(&lapb->ack_queue) ? lapb->va : lapb->vs;
start = (skb_peek(&lapb->ack_queue) == NULL) ? lapb->va : lapb->vs;
end = (lapb->va + lapb->window) % modulus; end = (lapb->va + lapb->window) % modulus;
if (!(lapb->condition & LAPB_PEER_RX_BUSY_CONDITION) && if (!(lapb->condition & LAPB_PEER_RX_BUSY_CONDITION) &&
start != end && start != end && skb_peek(&lapb->write_queue)) {
skb_peek(&lapb->write_queue) != NULL) {
lapb->vs = start; lapb->vs = start;
/* /*
* Dequeue the frame and copy it. * Dequeue the frame and copy it.
*/ */
skb = skb_dequeue(&lapb->write_queue); skb = skb_dequeue(&lapb->write_queue);
do { do {
if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) { if ((skbn = skb_clone(skb, GFP_ATOMIC)) == NULL) {
...@@ -95,7 +93,7 @@ void lapb_kick(lapb_cb *lapb) ...@@ -95,7 +93,7 @@ void lapb_kick(lapb_cb *lapb)
break; break;
} }
if (skb->sk != NULL) if (skb->sk)
skb_set_owner_w(skbn, skb->sk); skb_set_owner_w(skbn, skb->sk);
/* /*
...@@ -119,7 +117,7 @@ void lapb_kick(lapb_cb *lapb) ...@@ -119,7 +117,7 @@ void lapb_kick(lapb_cb *lapb)
} }
} }
void lapb_transmit_buffer(lapb_cb *lapb, struct sk_buff *skb, int type) void lapb_transmit_buffer(struct lapb_cb *lapb, struct sk_buff *skb, int type)
{ {
unsigned char *ptr; unsigned char *ptr;
...@@ -152,26 +150,30 @@ void lapb_transmit_buffer(lapb_cb *lapb, struct sk_buff *skb, int type) ...@@ -152,26 +150,30 @@ void lapb_transmit_buffer(lapb_cb *lapb, struct sk_buff *skb, int type)
} }
#if LAPB_DEBUG > 2 #if LAPB_DEBUG > 2
printk(KERN_DEBUG "lapb: (%p) S%d TX %02X %02X %02X\n", lapb->token, lapb->state, skb->data[0], skb->data[1], skb->data[2]); printk(KERN_DEBUG "lapb: (%p) S%d TX %02X %02X %02X\n",
lapb->token, lapb->state,
skb->data[0], skb->data[1], skb->data[2]);
#endif #endif
if (!lapb_data_transmit(lapb, skb)) if (!lapb_data_transmit(lapb, skb))
kfree_skb(skb); kfree_skb(skb);
} }
void lapb_establish_data_link(lapb_cb *lapb) void lapb_establish_data_link(struct lapb_cb *lapb)
{ {
lapb->condition = 0x00; lapb->condition = 0x00;
lapb->n2count = 0; lapb->n2count = 0;
if (lapb->mode & LAPB_EXTENDED) { if (lapb->mode & LAPB_EXTENDED) {
#if LAPB_DEBUG > 1 #if LAPB_DEBUG > 1
printk(KERN_DEBUG "lapb: (%p) S%d TX SABME(1)\n", lapb->token, lapb->state); printk(KERN_DEBUG "lapb: (%p) S%d TX SABME(1)\n",
lapb->token, lapb->state);
#endif #endif
lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND); lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND);
} else { } else {
#if LAPB_DEBUG > 1 #if LAPB_DEBUG > 1
printk(KERN_DEBUG "lapb: (%p) S%d TX SABM(1)\n", lapb->token, lapb->state); printk(KERN_DEBUG "lapb: (%p) S%d TX SABM(1)\n",
lapb->token, lapb->state);
#endif #endif
lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND); lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND);
} }
...@@ -180,10 +182,11 @@ void lapb_establish_data_link(lapb_cb *lapb) ...@@ -180,10 +182,11 @@ void lapb_establish_data_link(lapb_cb *lapb)
lapb_stop_t2timer(lapb); lapb_stop_t2timer(lapb);
} }
void lapb_enquiry_response(lapb_cb *lapb) void lapb_enquiry_response(struct lapb_cb *lapb)
{ {
#if LAPB_DEBUG > 1 #if LAPB_DEBUG > 1
printk(KERN_DEBUG "lapb: (%p) S%d TX RR(1) R%d\n", lapb->token, lapb->state, lapb->vr); printk(KERN_DEBUG "lapb: (%p) S%d TX RR(1) R%d\n",
lapb->token, lapb->state, lapb->vr);
#endif #endif
lapb_send_control(lapb, LAPB_RR, LAPB_POLLON, LAPB_RESPONSE); lapb_send_control(lapb, LAPB_RR, LAPB_POLLON, LAPB_RESPONSE);
...@@ -191,32 +194,30 @@ void lapb_enquiry_response(lapb_cb *lapb) ...@@ -191,32 +194,30 @@ void lapb_enquiry_response(lapb_cb *lapb)
lapb->condition &= ~LAPB_ACK_PENDING_CONDITION; lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
} }
void lapb_timeout_response(lapb_cb *lapb) void lapb_timeout_response(struct lapb_cb *lapb)
{ {
#if LAPB_DEBUG > 1 #if LAPB_DEBUG > 1
printk(KERN_DEBUG "lapb: (%p) S%d TX RR(0) R%d\n", lapb->token, lapb->state, lapb->vr); printk(KERN_DEBUG "lapb: (%p) S%d TX RR(0) R%d\n",
lapb->token, lapb->state, lapb->vr);
#endif #endif
lapb_send_control(lapb, LAPB_RR, LAPB_POLLOFF, LAPB_RESPONSE); lapb_send_control(lapb, LAPB_RR, LAPB_POLLOFF, LAPB_RESPONSE);
lapb->condition &= ~LAPB_ACK_PENDING_CONDITION; lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
} }
void lapb_check_iframes_acked(lapb_cb *lapb, unsigned short nr) void lapb_check_iframes_acked(struct lapb_cb *lapb, unsigned short nr)
{ {
if (lapb->vs == nr) { if (lapb->vs == nr) {
lapb_frames_acked(lapb, nr); lapb_frames_acked(lapb, nr);
lapb_stop_t1timer(lapb); lapb_stop_t1timer(lapb);
lapb->n2count = 0; lapb->n2count = 0;
} else { } else if (lapb->va != nr) {
if (lapb->va != nr) { lapb_frames_acked(lapb, nr);
lapb_frames_acked(lapb, nr); lapb_start_t1timer(lapb);
lapb_start_t1timer(lapb);
}
} }
} }
void lapb_check_need_response(lapb_cb *lapb, int type, int pf) void lapb_check_need_response(struct lapb_cb *lapb, int type, int pf)
{ {
if (type == LAPB_COMMAND && pf) if (type == LAPB_COMMAND && pf)
lapb_enquiry_response(lapb); lapb_enquiry_response(lapb);
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
/* /*
* This routine purges all the queues of frames. * This routine purges all the queues of frames.
*/ */
void lapb_clear_queues(lapb_cb *lapb) void lapb_clear_queues(struct lapb_cb *lapb)
{ {
skb_queue_purge(&lapb->write_queue); skb_queue_purge(&lapb->write_queue);
skb_queue_purge(&lapb->ack_queue); skb_queue_purge(&lapb->ack_queue);
...@@ -47,7 +47,7 @@ void lapb_clear_queues(lapb_cb *lapb) ...@@ -47,7 +47,7 @@ void lapb_clear_queues(lapb_cb *lapb)
* acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the * acknowledged. This replaces the boxes labelled "V(a) <- N(r)" on the
* SDL diagram. * SDL diagram.
*/ */
void lapb_frames_acked(lapb_cb *lapb, unsigned short nr) void lapb_frames_acked(struct lapb_cb *lapb, unsigned short nr)
{ {
struct sk_buff *skb; struct sk_buff *skb;
int modulus; int modulus;
...@@ -57,16 +57,15 @@ void lapb_frames_acked(lapb_cb *lapb, unsigned short nr) ...@@ -57,16 +57,15 @@ void lapb_frames_acked(lapb_cb *lapb, unsigned short nr)
/* /*
* Remove all the ack-ed frames from the ack queue. * Remove all the ack-ed frames from the ack queue.
*/ */
if (lapb->va != nr) { if (lapb->va != nr)
while (skb_peek(&lapb->ack_queue) != NULL && lapb->va != nr) { while (skb_peek(&lapb->ack_queue) && lapb->va != nr) {
skb = skb_dequeue(&lapb->ack_queue); skb = skb_dequeue(&lapb->ack_queue);
kfree_skb(skb); kfree_skb(skb);
lapb->va = (lapb->va + 1) % modulus; lapb->va = (lapb->va + 1) % modulus;
} }
}
} }
void lapb_requeue_frames(lapb_cb *lapb) void lapb_requeue_frames(struct lapb_cb *lapb)
{ {
struct sk_buff *skb, *skb_prev = NULL; struct sk_buff *skb, *skb_prev = NULL;
...@@ -76,7 +75,7 @@ void lapb_requeue_frames(lapb_cb *lapb) ...@@ -76,7 +75,7 @@ void lapb_requeue_frames(lapb_cb *lapb)
* possibility of an empty output queue. * possibility of an empty output queue.
*/ */
while ((skb = skb_dequeue(&lapb->ack_queue)) != NULL) { while ((skb = skb_dequeue(&lapb->ack_queue)) != NULL) {
if (skb_prev == NULL) if (!skb_prev)
skb_queue_head(&lapb->write_queue, skb); skb_queue_head(&lapb->write_queue, skb);
else else
skb_append(skb_prev, skb); skb_append(skb_prev, skb);
...@@ -88,7 +87,7 @@ void lapb_requeue_frames(lapb_cb *lapb) ...@@ -88,7 +87,7 @@ void lapb_requeue_frames(lapb_cb *lapb)
* Validate that the value of nr is between va and vs. Return true or * Validate that the value of nr is between va and vs. Return true or
* false for testing. * false for testing.
*/ */
int lapb_validate_nr(lapb_cb *lapb, unsigned short nr) int lapb_validate_nr(struct lapb_cb *lapb, unsigned short nr)
{ {
unsigned short vc = lapb->va; unsigned short vc = lapb->va;
int modulus; int modulus;
...@@ -96,25 +95,27 @@ int lapb_validate_nr(lapb_cb *lapb, unsigned short nr) ...@@ -96,25 +95,27 @@ int lapb_validate_nr(lapb_cb *lapb, unsigned short nr)
modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS; modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS;
while (vc != lapb->vs) { while (vc != lapb->vs) {
if (nr == vc) return 1; if (nr == vc)
return 1;
vc = (vc + 1) % modulus; vc = (vc + 1) % modulus;
} }
if (nr == lapb->vs) return 1; return nr == lapb->vs;
return 0;
} }
/* /*
* This routine is the centralised routine for parsing the control * This routine is the centralised routine for parsing the control
* information for the different frame formats. * information for the different frame formats.
*/ */
void lapb_decode(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame) void lapb_decode(struct lapb_cb *lapb, struct sk_buff *skb,
struct lapb_frame *frame)
{ {
frame->type = LAPB_ILLEGAL; frame->type = LAPB_ILLEGAL;
#if LAPB_DEBUG > 2 #if LAPB_DEBUG > 2
printk(KERN_DEBUG "lapb: (%p) S%d RX %02X %02X %02X\n", lapb->token, lapb->state, skb->data[0], skb->data[1], skb->data[2]); printk(KERN_DEBUG "lapb: (%p) S%d RX %02X %02X %02X\n",
lapb->token, lapb->state,
skb->data[0], skb->data[1], skb->data[2]);
#endif #endif
if (lapb->mode & LAPB_MLP) { if (lapb->mode & LAPB_MLP) {
...@@ -146,22 +147,31 @@ void lapb_decode(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame) ...@@ -146,22 +147,31 @@ void lapb_decode(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
skb_pull(skb, 1); skb_pull(skb, 1);
if (lapb->mode & LAPB_EXTENDED) { if (lapb->mode & LAPB_EXTENDED) {
if ((skb->data[0] & LAPB_S) == 0) { if (!(skb->data[0] & LAPB_S)) {
frame->type = LAPB_I; /* I frame - carries NR/NS/PF */ /*
* I frame - carries NR/NS/PF
*/
frame->type = LAPB_I;
frame->ns = (skb->data[0] >> 1) & 0x7F; frame->ns = (skb->data[0] >> 1) & 0x7F;
frame->nr = (skb->data[1] >> 1) & 0x7F; frame->nr = (skb->data[1] >> 1) & 0x7F;
frame->pf = skb->data[1] & LAPB_EPF; frame->pf = skb->data[1] & LAPB_EPF;
frame->control[0] = skb->data[0]; frame->control[0] = skb->data[0];
frame->control[1] = skb->data[1]; frame->control[1] = skb->data[1];
skb_pull(skb, 2); skb_pull(skb, 2);
} else if ((skb->data[0] & LAPB_U) == 1) { /* S frame - take out PF/NR */ } else if ((skb->data[0] & LAPB_U) == 1) {
/*
* S frame - take out PF/NR
*/
frame->type = skb->data[0] & 0x0F; frame->type = skb->data[0] & 0x0F;
frame->nr = (skb->data[1] >> 1) & 0x7F; frame->nr = (skb->data[1] >> 1) & 0x7F;
frame->pf = skb->data[1] & LAPB_EPF; frame->pf = skb->data[1] & LAPB_EPF;
frame->control[0] = skb->data[0]; frame->control[0] = skb->data[0];
frame->control[1] = skb->data[1]; frame->control[1] = skb->data[1];
skb_pull(skb, 2); skb_pull(skb, 2);
} else if ((skb->data[0] & LAPB_U) == 3) { /* U frame - take out PF */ } else if ((skb->data[0] & LAPB_U) == 3) {
/*
* U frame - take out PF
*/
frame->type = skb->data[0] & ~LAPB_SPF; frame->type = skb->data[0] & ~LAPB_SPF;
frame->pf = skb->data[0] & LAPB_SPF; frame->pf = skb->data[0] & LAPB_SPF;
frame->control[0] = skb->data[0]; frame->control[0] = skb->data[0];
...@@ -169,16 +179,25 @@ void lapb_decode(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame) ...@@ -169,16 +179,25 @@ void lapb_decode(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
skb_pull(skb, 1); skb_pull(skb, 1);
} }
} else { } else {
if ((skb->data[0] & LAPB_S) == 0) { if (!(skb->data[0] & LAPB_S)) {
frame->type = LAPB_I; /* I frame - carries NR/NS/PF */ /*
* I frame - carries NR/NS/PF
*/
frame->type = LAPB_I;
frame->ns = (skb->data[0] >> 1) & 0x07; frame->ns = (skb->data[0] >> 1) & 0x07;
frame->nr = (skb->data[0] >> 5) & 0x07; frame->nr = (skb->data[0] >> 5) & 0x07;
frame->pf = skb->data[0] & LAPB_SPF; frame->pf = skb->data[0] & LAPB_SPF;
} else if ((skb->data[0] & LAPB_U) == 1) { /* S frame - take out PF/NR */ } else if ((skb->data[0] & LAPB_U) == 1) {
/*
* S frame - take out PF/NR
*/
frame->type = skb->data[0] & 0x0F; frame->type = skb->data[0] & 0x0F;
frame->nr = (skb->data[0] >> 5) & 0x07; frame->nr = (skb->data[0] >> 5) & 0x07;
frame->pf = skb->data[0] & LAPB_SPF; frame->pf = skb->data[0] & LAPB_SPF;
} else if ((skb->data[0] & LAPB_U) == 3) { /* U frame - take out PF */ } else if ((skb->data[0] & LAPB_U) == 3) {
/*
* U frame - take out PF
*/
frame->type = skb->data[0] & ~LAPB_SPF; frame->type = skb->data[0] & ~LAPB_SPF;
frame->pf = skb->data[0] & LAPB_SPF; frame->pf = skb->data[0] & LAPB_SPF;
} }
...@@ -195,7 +214,8 @@ void lapb_decode(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame) ...@@ -195,7 +214,8 @@ void lapb_decode(lapb_cb *lapb, struct sk_buff *skb, struct lapb_frame *frame)
* Only supervisory or unnumbered frames are processed, FRMRs are handled * Only supervisory or unnumbered frames are processed, FRMRs are handled
* by lapb_transmit_frmr below. * by lapb_transmit_frmr below.
*/ */
void lapb_send_control(lapb_cb *lapb, int frametype, int poll_bit, int type) void lapb_send_control(struct lapb_cb *lapb, int frametype,
int poll_bit, int type)
{ {
struct sk_buff *skb; struct sk_buff *skb;
unsigned char *dptr; unsigned char *dptr;
...@@ -209,18 +229,18 @@ void lapb_send_control(lapb_cb *lapb, int frametype, int poll_bit, int type) ...@@ -209,18 +229,18 @@ void lapb_send_control(lapb_cb *lapb, int frametype, int poll_bit, int type)
if ((frametype & LAPB_U) == LAPB_U) { if ((frametype & LAPB_U) == LAPB_U) {
dptr = skb_put(skb, 1); dptr = skb_put(skb, 1);
*dptr = frametype; *dptr = frametype;
*dptr |= (poll_bit) ? LAPB_SPF : 0; *dptr |= poll_bit ? LAPB_SPF : 0;
} else { } else {
dptr = skb_put(skb, 2); dptr = skb_put(skb, 2);
dptr[0] = frametype; dptr[0] = frametype;
dptr[1] = (lapb->vr << 1); dptr[1] = (lapb->vr << 1);
dptr[1] |= (poll_bit) ? LAPB_EPF : 0; dptr[1] |= poll_bit ? LAPB_EPF : 0;
} }
} else { } else {
dptr = skb_put(skb, 1); dptr = skb_put(skb, 1);
*dptr = frametype; *dptr = frametype;
*dptr |= (poll_bit) ? LAPB_SPF : 0; *dptr |= poll_bit ? LAPB_SPF : 0;
if ((frametype & LAPB_U) == LAPB_S) /* S frames carry NR */ if ((frametype & LAPB_U) == LAPB_S) /* S frames carry NR */
*dptr |= (lapb->vr << 5); *dptr |= (lapb->vr << 5);
} }
...@@ -231,7 +251,7 @@ void lapb_send_control(lapb_cb *lapb, int frametype, int poll_bit, int type) ...@@ -231,7 +251,7 @@ void lapb_send_control(lapb_cb *lapb, int frametype, int poll_bit, int type)
* This routine generates FRMRs based on information previously stored in * This routine generates FRMRs based on information previously stored in
* the LAPB control block. * the LAPB control block.
*/ */
void lapb_transmit_frmr(lapb_cb *lapb) void lapb_transmit_frmr(struct lapb_cb *lapb)
{ {
struct sk_buff *skb; struct sk_buff *skb;
unsigned char *dptr; unsigned char *dptr;
...@@ -254,7 +274,10 @@ void lapb_transmit_frmr(lapb_cb *lapb) ...@@ -254,7 +274,10 @@ void lapb_transmit_frmr(lapb_cb *lapb)
*dptr++ = lapb->frmr_type; *dptr++ = lapb->frmr_type;
#if LAPB_DEBUG > 1 #if LAPB_DEBUG > 1
printk(KERN_DEBUG "lapb: (%p) S%d TX FRMR %02X %02X %02X %02X %02X\n", lapb->token, lapb->state, skb->data[1], skb->data[2], skb->data[3], skb->data[4], skb->data[5]); printk(KERN_DEBUG "lapb: (%p) S%d TX FRMR %02X %02X %02X %02X %02X\n",
lapb->token, lapb->state,
skb->data[1], skb->data[2], skb->data[3],
skb->data[4], skb->data[5]);
#endif #endif
} else { } else {
dptr = skb_put(skb, 4); dptr = skb_put(skb, 4);
...@@ -268,7 +291,9 @@ void lapb_transmit_frmr(lapb_cb *lapb) ...@@ -268,7 +291,9 @@ void lapb_transmit_frmr(lapb_cb *lapb)
*dptr++ = lapb->frmr_type; *dptr++ = lapb->frmr_type;
#if LAPB_DEBUG > 1 #if LAPB_DEBUG > 1
printk(KERN_DEBUG "lapb: (%p) S%d TX FRMR %02X %02X %02X\n", lapb->token, lapb->state, skb->data[1], skb->data[2], skb->data[3]); printk(KERN_DEBUG "lapb: (%p) S%d TX FRMR %02X %02X %02X\n",
lapb->token, lapb->state, skb->data[1],
skb->data[2], skb->data[3]);
#endif #endif
} }
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
static void lapb_t1timer_expiry(unsigned long); static void lapb_t1timer_expiry(unsigned long);
static void lapb_t2timer_expiry(unsigned long); static void lapb_t2timer_expiry(unsigned long);
void lapb_start_t1timer(lapb_cb *lapb) void lapb_start_t1timer(struct lapb_cb *lapb)
{ {
del_timer(&lapb->t1timer); del_timer(&lapb->t1timer);
...@@ -48,7 +48,7 @@ void lapb_start_t1timer(lapb_cb *lapb) ...@@ -48,7 +48,7 @@ void lapb_start_t1timer(lapb_cb *lapb)
add_timer(&lapb->t1timer); add_timer(&lapb->t1timer);
} }
void lapb_start_t2timer(lapb_cb *lapb) void lapb_start_t2timer(struct lapb_cb *lapb)
{ {
del_timer(&lapb->t2timer); del_timer(&lapb->t2timer);
...@@ -59,24 +59,24 @@ void lapb_start_t2timer(lapb_cb *lapb) ...@@ -59,24 +59,24 @@ void lapb_start_t2timer(lapb_cb *lapb)
add_timer(&lapb->t2timer); add_timer(&lapb->t2timer);
} }
void lapb_stop_t1timer(lapb_cb *lapb) void lapb_stop_t1timer(struct lapb_cb *lapb)
{ {
del_timer(&lapb->t1timer); del_timer(&lapb->t1timer);
} }
void lapb_stop_t2timer(lapb_cb *lapb) void lapb_stop_t2timer(struct lapb_cb *lapb)
{ {
del_timer(&lapb->t2timer); del_timer(&lapb->t2timer);
} }
int lapb_t1timer_running(lapb_cb *lapb) int lapb_t1timer_running(struct lapb_cb *lapb)
{ {
return timer_pending(&lapb->t1timer); return timer_pending(&lapb->t1timer);
} }
static void lapb_t2timer_expiry(unsigned long param) static void lapb_t2timer_expiry(unsigned long param)
{ {
lapb_cb *lapb = (lapb_cb *)param; struct lapb_cb *lapb = (struct lapb_cb *)param;
if (lapb->condition & LAPB_ACK_PENDING_CONDITION) { if (lapb->condition & LAPB_ACK_PENDING_CONDITION) {
lapb->condition &= ~LAPB_ACK_PENDING_CONDITION; lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
...@@ -86,7 +86,7 @@ static void lapb_t2timer_expiry(unsigned long param) ...@@ -86,7 +86,7 @@ static void lapb_t2timer_expiry(unsigned long param)
static void lapb_t1timer_expiry(unsigned long param) static void lapb_t1timer_expiry(unsigned long param)
{ {
lapb_cb *lapb = (lapb_cb *)param; struct lapb_cb *lapb = (struct lapb_cb *)param;
switch (lapb->state) { switch (lapb->state) {
......
This diff is collapsed.
...@@ -13,38 +13,88 @@ ...@@ -13,38 +13,88 @@
#include <linux/init.h> #include <linux/init.h>
#include <net/x25.h> #include <net/x25.h>
static int min_timer[] = {1 * HZ}; static int min_timer[] = { 1 * HZ };
static int max_timer[] = {300 * HZ}; static int max_timer[] = { 300 * HZ };
static struct ctl_table_header *x25_table_header; static struct ctl_table_header *x25_table_header;
static ctl_table x25_table[] = { static struct ctl_table x25_table[] = {
{NET_X25_RESTART_REQUEST_TIMEOUT, "restart_request_timeout", {
&sysctl_x25_restart_request_timeout, sizeof(int), 0644, NULL, .ctl_name = NET_X25_RESTART_REQUEST_TIMEOUT,
&proc_dointvec_minmax, &sysctl_intvec, NULL, &min_timer, &max_timer}, .procname = "restart_request_timeout",
{NET_X25_CALL_REQUEST_TIMEOUT, "call_request_timeout", .data = &sysctl_x25_restart_request_timeout,
&sysctl_x25_call_request_timeout, sizeof(int), 0644, NULL, .maxlen = sizeof(int),
&proc_dointvec_minmax, &sysctl_intvec, NULL, &min_timer, &max_timer}, .mode = 0644,
{NET_X25_RESET_REQUEST_TIMEOUT, "reset_request_timeout", .proc_handler = &proc_dointvec_minmax,
&sysctl_x25_reset_request_timeout, sizeof(int), 0644, NULL, .strategy = &sysctl_intvec,
&proc_dointvec_minmax, &sysctl_intvec, NULL, &min_timer, &max_timer}, .extra1 = &min_timer,
{NET_X25_CLEAR_REQUEST_TIMEOUT, "clear_request_timeout", .extra2 = &max_timer,
&sysctl_x25_clear_request_timeout, sizeof(int), 0644, NULL, },
&proc_dointvec_minmax, &sysctl_intvec, NULL, &min_timer, &max_timer}, {
{NET_X25_ACK_HOLD_BACK_TIMEOUT, "acknowledgement_hold_back_timeout", .ctl_name = NET_X25_CALL_REQUEST_TIMEOUT,
&sysctl_x25_ack_holdback_timeout, sizeof(int), 0644, NULL, .procname = "call_request_timeout",
&proc_dointvec_minmax, &sysctl_intvec, NULL, &min_timer, &max_timer}, .data = &sysctl_x25_call_request_timeout,
{0} .maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
.strategy = &sysctl_intvec,
.extra1 = &min_timer,
.extra2 = &max_timer,
},
{
.ctl_name = NET_X25_RESET_REQUEST_TIMEOUT,
.procname = "reset_request_timeout",
.data = &sysctl_x25_reset_request_timeout,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
.strategy = &sysctl_intvec,
.extra1 = &min_timer,
.extra2 = &max_timer,
},
{
.ctl_name = NET_X25_CLEAR_REQUEST_TIMEOUT,
.procname = "clear_request_timeout",
.data = &sysctl_x25_clear_request_timeout,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
.strategy = &sysctl_intvec,
.extra1 = &min_timer,
.extra2 = &max_timer,
},
{
.ctl_name = NET_X25_ACK_HOLD_BACK_TIMEOUT,
.procname = "acknowledgement_hold_back_timeout",
.data = &sysctl_x25_ack_holdback_timeout,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_dointvec_minmax,
.strategy = &sysctl_intvec,
.extra1 = &min_timer,
.extra2 = &max_timer,
},
{ 0, },
}; };
static ctl_table x25_dir_table[] = { static struct ctl_table x25_dir_table[] = {
{NET_X25, "x25", NULL, 0, 0555, x25_table}, {
{0} .ctl_name = NET_X25,
.procname = "x25",
.mode = 0555,
.child = x25_table,
},
{ 0, },
}; };
static ctl_table x25_root_table[] = { static struct ctl_table x25_root_table[] = {
{CTL_NET, "net", NULL, 0, 0555, x25_dir_table}, {
{0} .ctl_name = CTL_NET,
.procname = "net",
.mode = 0555,
.child = x25_dir_table,
},
{ 0, },
}; };
void __init x25_register_sysctl(void) void __init x25_register_sysctl(void)
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#include <linux/if_arp.h> #include <linux/if_arp.h>
#include <net/x25.h> #include <net/x25.h>
static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *neigh) static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *nb)
{ {
struct sock *sk; struct sock *sk;
unsigned short frametype; unsigned short frametype;
...@@ -58,14 +58,14 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *neigh) ...@@ -58,14 +58,14 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *neigh)
* frame. * frame.
*/ */
if (lci == 0) { if (lci == 0) {
x25_link_control(skb, neigh, frametype); x25_link_control(skb, nb, frametype);
return 0; return 0;
} }
/* /*
* Find an existing socket. * Find an existing socket.
*/ */
if ((sk = x25_find_socket(lci, neigh)) != NULL) { if ((sk = x25_find_socket(lci, nb)) != NULL) {
int queued = 1; int queued = 1;
skb->h.raw = skb->data; skb->h.raw = skb->data;
...@@ -83,91 +83,87 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *neigh) ...@@ -83,91 +83,87 @@ static int x25_receive_data(struct sk_buff *skb, struct x25_neigh *neigh)
* Is is a Call Request ? if so process it. * Is is a Call Request ? if so process it.
*/ */
if (frametype == X25_CALL_REQUEST) if (frametype == X25_CALL_REQUEST)
return x25_rx_call_request(skb, neigh, lci); return x25_rx_call_request(skb, nb, lci);
/* /*
* Its not a Call Request, nor is it a control frame. * Its not a Call Request, nor is it a control frame.
* Let caller throw it away. * Let caller throw it away.
*/ */
/* /*
x25_transmit_clear_request(neigh, lci, 0x0D); x25_transmit_clear_request(nb, lci, 0x0D);
*/ */
printk(KERN_DEBUG "x25_receive_data(): unknown frame type %2x\n",frametype); printk(KERN_DEBUG "x25_receive_data(): unknown frame type %2x\n",frametype);
return 0; return 0;
} }
int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype) int x25_lapb_receive_frame(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype)
{ {
struct x25_neigh *neigh; struct x25_neigh *nb;
int queued;
skb->sk = NULL; skb->sk = NULL;
/* /*
* Packet received from unrecognised device, throw it away. * Packet received from unrecognised device, throw it away.
*/ */
if ((neigh = x25_get_neigh(dev)) == NULL) { nb = x25_get_neigh(dev);
if (!nb) {
printk(KERN_DEBUG "X.25: unknown neighbour - %s\n", dev->name); printk(KERN_DEBUG "X.25: unknown neighbour - %s\n", dev->name);
kfree_skb(skb); goto drop;
return 0;
} }
switch (skb->data[0]) { switch (skb->data[0]) {
case 0x00: case 0x00:
skb_pull(skb, 1); skb_pull(skb, 1);
queued = x25_receive_data(skb, neigh); if (x25_receive_data(skb, nb)) {
if( ! queued ) x25_neigh_put(nb);
/* We need to free the skb ourselves because goto out;
* net_bh() won't care about our return code. }
*/ break;
kfree_skb(skb);
return 0;
case 0x01: case 0x01:
x25_link_established(neigh); x25_link_established(nb);
kfree_skb(skb); break;
return 0;
case 0x02: case 0x02:
x25_link_terminated(neigh); x25_link_terminated(nb);
kfree_skb(skb); break;
return 0;
case 0x03:
kfree_skb(skb);
return 0;
default:
kfree_skb(skb);
return 0;
} }
x25_neigh_put(nb);
drop:
kfree_skb(skb);
out:
return 0;
} }
int x25_llc_receive_frame(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype) int x25_llc_receive_frame(struct sk_buff *skb, struct net_device *dev,
struct packet_type *ptype)
{ {
struct x25_neigh *neigh; struct x25_neigh *nb;
int rc = 0;
skb->sk = NULL; skb->sk = NULL;
/* /*
* Packet received from unrecognised device, throw it away. * Packet received from unrecognised device, throw it away.
*/ */
if ((neigh = x25_get_neigh(dev)) == NULL) { nb = x25_get_neigh(dev);
if (!nb) {
printk(KERN_DEBUG "X.25: unknown_neighbour - %s\n", dev->name); printk(KERN_DEBUG "X.25: unknown_neighbour - %s\n", dev->name);
kfree_skb(skb); kfree_skb(skb);
return 0; } else {
rc = x25_receive_data(skb, nb);
x25_neigh_put(nb);
} }
return x25_receive_data(skb, neigh); return rc;
} }
void x25_establish_link(struct x25_neigh *neigh) void x25_establish_link(struct x25_neigh *nb)
{ {
struct sk_buff *skb; struct sk_buff *skb;
unsigned char *ptr; unsigned char *ptr;
switch (neigh->dev->type) { switch (nb->dev->type) {
case ARPHRD_X25: case ARPHRD_X25:
if ((skb = alloc_skb(1, GFP_ATOMIC)) == NULL) { if ((skb = alloc_skb(1, GFP_ATOMIC)) == NULL) {
printk(KERN_ERR "x25_dev: out of memory\n"); printk(KERN_ERR "x25_dev: out of memory\n");
...@@ -186,47 +182,44 @@ void x25_establish_link(struct x25_neigh *neigh) ...@@ -186,47 +182,44 @@ void x25_establish_link(struct x25_neigh *neigh)
} }
skb->protocol = htons(ETH_P_X25); skb->protocol = htons(ETH_P_X25);
skb->dev = neigh->dev; skb->dev = nb->dev;
dev_queue_xmit(skb); dev_queue_xmit(skb);
} }
void x25_terminate_link(struct x25_neigh *neigh) void x25_terminate_link(struct x25_neigh *nb)
{ {
struct sk_buff *skb; struct sk_buff *skb;
unsigned char *ptr; unsigned char *ptr;
switch (neigh->dev->type) {
case ARPHRD_X25:
if ((skb = alloc_skb(1, GFP_ATOMIC)) == NULL) {
printk(KERN_ERR "x25_dev: out of memory\n");
return;
}
ptr = skb_put(skb, 1);
*ptr = 0x02;
break;
#if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE) #if defined(CONFIG_LLC) || defined(CONFIG_LLC_MODULE)
case ARPHRD_ETHER: if (nb->dev->type == ARPHRD_ETHER)
return; return;
#endif #endif
default: if (nb->dev->type != ARPHRD_X25)
return; return;
skb = alloc_skb(1, GFP_ATOMIC);
if (!skb) {
printk(KERN_ERR "x25_dev: out of memory\n");
return;
} }
skb->protocol = htons(ETH_P_X25); ptr = skb_put(skb, 1);
skb->dev = neigh->dev; *ptr = 0x02;
skb->protocol = htons(ETH_P_X25);
skb->dev = nb->dev;
dev_queue_xmit(skb); dev_queue_xmit(skb);
} }
void x25_send_frame(struct sk_buff *skb, struct x25_neigh *neigh) void x25_send_frame(struct sk_buff *skb, struct x25_neigh *nb)
{ {
unsigned char *dptr; unsigned char *dptr;
skb->nh.raw = skb->data; skb->nh.raw = skb->data;
switch (neigh->dev->type) { switch (nb->dev->type) {
case ARPHRD_X25: case ARPHRD_X25:
dptr = skb_push(skb, 1); dptr = skb_push(skb, 1);
*dptr = 0x00; *dptr = 0x00;
...@@ -243,7 +236,7 @@ void x25_send_frame(struct sk_buff *skb, struct x25_neigh *neigh) ...@@ -243,7 +236,7 @@ void x25_send_frame(struct sk_buff *skb, struct x25_neigh *neigh)
} }
skb->protocol = htons(ETH_P_X25); skb->protocol = htons(ETH_P_X25);
skb->dev = neigh->dev; skb->dev = nb->dev;
dev_queue_xmit(skb); dev_queue_xmit(skb);
} }
/* /*
* X.25 Packet Layer release 002 * X.25 Packet Layer release 002
* *
* This is ALPHA test software. This code may break your machine, randomly fail to work with new * This is ALPHA test software. This code may break your machine,
* releases, misbehave and/or generally screw up. It might even work. * randomly fail to work with new releases, misbehave and/or generally
* screw up. It might even work.
* *
* This code REQUIRES 2.1.15 or higher * This code REQUIRES 2.1.15 or higher
* *
...@@ -42,65 +43,71 @@ ...@@ -42,65 +43,71 @@
* Parse a set of facilities into the facilities structure. Unrecognised * Parse a set of facilities into the facilities structure. Unrecognised
* facilities are written to the debug log file. * facilities are written to the debug log file.
*/ */
int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, unsigned long *vc_fac_mask) int x25_parse_facilities(struct sk_buff *skb,
struct x25_facilities *facilities,
unsigned long *vc_fac_mask)
{ {
unsigned int len;
unsigned char *p = skb->data; unsigned char *p = skb->data;
unsigned int len = *p++;
len = *p++;
*vc_fac_mask = 0; *vc_fac_mask = 0;
while (len > 0) { while (len > 0) {
switch (*p & X25_FAC_CLASS_MASK) { switch (*p & X25_FAC_CLASS_MASK) {
case X25_FAC_CLASS_A: case X25_FAC_CLASS_A:
switch (*p) { switch (*p) {
case X25_FAC_REVERSE: case X25_FAC_REVERSE:
facilities->reverse = (p[1] & 0x01); facilities->reverse = p[1] & 0x01;
*vc_fac_mask |= X25_MASK_REVERSE; *vc_fac_mask |= X25_MASK_REVERSE;
break;
case X25_FAC_THROUGHPUT:
facilities->throughput = p[1];
*vc_fac_mask |= X25_MASK_THROUGHPUT;
break;
default:
printk(KERN_DEBUG "X.25: unknown facility %02X, value %02X\n", p[0], p[1]);
break;
}
p += 2;
len -= 2;
break; break;
case X25_FAC_THROUGHPUT:
case X25_FAC_CLASS_B: facilities->throughput = p[1];
switch (*p) { *vc_fac_mask |= X25_MASK_THROUGHPUT;
case X25_FAC_PACKET_SIZE:
facilities->pacsize_in = p[1];
facilities->pacsize_out = p[2];
*vc_fac_mask |= X25_MASK_PACKET_SIZE;
break;
case X25_FAC_WINDOW_SIZE:
facilities->winsize_in = p[1];
facilities->winsize_out = p[2];
*vc_fac_mask |= X25_MASK_WINDOW_SIZE;
break;
default:
printk(KERN_DEBUG "X.25: unknown facility %02X, values %02X, %02X\n", p[0], p[1], p[2]);
break;
}
p += 3;
len -= 3;
break; break;
default:
case X25_FAC_CLASS_C: printk(KERN_DEBUG "X.25: unknown facility "
printk(KERN_DEBUG "X.25: unknown facility %02X, values %02X, %02X, %02X\n", p[0], p[1], p[2], p[3]); "%02X, value %02X\n",
p += 4; p[0], p[1]);
len -= 4;
break; break;
}
case X25_FAC_CLASS_D: p += 2;
printk(KERN_DEBUG "X.25: unknown facility %02X, length %d, values %02X, %02X, %02X, %02X\n", p[0], p[1], p[2], p[3], p[4], p[5]); len -= 2;
p += p[1] + 2; break;
len -= p[1] + 2; case X25_FAC_CLASS_B:
switch (*p) {
case X25_FAC_PACKET_SIZE:
facilities->pacsize_in = p[1];
facilities->pacsize_out = p[2];
*vc_fac_mask |= X25_MASK_PACKET_SIZE;
break;
case X25_FAC_WINDOW_SIZE:
facilities->winsize_in = p[1];
facilities->winsize_out = p[2];
*vc_fac_mask |= X25_MASK_WINDOW_SIZE;
break; break;
default:
printk(KERN_DEBUG "X.25: unknown facility "
"%02X, values %02X, %02X\n",
p[0], p[1], p[2]);
break;
}
p += 3;
len -= 3;
break;
case X25_FAC_CLASS_C:
printk(KERN_DEBUG "X.25: unknown facility %02X, "
"values %02X, %02X, %02X\n",
p[0], p[1], p[2], p[3]);
p += 4;
len -= 4;
break;
case X25_FAC_CLASS_D:
printk(KERN_DEBUG "X.25: unknown facility %02X, "
"length %d, values %02X, %02X, %02X, %02X\n",
p[0], p[1], p[2], p[3], p[4], p[5]);
p += p[1] + 2;
len -= p[1] + 2;
break;
} }
} }
...@@ -110,37 +117,45 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, ...@@ -110,37 +117,45 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities,
/* /*
* Create a set of facilities. * Create a set of facilities.
*/ */
int x25_create_facilities(unsigned char *buffer, struct x25_facilities *facilities, unsigned long facil_mask) int x25_create_facilities(unsigned char *buffer,
struct x25_facilities *facilities,
unsigned long facil_mask)
{ {
unsigned char *p = buffer + 1; unsigned char *p = buffer + 1;
int len; int len;
if (facil_mask == 0) { if (!facil_mask) {
buffer [0] = 0; /* length of the facilities field in call_req or call_accept packets */ /*
* Length of the facilities field in call_req or
* call_accept packets
*/
buffer[0] = 0;
len = 1; /* 1 byte for the length field */ len = 1; /* 1 byte for the length field */
return len; return len;
} }
if ((facilities->reverse != 0) && (facil_mask & X25_MASK_REVERSE)) { if (facilities->reverse && (facil_mask & X25_MASK_REVERSE)) {
*p++ = X25_FAC_REVERSE; *p++ = X25_FAC_REVERSE;
*p++ = (facilities->reverse) ? 0x01 : 0x00; *p++ = !!facilities->reverse;
} }
if ((facilities->throughput != 0) && (facil_mask & X25_MASK_THROUGHPUT)) { if (facilities->throughput && (facil_mask & X25_MASK_THROUGHPUT)) {
*p++ = X25_FAC_THROUGHPUT; *p++ = X25_FAC_THROUGHPUT;
*p++ = facilities->throughput; *p++ = facilities->throughput;
} }
if ((facilities->pacsize_in != 0 || facilities->pacsize_out != 0) && (facil_mask & X25_MASK_PACKET_SIZE)) { if ((facilities->pacsize_in || facilities->pacsize_out) &&
(facil_mask & X25_MASK_PACKET_SIZE)) {
*p++ = X25_FAC_PACKET_SIZE; *p++ = X25_FAC_PACKET_SIZE;
*p++ = (facilities->pacsize_in == 0) ? facilities->pacsize_out : facilities->pacsize_in; *p++ = facilities->pacsize_in ? : facilities->pacsize_out;
*p++ = (facilities->pacsize_out == 0) ? facilities->pacsize_in : facilities->pacsize_out; *p++ = facilities->pacsize_out ? : facilities->pacsize_in;
} }
if ((facilities->winsize_in != 0 || facilities->winsize_out != 0) && (facil_mask & X25_MASK_WINDOW_SIZE)) { if ((facilities->winsize_in || facilities->winsize_out) &&
(facil_mask & X25_MASK_WINDOW_SIZE)) {
*p++ = X25_FAC_WINDOW_SIZE; *p++ = X25_FAC_WINDOW_SIZE;
*p++ = (facilities->winsize_in == 0) ? facilities->winsize_out : facilities->winsize_in; *p++ = facilities->winsize_in ? : facilities->winsize_out;
*p++ = (facilities->winsize_out == 0) ? facilities->winsize_in : facilities->winsize_out; *p++ = facilities->winsize_out ? : facilities->winsize_in;
} }
len = p - buffer; len = p - buffer;
...@@ -154,39 +169,37 @@ int x25_create_facilities(unsigned char *buffer, struct x25_facilities *faciliti ...@@ -154,39 +169,37 @@ int x25_create_facilities(unsigned char *buffer, struct x25_facilities *faciliti
* *
* The only real problem is with reverse charging. * The only real problem is with reverse charging.
*/ */
int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, struct x25_facilities *new) int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
struct x25_facilities *new)
{ {
x25_cb *x25 = x25_sk(sk); struct x25_opt *x25 = x25_sk(sk);
struct x25_facilities *ours; struct x25_facilities *ours = &x25->facilities;
struct x25_facilities theirs; struct x25_facilities theirs;
int len; int len;
memset(&theirs, 0x00, sizeof(struct x25_facilities)); memset(&theirs, 0, sizeof(theirs));
memcpy(new, ours, sizeof(*new));
ours = &x25->facilities;
*new = *ours;
len = x25_parse_facilities(skb, &theirs, &x25->vc_facil_mask); len = x25_parse_facilities(skb, &theirs, &x25->vc_facil_mask);
/* /*
* They want reverse charging, we won't accept it. * They want reverse charging, we won't accept it.
*/ */
if (theirs.reverse != 0 && ours->reverse == 0) { if (theirs.reverse && ours->reverse) {
SOCK_DEBUG(sk, "X.25: rejecting reverse charging request"); SOCK_DEBUG(sk, "X.25: rejecting reverse charging request");
return -1; return -1;
} }
new->reverse = theirs.reverse; new->reverse = theirs.reverse;
if (theirs.throughput != 0) { if (theirs.throughput) {
if (theirs.throughput < ours->throughput) { if (theirs.throughput < ours->throughput) {
SOCK_DEBUG(sk, "X.25: throughput negotiated down"); SOCK_DEBUG(sk, "X.25: throughput negotiated down");
new->throughput = theirs.throughput; new->throughput = theirs.throughput;
} }
} }
if (theirs.pacsize_in != 0 && theirs.pacsize_out != 0) { if (theirs.pacsize_in && theirs.pacsize_out) {
if (theirs.pacsize_in < ours->pacsize_in) { if (theirs.pacsize_in < ours->pacsize_in) {
SOCK_DEBUG(sk, "X.25: packet size inwards negotiated down"); SOCK_DEBUG(sk, "X.25: packet size inwards negotiated down");
new->pacsize_in = theirs.pacsize_in; new->pacsize_in = theirs.pacsize_in;
...@@ -197,7 +210,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, struct x25_fa ...@@ -197,7 +210,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, struct x25_fa
} }
} }
if (theirs.winsize_in != 0 && theirs.winsize_out != 0) { if (theirs.winsize_in && theirs.winsize_out) {
if (theirs.winsize_in < ours->winsize_in) { if (theirs.winsize_in < ours->winsize_in) {
SOCK_DEBUG(sk, "X.25: window size inwards negotiated down"); SOCK_DEBUG(sk, "X.25: window size inwards negotiated down");
new->winsize_in = theirs.winsize_in; new->winsize_in = theirs.winsize_in;
...@@ -216,15 +229,15 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, struct x25_fa ...@@ -216,15 +229,15 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk, struct x25_fa
* currently attached x25 link. * currently attached x25 link.
*/ */
void x25_limit_facilities(struct x25_facilities *facilities, void x25_limit_facilities(struct x25_facilities *facilities,
struct x25_neigh *neighbour) struct x25_neigh *nb)
{ {
if( ! neighbour->extended ){ if (!nb->extended) {
if( facilities->winsize_in > 7 ){ if (facilities->winsize_in > 7) {
printk(KERN_DEBUG "X.25: incoming winsize limited to 7\n"); printk(KERN_DEBUG "X.25: incoming winsize limited to 7\n");
facilities->winsize_in = 7; facilities->winsize_in = 7;
} }
if( facilities->winsize_out > 7 ){ if (facilities->winsize_out > 7) {
facilities->winsize_out = 7; facilities->winsize_out = 7;
printk( KERN_DEBUG "X.25: outgoing winsize limited to 7\n"); printk( KERN_DEBUG "X.25: outgoing winsize limited to 7\n");
} }
......
/* /*
* X.25 Packet Layer release 002 * X.25 Packet Layer release 002
* *
* This is ALPHA test software. This code may break your machine, randomly fail to work with new * This is ALPHA test software. This code may break your machine,
* releases, misbehave and/or generally screw up. It might even work. * randomly fail to work with new releases, misbehave and/or generally
* screw up. It might even work.
* *
* This code REQUIRES 2.1.15 or higher * This code REQUIRES 2.1.15 or higher
* *
...@@ -47,7 +48,7 @@ ...@@ -47,7 +48,7 @@
static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more) static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
{ {
struct sk_buff *skbo, *skbn = skb; struct sk_buff *skbo, *skbn = skb;
x25_cb *x25 = x25_sk(sk); struct x25_opt *x25 = x25_sk(sk);
if (more) { if (more) {
x25->fraglen += skb->len; x25->fraglen += skb->len;
...@@ -86,7 +87,7 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more) ...@@ -86,7 +87,7 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
skb_set_owner_r(skbn, sk); skb_set_owner_r(skbn, sk);
skb_queue_tail(&sk->receive_queue, skbn); skb_queue_tail(&sk->receive_queue, skbn);
if (!sk->dead) if (!sk->dead)
sk->data_ready(sk,skbn->len); sk->data_ready(sk, skbn->len);
return 0; return 0;
} }
...@@ -98,11 +99,11 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more) ...@@ -98,11 +99,11 @@ static int x25_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
*/ */
static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype) static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
{ {
x25_address source_addr, dest_addr; struct x25_address source_addr, dest_addr;
switch (frametype) { switch (frametype) {
case X25_CALL_ACCEPTED: { case X25_CALL_ACCEPTED: {
x25_cb *x25 = x25_sk(sk); struct x25_opt *x25 = x25_sk(sk);
x25_stop_timer(sk); x25_stop_timer(sk);
x25->condition = 0x00; x25->condition = 0x00;
...@@ -178,7 +179,7 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp ...@@ -178,7 +179,7 @@ static int x25_state3_machine(struct sock *sk, struct sk_buff *skb, int frametyp
{ {
int queued = 0; int queued = 0;
int modulus; int modulus;
x25_cb *x25 = x25_sk(sk); struct x25_opt *x25 = x25_sk(sk);
modulus = (x25->neighbour->extended) ? X25_EMODULUS : X25_SMODULUS; modulus = (x25->neighbour->extended) ? X25_EMODULUS : X25_SMODULUS;
...@@ -307,7 +308,7 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp ...@@ -307,7 +308,7 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp
case X25_RESET_REQUEST: case X25_RESET_REQUEST:
x25_write_internal(sk, X25_RESET_CONFIRMATION); x25_write_internal(sk, X25_RESET_CONFIRMATION);
case X25_RESET_CONFIRMATION: { case X25_RESET_CONFIRMATION: {
x25_cb *x25 = x25_sk(sk); struct x25_opt *x25 = x25_sk(sk);
x25_stop_timer(sk); x25_stop_timer(sk);
x25->condition = 0x00; x25->condition = 0x00;
...@@ -334,7 +335,7 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp ...@@ -334,7 +335,7 @@ static int x25_state4_machine(struct sock *sk, struct sk_buff *skb, int frametyp
/* Higher level upcall for a LAPB frame */ /* Higher level upcall for a LAPB frame */
int x25_process_rx_frame(struct sock *sk, struct sk_buff *skb) int x25_process_rx_frame(struct sock *sk, struct sk_buff *skb)
{ {
x25_cb *x25 = x25_sk(sk); struct x25_opt *x25 = x25_sk(sk);
int queued = 0, frametype, ns, nr, q, d, m; int queued = 0, frametype, ns, nr, q, d, m;
if (x25->state == X25_STATE_0) if (x25->state == X25_STATE_0)
...@@ -364,10 +365,10 @@ int x25_process_rx_frame(struct sock *sk, struct sk_buff *skb) ...@@ -364,10 +365,10 @@ int x25_process_rx_frame(struct sock *sk, struct sk_buff *skb)
int x25_backlog_rcv(struct sock *sk, struct sk_buff *skb) int x25_backlog_rcv(struct sock *sk, struct sk_buff *skb)
{ {
int queued; int queued = x25_process_rx_frame(sk, skb);
queued = x25_process_rx_frame(sk,skb); if (!queued)
if(!queued) kfree_skb(skb); kfree_skb(skb);
return 0; return 0;
} }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment