diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-01-04 16:03:48 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-01-04 16:03:48 +0000 |
commit | 78c388aed2b7184182c08428db1de6c872d815f5 (patch) | |
tree | 4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /net/netrom | |
parent | eb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (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.c | 17 | ||||
-rw-r--r-- | net/netrom/nr_loopback.c | 12 | ||||
-rw-r--r-- | net/netrom/nr_route.c | 16 |
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; |