patch-2.1.22 linux/net/netrom/af_netrom.c
Next file: linux/net/netrom/nr_dev.c
Previous file: linux/net/netbeui/netbeui.c
Back to the patch index
Back to the overall index
- Lines: 712
- Date:
Sun Jan 19 15:47:29 1997
- Orig file:
v2.1.21/linux/net/netrom/af_netrom.c
- Orig date:
Thu Jan 2 15:55:28 1997
diff -u --recursive --new-file v2.1.21/linux/net/netrom/af_netrom.c linux/net/netrom/af_netrom.c
@@ -31,7 +31,7 @@
* Alan(GW4PTS) Started POSIXisms
* NET/ROM 006 Alan(GW4PTS) Brought in line with the ANK changes
*/
-
+
#include <linux/config.h>
#if defined(CONFIG_NETROM) || defined(CONFIG_NETROM_MODULE)
#include <linux/module.h>
@@ -75,7 +75,8 @@
int sysctl_netrom_transport_requested_window_size = NR_DEFAULT_WINDOW;
int sysctl_netrom_transport_no_activity_timeout = NR_DEFAULT_IDLE;
int sysctl_netrom_transport_packet_length = NR_DEFAULT_PACLEN;
-int sysctl_netrom_routing_control = 1;
+int sysctl_netrom_routing_control = NR_DEFAULT_ROUTING;
+int sysctl_netrom_link_fails_count = NR_DEFAULT_FAILS;
static unsigned short circuit = 0x101;
@@ -88,7 +89,7 @@
kfree_s(sk->protinfo.nr, sizeof(*sk->protinfo.nr));
sk_free(sk);
-
+
MOD_DEC_USE_COUNT;
}
@@ -118,11 +119,12 @@
/*
* Socket removal during an interrupt is now safe.
*/
+
static void nr_remove_socket(struct sock *sk)
{
struct sock *s;
unsigned long flags;
-
+
save_flags(flags);
cli();
@@ -151,7 +153,7 @@
static void nr_kill_by_device(struct device *dev)
{
struct sock *s;
-
+
for (s = nr_list; s != NULL; s = s->next) {
if (s->protinfo.nr->device == dev) {
s->protinfo.nr->state = NR_STATE_0;
@@ -174,7 +176,7 @@
if (event != NETDEV_DOWN)
return NOTIFY_DONE;
-
+
nr_kill_by_device(dev);
nr_rt_device_down(dev);
@@ -269,7 +271,7 @@
/*
* Deferred destroy.
*/
-void nr_destroy_socket(struct sock * sk);
+void nr_destroy_socket(struct sock *);
/*
* Handler for deferred kills.
@@ -289,15 +291,15 @@
{
struct sk_buff *skb;
unsigned long flags;
-
+
save_flags(flags);
cli();
-
+
del_timer(&sk->timer);
-
+
nr_remove_socket(sk);
nr_clear_queues(sk); /* Flush the queues */
-
+
while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
if (skb->sk != sk) { /* A pending connection */
skb->sk->dead = 1; /* Queue the unaccepted socket for death */
@@ -307,8 +309,8 @@
kfree_skb(skb, FREE_READ);
}
-
- if (sk->wmem_alloc || sk->rmem_alloc) { /* Defer: outstanding buffers */
+
+ if (sk->wmem_alloc || sk->rmem_alloc) { /* Defer: outstanding buffers */
init_timer(&sk->timer);
sk->timer.expires = jiffies + 10 * HZ;
sk->timer.function = nr_destroy_timer;
@@ -325,11 +327,6 @@
* Handling for system calls applied via the various interfaces to a
* NET/ROM socket object.
*/
-
-static int nr_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
- return -EINVAL;
-}
/*
* dl1bke 960311: set parameters for existing NET/ROM connections,
@@ -342,12 +339,12 @@
struct sock *sk;
unsigned long flags;
int err;
-
+
if ((err = verify_area(VERIFY_READ, arg, sizeof(nr_ctl))) != 0)
return err;
copy_from_user(&nr_ctl, arg, sizeof(nr_ctl));
-
+
if ((sk = nr_find_socket(nr_ctl.index, nr_ctl.id)) == NULL)
return -ENOTCONN;
@@ -368,8 +365,8 @@
case NETROM_T1:
if (nr_ctl.arg < 1)
return -EINVAL;
- sk->protinfo.nr->rtt = (nr_ctl.arg * PR_SLOWHZ) / 2;
- sk->protinfo.nr->t1 = nr_ctl.arg * PR_SLOWHZ;
+ sk->protinfo.nr->rtt = (nr_ctl.arg * NR_SLOWHZ) / 2;
+ sk->protinfo.nr->t1 = nr_ctl.arg * NR_SLOWHZ;
save_flags(flags); cli();
if (sk->protinfo.nr->t1timer > sk->protinfo.nr->t1)
sk->protinfo.nr->t1timer = sk->protinfo.nr->t1;
@@ -380,7 +377,7 @@
if (nr_ctl.arg < 1)
return -EINVAL;
save_flags(flags); cli();
- sk->protinfo.nr->t2 = nr_ctl.arg * PR_SLOWHZ;
+ sk->protinfo.nr->t2 = nr_ctl.arg * NR_SLOWHZ;
if (sk->protinfo.nr->t2timer > sk->protinfo.nr->t2)
sk->protinfo.nr->t2timer = sk->protinfo.nr->t2;
restore_flags(flags);
@@ -397,7 +394,7 @@
if (nr_ctl.arg < 1)
return -EINVAL;
save_flags(flags); cli();
- sk->protinfo.nr->t4 = nr_ctl.arg * PR_SLOWHZ;
+ sk->protinfo.nr->t4 = nr_ctl.arg * NR_SLOWHZ;
if (sk->protinfo.nr->t4timer > sk->protinfo.nr->t4)
sk->protinfo.nr->t4timer = sk->protinfo.nr->t4;
restore_flags(flags);
@@ -407,7 +404,7 @@
if (nr_ctl.arg < 1)
return -EINVAL;
save_flags(flags); cli();
- sk->protinfo.nr->idle = nr_ctl.arg * 60 * PR_SLOWHZ;
+ sk->protinfo.nr->idle = nr_ctl.arg * 60 * NR_SLOWHZ;
if (sk->protinfo.nr->idletimer > sk->protinfo.nr->idle)
sk->protinfo.nr->idletimer = sk->protinfo.nr->idle;
restore_flags(flags);
@@ -431,11 +428,9 @@
static int nr_setsockopt(struct socket *sock, int level, int optname,
char *optval, int optlen)
{
- struct sock *sk;
+ struct sock *sk = sock->sk;
int err, opt;
- sk = sock->sk;
-
if (level != SOL_NETROM)
return -EOPNOTSUPP;
@@ -446,38 +441,38 @@
return err;
get_user(opt, (int *)optval);
-
+
switch (optname) {
case NETROM_T1:
if (opt < 1)
return -EINVAL;
- sk->protinfo.nr->rtt = (opt * PR_SLOWHZ) / 2;
+ sk->protinfo.nr->rtt = (opt * NR_SLOWHZ) / 2;
return 0;
case NETROM_T2:
if (opt < 1)
return -EINVAL;
- sk->protinfo.nr->t2 = opt * PR_SLOWHZ;
+ sk->protinfo.nr->t2 = opt * NR_SLOWHZ;
return 0;
-
+
case NETROM_N2:
if (opt < 1 || opt > 31)
return -EINVAL;
sk->protinfo.nr->n2 = opt;
return 0;
-
+
case NETROM_T4:
if (opt < 1)
return -EINVAL;
- sk->protinfo.nr->t4 = opt * PR_SLOWHZ;
+ sk->protinfo.nr->t4 = opt * NR_SLOWHZ;
return 0;
-
+
case NETROM_IDLE:
if (opt < 1)
return -EINVAL;
- sk->protinfo.nr->idle = opt * 60 * PR_SLOWHZ;
+ sk->protinfo.nr->idle = opt * 60 * NR_SLOWHZ;
return 0;
-
+
case NETROM_HDRINCL:
sk->protinfo.nr->hdrincl = opt ? 1 : 0;
return 0;
@@ -487,7 +482,7 @@
return -EINVAL;
sk->protinfo.nr->paclen = opt;
return 0;
-
+
default:
return -ENOPROTOOPT;
}
@@ -496,36 +491,34 @@
static int nr_getsockopt(struct socket *sock, int level, int optname,
char *optval, int *optlen)
{
- struct sock *sk;
+ struct sock *sk = sock->sk;
int val = 0;
int err;
- sk = sock->sk;
-
if (level != SOL_NETROM)
return -EOPNOTSUPP;
-
+
switch (optname) {
case NETROM_T1:
- val = (sk->protinfo.nr->t1 * 2) / PR_SLOWHZ;
+ val = (sk->protinfo.nr->t1 * 2) / NR_SLOWHZ;
break;
-
+
case NETROM_T2:
- val = sk->protinfo.nr->t2 / PR_SLOWHZ;
+ val = sk->protinfo.nr->t2 / NR_SLOWHZ;
break;
-
+
case NETROM_N2:
val = sk->protinfo.nr->n2;
break;
-
+
case NETROM_T4:
- val = sk->protinfo.nr->t4 / PR_SLOWHZ;
+ val = sk->protinfo.nr->t4 / NR_SLOWHZ;
break;
-
+
case NETROM_IDLE:
- val = sk->protinfo.nr->idle / (PR_SLOWHZ * 60);
+ val = sk->protinfo.nr->idle / (NR_SLOWHZ * 60);
break;
-
+
case NETROM_HDRINCL:
val = sk->protinfo.nr->hdrincl;
break;
@@ -565,30 +558,6 @@
return -EOPNOTSUPP;
}
-static void def_callback1(struct sock *sk)
-{
- if (!sk->dead)
- wake_up_interruptible(sk->sleep);
-}
-
-static void def_callback2(struct sock *sk, int len)
-{
- if (!sk->dead)
- {
- sock_wake_async(sk->socket,1);
- wake_up_interruptible(sk->sleep);
- }
-}
-
-static void def_callback3(struct sock *sk, int len)
-{
- if (!sk->dead)
- {
- sock_wake_async(sk->socket,2);
- wake_up_interruptible(sk->sleep);
- }
-}
-
static int nr_create(struct socket *sock, int protocol)
{
struct sock *sk;
@@ -602,34 +571,14 @@
nr = sk->protinfo.nr;
- skb_queue_head_init(&sk->receive_queue);
- skb_queue_head_init(&sk->write_queue);
- skb_queue_head_init(&sk->back_log);
+ sock_init_data(sock,sk);
init_timer(&sk->timer);
-
+
sock->ops = &nr_proto_ops;
- sk->socket = sock;
- sk->type = sock->type;
sk->protocol = protocol;
- sk->allocation = GFP_KERNEL;
- sk->rcvbuf = SK_RMEM_MAX;
- sk->sndbuf = SK_WMEM_MAX;
- sk->state = TCP_CLOSE;
- sk->priority = SOPRI_NORMAL;
sk->mtu = NETROM_MTU; /* 236 */
- sk->zapped = 1;
-
- sk->state_change = def_callback1;
- sk->data_ready = def_callback2;
- sk->write_space = def_callback3;
- sk->error_report = def_callback1;
-
- if (sock != NULL) {
- sock->sk = sk;
- sk->sleep = &sock->wait;
- }
skb_queue_head_init(&nr->ack_queue);
skb_queue_head_init(&nr->reseq_queue);
@@ -663,9 +612,7 @@
nr = sk->protinfo.nr;
- skb_queue_head_init(&sk->receive_queue);
- skb_queue_head_init(&sk->write_queue);
- skb_queue_head_init(&sk->back_log);
+ sock_init_data(NULL,sk);
init_timer(&sk->timer);
@@ -681,11 +628,6 @@
sk->sleep = osk->sleep;
sk->zapped = osk->zapped;
- sk->state_change = def_callback1;
- sk->data_ready = def_callback2;
- sk->write_space = def_callback3;
- sk->error_report = def_callback1;
-
skb_queue_head_init(&nr->ack_queue);
skb_queue_head_init(&nr->reseq_queue);
skb_queue_head_init(&nr->frag_queue);
@@ -710,6 +652,9 @@
{
struct sock *sk = oldsock->sk;
+ if (sk == NULL || newsock == NULL)
+ return -EINVAL;
+
return nr_create(newsock, sk->protocol);
}
@@ -775,19 +720,20 @@
static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
{
- struct sock *sk;
+ struct sock *sk = sock->sk;
struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr;
struct device *dev;
ax25_address *user, *source;
-
- sk = sock->sk;
if (sk->zapped == 0)
return -EINVAL;
-
+
if (addr_len != sizeof(struct sockaddr_ax25) && addr_len != sizeof(struct full_sockaddr_ax25))
return -EINVAL;
+ if (addr->fsa_ax25.sax25_family != AF_NETROM)
+ return -EINVAL;
+
if ((dev = nr_dev_get(&addr->fsa_ax25.sax25_call)) == NULL) {
if (sk->debug)
printk("NET/ROM: bind failed: invalid node callsign\n");
@@ -833,26 +779,29 @@
struct sockaddr_ax25 *addr = (struct sockaddr_ax25 *)uaddr;
ax25_address *user, *source = NULL;
struct device *dev;
-
+
if (sk->state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
sock->state = SS_CONNECTED;
return 0; /* Connect completed during a ERESTARTSYS event */
}
-
+
if (sk->state == TCP_CLOSE && sock->state == SS_CONNECTING) {
sock->state = SS_UNCONNECTED;
return -ECONNREFUSED;
}
-
+
if (sk->state == TCP_ESTABLISHED)
return -EISCONN; /* No reconnect on a seqpacket socket */
-
+
sk->state = TCP_CLOSE;
sock->state = SS_UNCONNECTED;
if (addr_len != sizeof(struct sockaddr_ax25) && addr_len != sizeof(struct full_sockaddr_ax25))
return -EINVAL;
+ if (addr->sax25_family != AF_NETROM)
+ return -EINVAL;
+
if (sk->zapped) { /* Must bind first - autobinding in this may or may not work */
sk->zapped = 0;
@@ -883,14 +832,14 @@
sk->protinfo.nr->my_id = circuit % 256;
circuit++;
-
+
/* Move to connecting socket, start sending Connect Requests */
sock->state = SS_CONNECTING;
sk->state = TCP_SYN_SENT;
nr_establish_data_link(sk);
sk->protinfo.nr->state = NR_STATE_1;
nr_set_timer(sk);
-
+
/* Now the loop */
if (sk->state != TCP_ESTABLISHED && (flags & O_NONBLOCK))
return -EINPROGRESS;
@@ -913,14 +862,14 @@
sock->state = SS_UNCONNECTED;
return sock_error(sk); /* Always set at this point */
}
-
+
sock->state = SS_CONNECTED;
sti();
-
+
return 0;
}
-
+
static int nr_socketpair(struct socket *sock1, struct socket *sock2)
{
return -EOPNOTSUPP;
@@ -932,19 +881,20 @@
struct sock *newsk;
struct sk_buff *skb;
- if (newsock->sk)
- sk_free(newsock->sk);
+ if (newsock->sk != NULL)
+ nr_destroy_socket(newsock->sk);
newsock->sk = NULL;
-
- sk = sock->sk;
+
+ if ((sk = sock->sk) == NULL)
+ return -EINVAL;
if (sk->type != SOCK_SEQPACKET)
return -EOPNOTSUPP;
-
+
if (sk->state != TCP_LISTEN)
return -EINVAL;
-
+
/*
* The write queue this time is holding sockets ready to use
* hooked into the SABM we saved
@@ -954,7 +904,7 @@
if ((skb = skb_dequeue(&sk->receive_queue)) == NULL) {
if (flags & O_NONBLOCK) {
sti();
- return 0;
+ return -EWOULDBLOCK;
}
interruptible_sleep_on(sk->sleep);
if (current->signal & ~current->blocked) {
@@ -981,10 +931,8 @@
int *uaddr_len, int peer)
{
struct full_sockaddr_ax25 *sax = (struct full_sockaddr_ax25 *)uaddr;
- struct sock *sk;
-
- sk = sock->sk;
-
+ struct sock *sk = sock->sk;
+
if (peer != 0) {
if (sk->state != TCP_ESTABLISHED)
return -ENOTCONN;
@@ -1002,7 +950,7 @@
return 0;
}
-
+
int nr_rx_frame(struct sk_buff *skb, struct device *dev)
{
struct sock *sk;
@@ -1054,7 +1002,7 @@
if ((frametype & 0x0F) != NR_CONNREQ)
return 0;
-
+
sk = nr_find_listener(dest);
user = (ax25_address *)(skb->data + 21);
@@ -1079,7 +1027,7 @@
make->protinfo.nr->my_index = circuit / 256;
make->protinfo.nr->my_id = circuit % 256;
-
+
circuit++;
/* Window negotiation */
@@ -1089,8 +1037,8 @@
/* L4 timeout negotiation */
if (skb->len == 37) {
timeout = skb->data[36] * 256 + skb->data[35];
- if (timeout * PR_SLOWHZ < make->protinfo.nr->rtt * 2)
- make->protinfo.nr->rtt = (timeout * PR_SLOWHZ) / 2;
+ if (timeout * NR_SLOWHZ < make->protinfo.nr->rtt * 2)
+ make->protinfo.nr->rtt = (timeout * NR_SLOWHZ) / 2;
make->protinfo.nr->bpqext = 1;
} else {
make->protinfo.nr->bpqext = 0;
@@ -1128,7 +1076,7 @@
struct sk_buff *skb;
unsigned char *asmptr;
int size;
-
+
if (msg->msg_flags & ~MSG_DONTWAIT)
return -EINVAL;
@@ -1142,7 +1090,7 @@
if (sk->protinfo.nr->device == NULL)
return -ENETUNREACH;
-
+
if (usax) {
if (msg->msg_namelen < sizeof(sax))
return -EINVAL;
@@ -1157,7 +1105,7 @@
sax.sax25_family = AF_NETROM;
sax.sax25_call = sk->protinfo.nr->dest_addr;
}
-
+
if (sk->debug)
printk("NET/ROM: sendto: Addresses built.\n");
@@ -1170,11 +1118,10 @@
if ((skb = sock_alloc_send_skb(sk, size, 0, msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
return err;
- skb->sk = sk;
- skb->arp = 1;
+ skb->arp = 1;
skb_reserve(skb, size - len);
-
+
/*
* Push down the NET/ROM header
*/
@@ -1191,7 +1138,7 @@
*asmptr++ = 0; /* To be filled in later */
*asmptr++ = 0; /* Ditto */
*asmptr++ = NR_INFO;
-
+
if (sk->debug)
printk("Built header.\n");
@@ -1202,7 +1149,7 @@
skb->h.raw = skb_put(skb, len);
asmptr = skb->h.raw;
-
+
if (sk->debug)
printk("NET/ROM: Appending user data\n");
@@ -1257,17 +1204,13 @@
}
skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
-
- if (sax != NULL) {
- struct sockaddr_ax25 addr;
-
- addr.sax25_family = AF_NETROM;
- memcpy(&addr.sax25_call, skb->data + 7, AX25_ADDR_LEN);
- *sax = addr;
+ if (sax != NULL) {
+ sax->sax25_family = AF_NETROM;
+ memcpy(sax->sax25_call.ax25_call, skb->data + 7, AX25_ADDR_LEN);
}
- msg->msg_namelen=sizeof(*sax);
+ msg->msg_namelen = sizeof(*sax);
skb_free_datagram(sk, skb);
@@ -1355,7 +1298,7 @@
int len = 0;
off_t pos = 0;
off_t begin = 0;
-
+
cli();
len += sprintf(buffer, "user_addr dest_node src_node dev my your st vs vr va t1 t2 n2 rtt wnd paclen Snd-Q Rcv-Q\n");
@@ -1365,7 +1308,7 @@
devname = "???";
else
devname = dev->name;
-
+
len += sprintf(buffer + len, "%-9s ",
ax2asc(&s->protinfo.nr->user_addr));
len += sprintf(buffer + len, "%-9s ",
@@ -1376,22 +1319,22 @@
s->protinfo.nr->your_index, s->protinfo.nr->your_id,
s->protinfo.nr->state,
s->protinfo.nr->vs, s->protinfo.nr->vr, s->protinfo.nr->va,
- s->protinfo.nr->t1timer / PR_SLOWHZ,
- s->protinfo.nr->t1 / PR_SLOWHZ,
- s->protinfo.nr->t2timer / PR_SLOWHZ,
- s->protinfo.nr->t2 / PR_SLOWHZ,
+ s->protinfo.nr->t1timer / NR_SLOWHZ,
+ s->protinfo.nr->t1 / NR_SLOWHZ,
+ s->protinfo.nr->t2timer / NR_SLOWHZ,
+ s->protinfo.nr->t2 / NR_SLOWHZ,
s->protinfo.nr->n2count, s->protinfo.nr->n2,
- s->protinfo.nr->rtt / PR_SLOWHZ,
+ s->protinfo.nr->rtt / NR_SLOWHZ,
s->protinfo.nr->window, s->protinfo.nr->paclen,
s->wmem_alloc, s->rmem_alloc);
-
+
pos = begin + len;
if (pos < offset) {
len = 0;
begin = pos;
}
-
+
if (pos > offset + length)
break;
}
@@ -1414,7 +1357,7 @@
static struct proto_ops nr_proto_ops = {
AF_NETROM,
-
+
nr_dup,
nr_release,
nr_bind,
@@ -1428,7 +1371,7 @@
nr_shutdown,
nr_setsockopt,
nr_getsockopt,
- nr_fcntl,
+ sock_no_fcntl,
nr_sendmsg,
nr_recvmsg
};
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov