summaryrefslogtreecommitdiffstats
path: root/net/netrom
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-01-04 16:03:48 +0000
commit78c388aed2b7184182c08428db1de6c872d815f5 (patch)
tree4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /net/netrom
parenteb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (diff)
Merge with Linux 2.1.131 and more MIPS goodies.
(Did I mention that CVS is buggy ...)
Diffstat (limited to 'net/netrom')
-rw-r--r--net/netrom/af_netrom.c17
-rw-r--r--net/netrom/nr_loopback.c12
-rw-r--r--net/netrom/nr_route.c16
3 files changed, 33 insertions, 12 deletions
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 66b49db8a..7813f3072 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -238,7 +238,7 @@ static struct sock *nr_find_socket(unsigned char index, unsigned char id)
/*
* Find a connected NET/ROM socket given their circuit IDs.
*/
-static struct sock *nr_find_peer(unsigned char index, unsigned char id)
+static struct sock *nr_find_peer(unsigned char index, unsigned char id, ax25_address *dest)
{
struct sock *s;
unsigned long flags;
@@ -247,7 +247,7 @@ static struct sock *nr_find_peer(unsigned char index, unsigned char id)
cli();
for (s = nr_list; s != NULL; s = s->next) {
- if (s->protinfo.nr->your_index == index && s->protinfo.nr->your_id == id) {
+ if (s->protinfo.nr->your_index == index && s->protinfo.nr->your_id == id && ax25cmp(&s->protinfo.nr->dest_addr, dest) == 0) {
restore_flags(flags);
return s;
}
@@ -575,14 +575,15 @@ static int nr_release(struct socket *sock, struct socket *peer)
sk->state_change(sk);
sk->dead = 1;
sk->destroy = 1;
+ sk->socket = NULL;
break;
default:
+ sk->socket = NULL;
break;
}
sock->sk = NULL;
- sk->socket = NULL; /* Not used, but we should do this */
return 0;
}
@@ -597,7 +598,11 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
if (sk->zapped == 0)
return -EINVAL;
- if (addr_len != sizeof(struct sockaddr_ax25) && addr_len != sizeof(struct full_sockaddr_ax25))
+ if (addr_len < sizeof(struct sockaddr_ax25) || addr_len > sizeof(struct
+full_sockaddr_ax25))
+ return -EINVAL;
+
+ if (addr_len < (addr->fsa_ax25.sax25_ndigis * sizeof(ax25_address) + sizeof(struct sockaddr_ax25)))
return -EINVAL;
if (addr->fsa_ax25.sax25_family != AF_NETROM)
@@ -863,10 +868,10 @@ int nr_rx_frame(struct sk_buff *skb, struct device *dev)
if (circuit_index == 0 && circuit_id == 0) {
if (frametype == NR_CONNACK && flags == NR_CHOKE_FLAG)
- sk = nr_find_peer(peer_circuit_index, peer_circuit_id);
+ sk = nr_find_peer(peer_circuit_index, peer_circuit_id, src);
} else {
if (frametype == NR_CONNREQ)
- sk = nr_find_peer(circuit_index, circuit_id);
+ sk = nr_find_peer(circuit_index, circuit_id, src);
else
sk = nr_find_socket(circuit_index, circuit_id);
}
diff --git a/net/netrom/nr_loopback.c b/net/netrom/nr_loopback.c
index ba9644cbe..007cb8738 100644
--- a/net/netrom/nr_loopback.c
+++ b/net/netrom/nr_loopback.c
@@ -77,16 +77,16 @@ static void nr_loopback_timer(unsigned long param)
ax25_address *nr_dest;
struct device *dev;
- while ((skb = skb_dequeue(&loopback_queue)) != NULL) {
+ if ((skb = skb_dequeue(&loopback_queue)) != NULL) {
nr_dest = (ax25_address *)(skb->data + 7);
- if ((dev = nr_dev_get(nr_dest)) == NULL) {
- kfree_skb(skb);
- continue;
- }
+ dev = nr_dev_get(nr_dest);
- if (nr_rx_frame(skb, dev) == 0)
+ if (dev == NULL || nr_rx_frame(skb, dev) == 0)
kfree_skb(skb);
+
+ if (!skb_queue_empty(&loopback_queue) && !nr_loopback_running())
+ nr_set_loopback_timer();
}
}
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 26f5ac8dd..d46e45eb6 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -81,6 +81,22 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
if (ax25cmp(ax25, &nr_neigh->callsign) == 0 && nr_neigh->dev == dev)
break;
+ /*
+ * The L2 link to a neighbour has failed in the past
+ * and now a frame comes from this neighbour. We assume
+ * it was a temporary trouble with the link and reset the
+ * routes now (and not wait for a node broadcast).
+ */
+ if (nr_neigh != NULL && nr_neigh->failed != 0 && quality == 0) {
+ struct nr_node *node;
+
+ for (node = nr_node_list; node != NULL; node = node->next)
+ for (i = 0; i < node->count; i++)
+ if (node->routes[i].neighbour == nr_neigh)
+ if (i < node->which)
+ node->which = i;
+ }
+
if (nr_neigh != NULL)
nr_neigh->failed = 0;