diff options
Diffstat (limited to 'net/x25/x25_link.c')
| -rw-r--r-- | net/x25/x25_link.c | 86 |
1 files changed, 49 insertions, 37 deletions
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 4acacf3c6617..4608aa5b4f31 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * X.25 Packet Layer release 002 * @@ -7,12 +8,6 @@ * * This code REQUIRES 2.1.15 or higher * - * 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 * X.25 001 Jonathan Naylor Started coding. * X.25 002 Jonathan Naylor New timer architecture. @@ -21,20 +16,22 @@ * 2000-09-04 Henner Eisen dev_hold() / dev_put() for x25_neigh. */ +#define pr_fmt(fmt) "X25: " fmt + #include <linux/kernel.h> #include <linux/jiffies.h> #include <linux/timer.h> #include <linux/slab.h> #include <linux/netdevice.h> #include <linux/skbuff.h> -#include <asm/uaccess.h> +#include <linux/uaccess.h> #include <linux/init.h> #include <net/x25.h> LIST_HEAD(x25_neigh_list); DEFINE_RWLOCK(x25_neigh_list_lock); -static void x25_t20timer_expiry(unsigned long); +static void x25_t20timer_expiry(struct timer_list *); static void x25_transmit_restart_confirmation(struct x25_neigh *nb); static void x25_transmit_restart_request(struct x25_neigh *nb); @@ -47,9 +44,9 @@ static inline void x25_start_t20timer(struct x25_neigh *nb) mod_timer(&nb->t20timer, jiffies + nb->t20); } -static void x25_t20timer_expiry(unsigned long param) +static void x25_t20timer_expiry(struct timer_list *t) { - struct x25_neigh *nb = (struct x25_neigh *)param; + struct x25_neigh *nb = timer_container_of(nb, t, t20timer); x25_transmit_restart_request(nb); @@ -58,12 +55,7 @@ static void x25_t20timer_expiry(unsigned long param) static inline void x25_stop_t20timer(struct x25_neigh *nb) { - del_timer(&nb->t20timer); -} - -static inline int x25_t20timer_pending(struct x25_neigh *nb) -{ - return timer_pending(&nb->t20timer); + timer_delete(&nb->t20timer); } /* @@ -73,33 +65,58 @@ void x25_link_control(struct sk_buff *skb, struct x25_neigh *nb, unsigned short frametype) { struct sk_buff *skbn; - int confirm; switch (frametype) { case X25_RESTART_REQUEST: - confirm = !x25_t20timer_pending(nb); - x25_stop_t20timer(nb); - nb->state = X25_LINK_STATE_3; - if (confirm) + switch (nb->state) { + case X25_LINK_STATE_0: + /* This can happen when the x25 module just gets loaded + * and doesn't know layer 2 has already connected + */ + nb->state = X25_LINK_STATE_3; x25_transmit_restart_confirmation(nb); + break; + case X25_LINK_STATE_2: + x25_stop_t20timer(nb); + nb->state = X25_LINK_STATE_3; + break; + case X25_LINK_STATE_3: + /* clear existing virtual calls */ + x25_kill_by_neigh(nb); + + x25_transmit_restart_confirmation(nb); + break; + } break; case X25_RESTART_CONFIRMATION: - x25_stop_t20timer(nb); - nb->state = X25_LINK_STATE_3; + switch (nb->state) { + case X25_LINK_STATE_2: + x25_stop_t20timer(nb); + nb->state = X25_LINK_STATE_3; + break; + case X25_LINK_STATE_3: + /* clear existing virtual calls */ + x25_kill_by_neigh(nb); + + x25_transmit_restart_request(nb); + nb->state = X25_LINK_STATE_2; + x25_start_t20timer(nb); + break; + } break; case X25_DIAGNOSTIC: if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 4)) break; - printk(KERN_WARNING "x25: diagnostic #%d - %02X %02X %02X\n", + pr_warn("diagnostic #%d - %02X %02X %02X\n", skb->data[3], skb->data[4], skb->data[5], skb->data[6]); break; default: - printk(KERN_WARNING "x25: received unknown %02X with LCI 000\n", + pr_warn("received unknown %02X with LCI 000\n", frametype); break; } @@ -217,8 +234,6 @@ void x25_link_established(struct x25_neigh *nb) { switch (nb->state) { case X25_LINK_STATE_0: - nb->state = X25_LINK_STATE_2; - break; case X25_LINK_STATE_1: x25_transmit_restart_request(nb); nb->state = X25_LINK_STATE_2; @@ -235,6 +250,9 @@ void x25_link_established(struct x25_neigh *nb) void x25_link_terminated(struct x25_neigh *nb) { nb->state = X25_LINK_STATE_0; + skb_queue_purge(&nb->queue); + x25_stop_t20timer(nb); + /* Out of order: clear existing virtual calls (X.25 03/93 4.6.3) */ x25_kill_by_neigh(nb); } @@ -250,7 +268,7 @@ void x25_link_device_up(struct net_device *dev) return; skb_queue_head_init(&nb->queue); - setup_timer(&nb->t20timer, x25_t20timer_expiry, (unsigned long)nb); + timer_setup(&nb->t20timer, x25_t20timer_expiry, 0); dev_hold(dev); nb->dev = dev; @@ -264,7 +282,7 @@ void x25_link_device_up(struct net_device *dev) X25_MASK_PACKET_SIZE | X25_MASK_WINDOW_SIZE; nb->t20 = sysctl_x25_restart_request_timeout; - atomic_set(&nb->refcnt, 1); + refcount_set(&nb->refcnt, 1); write_lock_bh(&x25_neigh_list_lock); list_add(&nb->node, &x25_neigh_list); @@ -273,16 +291,13 @@ void x25_link_device_up(struct net_device *dev) /** * __x25_remove_neigh - remove neighbour from x25_neigh_list - * @nb - neigh to remove + * @nb: - neigh to remove * * Remove neighbour from x25_neigh_list. If it was there. * Caller must hold x25_neigh_list_lock. */ static void __x25_remove_neigh(struct x25_neigh *nb) { - skb_queue_purge(&nb->queue); - x25_stop_t20timer(nb); - if (nb->node.next) { list_del(&nb->node); x25_neigh_put(nb); @@ -317,12 +332,9 @@ void x25_link_device_down(struct net_device *dev) struct x25_neigh *x25_get_neigh(struct net_device *dev) { struct x25_neigh *nb, *use = NULL; - struct list_head *entry; read_lock_bh(&x25_neigh_list_lock); - list_for_each(entry, &x25_neigh_list) { - nb = list_entry(entry, struct x25_neigh, node); - + list_for_each_entry(nb, &x25_neigh_list, node) { if (nb->dev == dev) { use = nb; break; |
