Commit b331768e authored by David S. Miller's avatar David S. Miller

Merge nuts.ninka.net:/home/davem/src/BK/ham-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents e65ca57c c2edf826
......@@ -240,8 +240,8 @@ L: linux-net@vger.kernel.org
S: Maintained
AX.25 NETWORK LAYER
P: Matthias Welwarsky
M: dg2fef@afthd.tu-darmstadt.de
P: Ralf Baechle
M: ralf@linux-mips.org
L: linux-hams@vger.kernel.org
S: Maintained
......@@ -1121,8 +1121,8 @@ L: netfilter-devel@lists.netfilter.org
S: Supported
NETROM NETWORK LAYER
P: Tomi Manninen
M: Tomi.Manninen@hut.fi
P: Ralf Baechle
M: ralf@linux-mips.org
L: linux-hams@vger.kernel.org
S: Maintained
......@@ -1371,8 +1371,8 @@ W: http://www.namesys.com
S: Supported
ROSE NETWORK LAYER
P: Jean-Paul Roubelat
M: jpr@f6fbb.org
P: Ralf Baechle
M: ralf@linux-mips.org
L: linux-hams@vger.kernel.org
S: Maintained
......
......@@ -3,11 +3,14 @@
*
* Alan Cox (GW4PTS) 10/11/93
*/
#ifndef _AX25_H
#define _AX25_H
#include <linux/config.h>
#include <linux/ax25.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <asm/atomic.h>
#define AX25_T1CLAMPLO 1
#define AX25_T1CLAMPHI (30 * HZ)
......@@ -66,6 +69,8 @@
#define AX25_UA 0x63 /* Unnumbered acknowledge */
#define AX25_FRMR 0x87 /* Frame reject */
#define AX25_UI 0x03 /* Unnumbered information */
#define AX25_XID 0xaf /* Exchange information */
#define AX25_TEST 0xe3 /* Test */
#define AX25_PF 0x10 /* Poll/final bit for standard AX.25 */
#define AX25_EPF 0x01 /* Poll/final bit for extended AX.25 */
......@@ -147,10 +152,12 @@ typedef struct {
typedef struct ax25_route {
struct ax25_route *next;
atomic_t ref;
ax25_address callsign;
struct net_device *dev;
ax25_digi *digipeat;
char ip_mode;
struct timer_list timer;
} ax25_route;
typedef struct {
......@@ -197,11 +204,12 @@ typedef struct ax25_cb {
#define ax25_sk(__sk) ((ax25_cb *)(__sk)->protinfo)
/* af_ax25.c */
extern ax25_cb *volatile ax25_list;
extern ax25_cb *ax25_list;
extern spinlock_t ax25_list_lock;
extern void ax25_free_cb(ax25_cb *);
extern void ax25_insert_socket(ax25_cb *);
struct sock *ax25_find_listener(ax25_address *, int, struct net_device *, int);
struct sock *ax25_find_socket(ax25_address *, ax25_address *, 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 sock *ax25_addr_match(ax25_address *);
extern void ax25_send_to_raw(struct sock *, struct sk_buff *, int);
......@@ -224,6 +232,7 @@ extern void ax25_digi_invert(ax25_digi *, ax25_digi *);
/* ax25_dev.c */
extern ax25_dev *ax25_dev_list;
extern spinlock_t ax25_dev_lock;
extern ax25_dev *ax25_dev_ax25dev(struct net_device *);
extern ax25_dev *ax25_addr_ax25dev(ax25_address *);
extern void ax25_dev_device_up(struct net_device *);
......@@ -286,10 +295,16 @@ extern void ax25_rt_device_down(struct net_device *);
extern int ax25_rt_ioctl(unsigned int, void *);
extern int ax25_rt_get_info(char *, char **, off_t, int);
extern int ax25_rt_autobind(ax25_cb *, ax25_address *);
extern ax25_route *ax25_rt_find_route(ax25_address *, struct net_device *);
extern ax25_route *ax25_rt_find_route(ax25_route *, ax25_address *,
struct net_device *);
extern struct sk_buff *ax25_rt_build_path(struct sk_buff *, ax25_address *, ax25_address *, ax25_digi *);
extern void ax25_rt_free(void);
static inline void ax25_put_route(ax25_route *ax25_rt)
{
atomic_dec(&ax25_rt->ref);
}
/* ax25_std_in.c */
extern int ax25_std_frame_in(ax25_cb *, struct sk_buff *, int);
......
Do the ax25_list_lock, ax25_dev_lock, linkfail_lockreally, ax25_frag_lock and
listen_lock have to be bh-safe?
Do the netrom and rose locks have to be bh-safe?
A device might be deleted after lookup in the SIOCADDRT ioctl but before it's
being used.
Routes to a device being taken down might be deleted by ax25_rt_device_down
but added by somebody else before the device has been deleted fully.
Massive amounts of lock_kernel / unlock_kernel are just a temporary solution to
get around the removal of SOCKOPS_WRAP. A serious locking strategy has to be
implemented.
The ax25_rt_find_route synopsys is pervert but I somehow had to deal with
the race caused by the static variable in it's previous implementation.
Implement proper socket locking in netrom and rose.
Check socket locking when ax25_rcv is sending to raw sockets. In particular
ax25_send_to_raw() seems fishy. Heck - ax25_rcv is fishy.
Handle XID and TEST frames properly.
This diff is collapsed.
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Most of this code is based on the SDL diagrams published in the 7th
* ARRL Computer Networking Conference papers. The diagrams have mistakes
* in them, but are mostly correct. Before you modify the code could you
* read the SDL diagrams as the code is not obvious and probably very
* easy to break;
*
* History
* AX.25 036 Jonathan(G4KLX) Split from ax25_subr.c.
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Other kernels modules in this kit are generally BSD derived. See the copyright headers.
*
*
* History
* AX.25 036 Jonathan(G4KLX) Split from ax25_route.c.
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
*/
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
......@@ -27,6 +17,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/spinlock.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
......@@ -41,27 +32,35 @@
#include <linux/init.h>
ax25_dev *ax25_dev_list;
spinlock_t ax25_dev_lock = SPIN_LOCK_UNLOCKED;
ax25_dev *ax25_dev_ax25dev(struct net_device *dev)
{
ax25_dev *ax25_dev;
ax25_dev *ax25_dev, *res = NULL;
spin_lock_bh(&ax25_dev_lock);
for (ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
if (ax25_dev->dev == dev)
return ax25_dev;
if (ax25_dev->dev == dev) {
res = ax25_dev;
break;
}
spin_unlock_bh(&ax25_dev_lock);
return NULL;
return res;
}
ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
{
ax25_dev *ax25_dev;
ax25_dev *ax25_dev, *res = NULL;
spin_lock_bh(&ax25_dev_lock);
for (ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
if (ax25cmp(addr, (ax25_address *)ax25_dev->dev->dev_addr) == 0)
return ax25_dev;
if (ax25cmp(addr, (ax25_address *)ax25_dev->dev->dev_addr) == 0) {
res = ax25_dev;
}
spin_unlock_bh(&ax25_dev_lock);
return NULL;
return res;
}
/*
......@@ -71,7 +70,6 @@ ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
void ax25_dev_device_up(struct net_device *dev)
{
ax25_dev *ax25_dev;
unsigned long flags;
if ((ax25_dev = kmalloc(sizeof(*ax25_dev), GFP_ATOMIC)) == NULL) {
printk(KERN_ERR "AX.25: ax25_dev_device_up - out of memory\n");
......@@ -100,10 +98,10 @@ void ax25_dev_device_up(struct net_device *dev)
ax25_dev->values[AX25_VALUES_PROTOCOL] = AX25_DEF_PROTOCOL;
ax25_dev->values[AX25_VALUES_DS_TIMEOUT]= AX25_DEF_DS_TIMEOUT;
save_flags(flags); cli();
spin_lock_bh(&ax25_dev_lock);
ax25_dev->next = ax25_dev_list;
ax25_dev_list = ax25_dev;
restore_flags(flags);
spin_unlock_bh(&ax25_dev_lock);
ax25_register_sysctl();
}
......@@ -111,14 +109,13 @@ void ax25_dev_device_up(struct net_device *dev)
void ax25_dev_device_down(struct net_device *dev)
{
ax25_dev *s, *ax25_dev;
unsigned long flags;
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
return;
ax25_unregister_sysctl();
save_flags(flags); cli();
spin_lock_bh(&ax25_dev_lock);
#ifdef CONFIG_AX25_DAMA_SLAVE
ax25_ds_del_timer(ax25_dev);
......@@ -133,7 +130,7 @@ void ax25_dev_device_down(struct net_device *dev)
if ((s = ax25_dev_list) == ax25_dev) {
ax25_dev_list = s->next;
restore_flags(flags);
spin_unlock_bh(&ax25_dev_lock);
kfree(ax25_dev);
ax25_register_sysctl();
return;
......@@ -142,7 +139,7 @@ void ax25_dev_device_down(struct net_device *dev)
while (s != NULL && s->next != NULL) {
if (s->next == ax25_dev) {
s->next = ax25_dev->next;
restore_flags(flags);
spin_unlock_bh(&ax25_dev_lock);
kfree(ax25_dev);
ax25_register_sysctl();
return;
......@@ -150,8 +147,8 @@ void ax25_dev_device_down(struct net_device *dev)
s = s->next;
}
spin_unlock_bh(&ax25_dev_lock);
restore_flags(flags);
ax25_register_sysctl();
}
......@@ -202,12 +199,16 @@ struct net_device *ax25_fwd_dev(struct net_device *dev)
*/
void __exit ax25_dev_free(void)
{
ax25_dev *s, *ax25_dev = ax25_dev_list;
ax25_dev *s, *ax25_dev;
spin_lock_bh(&ax25_dev_lock);
ax25_dev = ax25_dev_list;
while (ax25_dev != NULL) {
s = ax25_dev;
ax25_dev = ax25_dev->next;
kfree(s);
}
ax25_dev_list = NULL;
spin_unlock_bh(&ax25_dev_lock);
}
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Most of this code is based on the SDL diagrams published in the 7th
* ARRL Computer Networking Conference papers. The diagrams have mistakes
* in them, but are mostly correct. Before you modify the code could you
* read the SDL diagrams as the code is not obvious and probably very
* easy to break;
*
* History
* AX.25 036 Jonathan(G4KLX) Cloned from ax25_in.c
* Joerg(DL1BKE) Fixed it.
* AX.25 037 Jonathan(G4KLX) New timer architecture.
* Joerg(DL1BKE) ax25->n2count never got reset
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......@@ -95,11 +80,13 @@ static int ax25_ds_state1_machine(ax25_cb *ax25, struct sk_buff *skb, int framet
break;
case AX25_DM:
if (pf) ax25_disconnect(ax25, ECONNREFUSED);
if (pf)
ax25_disconnect(ax25, ECONNREFUSED);
break;
default:
if (pf) ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
if (pf)
ax25_send_control(ax25, AX25_SABM, AX25_POLLON, AX25_COMMAND);
break;
}
......
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Most of this code is based on the SDL diagrams published in the 7th
* ARRL Computer Networking Conference papers. The diagrams have mistakes
* in them, but are mostly correct. Before you modify the code could you
* read the SDL diagrams as the code is not obvious and probably very
* easy to break;
*
* History
* AX.25 036 Jonathan(G4KLX) Cloned from ax25_out.c and ax25_subr.c.
* Joerg(DL1BKE) Changed ax25_ds_enquiry_response(),
* fixed ax25_dama_on() and ax25_dama_off().
* AX.25 037 Jonathan(G4KLX) New timer architecture.
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......@@ -31,6 +16,7 @@
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/spinlock.h>
#include <linux/net.h>
#include <net/ax25.h>
#include <linux/inet.h>
......@@ -93,6 +79,7 @@ void ax25_ds_enquiry_response(ax25_cb *ax25)
ax25_start_t3timer(ax25);
ax25_ds_set_timer(ax25->ax25_dev);
spin_lock_bh(&ax25_list_lock);
for (ax25o = ax25_list; ax25o != NULL; ax25o = ax25o->next) {
if (ax25o == ax25)
continue;
......@@ -118,6 +105,7 @@ void ax25_ds_enquiry_response(ax25_cb *ax25)
if (ax25o->state != AX25_STATE_0)
ax25_start_t3timer(ax25o);
}
spin_unlock_bh(&ax25_list_lock);
}
void ax25_ds_establish_data_link(ax25_cb *ax25)
......@@ -171,12 +159,17 @@ static void ax25_kiss_cmd(ax25_dev *ax25_dev, unsigned char cmd, unsigned char p
static int ax25_check_dama_slave(ax25_dev *ax25_dev)
{
ax25_cb *ax25;
int res = 0;
spin_lock_bh(&ax25_list_lock);
for (ax25 = ax25_list; ax25 != NULL ; ax25 = ax25->next)
if (ax25->ax25_dev == ax25_dev && (ax25->condition & AX25_COND_DAMA_MODE) && ax25->state > AX25_STATE_1)
return 1;
if (ax25->ax25_dev == ax25_dev && (ax25->condition & AX25_COND_DAMA_MODE) && ax25->state > AX25_STATE_1) {
res = 1;
break;
}
spin_unlock_bh(&ax25_list_lock);
return 0;
return res;
}
void ax25_dev_dama_on(ax25_dev *ax25_dev)
......
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* AX.25 036 Jonathan(G4KLX) Cloned from ax25_timer.c.
* Joerg(DL1BKE) Added DAMA Slave Timeout timer
* AX.25 037 Jonathan(G4KLX) New timer architecture.
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/spinlock.h>
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/jiffies.h>
......@@ -58,7 +51,8 @@ static void ax25_ds_add_timer(ax25_dev *ax25_dev)
void ax25_ds_del_timer(ax25_dev *ax25_dev)
{
if (ax25_dev) del_timer(&ax25_dev->dama.slave_timer);
if (ax25_dev)
del_timer(&ax25_dev->dama.slave_timer);
}
void ax25_ds_set_timer(ax25_dev *ax25_dev)
......@@ -89,6 +83,7 @@ static void ax25_ds_timeout(unsigned long arg)
return;
}
spin_lock_bh(&ax25_list_lock);
for (ax25=ax25_list; ax25 != NULL; ax25 = ax25->next) {
if (ax25->ax25_dev != ax25_dev || !(ax25->condition & AX25_COND_DAMA_MODE))
continue;
......@@ -96,6 +91,7 @@ static void ax25_ds_timeout(unsigned long arg)
ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
ax25_disconnect(ax25, ETIMEDOUT);
}
spin_unlock_bh(&ax25_list_lock);
ax25_dev_dama_off(ax25_dev);
}
......@@ -178,7 +174,6 @@ void ax25_ds_idletimer_expiry(ax25_cb *ax25)
void ax25_ds_t1_timeout(ax25_cb *ax25)
{
switch (ax25->state) {
case AX25_STATE_1:
if (ax25->n2count == ax25->n2) {
if (ax25->modulus == AX25_MODULUS) {
......
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* AX.25 036 Jonathan(G4KLX) Split from ax25_timer.c.
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
*/
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
......@@ -20,6 +13,7 @@
#include <linux/in.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/sockios.h>
......@@ -40,22 +34,25 @@ static struct protocol_struct {
unsigned int pid;
int (*func)(struct sk_buff *, ax25_cb *);
} *protocol_list;
static rwlock_t protocol_list_lock = RW_LOCK_UNLOCKED;
static struct linkfail_struct {
struct linkfail_struct *next;
void (*func)(ax25_cb *, int);
} *linkfail_list;
static spinlock_t linkfail_lock = SPIN_LOCK_UNLOCKED;
static struct listen_struct {
struct listen_struct *next;
ax25_address callsign;
struct net_device *dev;
} *listen_list;
static spinlock_t listen_lock = SPIN_LOCK_UNLOCKED;
int ax25_protocol_register(unsigned int pid, int (*func)(struct sk_buff *, ax25_cb *))
int ax25_protocol_register(unsigned int pid,
int (*func)(struct sk_buff *, ax25_cb *))
{
struct protocol_struct *protocol;
unsigned long flags;
if (pid == AX25_P_TEXT || pid == AX25_P_SEGMENT)
return 0;
......@@ -69,31 +66,28 @@ int ax25_protocol_register(unsigned int pid, int (*func)(struct sk_buff *, ax25_
protocol->pid = pid;
protocol->func = func;
save_flags(flags);
cli();
write_lock(&protocol_list_lock);
protocol->next = protocol_list;
protocol_list = protocol;
restore_flags(flags);
write_unlock(&protocol_list_lock);
return 1;
}
void ax25_protocol_release(unsigned int pid)
{
struct protocol_struct *s, *protocol = protocol_list;
unsigned long flags;
struct protocol_struct *s, *protocol;
if (protocol == NULL)
write_lock(&protocol_list_lock);
protocol = protocol_list;
if (protocol == NULL) {
write_unlock(&protocol_list_lock);
return;
save_flags(flags);
cli();
}
if (protocol->pid == pid) {
protocol_list = protocol->next;
restore_flags(flags);
write_unlock(&protocol_list_lock);
kfree(protocol);
return;
}
......@@ -102,52 +96,45 @@ void ax25_protocol_release(unsigned int pid)
if (protocol->next->pid == pid) {
s = protocol->next;
protocol->next = protocol->next->next;
restore_flags(flags);
write_unlock(&protocol_list_lock);
kfree(s);
return;
}
protocol = protocol->next;
}
restore_flags(flags);
write_unlock(&protocol_list_lock);
}
int ax25_linkfail_register(void (*func)(ax25_cb *, int))
{
struct linkfail_struct *linkfail;
unsigned long flags;
if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL)
return 0;
linkfail->func = func;
save_flags(flags);
cli();
spin_lock_bh(&linkfail_lock);
linkfail->next = linkfail_list;
linkfail_list = linkfail;
restore_flags(flags);
spin_unlock_bh(&linkfail_lock);
return 1;
}
void ax25_linkfail_release(void (*func)(ax25_cb *, int))
{
struct linkfail_struct *s, *linkfail = linkfail_list;
unsigned long flags;
struct linkfail_struct *s, *linkfail;
spin_lock_bh(&linkfail_lock);
linkfail = linkfail_list;
if (linkfail == NULL)
return;
save_flags(flags);
cli();
if (linkfail->func == func) {
linkfail_list = linkfail->next;
restore_flags(flags);
spin_unlock_bh(&linkfail_lock);
kfree(linkfail);
return;
}
......@@ -156,21 +143,19 @@ void ax25_linkfail_release(void (*func)(ax25_cb *, int))
if (linkfail->next->func == func) {
s = linkfail->next;
linkfail->next = linkfail->next->next;
restore_flags(flags);
spin_unlock_bh(&linkfail_lock);
kfree(s);
return;
}
linkfail = linkfail->next;
}
restore_flags(flags);
spin_unlock_bh(&linkfail_lock);
}
int ax25_listen_register(ax25_address *callsign, struct net_device *dev)
{
struct listen_struct *listen;
unsigned long flags;
if (ax25_listen_mine(callsign, dev))
return 0;
......@@ -181,31 +166,26 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev)
listen->callsign = *callsign;
listen->dev = dev;
save_flags(flags);
cli();
spin_lock_bh(&listen_lock);
listen->next = listen_list;
listen_list = listen;
restore_flags(flags);
spin_unlock_bh(&listen_lock);
return 1;
}
void ax25_listen_release(ax25_address *callsign, struct net_device *dev)
{
struct listen_struct *s, *listen = listen_list;
unsigned long flags;
struct listen_struct *s, *listen;
spin_lock_bh(&listen_lock);
listen = listen_list;
if (listen == NULL)
return;
save_flags(flags);
cli();
if (ax25cmp(&listen->callsign, callsign) == 0 && listen->dev == dev) {
listen_list = listen->next;
restore_flags(flags);
spin_unlock_bh(&listen_lock);
kfree(listen);
return;
}
......@@ -214,35 +194,41 @@ void ax25_listen_release(ax25_address *callsign, struct net_device *dev)
if (ax25cmp(&listen->next->callsign, callsign) == 0 && listen->next->dev == dev) {
s = listen->next;
listen->next = listen->next->next;
restore_flags(flags);
spin_unlock_bh(&listen_lock);
kfree(s);
return;
}
listen = listen->next;
}
restore_flags(flags);
spin_unlock_bh(&listen_lock);
}
int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
{
int (*res)(struct sk_buff *, ax25_cb *) = NULL;
struct protocol_struct *protocol;
read_lock(&protocol_list_lock);
for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
if (protocol->pid == pid)
return protocol->func;
if (protocol->pid == pid) {
res = protocol->func;
break;
}
read_unlock(&protocol_list_lock);
return NULL;
return res;
}
int ax25_listen_mine(ax25_address *callsign, struct net_device *dev)
{
struct listen_struct *listen;
spin_lock_bh(&listen_lock);
for (listen = listen_list; listen != NULL; listen = listen->next)
if (ax25cmp(&listen->callsign, callsign) == 0 && (listen->dev == dev || listen->dev == NULL))
return 1;
spin_unlock_bh(&listen_lock);
return 0;
}
......@@ -251,18 +237,24 @@ void ax25_link_failed(ax25_cb *ax25, int reason)
{
struct linkfail_struct *linkfail;
spin_lock_bh(&linkfail_lock);
for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next)
(linkfail->func)(ax25, reason);
spin_unlock_bh(&linkfail_lock);
}
int ax25_protocol_is_registered(unsigned int pid)
{
struct protocol_struct *protocol;
int res = 0;
read_lock(&protocol_list_lock);
for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
if (protocol->pid == pid)
return 1;
if (protocol->pid == pid) {
res = 1;
break;
}
read_unlock(&protocol_list_lock);
return 0;
return res;
}
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Most of this code is based on the SDL diagrams published in the 7th
* ARRL Computer Networking Conference papers. The diagrams have mistakes
* in them, but are mostly correct. Before you modify the code could you
* read the SDL diagrams as the code is not obvious and probably very
* easy to break;
*
* History
* AX.25 028a Jonathan(G4KLX) New state machine based on SDL diagrams.
* AX.25 028b Jonathan(G4KLX) Extracted AX25 control block from
* the sock structure.
* AX.25 029 Alan(GW4PTS) Switched to KA9Q constant names.
* Jonathan(G4KLX) Added IP mode registration.
* AX.25 030 Jonathan(G4KLX) Added AX.25 fragment reception.
* Upgraded state machine for SABME.
* Added arbitrary protocol id support.
* AX.25 031 Joerg(DL1BKE) Added DAMA support
* HaJo(DD8NE) Added Idle Disc Timer T5
* Joerg(DL1BKE) Renamed it to "IDLE" with a slightly
* different behaviour. Fixed defrag
* routine (I hope)
* AX.25 032 Darryl(G7LED) AX.25 segmentation fixed.
* AX.25 033 Jonathan(G4KLX) Remove auto-router.
* Modularisation changes.
* AX.25 035 Hans(PE1AYX) Fixed interface to IP layer.
* AX.25 036 Jonathan(G4KLX) Move DAMA code into own file.
* Joerg(DL1BKE) Fixed DAMA Slave.
* AX.25 037 Jonathan(G4KLX) New timer architecture.
* Thomas(DL9SAU) Fixed missing initialization of skb->protocol.
* Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
* Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
*/
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
......@@ -217,19 +187,15 @@ static int ax25_process_rx_frame(ax25_cb *ax25, struct sk_buff *skb, int type, i
return queued;
}
static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, ax25_address *dev_addr, struct packet_type *ptype)
static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
ax25_address *dev_addr, struct packet_type *ptype)
{
struct sock *make;
struct sock *sk;
int type = 0;
ax25_address src, dest, *next_digi = NULL;
int type = 0, mine = 0, dama;
struct sock *make, *sk, *raw;
ax25_digi dp, reverse_dp;
ax25_cb *ax25;
ax25_address src, dest;
ax25_address *next_digi = NULL;
ax25_dev *ax25_dev;
struct sock *raw;
int mine = 0;
int dama;
/*
* Process the AX.25/LAPB frame.
......@@ -274,8 +240,10 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, ax25_address *d
if ((*skb->data & ~0x10) == AX25_UI && dp.lastrepeat + 1 == dp.ndigi) {
skb->h.raw = skb->data + 2; /* skip control and pid */
if ((raw = ax25_addr_match(&dest)) != NULL)
if ((raw = ax25_addr_match(&dest)) != NULL) {
ax25_send_to_raw(raw, skb, skb->data[1]);
release_sock(raw);
}
if (!mine && ax25cmp(&dest, (ax25_address *)dev->broadcast) != 0) {
kfree_skb(skb);
......@@ -307,7 +275,8 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, ax25_address *d
#endif
case AX25_P_TEXT:
/* Now find a suitable dgram socket */
if ((sk = ax25_find_socket(&dest, &src, SOCK_DGRAM)) != NULL) {
sk = ax25_get_socket(&dest, &src, SOCK_DGRAM);
if (sk != NULL) {
if (atomic_read(&sk->rmem_alloc) >= sk->rcvbuf) {
kfree_skb(skb);
} else {
......@@ -318,6 +287,7 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, ax25_address *d
if (sock_queue_rcv_skb(sk, skb) != 0)
kfree_skb(skb);
}
release_sock(sk);
} else {
kfree_skb(skb);
}
......@@ -349,9 +319,10 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, ax25_address *d
if ((ax25 = ax25_find_cb(&dest, &src, &reverse_dp, dev)) != NULL) {
/*
* Process the frame. If it is queued up internally it returns one otherwise we
* free it immediately. This routine itself wakes the user context layers so we
* do no further work
* Process the frame. If it is queued up internally it
* returns one otherwise we free it immediately. This
* routine itself wakes the user context layers so we do
* no further work
*/
if (ax25_process_rx_frame(ax25, skb, type, dama) == 0)
kfree_skb(skb);
......@@ -363,7 +334,8 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, ax25_address *d
/* a) received not a SABM(E) */
if ((*skb->data & ~AX25_PF) != AX25_SABM && (*skb->data & ~AX25_PF) != AX25_SABME) {
if ((*skb->data & ~AX25_PF) != AX25_SABM &&
(*skb->data & ~AX25_PF) != AX25_SABME) {
/*
* Never reply to a DM. Also ignore any connects for
* addresses that are not our interfaces and not a socket.
......@@ -383,9 +355,12 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev, ax25_address *d
sk = ax25_find_listener(next_digi, 1, dev, SOCK_SEQPACKET);
if (sk != NULL) {
if (sk->ack_backlog == sk->max_ack_backlog || (make = ax25_make_new(sk, ax25_dev)) == NULL) {
if (mine) ax25_return_dm(dev, &src, &dest, &dp);
if (sk->ack_backlog == sk->max_ack_backlog ||
(make = ax25_make_new(sk, ax25_dev)) == NULL) {
if (mine)
ax25_return_dm(dev, &src, &dest, &dp);
kfree_skb(skb);
return 0;
}
......@@ -486,4 +461,3 @@ int ax25_kiss_rcv(struct sk_buff *skb, struct net_device *dev,
return ax25_rcv(skb, dev, (ax25_address *)dev->dev_addr, ptype);
}
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* AX.25 036 Jonathan(G4KLX) Split from af_ax25.c.
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
*/
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
......@@ -112,8 +105,8 @@ int ax25_rebuild_header(struct sk_buff *skb)
unsigned char *bp = skb->data;
struct net_device *dev;
ax25_address *src, *dst;
ax25_route *route;
ax25_dev *ax25_dev;
ax25_route _route, *route = &_route;
dst = (ax25_address *)(bp + 1);
src = (ax25_address *)(bp + 8);
......@@ -121,14 +114,15 @@ int ax25_rebuild_header(struct sk_buff *skb)
if (arp_find(bp + 1, skb))
return 1;
route = ax25_rt_find_route(dst, NULL);
route = ax25_rt_find_route(route, dst, NULL);
dev = route->dev;
if (dev == NULL)
dev = skb->dev;
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
return 1;
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL) {
goto put;
}
if (bp[16] == AX25_P_IP) {
if (route->ip_mode == 'V' || (route->ip_mode == ' ' && ax25_dev->values[AX25_VALUES_IPDEFMODE])) {
......@@ -153,7 +147,7 @@ int ax25_rebuild_header(struct sk_buff *skb)
if ((ourskb = skb_copy(skb, GFP_ATOMIC)) == NULL) {
kfree_skb(skb);
return 1;
goto put;
}
if (skb->sk != NULL)
......@@ -170,7 +164,7 @@ int ax25_rebuild_header(struct sk_buff *skb)
ax25_send_frame(ourskb, ax25_dev->values[AX25_VALUES_PACLEN], &src_c,
&dst_c, route->digipeat, dev);
return 1;
goto put;
}
}
......@@ -187,7 +181,7 @@ int ax25_rebuild_header(struct sk_buff *skb)
if (route->digipeat != NULL) {
if ((ourskb = ax25_rt_build_path(skb, src, dst, route->digipeat)) == NULL) {
kfree_skb(skb);
return 1;
goto put;
}
skb = ourskb;
......@@ -197,6 +191,9 @@ int ax25_rebuild_header(struct sk_buff *skb)
ax25_queue_xmit(skb);
put:
ax25_put_route(route);
return 1;
}
......
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Most of this code is based on the SDL diagrams published in the 7th
* ARRL Computer Networking Conference papers. The diagrams have mistakes
* in them, but are mostly correct. Before you modify the code could you
* read the SDL diagrams as the code is not obvious and probably very
* easy to break;
*
* History
* AX.25 028a Jonathan(G4KLX) New state machine based on SDL diagrams.
* AX.25 029 Alan(GW4PTS) Switched to KA9Q constant names.
* Jonathan(G4KLX) Only poll when window is full.
* AX.25 030 Jonathan(G4KLX) Added fragmentation to ax25_output.
* Added support for extended AX.25.
* AX.25 031 Joerg(DL1BKE) Added DAMA support
* Joerg(DL1BKE) Modified fragmenter to fragment vanilla
* AX.25 I-Frames. Added PACLEN parameter.
* Joerg(DL1BKE) Fixed a problem with buffer allocation
* for fragments.
* AX.25 037 Jonathan(G4KLX) New timer architecture.
* Joerg(DL1BKE) Fixed DAMA Slave mode: will work
* on non-DAMA interfaces like AX25L2V2
* again (this behaviour is _required_).
* Joerg(DL1BKE) ax25_check_iframes_acked() returns a
* value now (for DAMA n2count handling)
* Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
*/
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
......@@ -44,6 +18,7 @@
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/spinlock.h>
#include <linux/net.h>
#include <net/ax25.h>
#include <linux/inet.h>
......@@ -57,6 +32,8 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
static spinlock_t ax25_frag_lock = SPIN_LOCK_UNLOCKED;
ax25_cb *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;
......@@ -138,7 +115,6 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
struct sk_buff *skbn;
unsigned char *p;
int frontlen, len, fragno, ka9qfrag, first = 1;
long flags;
if ((skb->len - 1) > paclen) {
if (*skb->data == AX25_P_TEXT) {
......@@ -155,11 +131,9 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
frontlen = skb_headroom(skb); /* Address space + CTRL */
while (skb->len > 0) {
save_flags(flags);
cli();
spin_lock_bh(&ax25_frag_lock);
if ((skbn = alloc_skb(paclen + 2 + frontlen, GFP_ATOMIC)) == NULL) {
restore_flags(flags);
spin_unlock_bh(&ax25_frag_lock);
printk(KERN_CRIT "AX.25: ax25_output - out of memory\n");
return;
}
......@@ -167,7 +141,7 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
if (skb->sk != NULL)
skb_set_owner_w(skbn, skb->sk);
restore_flags(flags);
spin_unlock_bh(&ax25_frag_lock);
len = (paclen > skb->len) ? skb->len : paclen;
......
This diff is collapsed.
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
* Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
* Copyright (C) Hans-Joachim Hetscher DD8NE (dd8ne@bnv-bamberg.de)
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Most of this code is based on the SDL diagrams published in the 7th
* ARRL Computer Networking Conference papers. The diagrams have mistakes
* in them, but are mostly correct. Before you modify the code could you
* read the SDL diagrams as the code is not obvious and probably very
* easy to break;
*
* History
* AX.25 028a Jonathan(G4KLX) New state machine based on SDL diagrams.
* AX.25 028b Jonathan(G4KLX) Extracted AX25 control block from
* the sock structure.
* AX.25 029 Alan(GW4PTS) Switched to KA9Q constant names.
* Jonathan(G4KLX) Added IP mode registration.
* AX.25 030 Jonathan(G4KLX) Added AX.25 fragment reception.
* Upgraded state machine for SABME.
* Added arbitrary protocol id support.
* AX.25 031 Joerg(DL1BKE) Added DAMA support
* HaJo(DD8NE) Added Idle Disc Timer T5
* Joerg(DL1BKE) Renamed it to "IDLE" with a slightly
* different behaviour. Fixed defrag
* routine (I hope)
* AX.25 032 Darryl(G7LED) AX.25 segmentation fixed.
* AX.25 033 Jonathan(G4KLX) Remove auto-router.
* Modularisation changes.
* AX.25 035 Hans(PE1AYX) Fixed interface to IP layer.
* AX.25 036 Jonathan(G4KLX) Cloned from ax25_in.c.
* AX.25 037 Jonathan(G4KLX) New timer architecture.
* Most of this code is based on the SDL diagrams published in the 7th ARRL
* Computer Networking Conference papers. The diagrams have mistakes in them,
* but are mostly correct. Before you modify the code could you read the SDL
* diagrams as the code is not obvious and probably very easy to break.
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......@@ -142,7 +119,8 @@ static int ax25_std_state2_machine(ax25_cb *ax25, struct sk_buff *skb, int frame
case AX25_DM:
case AX25_UA:
if (pf) ax25_disconnect(ax25, 0);
if (pf)
ax25_disconnect(ax25, 0);
break;
case AX25_I:
......@@ -397,7 +375,8 @@ static int ax25_std_state4_machine(ax25_cb *ax25, struct sk_buff *skb, int frame
}
ax25_frames_acked(ax25, nr);
if (ax25->condition & AX25_COND_OWN_RX_BUSY) {
if (pf) ax25_std_enquiry_response(ax25);
if (pf)
ax25_std_enquiry_response(ax25);
break;
}
if (ns == ax25->vr) {
......
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Most of this code is based on the SDL diagrams published in the 7th
* ARRL Computer Networking Conference papers. The diagrams have mistakes
* in them, but are mostly correct. Before you modify the code could you
* read the SDL diagrams as the code is not obvious and probably very
* easy to break;
*
* History
* AX.25 036 Jonathan(G4KLX) Split from ax25_out.c.
* AX.25 037 Jonathan(G4KLX) New timer architecture.
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* AX.25 028a Jonathan(G4KLX) New state machine based on SDL diagrams.
* AX.25 028b Jonathan(G4KLX) Extracted AX25 control block from the
* sock structure.
* AX.25 029 Alan(GW4PTS) Switched to KA9Q constant names.
* AX.25 031 Joerg(DL1BKE) Added DAMA support
* AX.25 032 Joerg(DL1BKE) Fixed DAMA timeout bug
* AX.25 033 Jonathan(G4KLX) Modularisation functions.
* AX.25 035 Frederic(F1OAT) Support for pseudo-digipeating.
* AX.25 036 Jonathan(G4KLX) Split from ax25_timer.c.
* AX.25 037 Jonathan(G4KLX) New timer architecture.
* Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
* Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......@@ -47,7 +34,6 @@
void ax25_std_heartbeat_expiry(ax25_cb *ax25)
{
switch (ax25->state) {
case AX25_STATE_0:
/* Magic here: If we listen() and a new link dies before it
is accepted() it isn't 'dead' so doesn't get removed. */
......
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Most of this code is based on the SDL diagrams published in the 7th
* ARRL Computer Networking Conference papers. The diagrams have mistakes
* in them, but are mostly correct. Before you modify the code could you
* read the SDL diagrams as the code is not obvious and probably very
* easy to break;
*
* History
* AX.25 029 Alan(GW4PTS) Switched to KA9Q constant names. Removed
* old BSD code.
* AX.25 030 Jonathan(G4KLX) Added support for extended AX.25.
* Added fragmentation support.
* Darryl(G7LED) Added function ax25_requeue_frames() to split
* it up from ax25_frames_acked().
* AX.25 031 Joerg(DL1BKE) DAMA needs KISS Fullduplex ON/OFF.
* Thus we have ax25_kiss_cmd() now... ;-)
* Dave Brown(N2RJT)
* Killed a silly bug in the DAMA code.
* Joerg(DL1BKE) Found the real bug in ax25.h, sri.
* AX.25 032 Joerg(DL1BKE) Added ax25_queue_length to count the number of
* enqueued buffers of a socket..
* AX.25 035 Frederic(F1OAT) Support for pseudo-digipeating.
* AX.25 037 Jonathan(G4KLX) New timer architecture.
* Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
* Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* AX.25 028a Jonathan(G4KLX) New state machine based on SDL diagrams.
* AX.25 028b Jonathan(G4KLX) Extracted AX25 control block from the
* sock structure.
* AX.25 029 Alan(GW4PTS) Switched to KA9Q constant names.
* AX.25 031 Joerg(DL1BKE) Added DAMA support
* AX.25 032 Joerg(DL1BKE) Fixed DAMA timeout bug
* AX.25 033 Jonathan(G4KLX) Modularisation functions.
* AX.25 035 Frederic(F1OAT) Support for pseudo-digipeating.
* AX.25 036 Jonathan(G4KLX) Split Standard and DAMA code into separate files.
* Joerg(DL1BKE) Fixed DAMA Slave. We are *required* to start with
* standard AX.25 mode.
* AX.25 037 Jonathan(G4KLX) New timer architecture.
* Tomi(OH2BNS) Fixed heartbeat expiry (check ax25_dev).
* Copyright (C) Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright (C) Tomi Manninen OH2BNS (oh2bns@sral.fi)
* Copyright (C) Darryl Miles G7LED (dlm@g7led.demon.co.uk)
* Copyright (C) Joerg Reuter DL1BKE (jreuter@yaina.de)
* Copyright (C) Frederic Rible F1OAT (frible@teaser.fr)
* Copyright (C) 2002 Ralf Baechle DO1GRB (ralf@gnu.org)
*/
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
......@@ -152,12 +139,15 @@ unsigned long ax25_display_timer(struct timer_list *timer)
static void ax25_heartbeat_expiry(unsigned long param)
{
ax25_cb *ax25 = (ax25_cb *)param;
int proto = AX25_PROTO_STD_SIMPLEX;
ax25_cb *ax25 = (ax25_cb *)param;
struct sock *sk = ax25->sk;
if (ax25->ax25_dev)
proto = ax25->ax25_dev->values[AX25_VALUES_PROTOCOL];
bh_lock_sock(sk);
switch (proto) {
case AX25_PROTO_STD_SIMPLEX:
case AX25_PROTO_STD_DUPLEX:
......@@ -173,12 +163,15 @@ static void ax25_heartbeat_expiry(unsigned long param)
break;
#endif
}
bh_unlock_sock(sk);
}
static void ax25_t1timer_expiry(unsigned long param)
{
ax25_cb *ax25 = (ax25_cb *)param;
struct sock *sk = ax25->sk;
bh_lock_sock(sk);
switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
case AX25_PROTO_STD_SIMPLEX:
case AX25_PROTO_STD_DUPLEX:
......@@ -192,12 +185,15 @@ static void ax25_t1timer_expiry(unsigned long param)
break;
#endif
}
bh_unlock_sock(sk);
}
static void ax25_t2timer_expiry(unsigned long param)
{
ax25_cb *ax25 = (ax25_cb *)param;
struct sock *sk = ax25->sk;
bh_lock_sock(sk);
switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
case AX25_PROTO_STD_SIMPLEX:
case AX25_PROTO_STD_DUPLEX:
......@@ -211,12 +207,15 @@ static void ax25_t2timer_expiry(unsigned long param)
break;
#endif
}
bh_unlock_sock(sk);
}
static void ax25_t3timer_expiry(unsigned long param)
{
ax25_cb *ax25 = (ax25_cb *)param;
struct sock *sk = ax25->sk;
bh_lock_sock(sk);
switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
case AX25_PROTO_STD_SIMPLEX:
case AX25_PROTO_STD_DUPLEX:
......@@ -232,12 +231,15 @@ static void ax25_t3timer_expiry(unsigned long param)
break;
#endif
}
bh_unlock_sock(sk);
}
static void ax25_idletimer_expiry(unsigned long param)
{
ax25_cb *ax25 = (ax25_cb *)param;
struct sock *sk = ax25->sk;
bh_lock_sock(sk);
switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
case AX25_PROTO_STD_SIMPLEX:
case AX25_PROTO_STD_DUPLEX:
......@@ -253,4 +255,5 @@ static void ax25_idletimer_expiry(unsigned long param)
break;
#endif
}
bh_unlock_sock(sk);
}
/*
* AX.25 release 037
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* AX.25 036 Jonathan(G4KLX) Split from af_ax25.c.
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......@@ -23,6 +16,7 @@
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/spinlock.h>
#include <net/ax25.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
......@@ -47,17 +41,23 @@
*/
static ax25_uid_assoc *ax25_uid_list;
static rwlock_t ax25_uid_lock = RW_LOCK_UNLOCKED;
int ax25_uid_policy = 0;
ax25_address *ax25_findbyuid(uid_t uid)
{
ax25_uid_assoc *ax25_uid;
ax25_address *res = NULL;
read_lock(&ax25_uid_lock);
for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) {
if (ax25_uid->uid == uid)
return &ax25_uid->call;
if (ax25_uid->uid == uid) {
res = &ax25_uid->call;
break;
}
}
read_unlock(&ax25_uid_lock);
return NULL;
}
......@@ -65,15 +65,21 @@ ax25_address *ax25_findbyuid(uid_t uid)
int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
{
ax25_uid_assoc *s, *ax25_uid;
unsigned long flags;
unsigned long res;
switch (cmd) {
case SIOCAX25GETUID:
res = -ENOENT;
read_lock(&ax25_uid_lock);
for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) {
if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0)
return ax25_uid->uid;
if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) {
res = ax25_uid->uid;
break;
}
return -ENOENT;
}
read_unlock(&ax25_uid_lock);
return res;
case SIOCAX25ADDUID:
if (!capable(CAP_NET_ADMIN))
......@@ -84,40 +90,48 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax)
return -EINVAL;
if ((ax25_uid = kmalloc(sizeof(*ax25_uid), GFP_KERNEL)) == NULL)
return -ENOMEM;
ax25_uid->uid = sax->sax25_uid;
ax25_uid->call = sax->sax25_call;
save_flags(flags); cli();
write_lock(&ax25_uid_lock);
ax25_uid->next = ax25_uid_list;
ax25_uid_list = ax25_uid;
restore_flags(flags);
write_unlock(&ax25_uid_lock);
return 0;
case SIOCAX25DELUID:
if (!capable(CAP_NET_ADMIN))
return -EPERM;
write_lock(&ax25_uid_lock);
for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) {
if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0)
if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) {
break;
}
if (ax25_uid == NULL)
}
if (ax25_uid == NULL) {
write_unlock(&ax25_uid_lock);
return -ENOENT;
save_flags(flags); cli();
}
if ((s = ax25_uid_list) == ax25_uid) {
ax25_uid_list = s->next;
restore_flags(flags);
write_unlock(&ax25_uid_lock);
kfree(ax25_uid);
return 0;
}
while (s != NULL && s->next != NULL) {
if (s->next == ax25_uid) {
s->next = ax25_uid->next;
restore_flags(flags);
write_unlock(&ax25_uid_lock);
kfree(ax25_uid);
return 0;
}
s = s->next;
}
restore_flags(flags);
write_unlock(&ax25_uid_lock);
return -ENOENT;
default:
......@@ -134,8 +148,7 @@ int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length)
off_t pos = 0;
off_t begin = 0;
cli();
read_lock(&ax25_uid_lock);
len += sprintf(buffer, "Policy: %d\n", ax25_uid_policy);
for (pt = ax25_uid_list; pt != NULL; pt = pt->next) {
......@@ -151,13 +164,13 @@ int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length)
if (pos > offset + length)
break;
}
sti();
read_unlock(&ax25_uid_lock);
*start = buffer + (offset - begin);
len -= offset - begin;
if (len > length) len = length;
if (len > length)
len = length;
return len;
}
......@@ -167,12 +180,16 @@ int ax25_uid_get_info(char *buffer, char **start, off_t offset, int length)
*/
void __exit ax25_uid_free(void)
{
ax25_uid_assoc *s, *ax25_uid = ax25_uid_list;
ax25_uid_assoc *s, *ax25_uid;
write_lock(&ax25_uid_lock);
ax25_uid = ax25_uid_list;
while (ax25_uid != NULL) {
s = ax25_uid;
ax25_uid = ax25_uid->next;
kfree(s);
}
ax25_uid_list = NULL;
write_unlock(&ax25_uid_lock);
}
/* -*- linux-c -*-
* sysctl_net_ax25.c: sysctl interface to net AX.25 subsystem.
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Begun April 1, 1996, Mike Shaver.
* Added /proc/sys/net/ax25 directory entry (empty =) ). [MS]
* Copyright (C) 1996 Mike Shaver (shaver@zeroknowledge.com)
*/
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/sysctl.h>
#include <linux/spinlock.h>
#include <net/ax25.h>
static int min_ipdefmode[] = {0}, max_ipdefmode[] = {1};
......@@ -105,6 +107,7 @@ void ax25_register_sysctl(void)
ax25_dev *ax25_dev;
int n, k;
spin_lock_bh(&ax25_dev_lock);
for (ax25_table_size = sizeof(ctl_table), ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
ax25_table_size += sizeof(ctl_table);
......@@ -119,6 +122,7 @@ void ax25_register_sysctl(void)
while (n--)
kfree(ax25_table[n].child);
kfree(ax25_table);
spin_unlock_bh(&ax25_dev_lock);
return;
}
memcpy(child, ax25_param_table, sizeof(ax25_param_table));
......@@ -144,6 +148,7 @@ void ax25_register_sysctl(void)
n++;
}
spin_unlock_bh(&ax25_dev_lock);
ax25_dir_table[0].child = ax25_table;
......
This diff is collapsed.
/*
* NET/ROM release 007
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* NET/ROM 001 Jonathan(G4KLX) Cloned from loopback.c
* NET/ROM 002 Steve Whitehouse(GW7RRM) fixed the set_mac_address
* NET/ROM 003 Jonathan(G4KLX) Put nr_rebuild_header into line with
* ax25_rebuild_header
* NET/ROM 004 Jonathan(G4KLX) Callsign registration with AX.25.
* NET/ROM 006 Hans(PE1AYX) Fixed interface to IP layer.
* Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
*/
#include <linux/config.h>
#define __NO_VERSION__
#include <linux/module.h>
......
/*
* NET/ROM release 007
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Most of this code is based on the SDL diagrams published in the 7th
* ARRL Computer Networking Conference papers. The diagrams have mistakes
* in them, but are mostly correct. Before you modify the code could you
* read the SDL diagrams as the code is not obvious and probably very
* easy to break;
*
* History
* NET/ROM 001 Jonathan(G4KLX) Cloned from ax25_in.c
* NET/ROM 003 Jonathan(G4KLX) Added NET/ROM fragment reception.
* Darryl(G7LED) Added missing INFO with NAK case, optimized
* INFOACK handling, removed reconnect on error.
* NET/ROM 006 Jonathan(G4KLX) Hdrincl removal changes.
* NET/ROM 007 Jonathan(G4KLX) New timer architecture.
* Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright Darryl Miles G7LED (dlm@g7led.demon.co.uk)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......@@ -88,10 +71,10 @@ static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
* The handling of the timer(s) is in file nr_timer.c.
* Handling of state 0 and connection release is in netrom.c.
*/
static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype)
static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
int frametype)
{
switch (frametype) {
case NR_CONNACK: {
nr_cb *nr = nr_sk(sk);
......@@ -128,10 +111,10 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb, int frametype
* The handling of the timer(s) is in file nr_timer.c
* Handling of state 0 and connection release is in netrom.c.
*/
static int nr_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype)
static int nr_state2_machine(struct sock *sk, struct sk_buff *skb,
int frametype)
{
switch (frametype) {
case NR_CONNACK | NR_CHOKE_FLAG:
nr_disconnect(sk, ECONNRESET);
break;
......@@ -168,7 +151,6 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
ns = skb->data[17];
switch (frametype) {
case NR_CONNREQ:
nr_write_internal(sk, NR_CONNACK);
break;
......
/*
* NET/ROM release 007
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* NET/ROM 007 Tomi(OH2BNS) Created this file.
* Small change in nr_loopback_queue().
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Copyright Tomi Manninen OH2BNS (oh2bns@sral.fi)
*/
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/timer.h>
......
/*
* NET/ROM release 007
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* NET/ROM 001 Jonathan(G4KLX) Cloned from ax25_out.c
* NET/ROM 003 Jonathan(G4KLX) Added NET/ROM fragmentation.
* Darryl(G7LED) Fixed NAK, to give out correct reponse.
* NET/ROM 007 Jonathan(G4KLX) New timer architecture.
* Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright Darryl Miles G7LED (dlm@g7led.demon.co.uk)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......
/*
* NET/ROM release 007
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* NET/ROM 001 Jonathan(G4KLX) First attempt.
* NET/ROM 003 Jonathan(G4KLX) Use SIOCADDRT/SIOCDELRT ioctl values
* for NET/ROM routes.
* Use '*' for a blank mnemonic in /proc/net/nr_nodes.
* Change default quality for new neighbour when same
* as node callsign.
* Alan Cox(GW4PTS) Added the firewall hooks.
* NET/ROM 006 Jonathan(G4KLX) Added the setting of digipeated neighbours.
* Tomi(OH2BNS) Routing quality and link failure changes.
* Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright Alan Cox GW4PTS (alan@lxorguk.ukuu.org.uk)
* Copyright Tomi Manninen OH2BNS (oh2bns@sral.fi)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......@@ -47,12 +34,15 @@
#include <linux/notifier.h>
#include <linux/netfilter.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <net/netrom.h>
static unsigned int nr_neigh_no = 1;
static struct nr_node *nr_node_list;
static spinlock_t nr_node_lock;
static struct nr_neigh *nr_neigh_list;
static spinlock_t nr_neigh_lock;
static void nr_remove_neigh(struct nr_neigh *);
......@@ -66,7 +56,6 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
struct nr_node *nr_node;
struct nr_neigh *nr_neigh;
struct nr_route nr_route;
unsigned long flags;
int i, found;
if (nr_dev_get(nr) != NULL) /* Can't add routes to ourself */
......@@ -124,13 +113,10 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
memcpy(nr_neigh->digipeat, ax25_digi, sizeof(ax25_digi));
}
save_flags(flags);
cli();
spin_lock_bh(&nr_neigh_lock);
nr_neigh->next = nr_neigh_list;
nr_neigh_list = nr_neigh;
restore_flags(flags);
spin_unlock_bh(&nr_neigh_lock);
}
if (quality != 0 && ax25cmp(nr, ax25) == 0 && !nr_neigh->locked)
......@@ -150,13 +136,10 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
nr_node->routes[0].obs_count = obs_count;
nr_node->routes[0].neighbour = nr_neigh;
save_flags(flags);
cli();
spin_lock_bh(&nr_node_lock);
nr_node->next = nr_node_list;
nr_node_list = nr_node;
restore_flags(flags);
spin_unlock_bh(&nr_node_lock);
nr_neigh->count++;
......@@ -220,9 +203,14 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
}
if (nr_node->routes[2].quality > nr_node->routes[1].quality) {
switch (nr_node->which) {
case 1: nr_node->which = 2; break;
case 2: nr_node->which = 1; break;
default: break;
case 1: nr_node->which = 2;
break;
case 2: nr_node->which = 1;
break;
default:
break;
}
nr_route = nr_node->routes[1];
nr_node->routes[1] = nr_node->routes[2];
......@@ -231,8 +219,12 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
case 2:
if (nr_node->routes[1].quality > nr_node->routes[0].quality) {
switch (nr_node->which) {
case 0: nr_node->which = 1; break;
case 1: nr_node->which = 0; break;
case 0: nr_node->which = 1;
break;
case 1: nr_node->which = 0;
break;
default: break;
}
nr_route = nr_node->routes[0];
......@@ -257,14 +249,11 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
static void nr_remove_node(struct nr_node *nr_node)
{
struct nr_node *s;
unsigned long flags;
save_flags(flags);
cli();
spin_lock_bh(&nr_node_lock);
if ((s = nr_node_list) == nr_node) {
nr_node_list = nr_node->next;
restore_flags(flags);
spin_unlock_bh(&nr_node_lock);
kfree(nr_node);
return;
}
......@@ -272,7 +261,7 @@ static void nr_remove_node(struct nr_node *nr_node)
while (s != NULL && s->next != NULL) {
if (s->next == nr_node) {
s->next = nr_node->next;
restore_flags(flags);
spin_unlock_bh(&nr_node_lock);
kfree(nr_node);
return;
}
......@@ -280,20 +269,17 @@ static void nr_remove_node(struct nr_node *nr_node)
s = s->next;
}
restore_flags(flags);
spin_unlock_bh(&nr_node_lock);
}
static void nr_remove_neigh(struct nr_neigh *nr_neigh)
{
struct nr_neigh *s;
unsigned long flags;
save_flags(flags);
cli();
spin_lock_bh(&nr_neigh_lock);
if ((s = nr_neigh_list) == nr_neigh) {
nr_neigh_list = nr_neigh->next;
restore_flags(flags);
spin_unlock_bh(&nr_neigh_lock);
if (nr_neigh->digipeat != NULL)
kfree(nr_neigh->digipeat);
kfree(nr_neigh);
......@@ -303,7 +289,7 @@ static void nr_remove_neigh(struct nr_neigh *nr_neigh)
while (s != NULL && s->next != NULL) {
if (s->next == nr_neigh) {
s->next = nr_neigh->next;
restore_flags(flags);
spin_unlock_bh(&nr_neigh_lock);
if (nr_neigh->digipeat != NULL)
kfree(nr_neigh->digipeat);
kfree(nr_neigh);
......@@ -312,8 +298,7 @@ static void nr_remove_neigh(struct nr_neigh *nr_neigh)
s = s->next;
}
restore_flags(flags);
spin_unlock_bh(&nr_neigh_lock);
}
/*
......@@ -330,13 +315,15 @@ static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct n
if (ax25cmp(callsign, &nr_node->callsign) == 0)
break;
if (nr_node == NULL) return -EINVAL;
if (nr_node == NULL)
return -EINVAL;
for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next)
if (ax25cmp(neighbour, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev)
break;
if (nr_neigh == NULL) return -EINVAL;
if (nr_neigh == NULL)
return -EINVAL;
for (i = 0; i < nr_node->count; i++) {
if (nr_node->routes[i].neighbour == nr_neigh) {
......@@ -373,7 +360,6 @@ static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct n
static int nr_add_neigh(ax25_address *callsign, ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
{
struct nr_neigh *nr_neigh;
unsigned long flags;
for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next) {
if (ax25cmp(callsign, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev) {
......@@ -404,13 +390,10 @@ static int nr_add_neigh(ax25_address *callsign, ax25_digi *ax25_digi, struct net
memcpy(nr_neigh->digipeat, ax25_digi, sizeof(ax25_digi));
}
save_flags(flags);
cli();
spin_lock_bh(&nr_neigh_lock);
nr_neigh->next = nr_neigh_list;
nr_neigh_list = nr_neigh;
restore_flags(flags);
spin_unlock_bh(&nr_neigh_lock);
return 0;
}
......@@ -457,7 +440,6 @@ static int nr_dec_obs(void)
for (i = 0; i < s->count; i++) {
switch (s->routes[i].obs_count) {
case 0: /* A locked entry */
break;
......@@ -622,7 +604,6 @@ int nr_rt_ioctl(unsigned int cmd, void *arg)
struct net_device *dev;
switch (cmd) {
case SIOCADDRT:
if (copy_from_user(&nr_route, arg, sizeof(struct nr_route_struct)))
return -EFAULT;
......@@ -758,8 +739,7 @@ int nr_nodes_get_info(char *buffer, char **start, off_t offset, int length)
off_t begin = 0;
int i;
cli();
spin_lock_bh(&nr_node_lock);
len += sprintf(buffer, "callsign mnemonic w n qual obs neigh qual obs neigh qual obs neigh\n");
for (nr_node = nr_node_list; nr_node != NULL; nr_node = nr_node->next) {
......@@ -788,8 +768,7 @@ int nr_nodes_get_info(char *buffer, char **start, off_t offset, int length)
if (pos > offset + length)
break;
}
sti();
spin_unlock_bh(&nr_node_lock);
*start = buffer + (offset - begin);
len -= (offset - begin);
......@@ -807,8 +786,7 @@ int nr_neigh_get_info(char *buffer, char **start, off_t offset, int length)
off_t begin = 0;
int i;
cli();
spin_lock_bh(&nr_neigh_lock);
len += sprintf(buffer, "addr callsign dev qual lock count failed digipeaters\n");
for (nr_neigh = nr_neigh_list; nr_neigh != NULL; nr_neigh = nr_neigh->next) {
......@@ -839,7 +817,7 @@ int nr_neigh_get_info(char *buffer, char **start, off_t offset, int length)
break;
}
sti();
spin_unlock_bh(&nr_neigh_lock);
*start = buffer + (offset - begin);
len -= (offset - begin);
......
/*
* NET/ROM release 007
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* NET/ROM 001 Jonathan(G4KLX) Cloned from ax25_subr.c
* NET/ROM 003 Jonathan(G4KLX) Added G8BPQ NET/ROM extensions.
* NET/ROM 007 Jonathan(G4KLX) New timer architecture.
* Copyright Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......@@ -165,7 +156,6 @@ void nr_write_internal(struct sock *sk, int frametype)
dptr = skb_put(skb, skb_tailroom(skb));
switch (frametype & 0x0F) {
case NR_CONNREQ:
timeout = nr->t1 / HZ;
*dptr++ = nr->my_index;
......
/*
* NET/ROM release 007
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This code REQUIRES 2.1.15 or higher/ NET3.038
*
* This module:
* This module is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* History
* NET/ROM 001 Jonathan(G4KLX) Cloned from ax25_timer.c
* NET/ROM 007 Jonathan(G4KLX) New timer architecture.
* Implemented idle timer.
* Copyright (C) Jonathan Naylor G4KLX (g4klx@g4klx.demon.co.uk)
* Copyright (C) 2002 Ralf Baechle DO1GRB (ralf@gnu.org)
*/
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
......@@ -144,8 +136,8 @@ static void nr_heartbeat_expiry(unsigned long param)
struct sock *sk = (struct sock *)param;
nr_cb *nr = nr_sk(sk);
bh_lock_sock(sk);
switch (nr->state) {
case NR_STATE_0:
/* Magic here: If we listen() and a new link dies before it
is accepted() it isn't 'dead' so doesn't get removed. */
......@@ -171,6 +163,7 @@ static void nr_heartbeat_expiry(unsigned long param)
}
nr_start_heartbeat(sk);
bh_unlock_sock(sk);
}
static void nr_t2timer_expiry(unsigned long param)
......@@ -178,17 +171,21 @@ static void nr_t2timer_expiry(unsigned long param)
struct sock *sk = (struct sock *)param;
nr_cb *nr = nr_sk(sk);
bh_lock_sock(sk);
if (nr->condition & NR_COND_ACK_PENDING) {
nr->condition &= ~NR_COND_ACK_PENDING;
nr_enquiry_response(sk);
}
bh_unlock_sock(sk);
}
static void nr_t4timer_expiry(unsigned long param)
{
struct sock *sk = (struct sock *)param;
bh_lock_sock(sk);
nr_sk(sk)->condition &= ~NR_COND_PEER_RX_BUSY;
bh_unlock_sock(sk);
}
static void nr_idletimer_expiry(unsigned long param)
......@@ -196,6 +193,8 @@ static void nr_idletimer_expiry(unsigned long param)
struct sock *sk = (struct sock *)param;
nr_cb *nr = nr_sk(sk);
bh_lock_sock(sk);
nr_clear_queues(sk);
nr->n2count = 0;
......@@ -214,6 +213,7 @@ static void nr_idletimer_expiry(unsigned long param)
sk->state_change(sk);
sk->dead = 1;
bh_unlock_sock(sk);
}
static void nr_t1timer_expiry(unsigned long param)
......@@ -221,8 +221,8 @@ static void nr_t1timer_expiry(unsigned long param)
struct sock *sk = (struct sock *)param;
nr_cb *nr = nr_sk(sk);
bh_lock_sock(sk);
switch (nr->state) {
case NR_STATE_1:
if (nr->n2count == nr->n2) {
nr_disconnect(sk, ETIMEDOUT);
......@@ -255,4 +255,5 @@ static void nr_t1timer_expiry(unsigned long param)
}
nr_start_t1timer(sk);
bh_unlock_sock(sk);
}
/* -*- linux-c -*-
* sysctl_net_netrom.c: sysctl interface to net NET/ROM subsystem.
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Begun April 1, 1996, Mike Shaver.
* Added /proc/sys/net/netrom directory entry (empty =) ). [MS]
* Copyright (C) 1996 Mike Shaver (shaver@zeroknowledge.com)
*/
#include <linux/mm.h>
#include <linux/sysctl.h>
#include <linux/init.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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