2019-05-19 19:08:20 +07:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2005-04-17 05:20:36 +07:00
|
|
|
/*
|
2007-02-09 21:24:29 +07:00
|
|
|
* lec.c: Lan Emulation driver
|
2005-04-17 05:20:36 +07:00
|
|
|
*
|
2006-09-30 07:11:14 +07:00
|
|
|
* Marko Kiiskila <mkiiskila@yahoo.com>
|
2005-04-17 05:20:36 +07:00
|
|
|
*/
|
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
|
|
|
|
|
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h
percpu.h is included by sched.h and module.h and thus ends up being
included when building most .c files. percpu.h includes slab.h which
in turn includes gfp.h making everything defined by the two files
universally available and complicating inclusion dependencies.
percpu.h -> slab.h dependency is about to be removed. Prepare for
this change by updating users of gfp and slab facilities include those
headers directly instead of assuming availability. As this conversion
needs to touch large number of source files, the following script is
used as the basis of conversion.
http://userweb.kernel.org/~tj/misc/slabh-sweep.py
The script does the followings.
* Scan files for gfp and slab usages and update includes such that
only the necessary includes are there. ie. if only gfp is used,
gfp.h, if slab is used, slab.h.
* When the script inserts a new include, it looks at the include
blocks and try to put the new include such that its order conforms
to its surrounding. It's put in the include block which contains
core kernel includes, in the same order that the rest are ordered -
alphabetical, Christmas tree, rev-Xmas-tree or at the end if there
doesn't seem to be any matching order.
* If the script can't find a place to put a new include (mostly
because the file doesn't have fitting include block), it prints out
an error message indicating which .h file needs to be added to the
file.
The conversion was done in the following steps.
1. The initial automatic conversion of all .c files updated slightly
over 4000 files, deleting around 700 includes and adding ~480 gfp.h
and ~3000 slab.h inclusions. The script emitted errors for ~400
files.
2. Each error was manually checked. Some didn't need the inclusion,
some needed manual addition while adding it to implementation .h or
embedding .c file was more appropriate for others. This step added
inclusions to around 150 files.
3. The script was run again and the output was compared to the edits
from #2 to make sure no file was left behind.
4. Several build tests were done and a couple of problems were fixed.
e.g. lib/decompress_*.c used malloc/free() wrappers around slab
APIs requiring slab.h to be added manually.
5. The script was run on all .h files but without automatically
editing them as sprinkling gfp.h and slab.h inclusions around .h
files could easily lead to inclusion dependency hell. Most gfp.h
inclusion directives were ignored as stuff from gfp.h was usually
wildly available and often used in preprocessor macros. Each
slab.h inclusion directive was examined and added manually as
necessary.
6. percpu.h was updated not to include slab.h.
7. Build test were done on the following configurations and failures
were fixed. CONFIG_GCOV_KERNEL was turned off for all tests (as my
distributed build env didn't work with gcov compiles) and a few
more options had to be turned off depending on archs to make things
build (like ipr on powerpc/64 which failed due to missing writeq).
* x86 and x86_64 UP and SMP allmodconfig and a custom test config.
* powerpc and powerpc64 SMP allmodconfig
* sparc and sparc64 SMP allmodconfig
* ia64 SMP allmodconfig
* s390 SMP allmodconfig
* alpha SMP allmodconfig
* um on x86_64 SMP allmodconfig
8. percpu.h modifications were reverted so that it could be applied as
a separate patch and serve as bisection point.
Given the fact that I had only a couple of failures from tests on step
6, I'm fairly confident about the coverage of this conversion patch.
If there is a breakage, it's likely to be something in one of the arch
headers which should be easily discoverable easily on most builds of
the specific arch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Guess-its-ok-by: Christoph Lameter <cl@linux-foundation.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Lee Schermerhorn <Lee.Schermerhorn@hp.com>
2010-03-24 15:04:11 +07:00
|
|
|
#include <linux/slab.h>
|
2005-04-17 05:20:36 +07:00
|
|
|
#include <linux/kernel.h>
|
|
|
|
#include <linux/bitops.h>
|
2006-01-12 03:17:47 +07:00
|
|
|
#include <linux/capability.h>
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
/* We are ethernet device */
|
|
|
|
#include <linux/if_ether.h>
|
|
|
|
#include <linux/netdevice.h>
|
|
|
|
#include <linux/etherdevice.h>
|
|
|
|
#include <net/sock.h>
|
|
|
|
#include <linux/skbuff.h>
|
|
|
|
#include <linux/ip.h>
|
|
|
|
#include <asm/byteorder.h>
|
2010-01-26 18:40:08 +07:00
|
|
|
#include <linux/uaccess.h>
|
2005-04-17 05:20:36 +07:00
|
|
|
#include <net/arp.h>
|
|
|
|
#include <net/dst.h>
|
|
|
|
#include <linux/proc_fs.h>
|
|
|
|
#include <linux/spinlock.h>
|
|
|
|
#include <linux/seq_file.h>
|
|
|
|
|
|
|
|
/* And atm device */
|
|
|
|
#include <linux/atmdev.h>
|
|
|
|
#include <linux/atmlec.h>
|
|
|
|
|
|
|
|
/* Proxy LEC knows about bridging */
|
2016-09-09 19:43:14 +07:00
|
|
|
#if IS_ENABLED(CONFIG_BRIDGE)
|
2005-04-17 05:20:36 +07:00
|
|
|
#include "../bridge/br_private.h"
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 };
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Modular too */
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/init.h>
|
|
|
|
|
2018-05-04 01:45:58 +07:00
|
|
|
/* Hardening for Spectre-v1 */
|
|
|
|
#include <linux/nospec.h>
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
#include "lec.h"
|
|
|
|
#include "lec_arpc.h"
|
|
|
|
#include "resources.h"
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
#define DUMP_PACKETS 0 /*
|
|
|
|
* 0 = None,
|
|
|
|
* 1 = 30 first bytes
|
|
|
|
* 2 = Whole packet
|
|
|
|
*/
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
#define LEC_UNRES_QUE_LEN 8 /*
|
|
|
|
* number of tx packets to queue for a
|
|
|
|
* single destination while waiting for SVC
|
|
|
|
*/
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
static int lec_open(struct net_device *dev);
|
2009-09-01 02:50:42 +07:00
|
|
|
static netdev_tx_t lec_start_xmit(struct sk_buff *skb,
|
|
|
|
struct net_device *dev);
|
2005-04-17 05:20:36 +07:00
|
|
|
static int lec_close(struct net_device *dev);
|
2006-09-30 07:11:14 +07:00
|
|
|
static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
|
2008-06-18 06:20:06 +07:00
|
|
|
const unsigned char *mac_addr);
|
2005-04-17 05:20:36 +07:00
|
|
|
static int lec_arp_remove(struct lec_priv *priv,
|
2006-09-30 07:11:14 +07:00
|
|
|
struct lec_arp_table *to_remove);
|
2005-04-17 05:20:36 +07:00
|
|
|
/* LANE2 functions */
|
2008-06-18 06:20:06 +07:00
|
|
|
static void lane2_associate_ind(struct net_device *dev, const u8 *mac_address,
|
|
|
|
const u8 *tlvs, u32 sizeoftlvs);
|
|
|
|
static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force,
|
2006-09-30 07:11:14 +07:00
|
|
|
u8 **tlvs, u32 *sizeoftlvs);
|
2008-06-18 06:20:06 +07:00
|
|
|
static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst,
|
|
|
|
const u8 *tlvs, u32 sizeoftlvs);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2008-06-18 06:20:06 +07:00
|
|
|
static int lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr,
|
2005-04-17 05:20:36 +07:00
|
|
|
unsigned long permanent);
|
|
|
|
static void lec_arp_check_empties(struct lec_priv *priv,
|
|
|
|
struct atm_vcc *vcc, struct sk_buff *skb);
|
|
|
|
static void lec_arp_destroy(struct lec_priv *priv);
|
|
|
|
static void lec_arp_init(struct lec_priv *priv);
|
2006-09-30 07:11:14 +07:00
|
|
|
static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
|
2008-06-18 06:20:06 +07:00
|
|
|
const unsigned char *mac_to_find,
|
2005-04-17 05:20:36 +07:00
|
|
|
int is_rdesc,
|
|
|
|
struct lec_arp_table **ret_entry);
|
2008-06-18 06:20:06 +07:00
|
|
|
static void lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr,
|
2010-01-26 18:40:08 +07:00
|
|
|
const unsigned char *atm_addr,
|
|
|
|
unsigned long remoteflag,
|
2005-04-17 05:20:36 +07:00
|
|
|
unsigned int targetless_le_arp);
|
|
|
|
static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id);
|
|
|
|
static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc);
|
|
|
|
static void lec_set_flush_tran_id(struct lec_priv *priv,
|
2008-06-18 06:20:06 +07:00
|
|
|
const unsigned char *atm_addr,
|
2005-04-17 05:20:36 +07:00
|
|
|
unsigned long tran_id);
|
2010-01-26 18:40:08 +07:00
|
|
|
static void lec_vcc_added(struct lec_priv *priv,
|
|
|
|
const struct atmlec_ioc *ioc_data,
|
2005-04-17 05:20:36 +07:00
|
|
|
struct atm_vcc *vcc,
|
2010-01-26 18:40:08 +07:00
|
|
|
void (*old_push)(struct atm_vcc *vcc,
|
|
|
|
struct sk_buff *skb));
|
2005-04-17 05:20:36 +07:00
|
|
|
static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc);
|
|
|
|
|
2006-09-30 07:16:48 +07:00
|
|
|
/* must be done under lec_arp_lock */
|
|
|
|
static inline void lec_arp_hold(struct lec_arp_table *entry)
|
|
|
|
{
|
2017-07-04 19:53:02 +07:00
|
|
|
refcount_inc(&entry->usage);
|
2006-09-30 07:16:48 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void lec_arp_put(struct lec_arp_table *entry)
|
|
|
|
{
|
2017-07-04 19:53:02 +07:00
|
|
|
if (refcount_dec_and_test(&entry->usage))
|
2006-09-30 07:16:48 +07:00
|
|
|
kfree(entry);
|
|
|
|
}
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
static struct lane2_ops lane2_ops = {
|
2016-12-17 07:58:43 +07:00
|
|
|
.resolve = lane2_resolve, /* spec 3.1.3 */
|
|
|
|
.associate_req = lane2_associate_req, /* spec 3.1.4 */
|
|
|
|
.associate_indicator = NULL /* spec 3.1.5 */
|
2005-04-17 05:20:36 +07:00
|
|
|
};
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
static unsigned char bus_mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
/* Device structures */
|
|
|
|
static struct net_device *dev_lec[MAX_LEC_ITF];
|
|
|
|
|
2016-09-09 19:43:14 +07:00
|
|
|
#if IS_ENABLED(CONFIG_BRIDGE)
|
2005-04-17 05:20:36 +07:00
|
|
|
static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev)
|
|
|
|
{
|
2006-09-30 07:11:14 +07:00
|
|
|
char *buff;
|
|
|
|
struct lec_priv *priv;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check if this is a BPDU. If so, ask zeppelin to send
|
|
|
|
* LE_TOPOLOGY_REQUEST with the same value of Topology Change bit
|
|
|
|
* as the Config BPDU has
|
|
|
|
*/
|
|
|
|
buff = skb->data + skb->dev->hard_header_len;
|
|
|
|
if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) {
|
2005-04-17 05:20:36 +07:00
|
|
|
struct sock *sk;
|
2006-09-30 07:11:14 +07:00
|
|
|
struct sk_buff *skb2;
|
|
|
|
struct atmlec_msg *mesg;
|
|
|
|
|
|
|
|
skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
|
|
|
|
if (skb2 == NULL)
|
|
|
|
return;
|
|
|
|
skb2->len = sizeof(struct atmlec_msg);
|
|
|
|
mesg = (struct atmlec_msg *)skb2->data;
|
|
|
|
mesg->type = l_topology_change;
|
|
|
|
buff += 4;
|
2010-01-26 18:40:08 +07:00
|
|
|
mesg->content.normal.flag = *buff & 0x01;
|
|
|
|
/* 0x01 is topology change */
|
2006-09-30 07:11:14 +07:00
|
|
|
|
2008-11-13 14:39:10 +07:00
|
|
|
priv = netdev_priv(dev);
|
2006-09-30 07:11:14 +07:00
|
|
|
atm_force_charge(priv->lecd, skb2->truesize);
|
2005-04-17 05:20:36 +07:00
|
|
|
sk = sk_atm(priv->lecd);
|
2006-09-30 07:11:14 +07:00
|
|
|
skb_queue_tail(&sk->sk_receive_queue, skb2);
|
2014-04-12 03:15:36 +07:00
|
|
|
sk->sk_data_ready(sk);
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
2016-09-09 19:43:14 +07:00
|
|
|
#endif /* IS_ENABLED(CONFIG_BRIDGE) */
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Open/initialize the netdevice. This is called (in the current kernel)
|
|
|
|
* sometime after booting when the 'ifconfig' program is run.
|
|
|
|
*
|
|
|
|
* This routine should set everything up anew at each open, even
|
|
|
|
* registers that "should" only need to be set once at boot, so that
|
|
|
|
* there is non-reboot way to recover if something goes wrong.
|
|
|
|
*/
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
static int lec_open(struct net_device *dev)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
netif_start_queue(dev);
|
2006-09-30 07:11:14 +07:00
|
|
|
|
|
|
|
return 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2009-01-09 20:01:01 +07:00
|
|
|
static void
|
|
|
|
lec_send(struct atm_vcc *vcc, struct sk_buff *skb)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2009-01-09 20:01:01 +07:00
|
|
|
struct net_device *dev = skb->dev;
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
ATM_SKB(skb)->vcc = vcc;
|
atm: Preserve value of skb->truesize when accounting to vcc
ATM accounts for in-flight TX packets in sk_wmem_alloc of the VCC on
which they are to be sent. But it doesn't take ownership of those
packets from the sock (if any) which originally owned them. They should
remain owned by their actual sender until they've left the box.
There's a hack in pskb_expand_head() to avoid adjusting skb->truesize
for certain skbs, precisely to avoid messing up sk_wmem_alloc
accounting. Ideally that hack would cover the ATM use case too, but it
doesn't — skbs which aren't owned by any sock, for example PPP control
frames, still get their truesize adjusted when the low-level ATM driver
adds headroom.
This has always been an issue, it seems. The truesize of a packet
increases, and sk_wmem_alloc on the VCC goes negative. But this wasn't
for normal traffic, only for control frames. So I think we just got away
with it, and we probably needed to send 2GiB of LCP echo frames before
the misaccounting would ever have caused a problem and caused
atm_may_send() to start refusing packets.
Commit 14afee4b609 ("net: convert sock.sk_wmem_alloc from atomic_t to
refcount_t") did exactly what it was intended to do, and turned this
mostly-theoretical problem into a real one, causing PPPoATM to fail
immediately as sk_wmem_alloc underflows and atm_may_send() *immediately*
starts refusing to allow new packets.
The least intrusive solution to this problem is to stash the value of
skb->truesize that was accounted to the VCC, in a new member of the
ATM_SKB(skb) structure. Then in atm_pop_raw() subtract precisely that
value instead of the then-current value of skb->truesize.
Fixes: 158f323b9868 ("net: adjust skb->truesize in pskb_expand_head()")
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Tested-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-06-16 17:55:44 +07:00
|
|
|
atm_account_tx(vcc, skb);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
if (vcc->send(vcc, skb) < 0) {
|
2009-01-09 20:01:01 +07:00
|
|
|
dev->stats.tx_dropped++;
|
2005-04-17 05:20:36 +07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-01-09 20:01:01 +07:00
|
|
|
dev->stats.tx_packets++;
|
|
|
|
dev->stats.tx_bytes += skb->len;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
netdev: pass the stuck queue to the timeout handler
This allows incrementing the correct timeout statistic without any mess.
Down the road, devices can learn to reset just the specific queue.
The patch was generated with the following script:
use strict;
use warnings;
our $^I = '.bak';
my @work = (
["arch/m68k/emu/nfeth.c", "nfeth_tx_timeout"],
["arch/um/drivers/net_kern.c", "uml_net_tx_timeout"],
["arch/um/drivers/vector_kern.c", "vector_net_tx_timeout"],
["arch/xtensa/platforms/iss/network.c", "iss_net_tx_timeout"],
["drivers/char/pcmcia/synclink_cs.c", "hdlcdev_tx_timeout"],
["drivers/infiniband/ulp/ipoib/ipoib_main.c", "ipoib_timeout"],
["drivers/infiniband/ulp/ipoib/ipoib_main.c", "ipoib_timeout"],
["drivers/message/fusion/mptlan.c", "mpt_lan_tx_timeout"],
["drivers/misc/sgi-xp/xpnet.c", "xpnet_dev_tx_timeout"],
["drivers/net/appletalk/cops.c", "cops_timeout"],
["drivers/net/arcnet/arcdevice.h", "arcnet_timeout"],
["drivers/net/arcnet/arcnet.c", "arcnet_timeout"],
["drivers/net/arcnet/com20020.c", "arcnet_timeout"],
["drivers/net/ethernet/3com/3c509.c", "el3_tx_timeout"],
["drivers/net/ethernet/3com/3c515.c", "corkscrew_timeout"],
["drivers/net/ethernet/3com/3c574_cs.c", "el3_tx_timeout"],
["drivers/net/ethernet/3com/3c589_cs.c", "el3_tx_timeout"],
["drivers/net/ethernet/3com/3c59x.c", "vortex_tx_timeout"],
["drivers/net/ethernet/3com/3c59x.c", "vortex_tx_timeout"],
["drivers/net/ethernet/3com/typhoon.c", "typhoon_tx_timeout"],
["drivers/net/ethernet/8390/8390.h", "ei_tx_timeout"],
["drivers/net/ethernet/8390/8390.h", "eip_tx_timeout"],
["drivers/net/ethernet/8390/8390.c", "ei_tx_timeout"],
["drivers/net/ethernet/8390/8390p.c", "eip_tx_timeout"],
["drivers/net/ethernet/8390/ax88796.c", "ax_ei_tx_timeout"],
["drivers/net/ethernet/8390/axnet_cs.c", "axnet_tx_timeout"],
["drivers/net/ethernet/8390/etherh.c", "__ei_tx_timeout"],
["drivers/net/ethernet/8390/hydra.c", "__ei_tx_timeout"],
["drivers/net/ethernet/8390/mac8390.c", "__ei_tx_timeout"],
["drivers/net/ethernet/8390/mcf8390.c", "__ei_tx_timeout"],
["drivers/net/ethernet/8390/lib8390.c", "__ei_tx_timeout"],
["drivers/net/ethernet/8390/ne2k-pci.c", "ei_tx_timeout"],
["drivers/net/ethernet/8390/pcnet_cs.c", "ei_tx_timeout"],
["drivers/net/ethernet/8390/smc-ultra.c", "ei_tx_timeout"],
["drivers/net/ethernet/8390/wd.c", "ei_tx_timeout"],
["drivers/net/ethernet/8390/zorro8390.c", "__ei_tx_timeout"],
["drivers/net/ethernet/adaptec/starfire.c", "tx_timeout"],
["drivers/net/ethernet/agere/et131x.c", "et131x_tx_timeout"],
["drivers/net/ethernet/allwinner/sun4i-emac.c", "emac_timeout"],
["drivers/net/ethernet/alteon/acenic.c", "ace_watchdog"],
["drivers/net/ethernet/amazon/ena/ena_netdev.c", "ena_tx_timeout"],
["drivers/net/ethernet/amd/7990.h", "lance_tx_timeout"],
["drivers/net/ethernet/amd/7990.c", "lance_tx_timeout"],
["drivers/net/ethernet/amd/a2065.c", "lance_tx_timeout"],
["drivers/net/ethernet/amd/am79c961a.c", "am79c961_timeout"],
["drivers/net/ethernet/amd/amd8111e.c", "amd8111e_tx_timeout"],
["drivers/net/ethernet/amd/ariadne.c", "ariadne_tx_timeout"],
["drivers/net/ethernet/amd/atarilance.c", "lance_tx_timeout"],
["drivers/net/ethernet/amd/au1000_eth.c", "au1000_tx_timeout"],
["drivers/net/ethernet/amd/declance.c", "lance_tx_timeout"],
["drivers/net/ethernet/amd/lance.c", "lance_tx_timeout"],
["drivers/net/ethernet/amd/mvme147.c", "lance_tx_timeout"],
["drivers/net/ethernet/amd/ni65.c", "ni65_timeout"],
["drivers/net/ethernet/amd/nmclan_cs.c", "mace_tx_timeout"],
["drivers/net/ethernet/amd/pcnet32.c", "pcnet32_tx_timeout"],
["drivers/net/ethernet/amd/sunlance.c", "lance_tx_timeout"],
["drivers/net/ethernet/amd/xgbe/xgbe-drv.c", "xgbe_tx_timeout"],
["drivers/net/ethernet/apm/xgene-v2/main.c", "xge_timeout"],
["drivers/net/ethernet/apm/xgene/xgene_enet_main.c", "xgene_enet_timeout"],
["drivers/net/ethernet/apple/macmace.c", "mace_tx_timeout"],
["drivers/net/ethernet/atheros/ag71xx.c", "ag71xx_tx_timeout"],
["drivers/net/ethernet/atheros/alx/main.c", "alx_tx_timeout"],
["drivers/net/ethernet/atheros/atl1c/atl1c_main.c", "atl1c_tx_timeout"],
["drivers/net/ethernet/atheros/atl1e/atl1e_main.c", "atl1e_tx_timeout"],
["drivers/net/ethernet/atheros/atlx/atl.c", "atlx_tx_timeout"],
["drivers/net/ethernet/atheros/atlx/atl1.c", "atlx_tx_timeout"],
["drivers/net/ethernet/atheros/atlx/atl2.c", "atl2_tx_timeout"],
["drivers/net/ethernet/broadcom/b44.c", "b44_tx_timeout"],
["drivers/net/ethernet/broadcom/bcmsysport.c", "bcm_sysport_tx_timeout"],
["drivers/net/ethernet/broadcom/bnx2.c", "bnx2_tx_timeout"],
["drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h", "bnx2x_tx_timeout"],
["drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c", "bnx2x_tx_timeout"],
["drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c", "bnx2x_tx_timeout"],
["drivers/net/ethernet/broadcom/bnxt/bnxt.c", "bnxt_tx_timeout"],
["drivers/net/ethernet/broadcom/genet/bcmgenet.c", "bcmgenet_timeout"],
["drivers/net/ethernet/broadcom/sb1250-mac.c", "sbmac_tx_timeout"],
["drivers/net/ethernet/broadcom/tg3.c", "tg3_tx_timeout"],
["drivers/net/ethernet/calxeda/xgmac.c", "xgmac_tx_timeout"],
["drivers/net/ethernet/cavium/liquidio/lio_main.c", "liquidio_tx_timeout"],
["drivers/net/ethernet/cavium/liquidio/lio_vf_main.c", "liquidio_tx_timeout"],
["drivers/net/ethernet/cavium/liquidio/lio_vf_rep.c", "lio_vf_rep_tx_timeout"],
["drivers/net/ethernet/cavium/thunder/nicvf_main.c", "nicvf_tx_timeout"],
["drivers/net/ethernet/cirrus/cs89x0.c", "net_timeout"],
["drivers/net/ethernet/cisco/enic/enic_main.c", "enic_tx_timeout"],
["drivers/net/ethernet/cisco/enic/enic_main.c", "enic_tx_timeout"],
["drivers/net/ethernet/cortina/gemini.c", "gmac_tx_timeout"],
["drivers/net/ethernet/davicom/dm9000.c", "dm9000_timeout"],
["drivers/net/ethernet/dec/tulip/de2104x.c", "de_tx_timeout"],
["drivers/net/ethernet/dec/tulip/tulip_core.c", "tulip_tx_timeout"],
["drivers/net/ethernet/dec/tulip/winbond-840.c", "tx_timeout"],
["drivers/net/ethernet/dlink/dl2k.c", "rio_tx_timeout"],
["drivers/net/ethernet/dlink/sundance.c", "tx_timeout"],
["drivers/net/ethernet/emulex/benet/be_main.c", "be_tx_timeout"],
["drivers/net/ethernet/ethoc.c", "ethoc_tx_timeout"],
["drivers/net/ethernet/faraday/ftgmac100.c", "ftgmac100_tx_timeout"],
["drivers/net/ethernet/fealnx.c", "fealnx_tx_timeout"],
["drivers/net/ethernet/freescale/dpaa/dpaa_eth.c", "dpaa_tx_timeout"],
["drivers/net/ethernet/freescale/fec_main.c", "fec_timeout"],
["drivers/net/ethernet/freescale/fec_mpc52xx.c", "mpc52xx_fec_tx_timeout"],
["drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c", "fs_timeout"],
["drivers/net/ethernet/freescale/gianfar.c", "gfar_timeout"],
["drivers/net/ethernet/freescale/ucc_geth.c", "ucc_geth_timeout"],
["drivers/net/ethernet/fujitsu/fmvj18x_cs.c", "fjn_tx_timeout"],
["drivers/net/ethernet/google/gve/gve_main.c", "gve_tx_timeout"],
["drivers/net/ethernet/hisilicon/hip04_eth.c", "hip04_timeout"],
["drivers/net/ethernet/hisilicon/hix5hd2_gmac.c", "hix5hd2_net_timeout"],
["drivers/net/ethernet/hisilicon/hns/hns_enet.c", "hns_nic_net_timeout"],
["drivers/net/ethernet/hisilicon/hns3/hns3_enet.c", "hns3_nic_net_timeout"],
["drivers/net/ethernet/huawei/hinic/hinic_main.c", "hinic_tx_timeout"],
["drivers/net/ethernet/i825xx/82596.c", "i596_tx_timeout"],
["drivers/net/ethernet/i825xx/ether1.c", "ether1_timeout"],
["drivers/net/ethernet/i825xx/lib82596.c", "i596_tx_timeout"],
["drivers/net/ethernet/i825xx/sun3_82586.c", "sun3_82586_timeout"],
["drivers/net/ethernet/ibm/ehea/ehea_main.c", "ehea_tx_watchdog"],
["drivers/net/ethernet/ibm/emac/core.c", "emac_tx_timeout"],
["drivers/net/ethernet/ibm/emac/core.c", "emac_tx_timeout"],
["drivers/net/ethernet/ibm/ibmvnic.c", "ibmvnic_tx_timeout"],
["drivers/net/ethernet/intel/e100.c", "e100_tx_timeout"],
["drivers/net/ethernet/intel/e1000/e1000_main.c", "e1000_tx_timeout"],
["drivers/net/ethernet/intel/e1000e/netdev.c", "e1000_tx_timeout"],
["drivers/net/ethernet/intel/fm10k/fm10k_netdev.c", "fm10k_tx_timeout"],
["drivers/net/ethernet/intel/i40e/i40e_main.c", "i40e_tx_timeout"],
["drivers/net/ethernet/intel/iavf/iavf_main.c", "iavf_tx_timeout"],
["drivers/net/ethernet/intel/ice/ice_main.c", "ice_tx_timeout"],
["drivers/net/ethernet/intel/ice/ice_main.c", "ice_tx_timeout"],
["drivers/net/ethernet/intel/igb/igb_main.c", "igb_tx_timeout"],
["drivers/net/ethernet/intel/igbvf/netdev.c", "igbvf_tx_timeout"],
["drivers/net/ethernet/intel/ixgb/ixgb_main.c", "ixgb_tx_timeout"],
["drivers/net/ethernet/intel/ixgbe/ixgbe_debugfs.c", "adapter->netdev->netdev_ops->ndo_tx_timeout(adapter->netdev);"],
["drivers/net/ethernet/intel/ixgbe/ixgbe_main.c", "ixgbe_tx_timeout"],
["drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c", "ixgbevf_tx_timeout"],
["drivers/net/ethernet/jme.c", "jme_tx_timeout"],
["drivers/net/ethernet/korina.c", "korina_tx_timeout"],
["drivers/net/ethernet/lantiq_etop.c", "ltq_etop_tx_timeout"],
["drivers/net/ethernet/marvell/mv643xx_eth.c", "mv643xx_eth_tx_timeout"],
["drivers/net/ethernet/marvell/pxa168_eth.c", "pxa168_eth_tx_timeout"],
["drivers/net/ethernet/marvell/skge.c", "skge_tx_timeout"],
["drivers/net/ethernet/marvell/sky2.c", "sky2_tx_timeout"],
["drivers/net/ethernet/marvell/sky2.c", "sky2_tx_timeout"],
["drivers/net/ethernet/mediatek/mtk_eth_soc.c", "mtk_tx_timeout"],
["drivers/net/ethernet/mellanox/mlx4/en_netdev.c", "mlx4_en_tx_timeout"],
["drivers/net/ethernet/mellanox/mlx4/en_netdev.c", "mlx4_en_tx_timeout"],
["drivers/net/ethernet/mellanox/mlx5/core/en_main.c", "mlx5e_tx_timeout"],
["drivers/net/ethernet/micrel/ks8842.c", "ks8842_tx_timeout"],
["drivers/net/ethernet/micrel/ksz884x.c", "netdev_tx_timeout"],
["drivers/net/ethernet/microchip/enc28j60.c", "enc28j60_tx_timeout"],
["drivers/net/ethernet/microchip/encx24j600.c", "encx24j600_tx_timeout"],
["drivers/net/ethernet/natsemi/sonic.h", "sonic_tx_timeout"],
["drivers/net/ethernet/natsemi/sonic.c", "sonic_tx_timeout"],
["drivers/net/ethernet/natsemi/jazzsonic.c", "sonic_tx_timeout"],
["drivers/net/ethernet/natsemi/macsonic.c", "sonic_tx_timeout"],
["drivers/net/ethernet/natsemi/natsemi.c", "ns_tx_timeout"],
["drivers/net/ethernet/natsemi/ns83820.c", "ns83820_tx_timeout"],
["drivers/net/ethernet/natsemi/xtsonic.c", "sonic_tx_timeout"],
["drivers/net/ethernet/neterion/s2io.h", "s2io_tx_watchdog"],
["drivers/net/ethernet/neterion/s2io.c", "s2io_tx_watchdog"],
["drivers/net/ethernet/neterion/vxge/vxge-main.c", "vxge_tx_watchdog"],
["drivers/net/ethernet/netronome/nfp/nfp_net_common.c", "nfp_net_tx_timeout"],
["drivers/net/ethernet/nvidia/forcedeth.c", "nv_tx_timeout"],
["drivers/net/ethernet/nvidia/forcedeth.c", "nv_tx_timeout"],
["drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c", "pch_gbe_tx_timeout"],
["drivers/net/ethernet/packetengines/hamachi.c", "hamachi_tx_timeout"],
["drivers/net/ethernet/packetengines/yellowfin.c", "yellowfin_tx_timeout"],
["drivers/net/ethernet/pensando/ionic/ionic_lif.c", "ionic_tx_timeout"],
["drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c", "netxen_tx_timeout"],
["drivers/net/ethernet/qlogic/qla3xxx.c", "ql3xxx_tx_timeout"],
["drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c", "qlcnic_tx_timeout"],
["drivers/net/ethernet/qualcomm/emac/emac.c", "emac_tx_timeout"],
["drivers/net/ethernet/qualcomm/qca_spi.c", "qcaspi_netdev_tx_timeout"],
["drivers/net/ethernet/qualcomm/qca_uart.c", "qcauart_netdev_tx_timeout"],
["drivers/net/ethernet/rdc/r6040.c", "r6040_tx_timeout"],
["drivers/net/ethernet/realtek/8139cp.c", "cp_tx_timeout"],
["drivers/net/ethernet/realtek/8139too.c", "rtl8139_tx_timeout"],
["drivers/net/ethernet/realtek/atp.c", "tx_timeout"],
["drivers/net/ethernet/realtek/r8169_main.c", "rtl8169_tx_timeout"],
["drivers/net/ethernet/renesas/ravb_main.c", "ravb_tx_timeout"],
["drivers/net/ethernet/renesas/sh_eth.c", "sh_eth_tx_timeout"],
["drivers/net/ethernet/renesas/sh_eth.c", "sh_eth_tx_timeout"],
["drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c", "sxgbe_tx_timeout"],
["drivers/net/ethernet/seeq/ether3.c", "ether3_timeout"],
["drivers/net/ethernet/seeq/sgiseeq.c", "timeout"],
["drivers/net/ethernet/sfc/efx.c", "efx_watchdog"],
["drivers/net/ethernet/sfc/falcon/efx.c", "ef4_watchdog"],
["drivers/net/ethernet/sgi/ioc3-eth.c", "ioc3_timeout"],
["drivers/net/ethernet/sgi/meth.c", "meth_tx_timeout"],
["drivers/net/ethernet/silan/sc92031.c", "sc92031_tx_timeout"],
["drivers/net/ethernet/sis/sis190.c", "sis190_tx_timeout"],
["drivers/net/ethernet/sis/sis900.c", "sis900_tx_timeout"],
["drivers/net/ethernet/smsc/epic100.c", "epic_tx_timeout"],
["drivers/net/ethernet/smsc/smc911x.c", "smc911x_timeout"],
["drivers/net/ethernet/smsc/smc9194.c", "smc_timeout"],
["drivers/net/ethernet/smsc/smc91c92_cs.c", "smc_tx_timeout"],
["drivers/net/ethernet/smsc/smc91x.c", "smc_timeout"],
["drivers/net/ethernet/stmicro/stmmac/stmmac_main.c", "stmmac_tx_timeout"],
["drivers/net/ethernet/sun/cassini.c", "cas_tx_timeout"],
["drivers/net/ethernet/sun/ldmvsw.c", "sunvnet_tx_timeout_common"],
["drivers/net/ethernet/sun/niu.c", "niu_tx_timeout"],
["drivers/net/ethernet/sun/sunbmac.c", "bigmac_tx_timeout"],
["drivers/net/ethernet/sun/sungem.c", "gem_tx_timeout"],
["drivers/net/ethernet/sun/sunhme.c", "happy_meal_tx_timeout"],
["drivers/net/ethernet/sun/sunqe.c", "qe_tx_timeout"],
["drivers/net/ethernet/sun/sunvnet.c", "sunvnet_tx_timeout_common"],
["drivers/net/ethernet/sun/sunvnet_common.c", "sunvnet_tx_timeout_common"],
["drivers/net/ethernet/sun/sunvnet_common.h", "sunvnet_tx_timeout_common"],
["drivers/net/ethernet/synopsys/dwc-xlgmac-net.c", "xlgmac_tx_timeout"],
["drivers/net/ethernet/ti/cpmac.c", "cpmac_tx_timeout"],
["drivers/net/ethernet/ti/cpsw.c", "cpsw_ndo_tx_timeout"],
["drivers/net/ethernet/ti/cpsw_priv.c", "cpsw_ndo_tx_timeout"],
["drivers/net/ethernet/ti/cpsw_priv.h", "cpsw_ndo_tx_timeout"],
["drivers/net/ethernet/ti/davinci_emac.c", "emac_dev_tx_timeout"],
["drivers/net/ethernet/ti/netcp_core.c", "netcp_ndo_tx_timeout"],
["drivers/net/ethernet/ti/tlan.c", "tlan_tx_timeout"],
["drivers/net/ethernet/toshiba/ps3_gelic_net.h", "gelic_net_tx_timeout"],
["drivers/net/ethernet/toshiba/ps3_gelic_net.c", "gelic_net_tx_timeout"],
["drivers/net/ethernet/toshiba/ps3_gelic_wireless.c", "gelic_net_tx_timeout"],
["drivers/net/ethernet/toshiba/spider_net.c", "spider_net_tx_timeout"],
["drivers/net/ethernet/toshiba/tc35815.c", "tc35815_tx_timeout"],
["drivers/net/ethernet/via/via-rhine.c", "rhine_tx_timeout"],
["drivers/net/ethernet/wiznet/w5100.c", "w5100_tx_timeout"],
["drivers/net/ethernet/wiznet/w5300.c", "w5300_tx_timeout"],
["drivers/net/ethernet/xilinx/xilinx_emaclite.c", "xemaclite_tx_timeout"],
["drivers/net/ethernet/xircom/xirc2ps_cs.c", "xirc_tx_timeout"],
["drivers/net/fjes/fjes_main.c", "fjes_tx_retry"],
["drivers/net/slip/slip.c", "sl_tx_timeout"],
["include/linux/usb/usbnet.h", "usbnet_tx_timeout"],
["drivers/net/usb/aqc111.c", "usbnet_tx_timeout"],
["drivers/net/usb/asix_devices.c", "usbnet_tx_timeout"],
["drivers/net/usb/asix_devices.c", "usbnet_tx_timeout"],
["drivers/net/usb/asix_devices.c", "usbnet_tx_timeout"],
["drivers/net/usb/ax88172a.c", "usbnet_tx_timeout"],
["drivers/net/usb/ax88179_178a.c", "usbnet_tx_timeout"],
["drivers/net/usb/catc.c", "catc_tx_timeout"],
["drivers/net/usb/cdc_mbim.c", "usbnet_tx_timeout"],
["drivers/net/usb/cdc_ncm.c", "usbnet_tx_timeout"],
["drivers/net/usb/dm9601.c", "usbnet_tx_timeout"],
["drivers/net/usb/hso.c", "hso_net_tx_timeout"],
["drivers/net/usb/int51x1.c", "usbnet_tx_timeout"],
["drivers/net/usb/ipheth.c", "ipheth_tx_timeout"],
["drivers/net/usb/kaweth.c", "kaweth_tx_timeout"],
["drivers/net/usb/lan78xx.c", "lan78xx_tx_timeout"],
["drivers/net/usb/mcs7830.c", "usbnet_tx_timeout"],
["drivers/net/usb/pegasus.c", "pegasus_tx_timeout"],
["drivers/net/usb/qmi_wwan.c", "usbnet_tx_timeout"],
["drivers/net/usb/r8152.c", "rtl8152_tx_timeout"],
["drivers/net/usb/rndis_host.c", "usbnet_tx_timeout"],
["drivers/net/usb/rtl8150.c", "rtl8150_tx_timeout"],
["drivers/net/usb/sierra_net.c", "usbnet_tx_timeout"],
["drivers/net/usb/smsc75xx.c", "usbnet_tx_timeout"],
["drivers/net/usb/smsc95xx.c", "usbnet_tx_timeout"],
["drivers/net/usb/sr9700.c", "usbnet_tx_timeout"],
["drivers/net/usb/sr9800.c", "usbnet_tx_timeout"],
["drivers/net/usb/usbnet.c", "usbnet_tx_timeout"],
["drivers/net/vmxnet3/vmxnet3_drv.c", "vmxnet3_tx_timeout"],
["drivers/net/wan/cosa.c", "cosa_net_timeout"],
["drivers/net/wan/farsync.c", "fst_tx_timeout"],
["drivers/net/wan/fsl_ucc_hdlc.c", "uhdlc_tx_timeout"],
["drivers/net/wan/lmc/lmc_main.c", "lmc_driver_timeout"],
["drivers/net/wan/x25_asy.c", "x25_asy_timeout"],
["drivers/net/wimax/i2400m/netdev.c", "i2400m_tx_timeout"],
["drivers/net/wireless/intel/ipw2x00/ipw2100.c", "ipw2100_tx_timeout"],
["drivers/net/wireless/intersil/hostap/hostap_main.c", "prism2_tx_timeout"],
["drivers/net/wireless/intersil/hostap/hostap_main.c", "prism2_tx_timeout"],
["drivers/net/wireless/intersil/hostap/hostap_main.c", "prism2_tx_timeout"],
["drivers/net/wireless/intersil/orinoco/main.c", "orinoco_tx_timeout"],
["drivers/net/wireless/intersil/orinoco/orinoco_usb.c", "orinoco_tx_timeout"],
["drivers/net/wireless/intersil/orinoco/orinoco.h", "orinoco_tx_timeout"],
["drivers/net/wireless/intersil/prism54/islpci_dev.c", "islpci_eth_tx_timeout"],
["drivers/net/wireless/intersil/prism54/islpci_eth.c", "islpci_eth_tx_timeout"],
["drivers/net/wireless/intersil/prism54/islpci_eth.h", "islpci_eth_tx_timeout"],
["drivers/net/wireless/marvell/mwifiex/main.c", "mwifiex_tx_timeout"],
["drivers/net/wireless/quantenna/qtnfmac/core.c", "qtnf_netdev_tx_timeout"],
["drivers/net/wireless/quantenna/qtnfmac/core.h", "qtnf_netdev_tx_timeout"],
["drivers/net/wireless/rndis_wlan.c", "usbnet_tx_timeout"],
["drivers/net/wireless/wl3501_cs.c", "wl3501_tx_timeout"],
["drivers/net/wireless/zydas/zd1201.c", "zd1201_tx_timeout"],
["drivers/s390/net/qeth_core.h", "qeth_tx_timeout"],
["drivers/s390/net/qeth_core_main.c", "qeth_tx_timeout"],
["drivers/s390/net/qeth_l2_main.c", "qeth_tx_timeout"],
["drivers/s390/net/qeth_l2_main.c", "qeth_tx_timeout"],
["drivers/s390/net/qeth_l3_main.c", "qeth_tx_timeout"],
["drivers/s390/net/qeth_l3_main.c", "qeth_tx_timeout"],
["drivers/staging/ks7010/ks_wlan_net.c", "ks_wlan_tx_timeout"],
["drivers/staging/qlge/qlge_main.c", "qlge_tx_timeout"],
["drivers/staging/rtl8192e/rtl8192e/rtl_core.c", "_rtl92e_tx_timeout"],
["drivers/staging/rtl8192u/r8192U_core.c", "tx_timeout"],
["drivers/staging/unisys/visornic/visornic_main.c", "visornic_xmit_timeout"],
["drivers/staging/wlan-ng/p80211netdev.c", "p80211knetdev_tx_timeout"],
["drivers/tty/n_gsm.c", "gsm_mux_net_tx_timeout"],
["drivers/tty/synclink.c", "hdlcdev_tx_timeout"],
["drivers/tty/synclink_gt.c", "hdlcdev_tx_timeout"],
["drivers/tty/synclinkmp.c", "hdlcdev_tx_timeout"],
["net/atm/lec.c", "lec_tx_timeout"],
["net/bluetooth/bnep/netdev.c", "bnep_net_timeout"]
);
for my $p (@work) {
my @pair = @$p;
my $file = $pair[0];
my $func = $pair[1];
print STDERR $file , ": ", $func,"\n";
our @ARGV = ($file);
while (<ARGV>) {
if (m/($func\s*\(struct\s+net_device\s+\*[A-Za-z_]?[A-Za-z-0-9_]*)(\))/) {
print STDERR "found $1+$2 in $file\n";
}
if (s/($func\s*\(struct\s+net_device\s+\*[A-Za-z_]?[A-Za-z-0-9_]*)(\))/$1, unsigned int txqueue$2/) {
print STDERR "$func found in $file\n";
}
print;
}
}
where the list of files and functions is simply from:
git grep ndo_tx_timeout, with manual addition of headers
in the rare cases where the function is from a header,
then manually changing the few places which actually
call ndo_tx_timeout.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Acked-by: Heiner Kallweit <hkallweit1@gmail.com>
Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Acked-by: Shannon Nelson <snelson@pensando.io>
Reviewed-by: Martin Habets <mhabets@solarflare.com>
changes from v9:
fixup a forward declaration
changes from v9:
more leftovers from v3 change
changes from v8:
fix up a missing direct call to timeout
rebased on net-next
changes from v7:
fixup leftovers from v3 change
changes from v6:
fix typo in rtl driver
changes from v5:
add missing files (allow any net device argument name)
changes from v4:
add a missing driver header
changes from v3:
change queue # to unsigned
Changes from v2:
added headers
Changes from v1:
Fix errors found by kbuild:
generalize the pattern a bit, to pick up
a couple of instances missed by the previous
version.
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-12-10 21:23:51 +07:00
|
|
|
static void lec_tx_timeout(struct net_device *dev, unsigned int txqueue)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_info("%s\n", dev->name);
|
2016-05-03 21:33:13 +07:00
|
|
|
netif_trans_update(dev);
|
2005-04-17 05:20:36 +07:00
|
|
|
netif_wake_queue(dev);
|
|
|
|
}
|
|
|
|
|
2009-09-01 02:50:42 +07:00
|
|
|
static netdev_tx_t lec_start_xmit(struct sk_buff *skb,
|
|
|
|
struct net_device *dev)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:14 +07:00
|
|
|
struct sk_buff *skb2;
|
2008-11-13 14:39:10 +07:00
|
|
|
struct lec_priv *priv = netdev_priv(dev);
|
2006-09-30 07:11:14 +07:00
|
|
|
struct lecdatahdr_8023 *lec_h;
|
|
|
|
struct atm_vcc *vcc;
|
2005-04-17 05:20:36 +07:00
|
|
|
struct lec_arp_table *entry;
|
2006-09-30 07:11:14 +07:00
|
|
|
unsigned char *dst;
|
2005-04-17 05:20:36 +07:00
|
|
|
int min_frame_size;
|
2006-09-30 07:11:14 +07:00
|
|
|
int is_rdesc;
|
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("called\n");
|
2006-09-30 07:11:14 +07:00
|
|
|
if (!priv->lecd) {
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("%s:No lecd attached\n", dev->name);
|
2009-01-09 20:01:01 +07:00
|
|
|
dev->stats.tx_errors++;
|
2006-09-30 07:11:14 +07:00
|
|
|
netif_stop_queue(dev);
|
2009-06-12 12:34:37 +07:00
|
|
|
kfree_skb(skb);
|
|
|
|
return NETDEV_TX_OK;
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
|
|
|
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("skbuff head:%lx data:%lx tail:%lx end:%lx\n",
|
2010-01-26 18:40:00 +07:00
|
|
|
(long)skb->head, (long)skb->data, (long)skb_tail_pointer(skb),
|
|
|
|
(long)skb_end_pointer(skb));
|
2016-09-09 19:43:14 +07:00
|
|
|
#if IS_ENABLED(CONFIG_BRIDGE)
|
2006-09-30 07:11:14 +07:00
|
|
|
if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0)
|
|
|
|
lec_handle_bridge(skb, dev);
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
/* Make sure we have room for lec_id */
|
|
|
|
if (skb_headroom(skb) < 2) {
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("reallocating skb\n");
|
2006-09-30 07:11:14 +07:00
|
|
|
skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN);
|
2012-06-04 08:17:19 +07:00
|
|
|
if (unlikely(!skb2)) {
|
|
|
|
kfree_skb(skb);
|
2009-06-23 13:03:08 +07:00
|
|
|
return NETDEV_TX_OK;
|
2012-06-04 08:17:19 +07:00
|
|
|
}
|
|
|
|
consume_skb(skb);
|
2006-09-30 07:11:14 +07:00
|
|
|
skb = skb2;
|
|
|
|
}
|
|
|
|
skb_push(skb, 2);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2012-05-11 03:17:00 +07:00
|
|
|
/* Put le header to place */
|
2006-09-30 07:11:14 +07:00
|
|
|
lec_h = (struct lecdatahdr_8023 *)skb->data;
|
|
|
|
lec_h->le_header = htons(priv->lecid);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
#if DUMP_PACKETS >= 2
|
2010-01-26 18:40:08 +07:00
|
|
|
#define MAX_DUMP_SKB 99
|
2005-04-17 05:20:36 +07:00
|
|
|
#elif DUMP_PACKETS >= 1
|
2010-01-26 18:40:08 +07:00
|
|
|
#define MAX_DUMP_SKB 30
|
|
|
|
#endif
|
|
|
|
#if DUMP_PACKETS >= 1
|
|
|
|
printk(KERN_DEBUG "%s: send datalen:%ld lecid:%4.4x\n",
|
|
|
|
dev->name, skb->len, priv->lecid);
|
|
|
|
print_hex_dump(KERN_DEBUG, "", DUMP_OFFSET, 16, 1,
|
|
|
|
skb->data, min(skb->len, MAX_DUMP_SKB), true);
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif /* DUMP_PACKETS >= 1 */
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
/* Minimum ethernet-frame size */
|
2012-05-11 03:17:00 +07:00
|
|
|
min_frame_size = LEC_MINIMUM_8023_SIZE;
|
2006-09-30 07:11:14 +07:00
|
|
|
if (skb->len < min_frame_size) {
|
|
|
|
if ((skb->len + skb_tailroom(skb)) < min_frame_size) {
|
|
|
|
skb2 = skb_copy_expand(skb, 0,
|
|
|
|
min_frame_size - skb->truesize,
|
|
|
|
GFP_ATOMIC);
|
|
|
|
dev_kfree_skb(skb);
|
|
|
|
if (skb2 == NULL) {
|
2009-01-09 20:01:01 +07:00
|
|
|
dev->stats.tx_dropped++;
|
2009-06-23 13:03:08 +07:00
|
|
|
return NETDEV_TX_OK;
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
|
|
|
skb = skb2;
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
skb_put(skb, min_frame_size - skb->len);
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Send to right vcc */
|
|
|
|
is_rdesc = 0;
|
|
|
|
dst = lec_h->h_dest;
|
|
|
|
entry = NULL;
|
|
|
|
vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry);
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("%s:vcc:%p vcc_flags:%lx, entry:%p\n",
|
|
|
|
dev->name, vcc, vcc ? vcc->flags : 0, entry);
|
2006-09-30 07:11:14 +07:00
|
|
|
if (!vcc || !test_bit(ATM_VF_READY, &vcc->flags)) {
|
|
|
|
if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("%s:queuing packet, MAC address %pM\n",
|
|
|
|
dev->name, lec_h->h_dest);
|
2006-09-30 07:11:14 +07:00
|
|
|
skb_queue_tail(&entry->tx_wait, skb);
|
|
|
|
} else {
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("%s:tx queue full or no arp entry, dropping, MAC address: %pM\n",
|
|
|
|
dev->name, lec_h->h_dest);
|
2009-01-09 20:01:01 +07:00
|
|
|
dev->stats.tx_dropped++;
|
2006-09-30 07:11:14 +07:00
|
|
|
dev_kfree_skb(skb);
|
|
|
|
}
|
2006-09-30 07:17:17 +07:00
|
|
|
goto out;
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
|
|
|
#if DUMP_PACKETS > 0
|
2010-01-26 18:40:08 +07:00
|
|
|
printk(KERN_DEBUG "%s:sending to vpi:%d vci:%d\n",
|
|
|
|
dev->name, vcc->vpi, vcc->vci);
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif /* DUMP_PACKETS > 0 */
|
2006-09-30 07:11:14 +07:00
|
|
|
|
|
|
|
while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("emptying tx queue, MAC address %pM\n", lec_h->h_dest);
|
2009-01-09 20:01:01 +07:00
|
|
|
lec_send(vcc, skb2);
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2009-01-09 20:01:01 +07:00
|
|
|
lec_send(vcc, skb);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
if (!atm_may_send(vcc, 0)) {
|
|
|
|
struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
|
|
|
|
|
|
|
|
vpriv->xoff = 1;
|
|
|
|
netif_stop_queue(dev);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* vcc->pop() might have occurred in between, making
|
|
|
|
* the vcc usuable again. Since xmit is serialized,
|
|
|
|
* this is the only situation we have to re-test.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (atm_may_send(vcc, 0))
|
|
|
|
netif_wake_queue(dev);
|
|
|
|
}
|
|
|
|
|
2006-09-30 07:17:17 +07:00
|
|
|
out:
|
|
|
|
if (entry)
|
|
|
|
lec_arp_put(entry);
|
2016-05-03 21:33:13 +07:00
|
|
|
netif_trans_update(dev);
|
2009-06-23 13:03:08 +07:00
|
|
|
return NETDEV_TX_OK;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* The inverse routine to net_open(). */
|
2006-09-30 07:11:14 +07:00
|
|
|
static int lec_close(struct net_device *dev)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:14 +07:00
|
|
|
netif_stop_queue(dev);
|
|
|
|
return 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2006-09-30 07:11:14 +07:00
|
|
|
struct net_device *dev = (struct net_device *)vcc->proto_data;
|
2008-11-13 14:39:10 +07:00
|
|
|
struct lec_priv *priv = netdev_priv(dev);
|
2006-09-30 07:11:14 +07:00
|
|
|
struct atmlec_msg *mesg;
|
|
|
|
struct lec_arp_table *entry;
|
|
|
|
int i;
|
|
|
|
char *tmp; /* FIXME */
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2017-06-30 17:08:00 +07:00
|
|
|
WARN_ON(refcount_sub_and_test(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc));
|
2006-09-30 07:11:14 +07:00
|
|
|
mesg = (struct atmlec_msg *)skb->data;
|
|
|
|
tmp = skb->data;
|
|
|
|
tmp += sizeof(struct atmlec_msg);
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("%s: msg from zeppelin:%d\n", dev->name, mesg->type);
|
2006-09-30 07:11:14 +07:00
|
|
|
switch (mesg->type) {
|
|
|
|
case l_set_mac_addr:
|
2010-01-26 18:40:08 +07:00
|
|
|
for (i = 0; i < 6; i++)
|
2006-09-30 07:11:14 +07:00
|
|
|
dev->dev_addr[i] = mesg->content.normal.mac_addr[i];
|
|
|
|
break;
|
|
|
|
case l_del_mac_addr:
|
2010-01-26 18:40:08 +07:00
|
|
|
for (i = 0; i < 6; i++)
|
2006-09-30 07:11:14 +07:00
|
|
|
dev->dev_addr[i] = 0;
|
|
|
|
break;
|
|
|
|
case l_addr_delete:
|
|
|
|
lec_addr_delete(priv, mesg->content.normal.atm_addr,
|
|
|
|
mesg->content.normal.flag);
|
|
|
|
break;
|
|
|
|
case l_topology_change:
|
|
|
|
priv->topology_change = mesg->content.normal.flag;
|
|
|
|
break;
|
|
|
|
case l_flush_complete:
|
|
|
|
lec_flush_complete(priv, mesg->content.normal.flag);
|
|
|
|
break;
|
|
|
|
case l_narp_req: /* LANE2: see 7.1.35 in the lane2 spec */
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:14 +07:00
|
|
|
entry = lec_arp_find(priv, mesg->content.normal.mac_addr);
|
|
|
|
lec_arp_remove(priv, entry);
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
if (mesg->content.normal.no_source_le_narp)
|
|
|
|
break;
|
|
|
|
/* FALL THROUGH */
|
|
|
|
case l_arp_update:
|
|
|
|
lec_arp_update(priv, mesg->content.normal.mac_addr,
|
|
|
|
mesg->content.normal.atm_addr,
|
|
|
|
mesg->content.normal.flag,
|
|
|
|
mesg->content.normal.targetless_le_arp);
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("in l_arp_update\n");
|
2006-09-30 07:11:14 +07:00
|
|
|
if (mesg->sizeoftlvs != 0) { /* LANE2 3.1.5 */
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("LANE2 3.1.5, got tlvs, size %d\n",
|
|
|
|
mesg->sizeoftlvs);
|
2006-09-30 07:11:14 +07:00
|
|
|
lane2_associate_ind(dev, mesg->content.normal.mac_addr,
|
|
|
|
tmp, mesg->sizeoftlvs);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case l_config:
|
|
|
|
priv->maximum_unknown_frame_count =
|
|
|
|
mesg->content.config.maximum_unknown_frame_count;
|
|
|
|
priv->max_unknown_frame_time =
|
|
|
|
(mesg->content.config.max_unknown_frame_time * HZ);
|
|
|
|
priv->max_retry_count = mesg->content.config.max_retry_count;
|
|
|
|
priv->aging_time = (mesg->content.config.aging_time * HZ);
|
|
|
|
priv->forward_delay_time =
|
|
|
|
(mesg->content.config.forward_delay_time * HZ);
|
|
|
|
priv->arp_response_time =
|
|
|
|
(mesg->content.config.arp_response_time * HZ);
|
|
|
|
priv->flush_timeout = (mesg->content.config.flush_timeout * HZ);
|
|
|
|
priv->path_switching_delay =
|
|
|
|
(mesg->content.config.path_switching_delay * HZ);
|
2010-01-26 18:40:08 +07:00
|
|
|
priv->lane_version = mesg->content.config.lane_version;
|
|
|
|
/* LANE2 */
|
2005-04-17 05:20:36 +07:00
|
|
|
priv->lane2_ops = NULL;
|
|
|
|
if (priv->lane_version > 1)
|
|
|
|
priv->lane2_ops = &lane2_ops;
|
2014-08-14 20:19:47 +07:00
|
|
|
rtnl_lock();
|
2009-03-22 03:37:28 +07:00
|
|
|
if (dev_set_mtu(dev, mesg->content.config.mtu))
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("%s: change_mtu to %d failed\n",
|
|
|
|
dev->name, mesg->content.config.mtu);
|
2014-08-14 20:19:47 +07:00
|
|
|
rtnl_unlock();
|
2005-04-17 05:20:36 +07:00
|
|
|
priv->is_proxy = mesg->content.config.is_proxy;
|
2006-09-30 07:11:14 +07:00
|
|
|
break;
|
|
|
|
case l_flush_tran_id:
|
|
|
|
lec_set_flush_tran_id(priv, mesg->content.normal.atm_addr,
|
|
|
|
mesg->content.normal.flag);
|
|
|
|
break;
|
|
|
|
case l_set_lecid:
|
|
|
|
priv->lecid =
|
|
|
|
(unsigned short)(0xffff & mesg->content.normal.flag);
|
|
|
|
break;
|
|
|
|
case l_should_bridge:
|
2016-09-09 19:43:14 +07:00
|
|
|
#if IS_ENABLED(CONFIG_BRIDGE)
|
2010-01-26 18:40:19 +07:00
|
|
|
{
|
|
|
|
pr_debug("%s: bridge zeppelin asks about %pM\n",
|
|
|
|
dev->name, mesg->content.proxy.mac_addr);
|
2006-09-30 07:11:14 +07:00
|
|
|
|
2010-01-26 18:40:19 +07:00
|
|
|
if (br_fdb_test_addr_hook == NULL)
|
|
|
|
break;
|
2006-09-30 07:11:14 +07:00
|
|
|
|
2010-01-26 18:40:19 +07:00
|
|
|
if (br_fdb_test_addr_hook(dev, mesg->content.proxy.mac_addr)) {
|
|
|
|
/* hit from bridge table, send LE_ARP_RESPONSE */
|
|
|
|
struct sk_buff *skb2;
|
|
|
|
struct sock *sk;
|
|
|
|
|
|
|
|
pr_debug("%s: entry found, responding to zeppelin\n",
|
|
|
|
dev->name);
|
|
|
|
skb2 = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
|
|
|
|
if (skb2 == NULL)
|
|
|
|
break;
|
|
|
|
skb2->len = sizeof(struct atmlec_msg);
|
|
|
|
skb_copy_to_linear_data(skb2, mesg, sizeof(*mesg));
|
|
|
|
atm_force_charge(priv->lecd, skb2->truesize);
|
|
|
|
sk = sk_atm(priv->lecd);
|
|
|
|
skb_queue_tail(&sk->sk_receive_queue, skb2);
|
2014-04-12 03:15:36 +07:00
|
|
|
sk->sk_data_ready(sk);
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
2010-01-26 18:40:19 +07:00
|
|
|
}
|
2016-09-09 19:43:14 +07:00
|
|
|
#endif /* IS_ENABLED(CONFIG_BRIDGE) */
|
2006-09-30 07:11:14 +07:00
|
|
|
break;
|
|
|
|
default:
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("%s: Unknown message type %d\n", dev->name, mesg->type);
|
2006-09-30 07:11:14 +07:00
|
|
|
dev_kfree_skb(skb);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
dev_kfree_skb(skb);
|
|
|
|
return 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
static void lec_atm_close(struct atm_vcc *vcc)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:14 +07:00
|
|
|
struct sk_buff *skb;
|
|
|
|
struct net_device *dev = (struct net_device *)vcc->proto_data;
|
2008-11-13 14:39:10 +07:00
|
|
|
struct lec_priv *priv = netdev_priv(dev);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
priv->lecd = NULL;
|
|
|
|
/* Do something needful? */
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
netif_stop_queue(dev);
|
|
|
|
lec_arp_destroy(priv);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
if (skb_peek(&sk_atm(vcc)->sk_receive_queue))
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("%s closing with messages pending\n", dev->name);
|
2010-01-26 18:40:19 +07:00
|
|
|
while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue))) {
|
2006-09-30 07:11:14 +07:00
|
|
|
atm_return(vcc, skb->truesize);
|
2005-04-17 05:20:36 +07:00
|
|
|
dev_kfree_skb(skb);
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("%s: Shut down!\n", dev->name);
|
2006-09-30 07:11:14 +07:00
|
|
|
module_put(THIS_MODULE);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2017-08-09 16:32:08 +07:00
|
|
|
static const struct atmdev_ops lecdev_ops = {
|
2006-09-30 07:11:14 +07:00
|
|
|
.close = lec_atm_close,
|
|
|
|
.send = lec_atm_send
|
2005-04-17 05:20:36 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct atm_dev lecatm_dev = {
|
2006-09-30 07:11:14 +07:00
|
|
|
.ops = &lecdev_ops,
|
|
|
|
.type = "lec",
|
|
|
|
.number = 999, /* dummy device number */
|
2007-04-26 15:37:44 +07:00
|
|
|
.lock = __SPIN_LOCK_UNLOCKED(lecatm_dev.lock)
|
2005-04-17 05:20:36 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* LANE2: new argument struct sk_buff *data contains
|
|
|
|
* the LE_ARP based TLVs introduced in the LANE2 spec
|
|
|
|
*/
|
2006-09-30 07:11:14 +07:00
|
|
|
static int
|
|
|
|
send_to_lecd(struct lec_priv *priv, atmlec_msg_type type,
|
2008-06-18 06:20:06 +07:00
|
|
|
const unsigned char *mac_addr, const unsigned char *atm_addr,
|
2006-09-30 07:11:14 +07:00
|
|
|
struct sk_buff *data)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
struct sock *sk;
|
|
|
|
struct sk_buff *skb;
|
|
|
|
struct atmlec_msg *mesg;
|
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
if (!priv || !priv->lecd)
|
2005-04-17 05:20:36 +07:00
|
|
|
return -1;
|
|
|
|
skb = alloc_skb(sizeof(struct atmlec_msg), GFP_ATOMIC);
|
|
|
|
if (!skb)
|
|
|
|
return -1;
|
|
|
|
skb->len = sizeof(struct atmlec_msg);
|
|
|
|
mesg = (struct atmlec_msg *)skb->data;
|
2006-09-30 07:11:14 +07:00
|
|
|
memset(mesg, 0, sizeof(struct atmlec_msg));
|
2005-04-17 05:20:36 +07:00
|
|
|
mesg->type = type;
|
2006-09-30 07:11:14 +07:00
|
|
|
if (data != NULL)
|
|
|
|
mesg->sizeoftlvs = data->len;
|
2005-04-17 05:20:36 +07:00
|
|
|
if (mac_addr)
|
2014-01-22 09:55:22 +07:00
|
|
|
ether_addr_copy(mesg->content.normal.mac_addr, mac_addr);
|
2006-09-30 07:11:14 +07:00
|
|
|
else
|
|
|
|
mesg->content.normal.targetless_le_arp = 1;
|
2005-04-17 05:20:36 +07:00
|
|
|
if (atm_addr)
|
|
|
|
memcpy(&mesg->content.normal.atm_addr, atm_addr, ATM_ESA_LEN);
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
atm_force_charge(priv->lecd, skb->truesize);
|
2005-04-17 05:20:36 +07:00
|
|
|
sk = sk_atm(priv->lecd);
|
|
|
|
skb_queue_tail(&sk->sk_receive_queue, skb);
|
2014-04-12 03:15:36 +07:00
|
|
|
sk->sk_data_ready(sk);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
if (data != NULL) {
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("about to send %d bytes of data\n", data->len);
|
2006-09-30 07:11:14 +07:00
|
|
|
atm_force_charge(priv->lecd, data->truesize);
|
|
|
|
skb_queue_tail(&sk->sk_receive_queue, data);
|
2014-04-12 03:15:36 +07:00
|
|
|
sk->sk_data_ready(sk);
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
return 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void lec_set_multicast_list(struct net_device *dev)
|
|
|
|
{
|
2006-09-30 07:11:14 +07:00
|
|
|
/*
|
|
|
|
* by default, all multicast frames arrive over the bus.
|
|
|
|
* eventually support selective multicast service
|
|
|
|
*/
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2009-01-09 20:01:02 +07:00
|
|
|
static const struct net_device_ops lec_netdev_ops = {
|
|
|
|
.ndo_open = lec_open,
|
|
|
|
.ndo_stop = lec_close,
|
|
|
|
.ndo_start_xmit = lec_start_xmit,
|
|
|
|
.ndo_tx_timeout = lec_tx_timeout,
|
2011-08-16 13:29:01 +07:00
|
|
|
.ndo_set_rx_mode = lec_set_multicast_list,
|
2009-01-09 20:01:02 +07:00
|
|
|
};
|
|
|
|
|
2008-06-18 06:20:06 +07:00
|
|
|
static const unsigned char lec_ctrl_magic[] = {
|
2006-09-30 07:11:14 +07:00
|
|
|
0xff,
|
|
|
|
0x00,
|
|
|
|
0x01,
|
|
|
|
0x01
|
|
|
|
};
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2005-09-30 07:30:54 +07:00
|
|
|
#define LEC_DATA_DIRECT_8023 2
|
|
|
|
#define LEC_DATA_DIRECT_8025 3
|
|
|
|
|
|
|
|
static int lec_is_data_direct(struct atm_vcc *vcc)
|
2006-09-30 07:11:14 +07:00
|
|
|
{
|
2005-09-30 07:30:54 +07:00
|
|
|
return ((vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8023) ||
|
|
|
|
(vcc->sap.blli[0].l3.tr9577.snap[4] == LEC_DATA_DIRECT_8025));
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
2005-09-30 07:30:54 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2005-09-30 07:30:54 +07:00
|
|
|
unsigned long flags;
|
2006-09-30 07:11:14 +07:00
|
|
|
struct net_device *dev = (struct net_device *)vcc->proto_data;
|
2008-11-13 14:39:10 +07:00
|
|
|
struct lec_priv *priv = netdev_priv(dev);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
#if DUMP_PACKETS > 0
|
2010-01-26 18:40:00 +07:00
|
|
|
printk(KERN_DEBUG "%s: vcc vpi:%d vci:%d\n",
|
|
|
|
dev->name, vcc->vpi, vcc->vci);
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
2006-09-30 07:11:14 +07:00
|
|
|
if (!skb) {
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("%s: null skb\n", dev->name);
|
2006-09-30 07:11:14 +07:00
|
|
|
lec_vcc_close(priv, vcc);
|
|
|
|
return;
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
#if DUMP_PACKETS >= 2
|
2010-01-26 18:40:00 +07:00
|
|
|
#define MAX_SKB_DUMP 99
|
2005-04-17 05:20:36 +07:00
|
|
|
#elif DUMP_PACKETS >= 1
|
2010-01-26 18:40:00 +07:00
|
|
|
#define MAX_SKB_DUMP 30
|
|
|
|
#endif
|
|
|
|
#if DUMP_PACKETS > 0
|
|
|
|
printk(KERN_DEBUG "%s: rcv datalen:%ld lecid:%4.4x\n",
|
|
|
|
dev->name, skb->len, priv->lecid);
|
|
|
|
print_hex_dump(KERN_DEBUG, "", DUMP_OFFSET, 16, 1,
|
|
|
|
skb->data, min(MAX_SKB_DUMP, skb->len), true);
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif /* DUMP_PACKETS > 0 */
|
2010-01-26 18:40:00 +07:00
|
|
|
if (memcmp(skb->data, lec_ctrl_magic, 4) == 0) {
|
|
|
|
/* Control frame, to daemon */
|
2005-04-17 05:20:36 +07:00
|
|
|
struct sock *sk = sk_atm(vcc);
|
|
|
|
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("%s: To daemon\n", dev->name);
|
2006-09-30 07:11:14 +07:00
|
|
|
skb_queue_tail(&sk->sk_receive_queue, skb);
|
2014-04-12 03:15:36 +07:00
|
|
|
sk->sk_data_ready(sk);
|
2006-09-30 07:11:14 +07:00
|
|
|
} else { /* Data frame, queue to protocol handlers */
|
2005-09-30 07:30:54 +07:00
|
|
|
struct lec_arp_table *entry;
|
2006-09-30 07:11:14 +07:00
|
|
|
unsigned char *src, *dst;
|
|
|
|
|
|
|
|
atm_return(vcc, skb->truesize);
|
2006-11-15 12:11:29 +07:00
|
|
|
if (*(__be16 *) skb->data == htons(priv->lecid) ||
|
2006-09-30 07:11:14 +07:00
|
|
|
!priv->lecd || !(dev->flags & IFF_UP)) {
|
|
|
|
/*
|
|
|
|
* Probably looping back, or if lecd is missing,
|
|
|
|
* lecd has gone down
|
|
|
|
*/
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("Ignoring frame...\n");
|
2006-09-30 07:11:14 +07:00
|
|
|
dev_kfree_skb(skb);
|
|
|
|
return;
|
|
|
|
}
|
2012-05-11 03:17:00 +07:00
|
|
|
dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest;
|
2005-09-30 07:30:54 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
/*
|
|
|
|
* If this is a Data Direct VCC, and the VCC does not match
|
2005-09-30 07:30:54 +07:00
|
|
|
* the LE_ARP cache entry, delete the LE_ARP cache entry.
|
|
|
|
*/
|
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
|
|
|
if (lec_is_data_direct(vcc)) {
|
2012-05-11 03:17:00 +07:00
|
|
|
src = ((struct lecdatahdr_8023 *)skb->data)->h_source;
|
2005-09-30 07:30:54 +07:00
|
|
|
entry = lec_arp_find(priv, src);
|
|
|
|
if (entry && entry->vcc != vcc) {
|
|
|
|
lec_arp_remove(priv, entry);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2005-09-30 07:30:54 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
if (!(dst[0] & 0x01) && /* Never filter Multi/Broadcast */
|
|
|
|
!priv->is_proxy && /* Proxy wants all the packets */
|
2005-04-17 05:20:36 +07:00
|
|
|
memcmp(dst, dev->dev_addr, dev->addr_len)) {
|
2006-09-30 07:11:14 +07:00
|
|
|
dev_kfree_skb(skb);
|
|
|
|
return;
|
|
|
|
}
|
2010-01-26 18:40:08 +07:00
|
|
|
if (!hlist_empty(&priv->lec_arp_empty_ones))
|
2006-09-30 07:11:14 +07:00
|
|
|
lec_arp_check_empties(priv, vcc, skb);
|
|
|
|
skb_pull(skb, 2); /* skip lec_id */
|
2012-05-11 03:17:00 +07:00
|
|
|
skb->protocol = eth_type_trans(skb, dev);
|
2009-01-09 20:01:01 +07:00
|
|
|
dev->stats.rx_packets++;
|
|
|
|
dev->stats.rx_bytes += skb->len;
|
2006-09-30 07:11:14 +07:00
|
|
|
memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
|
|
|
|
netif_rx(skb);
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
static void lec_pop(struct atm_vcc *vcc, struct sk_buff *skb)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
|
|
|
|
struct net_device *dev = skb->dev;
|
|
|
|
|
|
|
|
if (vpriv == NULL) {
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_info("vpriv = NULL!?!?!?\n");
|
2005-04-17 05:20:36 +07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vpriv->old_pop(vcc, skb);
|
|
|
|
|
|
|
|
if (vpriv->xoff && atm_may_send(vcc, 0)) {
|
|
|
|
vpriv->xoff = 0;
|
|
|
|
if (netif_running(dev) && netif_queue_stopped(dev))
|
|
|
|
netif_wake_queue(dev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
struct lec_vcc_priv *vpriv;
|
2006-09-30 07:11:14 +07:00
|
|
|
int bytes_left;
|
|
|
|
struct atmlec_ioc ioc_data;
|
|
|
|
|
|
|
|
/* Lecd must be up in this case */
|
|
|
|
bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmlec_ioc));
|
2010-01-26 18:40:00 +07:00
|
|
|
if (bytes_left != 0)
|
|
|
|
pr_info("copy from user failed for %d bytes\n", bytes_left);
|
2018-05-04 01:45:58 +07:00
|
|
|
if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF)
|
|
|
|
return -EINVAL;
|
|
|
|
ioc_data.dev_num = array_index_nospec(ioc_data.dev_num, MAX_LEC_ITF);
|
|
|
|
if (!dev_lec[ioc_data.dev_num])
|
2006-09-30 07:11:14 +07:00
|
|
|
return -EINVAL;
|
2010-01-26 18:40:08 +07:00
|
|
|
vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL);
|
|
|
|
if (!vpriv)
|
2005-04-17 05:20:36 +07:00
|
|
|
return -ENOMEM;
|
|
|
|
vpriv->xoff = 0;
|
|
|
|
vpriv->old_pop = vcc->pop;
|
|
|
|
vcc->user_back = vpriv;
|
|
|
|
vcc->pop = lec_pop;
|
2008-11-13 14:39:10 +07:00
|
|
|
lec_vcc_added(netdev_priv(dev_lec[ioc_data.dev_num]),
|
2006-09-30 07:11:14 +07:00
|
|
|
&ioc_data, vcc, vcc->push);
|
|
|
|
vcc->proto_data = dev_lec[ioc_data.dev_num];
|
|
|
|
vcc->push = lec_push;
|
|
|
|
return 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
static int lec_mcast_attach(struct atm_vcc *vcc, int arg)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2019-04-16 03:57:23 +07:00
|
|
|
if (arg < 0 || arg >= MAX_LEC_ITF)
|
|
|
|
return -EINVAL;
|
|
|
|
arg = array_index_nospec(arg, MAX_LEC_ITF);
|
|
|
|
if (!dev_lec[arg])
|
2006-09-30 07:11:14 +07:00
|
|
|
return -EINVAL;
|
|
|
|
vcc->proto_data = dev_lec[arg];
|
2010-11-15 18:12:33 +07:00
|
|
|
return lec_mcast_make(netdev_priv(dev_lec[arg]), vcc);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize device. */
|
2006-09-30 07:11:14 +07:00
|
|
|
static int lecd_attach(struct atm_vcc *vcc, int arg)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
struct lec_priv *priv;
|
|
|
|
|
|
|
|
if (arg < 0)
|
2019-05-03 19:39:48 +07:00
|
|
|
arg = 0;
|
2006-09-30 07:11:14 +07:00
|
|
|
if (arg >= MAX_LEC_ITF)
|
|
|
|
return -EINVAL;
|
2019-04-16 03:57:23 +07:00
|
|
|
i = array_index_nospec(arg, MAX_LEC_ITF);
|
2006-09-30 07:11:14 +07:00
|
|
|
if (!dev_lec[i]) {
|
2012-05-11 03:17:00 +07:00
|
|
|
int size;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
size = sizeof(struct lec_priv);
|
2012-05-11 03:17:00 +07:00
|
|
|
dev_lec[i] = alloc_etherdev(size);
|
2006-09-30 07:11:14 +07:00
|
|
|
if (!dev_lec[i])
|
|
|
|
return -ENOMEM;
|
2009-12-04 12:19:30 +07:00
|
|
|
dev_lec[i]->netdev_ops = &lec_netdev_ops;
|
2016-10-21 00:55:19 +07:00
|
|
|
dev_lec[i]->max_mtu = 18190;
|
2006-09-30 07:11:14 +07:00
|
|
|
snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i);
|
|
|
|
if (register_netdev(dev_lec[i])) {
|
|
|
|
free_netdev(dev_lec[i]);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2008-11-13 14:39:10 +07:00
|
|
|
priv = netdev_priv(dev_lec[i]);
|
2006-09-30 07:11:14 +07:00
|
|
|
} else {
|
2008-11-13 14:39:10 +07:00
|
|
|
priv = netdev_priv(dev_lec[i]);
|
2006-09-30 07:11:14 +07:00
|
|
|
if (priv->lecd)
|
|
|
|
return -EADDRINUSE;
|
|
|
|
}
|
|
|
|
lec_arp_init(priv);
|
|
|
|
priv->itfnum = i; /* LANE2 addition */
|
|
|
|
priv->lecd = vcc;
|
|
|
|
vcc->dev = &lecatm_dev;
|
|
|
|
vcc_insert_socket(sk_atm(vcc));
|
|
|
|
|
|
|
|
vcc->proto_data = dev_lec[i];
|
|
|
|
set_bit(ATM_VF_META, &vcc->flags);
|
|
|
|
set_bit(ATM_VF_READY, &vcc->flags);
|
|
|
|
|
|
|
|
/* Set default values to these variables */
|
|
|
|
priv->maximum_unknown_frame_count = 1;
|
|
|
|
priv->max_unknown_frame_time = (1 * HZ);
|
|
|
|
priv->vcc_timeout_period = (1200 * HZ);
|
|
|
|
priv->max_retry_count = 1;
|
|
|
|
priv->aging_time = (300 * HZ);
|
|
|
|
priv->forward_delay_time = (15 * HZ);
|
|
|
|
priv->topology_change = 0;
|
|
|
|
priv->arp_response_time = (1 * HZ);
|
|
|
|
priv->flush_timeout = (4 * HZ);
|
|
|
|
priv->path_switching_delay = (6 * HZ);
|
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
if (dev_lec[i]->flags & IFF_UP)
|
2006-09-30 07:11:14 +07:00
|
|
|
netif_start_queue(dev_lec[i]);
|
|
|
|
__module_get(THIS_MODULE);
|
|
|
|
return i;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef CONFIG_PROC_FS
|
2009-08-06 00:42:58 +07:00
|
|
|
static const char *lec_arp_get_status_string(unsigned char status)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2009-08-06 00:42:58 +07:00
|
|
|
static const char *const lec_arp_status_string[] = {
|
2005-04-17 05:20:36 +07:00
|
|
|
"ESI_UNKNOWN ",
|
|
|
|
"ESI_ARP_PENDING ",
|
|
|
|
"ESI_VC_PENDING ",
|
|
|
|
"<Undefined> ",
|
|
|
|
"ESI_FLUSH_PENDING ",
|
|
|
|
"ESI_FORWARD_DIRECT"
|
|
|
|
};
|
|
|
|
|
|
|
|
if (status > ESI_FORWARD_DIRECT)
|
|
|
|
status = 3; /* ESI_UNDEFINED */
|
|
|
|
return lec_arp_status_string[status];
|
|
|
|
}
|
|
|
|
|
|
|
|
static void lec_info(struct seq_file *seq, struct lec_arp_table *entry)
|
|
|
|
{
|
2020-01-23 21:20:02 +07:00
|
|
|
seq_printf(seq, "%pM ", entry->mac_addr);
|
|
|
|
seq_printf(seq, "%*phN ", ATM_ESA_LEN, entry->atm_addr);
|
|
|
|
seq_printf(seq, "%s %4.4x", lec_arp_get_status_string(entry->status),
|
2005-04-17 05:20:36 +07:00
|
|
|
entry->flags & 0xffff);
|
|
|
|
if (entry->vcc)
|
|
|
|
seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci);
|
|
|
|
else
|
2006-09-30 07:11:14 +07:00
|
|
|
seq_printf(seq, " ");
|
2005-04-17 05:20:36 +07:00
|
|
|
if (entry->recv_vcc) {
|
|
|
|
seq_printf(seq, " %3d %3d", entry->recv_vcc->vpi,
|
|
|
|
entry->recv_vcc->vci);
|
2006-09-30 07:11:14 +07:00
|
|
|
}
|
|
|
|
seq_putc(seq, '\n');
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
struct lec_state {
|
|
|
|
unsigned long flags;
|
|
|
|
struct lec_priv *locked;
|
2006-09-30 07:14:27 +07:00
|
|
|
struct hlist_node *node;
|
2005-04-17 05:20:36 +07:00
|
|
|
struct net_device *dev;
|
|
|
|
int itf;
|
|
|
|
int arp_table;
|
|
|
|
int misc_table;
|
|
|
|
};
|
|
|
|
|
2006-09-30 07:14:27 +07:00
|
|
|
static void *lec_tbl_walk(struct lec_state *state, struct hlist_head *tbl,
|
2005-04-17 05:20:36 +07:00
|
|
|
loff_t *l)
|
|
|
|
{
|
2006-09-30 07:14:27 +07:00
|
|
|
struct hlist_node *e = state->node;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
if (!e)
|
2006-09-30 07:14:27 +07:00
|
|
|
e = tbl->first;
|
2008-04-10 17:33:03 +07:00
|
|
|
if (e == SEQ_START_TOKEN) {
|
2006-09-30 07:14:27 +07:00
|
|
|
e = tbl->first;
|
2005-04-17 05:20:36 +07:00
|
|
|
--*l;
|
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
|
2014-08-12 20:00:36 +07:00
|
|
|
for (; e; e = e->next) {
|
2005-04-17 05:20:36 +07:00
|
|
|
if (--*l < 0)
|
|
|
|
break;
|
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
state->node = e;
|
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
return (*l < 0) ? state : NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *lec_arp_walk(struct lec_state *state, loff_t *l,
|
2006-09-30 07:11:14 +07:00
|
|
|
struct lec_priv *priv)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
void *v = NULL;
|
|
|
|
int p;
|
|
|
|
|
|
|
|
for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
|
2006-09-30 07:14:27 +07:00
|
|
|
v = lec_tbl_walk(state, &priv->lec_arp_tables[p], l);
|
2005-04-17 05:20:36 +07:00
|
|
|
if (v)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
state->arp_table = p;
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *lec_misc_walk(struct lec_state *state, loff_t *l,
|
|
|
|
struct lec_priv *priv)
|
|
|
|
{
|
2006-09-30 07:14:27 +07:00
|
|
|
struct hlist_head *lec_misc_tables[] = {
|
|
|
|
&priv->lec_arp_empty_ones,
|
|
|
|
&priv->lec_no_forward,
|
|
|
|
&priv->mcast_fwds
|
2005-04-17 05:20:36 +07:00
|
|
|
};
|
|
|
|
void *v = NULL;
|
|
|
|
int q;
|
|
|
|
|
|
|
|
for (q = state->misc_table; q < ARRAY_SIZE(lec_misc_tables); q++) {
|
|
|
|
v = lec_tbl_walk(state, lec_misc_tables[q], l);
|
|
|
|
if (v)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
state->misc_table = q;
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *lec_priv_walk(struct lec_state *state, loff_t *l,
|
|
|
|
struct lec_priv *priv)
|
|
|
|
{
|
|
|
|
if (!state->locked) {
|
|
|
|
state->locked = priv;
|
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, state->flags);
|
|
|
|
}
|
2006-09-30 07:11:14 +07:00
|
|
|
if (!lec_arp_walk(state, l, priv) && !lec_misc_walk(state, l, priv)) {
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags);
|
|
|
|
state->locked = NULL;
|
|
|
|
/* Partial state reset for the next time we get called */
|
|
|
|
state->arp_table = state->misc_table = 0;
|
|
|
|
}
|
|
|
|
return state->locked;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *lec_itf_walk(struct lec_state *state, loff_t *l)
|
|
|
|
{
|
|
|
|
struct net_device *dev;
|
|
|
|
void *v;
|
|
|
|
|
|
|
|
dev = state->dev ? state->dev : dev_lec[state->itf];
|
2008-11-13 14:39:10 +07:00
|
|
|
v = (dev && netdev_priv(dev)) ?
|
|
|
|
lec_priv_walk(state, l, netdev_priv(dev)) : NULL;
|
2005-04-17 05:20:36 +07:00
|
|
|
if (!v && dev) {
|
|
|
|
dev_put(dev);
|
|
|
|
/* Partial state reset for the next time we get called */
|
|
|
|
dev = NULL;
|
|
|
|
}
|
|
|
|
state->dev = dev;
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *lec_get_idx(struct lec_state *state, loff_t l)
|
|
|
|
{
|
|
|
|
void *v = NULL;
|
|
|
|
|
|
|
|
for (; state->itf < MAX_LEC_ITF; state->itf++) {
|
|
|
|
v = lec_itf_walk(state, &l);
|
|
|
|
if (v)
|
|
|
|
break;
|
|
|
|
}
|
2006-09-30 07:11:14 +07:00
|
|
|
return v;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
|
|
|
|
{
|
|
|
|
struct lec_state *state = seq->private;
|
|
|
|
|
|
|
|
state->itf = 0;
|
|
|
|
state->dev = NULL;
|
|
|
|
state->locked = NULL;
|
|
|
|
state->arp_table = 0;
|
|
|
|
state->misc_table = 0;
|
2008-04-10 17:33:03 +07:00
|
|
|
state->node = SEQ_START_TOKEN;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2008-04-10 17:33:03 +07:00
|
|
|
return *pos ? lec_get_idx(state, *pos) : SEQ_START_TOKEN;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void lec_seq_stop(struct seq_file *seq, void *v)
|
|
|
|
{
|
|
|
|
struct lec_state *state = seq->private;
|
|
|
|
|
|
|
|
if (state->dev) {
|
|
|
|
spin_unlock_irqrestore(&state->locked->lec_arp_lock,
|
|
|
|
state->flags);
|
|
|
|
dev_put(state->dev);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
|
|
|
|
{
|
|
|
|
struct lec_state *state = seq->private;
|
|
|
|
|
|
|
|
v = lec_get_idx(state, 1);
|
|
|
|
*pos += !!PTR_ERR(v);
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int lec_seq_show(struct seq_file *seq, void *v)
|
|
|
|
{
|
2009-08-06 00:42:58 +07:00
|
|
|
static const char lec_banner[] =
|
|
|
|
"Itf MAC ATM destination"
|
2006-09-30 07:11:14 +07:00
|
|
|
" Status Flags "
|
|
|
|
"VPI/VCI Recv VPI/VCI\n";
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2008-04-10 17:33:03 +07:00
|
|
|
if (v == SEQ_START_TOKEN)
|
2005-04-17 05:20:36 +07:00
|
|
|
seq_puts(seq, lec_banner);
|
|
|
|
else {
|
|
|
|
struct lec_state *state = seq->private;
|
2006-09-30 07:11:14 +07:00
|
|
|
struct net_device *dev = state->dev;
|
2010-01-26 18:40:08 +07:00
|
|
|
struct lec_arp_table *entry = hlist_entry(state->node,
|
|
|
|
struct lec_arp_table,
|
|
|
|
next);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
seq_printf(seq, "%s ", dev->name);
|
2006-09-30 07:14:27 +07:00
|
|
|
lec_info(seq, entry);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-07-11 13:07:31 +07:00
|
|
|
static const struct seq_operations lec_seq_ops = {
|
2006-09-30 07:11:14 +07:00
|
|
|
.start = lec_seq_start,
|
|
|
|
.next = lec_seq_next,
|
|
|
|
.stop = lec_seq_stop,
|
|
|
|
.show = lec_seq_show,
|
2005-04-17 05:20:36 +07:00
|
|
|
};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
|
|
|
|
{
|
|
|
|
struct atm_vcc *vcc = ATM_SD(sock);
|
|
|
|
int err = 0;
|
2006-09-30 07:11:14 +07:00
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
switch (cmd) {
|
2006-09-30 07:11:14 +07:00
|
|
|
case ATMLEC_CTRL:
|
|
|
|
case ATMLEC_MCAST:
|
|
|
|
case ATMLEC_DATA:
|
|
|
|
if (!capable(CAP_NET_ADMIN))
|
|
|
|
return -EPERM;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return -ENOIOCTLCMD;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (cmd) {
|
2006-09-30 07:11:14 +07:00
|
|
|
case ATMLEC_CTRL:
|
|
|
|
err = lecd_attach(vcc, (int)arg);
|
|
|
|
if (err >= 0)
|
|
|
|
sock->state = SS_CONNECTED;
|
|
|
|
break;
|
|
|
|
case ATMLEC_MCAST:
|
|
|
|
err = lec_mcast_attach(vcc, (int)arg);
|
|
|
|
break;
|
|
|
|
case ATMLEC_DATA:
|
|
|
|
err = lec_vcc_attach(vcc, (void __user *)arg);
|
|
|
|
break;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct atm_ioctl lane_ioctl_ops = {
|
2006-09-30 07:11:14 +07:00
|
|
|
.owner = THIS_MODULE,
|
|
|
|
.ioctl = lane_ioctl,
|
2005-04-17 05:20:36 +07:00
|
|
|
};
|
|
|
|
|
|
|
|
static int __init lane_module_init(void)
|
|
|
|
{
|
|
|
|
#ifdef CONFIG_PROC_FS
|
|
|
|
struct proc_dir_entry *p;
|
|
|
|
|
2018-04-24 22:05:17 +07:00
|
|
|
p = proc_create_seq_private("lec", 0444, atm_proc_root, &lec_seq_ops,
|
|
|
|
sizeof(struct lec_state), NULL);
|
2008-03-24 11:45:36 +07:00
|
|
|
if (!p) {
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_err("Unable to initialize /proc/net/atm/lec\n");
|
2008-03-24 11:45:36 +07:00
|
|
|
return -ENOMEM;
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
|
|
|
|
|
|
|
register_atm_ioctl(&lane_ioctl_ops);
|
2011-04-01 17:41:20 +07:00
|
|
|
pr_info("lec.c: initialized\n");
|
2006-09-30 07:11:14 +07:00
|
|
|
return 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void __exit lane_module_cleanup(void)
|
|
|
|
{
|
2006-09-30 07:11:14 +07:00
|
|
|
int i;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2016-12-28 23:02:05 +07:00
|
|
|
#ifdef CONFIG_PROC_FS
|
2005-04-17 05:20:36 +07:00
|
|
|
remove_proc_entry("lec", atm_proc_root);
|
2016-12-28 23:02:05 +07:00
|
|
|
#endif
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
deregister_atm_ioctl(&lane_ioctl_ops);
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
for (i = 0; i < MAX_LEC_ITF; i++) {
|
|
|
|
if (dev_lec[i] != NULL) {
|
2005-04-17 05:20:36 +07:00
|
|
|
unregister_netdev(dev_lec[i]);
|
2006-09-30 07:11:14 +07:00
|
|
|
free_netdev(dev_lec[i]);
|
|
|
|
dev_lec[i] = NULL;
|
|
|
|
}
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
module_init(lane_module_init);
|
|
|
|
module_exit(lane_module_cleanup);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* LANE2: 3.1.3, LE_RESOLVE.request
|
|
|
|
* Non force allocates memory and fills in *tlvs, fills in *sizeoftlvs.
|
|
|
|
* If sizeoftlvs == NULL the default TLVs associated with with this
|
|
|
|
* lec will be used.
|
|
|
|
* If dst_mac == NULL, targetless LE_ARP will be sent
|
|
|
|
*/
|
2008-06-18 06:20:06 +07:00
|
|
|
static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force,
|
2006-09-30 07:11:14 +07:00
|
|
|
u8 **tlvs, u32 *sizeoftlvs)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2008-11-13 14:39:10 +07:00
|
|
|
struct lec_priv *priv = netdev_priv(dev);
|
2006-09-30 07:11:14 +07:00
|
|
|
struct lec_arp_table *table;
|
|
|
|
struct sk_buff *skb;
|
|
|
|
int retval;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
if (force == 0) {
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:14 +07:00
|
|
|
table = lec_arp_find(priv, dst_mac);
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:14 +07:00
|
|
|
if (table == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2006-11-21 10:14:33 +07:00
|
|
|
*tlvs = kmemdup(table->tlvs, table->sizeoftlvs, GFP_ATOMIC);
|
2006-09-30 07:11:14 +07:00
|
|
|
if (*tlvs == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
*sizeoftlvs = table->sizeoftlvs;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
if (sizeoftlvs == NULL)
|
|
|
|
retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL);
|
2006-09-30 07:11:14 +07:00
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
else {
|
|
|
|
skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC);
|
|
|
|
if (skb == NULL)
|
|
|
|
return -1;
|
|
|
|
skb->len = *sizeoftlvs;
|
2007-03-31 21:55:19 +07:00
|
|
|
skb_copy_to_linear_data(skb, *tlvs, *sizeoftlvs);
|
2005-04-17 05:20:36 +07:00
|
|
|
retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb);
|
|
|
|
}
|
2006-09-30 07:11:14 +07:00
|
|
|
return retval;
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* LANE2: 3.1.4, LE_ASSOCIATE.request
|
|
|
|
* Associate the *tlvs with the *lan_dst address.
|
|
|
|
* Will overwrite any previous association
|
|
|
|
* Returns 1 for success, 0 for failure (out of memory)
|
|
|
|
*
|
|
|
|
*/
|
2008-06-18 06:20:06 +07:00
|
|
|
static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst,
|
|
|
|
const u8 *tlvs, u32 sizeoftlvs)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:14 +07:00
|
|
|
int retval;
|
|
|
|
struct sk_buff *skb;
|
2008-11-13 14:39:10 +07:00
|
|
|
struct lec_priv *priv = netdev_priv(dev);
|
2006-09-30 07:11:14 +07:00
|
|
|
|
atm: Convert compare_ether_addr to ether_addr_equal
Use the new bool function ether_addr_equal to add
some clarity and reduce the likelihood for misuse
of compare_ether_addr for sorting.
Done via cocci script:
$ cat compare_ether_addr.cocci
@@
expression a,b;
@@
- !compare_ether_addr(a, b)
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- compare_ether_addr(a, b)
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) == 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) != 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) == 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) != 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !!ether_addr_equal(a, b)
+ ether_addr_equal(a, b)
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-05-09 01:56:50 +07:00
|
|
|
if (!ether_addr_equal(lan_dst, dev->dev_addr))
|
2010-01-26 18:40:08 +07:00
|
|
|
return 0; /* not our mac address */
|
2006-09-30 07:11:14 +07:00
|
|
|
|
|
|
|
kfree(priv->tlvs); /* NULL if there was no previous association */
|
|
|
|
|
2006-11-21 10:14:33 +07:00
|
|
|
priv->tlvs = kmemdup(tlvs, sizeoftlvs, GFP_KERNEL);
|
2006-09-30 07:11:14 +07:00
|
|
|
if (priv->tlvs == NULL)
|
2010-01-26 18:40:08 +07:00
|
|
|
return 0;
|
2006-09-30 07:11:14 +07:00
|
|
|
priv->sizeoftlvs = sizeoftlvs;
|
|
|
|
|
|
|
|
skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);
|
|
|
|
if (skb == NULL)
|
|
|
|
return 0;
|
|
|
|
skb->len = sizeoftlvs;
|
2007-03-31 21:55:19 +07:00
|
|
|
skb_copy_to_linear_data(skb, tlvs, sizeoftlvs);
|
2006-09-30 07:11:14 +07:00
|
|
|
retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb);
|
|
|
|
if (retval != 0)
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("lec.c: lane2_associate_req() failed\n");
|
2006-09-30 07:11:14 +07:00
|
|
|
/*
|
|
|
|
* If the previous association has changed we must
|
|
|
|
* somehow notify other LANE entities about the change
|
|
|
|
*/
|
2010-01-26 18:40:08 +07:00
|
|
|
return 1;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* LANE2: 3.1.5, LE_ASSOCIATE.indication
|
|
|
|
*
|
|
|
|
*/
|
2008-06-18 06:20:06 +07:00
|
|
|
static void lane2_associate_ind(struct net_device *dev, const u8 *mac_addr,
|
|
|
|
const u8 *tlvs, u32 sizeoftlvs)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
#if 0
|
2006-09-30 07:11:14 +07:00
|
|
|
int i = 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
2008-11-13 14:39:10 +07:00
|
|
|
struct lec_priv *priv = netdev_priv(dev);
|
2006-09-30 07:11:14 +07:00
|
|
|
#if 0 /*
|
|
|
|
* Why have the TLVs in LE_ARP entries
|
|
|
|
* since we do not use them? When you
|
|
|
|
* uncomment this code, make sure the
|
|
|
|
* TLVs get freed when entry is killed
|
|
|
|
*/
|
|
|
|
struct lec_arp_table *entry = lec_arp_find(priv, mac_addr);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
if (entry == NULL)
|
|
|
|
return; /* should not happen */
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
kfree(entry->tlvs);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-11-21 10:14:33 +07:00
|
|
|
entry->tlvs = kmemdup(tlvs, sizeoftlvs, GFP_KERNEL);
|
2006-09-30 07:11:14 +07:00
|
|
|
if (entry->tlvs == NULL)
|
|
|
|
return;
|
|
|
|
entry->sizeoftlvs = sizeoftlvs;
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
|
|
|
#if 0
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("\n");
|
|
|
|
pr_info("dump of tlvs, sizeoftlvs=%d\n", sizeoftlvs);
|
2006-09-30 07:11:14 +07:00
|
|
|
while (i < sizeoftlvs)
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_cont("%02x ", tlvs[i++]);
|
2006-09-30 07:11:14 +07:00
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_cont("\n");
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
|
|
|
|
2006-09-30 07:11:14 +07:00
|
|
|
/* tell MPOA about the TLVs we saw */
|
|
|
|
if (priv->lane2_ops && priv->lane2_ops->associate_indicator) {
|
|
|
|
priv->lane2_ops->associate_indicator(dev, mac_addr,
|
|
|
|
tlvs, sizeoftlvs);
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Here starts what used to lec_arpc.c
|
|
|
|
*
|
|
|
|
* lec_arpc.c was added here when making
|
|
|
|
* lane client modular. October 1997
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/types.h>
|
|
|
|
#include <linux/timer.h>
|
2010-01-26 18:40:08 +07:00
|
|
|
#include <linux/param.h>
|
2011-07-27 06:09:06 +07:00
|
|
|
#include <linux/atomic.h>
|
2005-04-17 05:20:36 +07:00
|
|
|
#include <linux/inetdevice.h>
|
|
|
|
#include <net/route.h>
|
|
|
|
|
|
|
|
#if 0
|
2010-01-26 18:40:08 +07:00
|
|
|
#define pr_debug(format, args...)
|
2005-04-17 05:20:36 +07:00
|
|
|
/*
|
2010-01-26 18:40:00 +07:00
|
|
|
#define pr_debug printk
|
2005-04-17 05:20:36 +07:00
|
|
|
*/
|
|
|
|
#endif
|
|
|
|
#define DEBUG_ARP_TABLE 0
|
|
|
|
|
|
|
|
#define LEC_ARP_REFRESH_INTERVAL (3*HZ)
|
|
|
|
|
2006-11-22 21:57:56 +07:00
|
|
|
static void lec_arp_check_expire(struct work_struct *work);
|
2017-10-17 07:29:37 +07:00
|
|
|
static void lec_arp_expire_arp(struct timer_list *t);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2007-02-09 21:24:29 +07:00
|
|
|
/*
|
2005-04-17 05:20:36 +07:00
|
|
|
* Arp table funcs
|
|
|
|
*/
|
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
#define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE - 1))
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialization of arp-cache
|
|
|
|
*/
|
2006-09-30 07:11:47 +07:00
|
|
|
static void lec_arp_init(struct lec_priv *priv)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:47 +07:00
|
|
|
unsigned short i;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
|
2006-09-30 07:14:27 +07:00
|
|
|
INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
|
2007-02-09 21:24:29 +07:00
|
|
|
INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
|
|
|
|
INIT_HLIST_HEAD(&priv->lec_no_forward);
|
|
|
|
INIT_HLIST_HEAD(&priv->mcast_fwds);
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_lock_init(&priv->lec_arp_lock);
|
2006-11-22 21:57:56 +07:00
|
|
|
INIT_DELAYED_WORK(&priv->lec_arp_work, lec_arp_check_expire);
|
2006-09-30 07:15:59 +07:00
|
|
|
schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
static void lec_arp_clear_vccs(struct lec_arp_table *entry)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:47 +07:00
|
|
|
if (entry->vcc) {
|
2005-04-17 05:20:36 +07:00
|
|
|
struct atm_vcc *vcc = entry->vcc;
|
|
|
|
struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc);
|
2006-09-30 07:11:47 +07:00
|
|
|
struct net_device *dev = (struct net_device *)vcc->proto_data;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
vcc->pop = vpriv->old_pop;
|
2005-04-17 05:20:36 +07:00
|
|
|
if (vpriv->xoff)
|
|
|
|
netif_wake_queue(dev);
|
|
|
|
kfree(vpriv);
|
|
|
|
vcc->user_back = NULL;
|
2006-09-30 07:11:47 +07:00
|
|
|
vcc->push = entry->old_push;
|
2005-04-17 05:20:36 +07:00
|
|
|
vcc_release_async(vcc, -EPIPE);
|
2006-09-30 07:14:27 +07:00
|
|
|
entry->vcc = NULL;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
if (entry->recv_vcc) {
|
|
|
|
entry->recv_vcc->push = entry->old_recv_push;
|
2005-04-17 05:20:36 +07:00
|
|
|
vcc_release_async(entry->recv_vcc, -EPIPE);
|
2006-09-30 07:11:47 +07:00
|
|
|
entry->recv_vcc = NULL;
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Insert entry to lec_arp_table
|
|
|
|
* LANE2: Add to the end of the list to satisfy 8.1.13
|
|
|
|
*/
|
2006-09-30 07:11:47 +07:00
|
|
|
static inline void
|
2006-09-30 07:14:27 +07:00
|
|
|
lec_arp_add(struct lec_priv *priv, struct lec_arp_table *entry)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:14:27 +07:00
|
|
|
struct hlist_head *tmp;
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2006-09-30 07:14:27 +07:00
|
|
|
tmp = &priv->lec_arp_tables[HASH(entry->mac_addr[ETH_ALEN - 1])];
|
|
|
|
hlist_add_head(&entry->next, tmp);
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("Added entry:%pM\n", entry->mac_addr);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove entry from lec_arp_table
|
|
|
|
*/
|
2006-09-30 07:11:47 +07:00
|
|
|
static int
|
|
|
|
lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:14:27 +07:00
|
|
|
struct lec_arp_table *entry;
|
|
|
|
int i, remove_vcc = 1;
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
if (!to_remove)
|
2006-09-30 07:11:47 +07:00
|
|
|
return -1;
|
2006-09-30 07:14:27 +07:00
|
|
|
|
|
|
|
hlist_del(&to_remove->next);
|
2006-09-30 07:11:47 +07:00
|
|
|
del_timer(&to_remove->timer);
|
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
/*
|
|
|
|
* If this is the only MAC connected to this VCC,
|
|
|
|
* also tear down the VCC
|
|
|
|
*/
|
2006-09-30 07:11:47 +07:00
|
|
|
if (to_remove->status >= ESI_FLUSH_PENDING) {
|
|
|
|
/*
|
|
|
|
* ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT
|
|
|
|
*/
|
2006-09-30 07:14:27 +07:00
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry(entry,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_tables[i], next) {
|
2006-09-30 07:14:27 +07:00
|
|
|
if (memcmp(to_remove->atm_addr,
|
|
|
|
entry->atm_addr, ATM_ESA_LEN) == 0) {
|
2006-09-30 07:11:47 +07:00
|
|
|
remove_vcc = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (remove_vcc)
|
|
|
|
lec_arp_clear_vccs(to_remove);
|
|
|
|
}
|
|
|
|
skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */
|
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("Removed entry:%pM\n", to_remove->mac_addr);
|
2006-09-30 07:11:47 +07:00
|
|
|
return 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG_ARP_TABLE
|
2009-08-06 00:42:58 +07:00
|
|
|
static const char *get_status_string(unsigned char st)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:47 +07:00
|
|
|
switch (st) {
|
|
|
|
case ESI_UNKNOWN:
|
|
|
|
return "ESI_UNKNOWN";
|
|
|
|
case ESI_ARP_PENDING:
|
|
|
|
return "ESI_ARP_PENDING";
|
|
|
|
case ESI_VC_PENDING:
|
|
|
|
return "ESI_VC_PENDING";
|
|
|
|
case ESI_FLUSH_PENDING:
|
|
|
|
return "ESI_FLUSH_PENDING";
|
|
|
|
case ESI_FORWARD_DIRECT:
|
|
|
|
return "ESI_FORWARD_DIRECT";
|
|
|
|
}
|
2010-01-26 18:40:08 +07:00
|
|
|
return "<UNKNOWN>";
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
static void dump_arp_table(struct lec_priv *priv)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:47 +07:00
|
|
|
struct lec_arp_table *rulla;
|
2006-09-30 07:14:27 +07:00
|
|
|
char buf[256];
|
2020-01-23 21:20:02 +07:00
|
|
|
int i, offset;
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("Dump %p:\n", priv);
|
2006-09-30 07:11:47 +07:00
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry(rulla,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_tables[i], next) {
|
2006-09-30 07:14:27 +07:00
|
|
|
offset = 0;
|
|
|
|
offset += sprintf(buf, "%d: %p\n", i, rulla);
|
2020-01-23 21:20:02 +07:00
|
|
|
offset += sprintf(buf + offset, "Mac: %pM ",
|
2010-01-26 18:40:08 +07:00
|
|
|
rulla->mac_addr);
|
2020-01-23 21:20:02 +07:00
|
|
|
offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN,
|
|
|
|
rulla->atm_addr);
|
2006-09-30 07:11:47 +07:00
|
|
|
offset += sprintf(buf + offset,
|
|
|
|
"Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
|
|
|
|
rulla->vcc ? rulla->vcc->vpi : 0,
|
|
|
|
rulla->vcc ? rulla->vcc->vci : 0,
|
|
|
|
rulla->recv_vcc ? rulla->recv_vcc->
|
|
|
|
vpi : 0,
|
|
|
|
rulla->recv_vcc ? rulla->recv_vcc->
|
|
|
|
vci : 0, rulla->last_used,
|
|
|
|
rulla->timestamp, rulla->no_tries);
|
|
|
|
offset +=
|
|
|
|
sprintf(buf + offset,
|
|
|
|
"Flags:%x, Packets_flooded:%x, Status: %s ",
|
|
|
|
rulla->flags, rulla->packets_flooded,
|
|
|
|
get_status_string(rulla->status));
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("%s\n", buf);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
|
|
|
|
if (!hlist_empty(&priv->lec_no_forward))
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("No forward\n");
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry(rulla, &priv->lec_no_forward, next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
offset = 0;
|
2020-01-23 21:20:02 +07:00
|
|
|
offset += sprintf(buf + offset, "Mac: %pM ", rulla->mac_addr);
|
|
|
|
offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN,
|
|
|
|
rulla->atm_addr);
|
2006-09-30 07:11:47 +07:00
|
|
|
offset += sprintf(buf + offset,
|
|
|
|
"Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
|
|
|
|
rulla->vcc ? rulla->vcc->vpi : 0,
|
|
|
|
rulla->vcc ? rulla->vcc->vci : 0,
|
|
|
|
rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
|
|
|
|
rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
|
|
|
|
rulla->last_used,
|
|
|
|
rulla->timestamp, rulla->no_tries);
|
|
|
|
offset += sprintf(buf + offset,
|
|
|
|
"Flags:%x, Packets_flooded:%x, Status: %s ",
|
|
|
|
rulla->flags, rulla->packets_flooded,
|
|
|
|
get_status_string(rulla->status));
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("%s\n", buf);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
|
|
|
|
if (!hlist_empty(&priv->lec_arp_empty_ones))
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("Empty ones\n");
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry(rulla, &priv->lec_arp_empty_ones, next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
offset = 0;
|
2020-01-23 21:20:02 +07:00
|
|
|
offset += sprintf(buf + offset, "Mac: %pM ", rulla->mac_addr);
|
|
|
|
offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN,
|
|
|
|
rulla->atm_addr);
|
2006-09-30 07:11:47 +07:00
|
|
|
offset += sprintf(buf + offset,
|
|
|
|
"Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
|
|
|
|
rulla->vcc ? rulla->vcc->vpi : 0,
|
|
|
|
rulla->vcc ? rulla->vcc->vci : 0,
|
|
|
|
rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
|
|
|
|
rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
|
|
|
|
rulla->last_used,
|
|
|
|
rulla->timestamp, rulla->no_tries);
|
|
|
|
offset += sprintf(buf + offset,
|
|
|
|
"Flags:%x, Packets_flooded:%x, Status: %s ",
|
|
|
|
rulla->flags, rulla->packets_flooded,
|
|
|
|
get_status_string(rulla->status));
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("%s", buf);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:14:27 +07:00
|
|
|
if (!hlist_empty(&priv->mcast_fwds))
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("Multicast Forward VCCs\n");
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry(rulla, &priv->mcast_fwds, next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
offset = 0;
|
2020-01-23 21:20:02 +07:00
|
|
|
offset += sprintf(buf + offset, "Mac: %pM ", rulla->mac_addr);
|
|
|
|
offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN,
|
|
|
|
rulla->atm_addr);
|
2006-09-30 07:11:47 +07:00
|
|
|
offset += sprintf(buf + offset,
|
|
|
|
"Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ",
|
|
|
|
rulla->vcc ? rulla->vcc->vpi : 0,
|
|
|
|
rulla->vcc ? rulla->vcc->vci : 0,
|
|
|
|
rulla->recv_vcc ? rulla->recv_vcc->vpi : 0,
|
|
|
|
rulla->recv_vcc ? rulla->recv_vcc->vci : 0,
|
|
|
|
rulla->last_used,
|
|
|
|
rulla->timestamp, rulla->no_tries);
|
|
|
|
offset += sprintf(buf + offset,
|
|
|
|
"Flags:%x, Packets_flooded:%x, Status: %s ",
|
|
|
|
rulla->flags, rulla->packets_flooded,
|
|
|
|
get_status_string(rulla->status));
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("%s\n", buf);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
#else
|
|
|
|
#define dump_arp_table(priv) do { } while (0)
|
|
|
|
#endif
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Destruction of arp-cache
|
|
|
|
*/
|
2006-09-30 07:11:47 +07:00
|
|
|
static void lec_arp_destroy(struct lec_priv *priv)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
struct hlist_node *next;
|
2006-09-30 07:14:27 +07:00
|
|
|
struct lec_arp_table *entry;
|
2006-09-30 07:11:47 +07:00
|
|
|
int i;
|
|
|
|
|
2010-12-14 22:21:17 +07:00
|
|
|
cancel_delayed_work_sync(&priv->lec_arp_work);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
/*
|
|
|
|
* Remove all entries
|
|
|
|
*/
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_tables[i], next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
lec_arp_remove(priv, entry);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
INIT_HLIST_HEAD(&priv->lec_arp_tables[i]);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_empty_ones, next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
del_timer_sync(&entry->timer);
|
|
|
|
lec_arp_clear_vccs(entry);
|
2006-09-30 07:14:27 +07:00
|
|
|
hlist_del(&entry->next);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
INIT_HLIST_HEAD(&priv->lec_arp_empty_ones);
|
|
|
|
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_no_forward, next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
del_timer_sync(&entry->timer);
|
|
|
|
lec_arp_clear_vccs(entry);
|
2006-09-30 07:14:27 +07:00
|
|
|
hlist_del(&entry->next);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
INIT_HLIST_HEAD(&priv->lec_no_forward);
|
|
|
|
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next, &priv->mcast_fwds, next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
/* No timer, LANEv2 7.1.20 and 2.3.5.3 */
|
|
|
|
lec_arp_clear_vccs(entry);
|
2006-09-30 07:14:27 +07:00
|
|
|
hlist_del(&entry->next);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
INIT_HLIST_HEAD(&priv->mcast_fwds);
|
2006-09-30 07:11:47 +07:00
|
|
|
priv->mcast_vcc = NULL;
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
|
|
|
}
|
|
|
|
|
2007-02-09 21:24:29 +07:00
|
|
|
/*
|
2005-04-17 05:20:36 +07:00
|
|
|
* Find entry by mac_address
|
|
|
|
*/
|
2006-09-30 07:11:47 +07:00
|
|
|
static struct lec_arp_table *lec_arp_find(struct lec_priv *priv,
|
2008-06-18 06:20:06 +07:00
|
|
|
const unsigned char *mac_addr)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:14:27 +07:00
|
|
|
struct hlist_head *head;
|
|
|
|
struct lec_arp_table *entry;
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("%pM\n", mac_addr);
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2006-09-30 07:14:27 +07:00
|
|
|
head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])];
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry(entry, head, next) {
|
atm: Convert compare_ether_addr to ether_addr_equal
Use the new bool function ether_addr_equal to add
some clarity and reduce the likelihood for misuse
of compare_ether_addr for sorting.
Done via cocci script:
$ cat compare_ether_addr.cocci
@@
expression a,b;
@@
- !compare_ether_addr(a, b)
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- compare_ether_addr(a, b)
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) == 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) != 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) == 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) != 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !!ether_addr_equal(a, b)
+ ether_addr_equal(a, b)
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-05-09 01:56:50 +07:00
|
|
|
if (ether_addr_equal(mac_addr, entry->mac_addr))
|
2006-09-30 07:14:27 +07:00
|
|
|
return entry;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
return NULL;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
static struct lec_arp_table *make_entry(struct lec_priv *priv,
|
2008-06-18 06:20:06 +07:00
|
|
|
const unsigned char *mac_addr)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:47 +07:00
|
|
|
struct lec_arp_table *to_return;
|
|
|
|
|
|
|
|
to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC);
|
|
|
|
if (!to_return) {
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("LEC: Arp entry kmalloc failed\n");
|
2006-09-30 07:11:47 +07:00
|
|
|
return NULL;
|
|
|
|
}
|
2014-01-21 00:52:16 +07:00
|
|
|
ether_addr_copy(to_return->mac_addr, mac_addr);
|
2006-09-30 07:14:27 +07:00
|
|
|
INIT_HLIST_NODE(&to_return->next);
|
2017-10-17 07:29:37 +07:00
|
|
|
timer_setup(&to_return->timer, lec_arp_expire_arp, 0);
|
2006-09-30 07:11:47 +07:00
|
|
|
to_return->last_used = jiffies;
|
|
|
|
to_return->priv = priv;
|
|
|
|
skb_queue_head_init(&to_return->tx_wait);
|
2017-07-04 19:53:02 +07:00
|
|
|
refcount_set(&to_return->usage, 1);
|
2006-09-30 07:11:47 +07:00
|
|
|
return to_return;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
/* Arp sent timer expired */
|
2017-10-17 07:29:37 +07:00
|
|
|
static void lec_arp_expire_arp(struct timer_list *t)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:47 +07:00
|
|
|
struct lec_arp_table *entry;
|
|
|
|
|
2017-10-17 07:29:37 +07:00
|
|
|
entry = from_timer(entry, t, timer);
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("\n");
|
2006-09-30 07:11:47 +07:00
|
|
|
if (entry->status == ESI_ARP_PENDING) {
|
|
|
|
if (entry->no_tries <= entry->priv->max_retry_count) {
|
|
|
|
if (entry->is_rdesc)
|
|
|
|
send_to_lecd(entry->priv, l_rdesc_arp_xmt,
|
|
|
|
entry->mac_addr, NULL, NULL);
|
|
|
|
else
|
|
|
|
send_to_lecd(entry->priv, l_arp_xmt,
|
|
|
|
entry->mac_addr, NULL, NULL);
|
|
|
|
entry->no_tries++;
|
|
|
|
}
|
|
|
|
mod_timer(&entry->timer, jiffies + (1 * HZ));
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
/* Unknown/unused vcc expire, remove associated entry */
|
2017-10-17 07:29:37 +07:00
|
|
|
static void lec_arp_expire_vcc(struct timer_list *t)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2017-10-17 07:29:37 +07:00
|
|
|
struct lec_arp_table *to_remove = from_timer(to_remove, t, timer);
|
2012-06-04 00:41:40 +07:00
|
|
|
struct lec_priv *priv = to_remove->priv;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
del_timer(&to_remove->timer);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("%p %p: vpi:%d vci:%d\n",
|
|
|
|
to_remove, priv,
|
|
|
|
to_remove->vcc ? to_remove->recv_vcc->vpi : 0,
|
|
|
|
to_remove->vcc ? to_remove->recv_vcc->vci : 0);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:14:27 +07:00
|
|
|
hlist_del(&to_remove->next);
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
lec_arp_clear_vccs(to_remove);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(to_remove);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2010-01-26 18:40:19 +07:00
|
|
|
static bool __lec_arp_check_expire(struct lec_arp_table *entry,
|
|
|
|
unsigned long now,
|
|
|
|
struct lec_priv *priv)
|
|
|
|
{
|
|
|
|
unsigned long time_to_check;
|
|
|
|
|
|
|
|
if ((entry->flags) & LEC_REMOTE_FLAG && priv->topology_change)
|
|
|
|
time_to_check = priv->forward_delay_time;
|
|
|
|
else
|
|
|
|
time_to_check = priv->aging_time;
|
|
|
|
|
|
|
|
pr_debug("About to expire: %lx - %lx > %lx\n",
|
|
|
|
now, entry->last_used, time_to_check);
|
|
|
|
if (time_after(now, entry->last_used + time_to_check) &&
|
|
|
|
!(entry->flags & LEC_PERMANENT_FLAG) &&
|
|
|
|
!(entry->mac_addr[0] & 0x01)) { /* LANE2: 7.1.20 */
|
|
|
|
/* Remove entry */
|
|
|
|
pr_debug("Entry timed out\n");
|
|
|
|
lec_arp_remove(priv, entry);
|
|
|
|
lec_arp_put(entry);
|
|
|
|
} else {
|
|
|
|
/* Something else */
|
|
|
|
if ((entry->status == ESI_VC_PENDING ||
|
|
|
|
entry->status == ESI_ARP_PENDING) &&
|
|
|
|
time_after_eq(now, entry->timestamp +
|
|
|
|
priv->max_unknown_frame_time)) {
|
|
|
|
entry->timestamp = jiffies;
|
|
|
|
entry->packets_flooded = 0;
|
|
|
|
if (entry->status == ESI_VC_PENDING)
|
|
|
|
send_to_lecd(priv, l_svc_setup,
|
|
|
|
entry->mac_addr,
|
|
|
|
entry->atm_addr,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
if (entry->status == ESI_FLUSH_PENDING &&
|
|
|
|
time_after_eq(now, entry->timestamp +
|
|
|
|
priv->path_switching_delay)) {
|
|
|
|
lec_arp_hold(entry);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
/*
|
|
|
|
* Expire entries.
|
|
|
|
* 1. Re-set timer
|
|
|
|
* 2. For each entry, delete entries that have aged past the age limit.
|
|
|
|
* 3. For each entry, depending on the status of the entry, perform
|
|
|
|
* the following maintenance.
|
|
|
|
* a. If status is ESI_VC_PENDING or ESI_ARP_PENDING then if the
|
|
|
|
* tick_count is above the max_unknown_frame_time, clear
|
|
|
|
* the tick_count to zero and clear the packets_flooded counter
|
|
|
|
* to zero. This supports the packet rate limit per address
|
|
|
|
* while flooding unknowns.
|
|
|
|
* b. If the status is ESI_FLUSH_PENDING and the tick_count is greater
|
|
|
|
* than or equal to the path_switching_delay, change the status
|
|
|
|
* to ESI_FORWARD_DIRECT. This causes the flush period to end
|
|
|
|
* regardless of the progress of the flush protocol.
|
|
|
|
*/
|
2006-11-22 21:57:56 +07:00
|
|
|
static void lec_arp_check_expire(struct work_struct *work)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2006-11-22 21:57:56 +07:00
|
|
|
struct lec_priv *priv =
|
|
|
|
container_of(work, struct lec_priv, lec_arp_work.work);
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
struct hlist_node *next;
|
2006-09-30 07:14:27 +07:00
|
|
|
struct lec_arp_table *entry;
|
2006-09-30 07:11:47 +07:00
|
|
|
unsigned long now;
|
|
|
|
int i;
|
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("%p\n", priv);
|
2005-04-17 05:20:36 +07:00
|
|
|
now = jiffies;
|
2006-09-30 07:17:17 +07:00
|
|
|
restart:
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_tables[i], next) {
|
2010-01-26 18:40:19 +07:00
|
|
|
if (__lec_arp_check_expire(entry, now, priv)) {
|
|
|
|
struct sk_buff *skb;
|
|
|
|
struct atm_vcc *vcc = entry->vcc;
|
|
|
|
|
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock,
|
|
|
|
flags);
|
|
|
|
while ((skb = skb_dequeue(&entry->tx_wait)))
|
|
|
|
lec_send(vcc, skb);
|
|
|
|
entry->last_used = jiffies;
|
|
|
|
entry->status = ESI_FORWARD_DIRECT;
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2010-01-26 18:40:19 +07:00
|
|
|
|
|
|
|
goto restart;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
|
|
|
|
2006-09-30 07:15:59 +07:00
|
|
|
schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
/*
|
|
|
|
* Try to find vcc where mac_address is attached.
|
2007-02-09 21:24:29 +07:00
|
|
|
*
|
2005-04-17 05:20:36 +07:00
|
|
|
*/
|
2006-09-30 07:11:47 +07:00
|
|
|
static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
|
2010-01-26 18:40:08 +07:00
|
|
|
const unsigned char *mac_to_find,
|
|
|
|
int is_rdesc,
|
2006-09-30 07:11:47 +07:00
|
|
|
struct lec_arp_table **ret_entry)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2006-09-30 07:11:47 +07:00
|
|
|
struct lec_arp_table *entry;
|
2005-04-17 05:20:36 +07:00
|
|
|
struct atm_vcc *found;
|
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
if (mac_to_find[0] & 0x01) {
|
|
|
|
switch (priv->lane_version) {
|
|
|
|
case 1:
|
|
|
|
return priv->mcast_vcc;
|
|
|
|
case 2: /* LANE2 wants arp for multicast addresses */
|
atm: Convert compare_ether_addr to ether_addr_equal
Use the new bool function ether_addr_equal to add
some clarity and reduce the likelihood for misuse
of compare_ether_addr for sorting.
Done via cocci script:
$ cat compare_ether_addr.cocci
@@
expression a,b;
@@
- !compare_ether_addr(a, b)
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- compare_ether_addr(a, b)
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) == 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !ether_addr_equal(a, b) != 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) == 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- ether_addr_equal(a, b) != 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- !!ether_addr_equal(a, b)
+ ether_addr_equal(a, b)
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2012-05-09 01:56:50 +07:00
|
|
|
if (ether_addr_equal(mac_to_find, bus_mac))
|
2006-09-30 07:11:47 +07:00
|
|
|
return priv->mcast_vcc;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
entry = lec_arp_find(priv, mac_to_find);
|
|
|
|
|
|
|
|
if (entry) {
|
|
|
|
if (entry->status == ESI_FORWARD_DIRECT) {
|
|
|
|
/* Connection Ok */
|
|
|
|
entry->last_used = jiffies;
|
2006-09-30 07:17:17 +07:00
|
|
|
lec_arp_hold(entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
*ret_entry = entry;
|
|
|
|
found = entry->vcc;
|
2005-04-17 05:20:36 +07:00
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* If the LE_ARP cache entry is still pending, reset count to 0
|
2005-09-30 07:31:30 +07:00
|
|
|
* so another LE_ARP request can be made for this frame.
|
|
|
|
*/
|
2010-01-26 18:40:08 +07:00
|
|
|
if (entry->status == ESI_ARP_PENDING)
|
2005-09-30 07:31:30 +07:00
|
|
|
entry->no_tries = 0;
|
2006-09-30 07:11:47 +07:00
|
|
|
/*
|
|
|
|
* Data direct VC not yet set up, check to see if the unknown
|
|
|
|
* frame count is greater than the limit. If the limit has
|
|
|
|
* not been reached, allow the caller to send packet to
|
|
|
|
* BUS.
|
|
|
|
*/
|
|
|
|
if (entry->status != ESI_FLUSH_PENDING &&
|
|
|
|
entry->packets_flooded <
|
|
|
|
priv->maximum_unknown_frame_count) {
|
|
|
|
entry->packets_flooded++;
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("Flooding..\n");
|
2006-09-30 07:11:47 +07:00
|
|
|
found = priv->mcast_vcc;
|
2005-04-17 05:20:36 +07:00
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* We got here because entry->status == ESI_FLUSH_PENDING
|
2005-04-17 05:20:36 +07:00
|
|
|
* or BUS flood limit was reached for an entry which is
|
|
|
|
* in ESI_ARP_PENDING or ESI_VC_PENDING state.
|
|
|
|
*/
|
2006-09-30 07:17:17 +07:00
|
|
|
lec_arp_hold(entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
*ret_entry = entry;
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("entry->status %d entry->vcc %p\n", entry->status,
|
|
|
|
entry->vcc);
|
2006-09-30 07:11:47 +07:00
|
|
|
found = NULL;
|
|
|
|
} else {
|
|
|
|
/* No matching entry was found */
|
|
|
|
entry = make_entry(priv, mac_to_find);
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("Making entry\n");
|
2006-09-30 07:11:47 +07:00
|
|
|
if (!entry) {
|
|
|
|
found = priv->mcast_vcc;
|
2005-04-17 05:20:36 +07:00
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
lec_arp_add(priv, entry);
|
|
|
|
/* We want arp-request(s) to be sent */
|
|
|
|
entry->packets_flooded = 1;
|
|
|
|
entry->status = ESI_ARP_PENDING;
|
|
|
|
entry->no_tries = 1;
|
|
|
|
entry->last_used = entry->timestamp = jiffies;
|
|
|
|
entry->is_rdesc = is_rdesc;
|
|
|
|
if (entry->is_rdesc)
|
|
|
|
send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL,
|
|
|
|
NULL);
|
|
|
|
else
|
|
|
|
send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL);
|
|
|
|
entry->timer.expires = jiffies + (1 * HZ);
|
2017-10-23 14:40:42 +07:00
|
|
|
entry->timer.function = lec_arp_expire_arp;
|
2006-09-30 07:11:47 +07:00
|
|
|
add_timer(&entry->timer);
|
|
|
|
found = priv->mcast_vcc;
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
out:
|
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2008-06-18 06:20:06 +07:00
|
|
|
lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr,
|
2006-09-30 07:11:47 +07:00
|
|
|
unsigned long permanent)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
struct hlist_node *next;
|
2006-09-30 07:14:27 +07:00
|
|
|
struct lec_arp_table *entry;
|
2006-09-30 07:11:47 +07:00
|
|
|
int i;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("\n");
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_tables[i], next) {
|
|
|
|
if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN) &&
|
|
|
|
(permanent ||
|
|
|
|
!(entry->flags & LEC_PERMANENT_FLAG))) {
|
2005-04-17 05:20:36 +07:00
|
|
|
lec_arp_remove(priv, entry);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
return -1;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-02-09 21:24:29 +07:00
|
|
|
* Notifies: Response to arp_request (atm_addr != NULL)
|
2005-04-17 05:20:36 +07:00
|
|
|
*/
|
|
|
|
static void
|
2008-06-18 06:20:06 +07:00
|
|
|
lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr,
|
|
|
|
const unsigned char *atm_addr, unsigned long remoteflag,
|
2006-09-30 07:11:47 +07:00
|
|
|
unsigned int targetless_le_arp)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
struct hlist_node *next;
|
2006-09-30 07:11:47 +07:00
|
|
|
struct lec_arp_table *entry, *tmp;
|
|
|
|
int i;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("%smac:%pM\n",
|
|
|
|
(targetless_le_arp) ? "targetless " : "", mac_addr);
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
entry = lec_arp_find(priv, mac_addr);
|
|
|
|
if (entry == NULL && targetless_le_arp)
|
|
|
|
goto out; /*
|
|
|
|
* LANE2: ignore targetless LE_ARPs for which
|
|
|
|
* we have no entry in the cache. 7.1.30
|
|
|
|
*/
|
2006-09-30 07:14:27 +07:00
|
|
|
if (!hlist_empty(&priv->lec_arp_empty_ones)) {
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_empty_ones, next) {
|
2006-09-30 07:14:27 +07:00
|
|
|
if (memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN) == 0) {
|
|
|
|
hlist_del(&entry->next);
|
2006-09-30 07:11:47 +07:00
|
|
|
del_timer(&entry->timer);
|
2006-09-30 07:14:27 +07:00
|
|
|
tmp = lec_arp_find(priv, mac_addr);
|
|
|
|
if (tmp) {
|
|
|
|
del_timer(&tmp->timer);
|
|
|
|
tmp->status = ESI_FORWARD_DIRECT;
|
|
|
|
memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN);
|
|
|
|
tmp->vcc = entry->vcc;
|
|
|
|
tmp->old_push = entry->old_push;
|
|
|
|
tmp->last_used = jiffies;
|
|
|
|
del_timer(&entry->timer);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2006-09-30 07:14:27 +07:00
|
|
|
entry = tmp;
|
|
|
|
} else {
|
|
|
|
entry->status = ESI_FORWARD_DIRECT;
|
2014-01-21 00:52:16 +07:00
|
|
|
ether_addr_copy(entry->mac_addr,
|
|
|
|
mac_addr);
|
2006-09-30 07:14:27 +07:00
|
|
|
entry->last_used = jiffies;
|
|
|
|
lec_arp_add(priv, entry);
|
|
|
|
}
|
|
|
|
if (remoteflag)
|
|
|
|
entry->flags |= LEC_REMOTE_FLAG;
|
|
|
|
else
|
|
|
|
entry->flags &= ~LEC_REMOTE_FLAG;
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("After update\n");
|
2006-09-30 07:14:27 +07:00
|
|
|
dump_arp_table(priv);
|
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
entry = lec_arp_find(priv, mac_addr);
|
|
|
|
if (!entry) {
|
|
|
|
entry = make_entry(priv, mac_addr);
|
|
|
|
if (!entry)
|
|
|
|
goto out;
|
|
|
|
entry->status = ESI_UNKNOWN;
|
|
|
|
lec_arp_add(priv, entry);
|
|
|
|
/* Temporary, changes before end of function */
|
|
|
|
}
|
|
|
|
memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
|
|
|
|
del_timer(&entry->timer);
|
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry(tmp,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_tables[i], next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
if (entry != tmp &&
|
|
|
|
!memcmp(tmp->atm_addr, atm_addr, ATM_ESA_LEN)) {
|
|
|
|
/* Vcc to this host exists */
|
|
|
|
if (tmp->status > ESI_VC_PENDING) {
|
|
|
|
/*
|
|
|
|
* ESI_FLUSH_PENDING,
|
|
|
|
* ESI_FORWARD_DIRECT
|
|
|
|
*/
|
|
|
|
entry->vcc = tmp->vcc;
|
|
|
|
entry->old_push = tmp->old_push;
|
|
|
|
}
|
|
|
|
entry->status = tmp->status;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (remoteflag)
|
|
|
|
entry->flags |= LEC_REMOTE_FLAG;
|
|
|
|
else
|
|
|
|
entry->flags &= ~LEC_REMOTE_FLAG;
|
|
|
|
if (entry->status == ESI_ARP_PENDING || entry->status == ESI_UNKNOWN) {
|
|
|
|
entry->status = ESI_VC_PENDING;
|
2006-09-30 07:14:27 +07:00
|
|
|
send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("After update2\n");
|
2006-09-30 07:11:47 +07:00
|
|
|
dump_arp_table(priv);
|
2005-04-17 05:20:36 +07:00
|
|
|
out:
|
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2007-02-09 21:24:29 +07:00
|
|
|
* Notifies: Vcc setup ready
|
2005-04-17 05:20:36 +07:00
|
|
|
*/
|
|
|
|
static void
|
2008-06-18 06:20:06 +07:00
|
|
|
lec_vcc_added(struct lec_priv *priv, const struct atmlec_ioc *ioc_data,
|
2006-09-30 07:11:47 +07:00
|
|
|
struct atm_vcc *vcc,
|
|
|
|
void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb))
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2006-09-30 07:11:47 +07:00
|
|
|
struct lec_arp_table *entry;
|
|
|
|
int i, found_entry = 0;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2010-01-26 18:40:08 +07:00
|
|
|
/* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */
|
2006-09-30 07:11:47 +07:00
|
|
|
if (ioc_data->receive == 2) {
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("LEC_ARP: Attaching mcast forward\n");
|
2005-04-17 05:20:36 +07:00
|
|
|
#if 0
|
2006-09-30 07:11:47 +07:00
|
|
|
entry = lec_arp_find(priv, bus_mac);
|
|
|
|
if (!entry) {
|
2010-01-26 18:40:08 +07:00
|
|
|
pr_info("LEC_ARP: Multicast entry not found!\n");
|
2005-04-17 05:20:36 +07:00
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
|
|
|
|
entry->recv_vcc = vcc;
|
|
|
|
entry->old_recv_push = old_push;
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
2006-09-30 07:11:47 +07:00
|
|
|
entry = make_entry(priv, bus_mac);
|
|
|
|
if (entry == NULL)
|
2005-04-17 05:20:36 +07:00
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
del_timer(&entry->timer);
|
|
|
|
memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
|
|
|
|
entry->recv_vcc = vcc;
|
|
|
|
entry->old_recv_push = old_push;
|
2006-09-30 07:14:27 +07:00
|
|
|
hlist_add_head(&entry->next, &priv->mcast_fwds);
|
2006-09-30 07:11:47 +07:00
|
|
|
goto out;
|
|
|
|
} else if (ioc_data->receive == 1) {
|
|
|
|
/*
|
|
|
|
* Vcc which we don't want to make default vcc,
|
|
|
|
* attach it anyway.
|
|
|
|
*/
|
2020-01-23 21:20:02 +07:00
|
|
|
pr_debug("LEC_ARP:Attaching data direct, not default: %*phN\n",
|
|
|
|
ATM_ESA_LEN, ioc_data->atm_addr);
|
2006-09-30 07:11:47 +07:00
|
|
|
entry = make_entry(priv, bus_mac);
|
|
|
|
if (entry == NULL)
|
2005-04-17 05:20:36 +07:00
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
|
2015-03-03 10:54:54 +07:00
|
|
|
eth_zero_addr(entry->mac_addr);
|
2006-09-30 07:11:47 +07:00
|
|
|
entry->recv_vcc = vcc;
|
|
|
|
entry->old_recv_push = old_push;
|
|
|
|
entry->status = ESI_UNKNOWN;
|
|
|
|
entry->timer.expires = jiffies + priv->vcc_timeout_period;
|
2017-10-23 14:40:42 +07:00
|
|
|
entry->timer.function = lec_arp_expire_vcc;
|
2006-09-30 07:14:27 +07:00
|
|
|
hlist_add_head(&entry->next, &priv->lec_no_forward);
|
2006-09-30 07:11:47 +07:00
|
|
|
add_timer(&entry->timer);
|
2005-04-17 05:20:36 +07:00
|
|
|
dump_arp_table(priv);
|
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2020-01-23 21:20:02 +07:00
|
|
|
pr_debug("LEC_ARP:Attaching data direct, default: %*phN\n",
|
|
|
|
ATM_ESA_LEN, ioc_data->atm_addr);
|
2006-09-30 07:11:47 +07:00
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry(entry,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_tables[i], next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
if (memcmp
|
|
|
|
(ioc_data->atm_addr, entry->atm_addr,
|
|
|
|
ATM_ESA_LEN) == 0) {
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("LEC_ARP: Attaching data direct\n");
|
|
|
|
pr_debug("Currently -> Vcc: %d, Rvcc:%d\n",
|
2010-01-26 18:40:00 +07:00
|
|
|
entry->vcc ? entry->vcc->vci : 0,
|
|
|
|
entry->recv_vcc ? entry->recv_vcc->
|
|
|
|
vci : 0);
|
2006-09-30 07:11:47 +07:00
|
|
|
found_entry = 1;
|
|
|
|
del_timer(&entry->timer);
|
|
|
|
entry->vcc = vcc;
|
|
|
|
entry->old_push = old_push;
|
|
|
|
if (entry->status == ESI_VC_PENDING) {
|
|
|
|
if (priv->maximum_unknown_frame_count
|
|
|
|
== 0)
|
|
|
|
entry->status =
|
|
|
|
ESI_FORWARD_DIRECT;
|
|
|
|
else {
|
|
|
|
entry->timestamp = jiffies;
|
|
|
|
entry->status =
|
|
|
|
ESI_FLUSH_PENDING;
|
2005-04-17 05:20:36 +07:00
|
|
|
#if 0
|
2006-09-30 07:11:47 +07:00
|
|
|
send_to_lecd(priv, l_flush_xmt,
|
|
|
|
NULL,
|
|
|
|
entry->atm_addr,
|
|
|
|
NULL);
|
2005-04-17 05:20:36 +07:00
|
|
|
#endif
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* They were forming a connection
|
|
|
|
* to us, and we to them. Our
|
|
|
|
* ATM address is numerically lower
|
|
|
|
* than theirs, so we make connection
|
|
|
|
* we formed into default VCC (8.1.11).
|
|
|
|
* Connection they made gets torn
|
|
|
|
* down. This might confuse some
|
|
|
|
* clients. Can be changed if
|
|
|
|
* someone reports trouble...
|
|
|
|
*/
|
|
|
|
;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (found_entry) {
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("After vcc was added\n");
|
2006-09-30 07:11:47 +07:00
|
|
|
dump_arp_table(priv);
|
2005-04-17 05:20:36 +07:00
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Not found, snatch address from first data packet that arrives
|
|
|
|
* from this vcc
|
|
|
|
*/
|
|
|
|
entry = make_entry(priv, bus_mac);
|
|
|
|
if (!entry)
|
2005-04-17 05:20:36 +07:00
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
entry->vcc = vcc;
|
|
|
|
entry->old_push = old_push;
|
|
|
|
memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
|
2015-03-03 10:54:54 +07:00
|
|
|
eth_zero_addr(entry->mac_addr);
|
2006-09-30 07:11:47 +07:00
|
|
|
entry->status = ESI_UNKNOWN;
|
2006-09-30 07:14:27 +07:00
|
|
|
hlist_add_head(&entry->next, &priv->lec_arp_empty_ones);
|
2006-09-30 07:11:47 +07:00
|
|
|
entry->timer.expires = jiffies + priv->vcc_timeout_period;
|
2017-10-23 14:40:42 +07:00
|
|
|
entry->timer.function = lec_arp_expire_vcc;
|
2006-09-30 07:11:47 +07:00
|
|
|
add_timer(&entry->timer);
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("After vcc was added\n");
|
2005-04-17 05:20:36 +07:00
|
|
|
dump_arp_table(priv);
|
|
|
|
out:
|
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2006-09-30 07:11:47 +07:00
|
|
|
struct lec_arp_table *entry;
|
|
|
|
int i;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2010-01-26 18:40:00 +07:00
|
|
|
pr_debug("%lx\n", tran_id);
|
2006-09-30 07:17:17 +07:00
|
|
|
restart:
|
2006-09-30 07:11:47 +07:00
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry(entry,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_tables[i], next) {
|
|
|
|
if (entry->flush_tran_id == tran_id &&
|
|
|
|
entry->status == ESI_FLUSH_PENDING) {
|
2006-09-30 07:11:47 +07:00
|
|
|
struct sk_buff *skb;
|
2006-09-30 07:17:17 +07:00
|
|
|
struct atm_vcc *vcc = entry->vcc;
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2006-09-30 07:17:17 +07:00
|
|
|
lec_arp_hold(entry);
|
2010-01-26 18:40:08 +07:00
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock,
|
|
|
|
flags);
|
2010-01-26 18:40:19 +07:00
|
|
|
while ((skb = skb_dequeue(&entry->tx_wait)))
|
2009-01-09 20:01:01 +07:00
|
|
|
lec_send(vcc, skb);
|
2006-09-30 07:17:17 +07:00
|
|
|
entry->last_used = jiffies;
|
2006-09-30 07:11:47 +07:00
|
|
|
entry->status = ESI_FORWARD_DIRECT;
|
2006-09-30 07:17:17 +07:00
|
|
|
lec_arp_put(entry);
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("LEC_ARP: Flushed\n");
|
2006-09-30 07:17:17 +07:00
|
|
|
goto restart;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
dump_arp_table(priv);
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
lec_set_flush_tran_id(struct lec_priv *priv,
|
2008-06-18 06:20:06 +07:00
|
|
|
const unsigned char *atm_addr, unsigned long tran_id)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2006-09-30 07:11:47 +07:00
|
|
|
struct lec_arp_table *entry;
|
|
|
|
int i;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++)
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry(entry,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_tables[i], next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) {
|
|
|
|
entry->flush_tran_id = tran_id;
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("Set flush transaction id to %lx for %p\n",
|
2010-01-26 18:40:00 +07:00
|
|
|
tran_id, entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
2006-09-30 07:14:27 +07:00
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
2006-09-30 07:11:47 +07:00
|
|
|
unsigned char mac_addr[] = {
|
|
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
|
|
|
|
};
|
|
|
|
struct lec_arp_table *to_add;
|
2005-04-17 05:20:36 +07:00
|
|
|
struct lec_vcc_priv *vpriv;
|
|
|
|
int err = 0;
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2010-01-26 18:40:08 +07:00
|
|
|
vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL);
|
|
|
|
if (!vpriv)
|
2005-04-17 05:20:36 +07:00
|
|
|
return -ENOMEM;
|
|
|
|
vpriv->xoff = 0;
|
|
|
|
vpriv->old_pop = vcc->pop;
|
|
|
|
vcc->user_back = vpriv;
|
2006-09-30 07:11:47 +07:00
|
|
|
vcc->pop = lec_pop;
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
to_add = make_entry(priv, mac_addr);
|
|
|
|
if (!to_add) {
|
2005-04-17 05:20:36 +07:00
|
|
|
vcc->pop = vpriv->old_pop;
|
|
|
|
kfree(vpriv);
|
2006-09-30 07:11:47 +07:00
|
|
|
err = -ENOMEM;
|
2005-04-17 05:20:36 +07:00
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
|
|
|
|
to_add->status = ESI_FORWARD_DIRECT;
|
|
|
|
to_add->flags |= LEC_PERMANENT_FLAG;
|
|
|
|
to_add->vcc = vcc;
|
|
|
|
to_add->old_push = vcc->push;
|
|
|
|
vcc->push = lec_push;
|
|
|
|
priv->mcast_vcc = vcc;
|
|
|
|
lec_arp_add(priv, to_add);
|
2005-04-17 05:20:36 +07:00
|
|
|
out:
|
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
2006-09-30 07:11:47 +07:00
|
|
|
return err;
|
2005-04-17 05:20:36 +07:00
|
|
|
}
|
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
|
|
|
unsigned long flags;
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
struct hlist_node *next;
|
2006-09-30 07:14:27 +07:00
|
|
|
struct lec_arp_table *entry;
|
2006-09-30 07:11:47 +07:00
|
|
|
int i;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n", vcc->vpi, vcc->vci);
|
2006-09-30 07:11:47 +07:00
|
|
|
dump_arp_table(priv);
|
2006-09-30 07:14:27 +07:00
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
2006-09-30 07:14:27 +07:00
|
|
|
|
2006-09-30 07:11:47 +07:00
|
|
|
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) {
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_tables[i], next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
if (vcc == entry->vcc) {
|
|
|
|
lec_arp_remove(priv, entry);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2010-01-26 18:40:08 +07:00
|
|
|
if (priv->mcast_vcc == vcc)
|
2006-09-30 07:11:47 +07:00
|
|
|
priv->mcast_vcc = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_empty_ones, next) {
|
2006-09-30 07:14:27 +07:00
|
|
|
if (entry->vcc == vcc) {
|
2006-09-30 07:11:47 +07:00
|
|
|
lec_arp_clear_vccs(entry);
|
|
|
|
del_timer(&entry->timer);
|
2006-09-30 07:14:27 +07:00
|
|
|
hlist_del(&entry->next);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_no_forward, next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
if (entry->recv_vcc == vcc) {
|
|
|
|
lec_arp_clear_vccs(entry);
|
|
|
|
del_timer(&entry->timer);
|
2006-09-30 07:14:27 +07:00
|
|
|
hlist_del(&entry->next);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next, &priv->mcast_fwds, next) {
|
2006-09-30 07:11:47 +07:00
|
|
|
if (entry->recv_vcc == vcc) {
|
|
|
|
lec_arp_clear_vccs(entry);
|
|
|
|
/* No timer, LANEv2 7.1.20 and 2.3.5.3 */
|
2006-09-30 07:14:27 +07:00
|
|
|
hlist_del(&entry->next);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(entry);
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
}
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
|
|
|
dump_arp_table(priv);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
lec_arp_check_empties(struct lec_priv *priv,
|
2006-09-30 07:11:47 +07:00
|
|
|
struct atm_vcc *vcc, struct sk_buff *skb)
|
2005-04-17 05:20:36 +07:00
|
|
|
{
|
2006-09-30 07:11:47 +07:00
|
|
|
unsigned long flags;
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
struct hlist_node *next;
|
2006-09-30 07:14:27 +07:00
|
|
|
struct lec_arp_table *entry, *tmp;
|
2006-09-30 07:11:47 +07:00
|
|
|
struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
|
2012-05-11 03:17:00 +07:00
|
|
|
unsigned char *src = hdr->h_source;
|
2005-04-17 05:20:36 +07:00
|
|
|
|
|
|
|
spin_lock_irqsave(&priv->lec_arp_lock, flags);
|
hlist: drop the node parameter from iterators
I'm not sure why, but the hlist for each entry iterators were conceived
list_for_each_entry(pos, head, member)
The hlist ones were greedy and wanted an extra parameter:
hlist_for_each_entry(tpos, pos, head, member)
Why did they need an extra pos parameter? I'm not quite sure. Not only
they don't really need it, it also prevents the iterator from looking
exactly like the list iterator, which is unfortunate.
Besides the semantic patch, there was some manual work required:
- Fix up the actual hlist iterators in linux/list.h
- Fix up the declaration of other iterators based on the hlist ones.
- A very small amount of places were using the 'node' parameter, this
was modified to use 'obj->member' instead.
- Coccinelle didn't handle the hlist_for_each_entry_safe iterator
properly, so those had to be fixed up manually.
The semantic patch which is mostly the work of Peter Senna Tschudin is here:
@@
iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
type T;
expression a,c,d,e;
identifier b;
statement S;
@@
-T b;
<+... when != b
(
hlist_for_each_entry(a,
- b,
c, d) S
|
hlist_for_each_entry_continue(a,
- b,
c) S
|
hlist_for_each_entry_from(a,
- b,
c) S
|
hlist_for_each_entry_rcu(a,
- b,
c, d) S
|
hlist_for_each_entry_rcu_bh(a,
- b,
c, d) S
|
hlist_for_each_entry_continue_rcu_bh(a,
- b,
c) S
|
for_each_busy_worker(a, c,
- b,
d) S
|
ax25_uid_for_each(a,
- b,
c) S
|
ax25_for_each(a,
- b,
c) S
|
inet_bind_bucket_for_each(a,
- b,
c) S
|
sctp_for_each_hentry(a,
- b,
c) S
|
sk_for_each(a,
- b,
c) S
|
sk_for_each_rcu(a,
- b,
c) S
|
sk_for_each_from
-(a, b)
+(a)
S
+ sk_for_each_from(a) S
|
sk_for_each_safe(a,
- b,
c, d) S
|
sk_for_each_bound(a,
- b,
c) S
|
hlist_for_each_entry_safe(a,
- b,
c, d, e) S
|
hlist_for_each_entry_continue_rcu(a,
- b,
c) S
|
nr_neigh_for_each(a,
- b,
c) S
|
nr_neigh_for_each_safe(a,
- b,
c, d) S
|
nr_node_for_each(a,
- b,
c) S
|
nr_node_for_each_safe(a,
- b,
c, d) S
|
- for_each_gfn_sp(a, c, d, b) S
+ for_each_gfn_sp(a, c, d) S
|
- for_each_gfn_indirect_valid_sp(a, c, d, b) S
+ for_each_gfn_indirect_valid_sp(a, c, d) S
|
for_each_host(a,
- b,
c) S
|
for_each_host_safe(a,
- b,
c, d) S
|
for_each_mesh_entry(a,
- b,
c, d) S
)
...+>
[akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
[akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
[akpm@linux-foundation.org: checkpatch fixes]
[akpm@linux-foundation.org: fix warnings]
[akpm@linux-foudnation.org: redo intrusive kvm changes]
Tested-by: Peter Senna Tschudin <peter.senna@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Cc: Wu Fengguang <fengguang.wu@intel.com>
Cc: Marcelo Tosatti <mtosatti@redhat.com>
Cc: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2013-02-28 08:06:00 +07:00
|
|
|
hlist_for_each_entry_safe(entry, next,
|
2010-01-26 18:40:08 +07:00
|
|
|
&priv->lec_arp_empty_ones, next) {
|
2006-09-30 07:14:27 +07:00
|
|
|
if (vcc == entry->vcc) {
|
|
|
|
del_timer(&entry->timer);
|
2014-01-21 00:52:16 +07:00
|
|
|
ether_addr_copy(entry->mac_addr, src);
|
2006-09-30 07:14:27 +07:00
|
|
|
entry->status = ESI_FORWARD_DIRECT;
|
|
|
|
entry->last_used = jiffies;
|
|
|
|
/* We might have got an entry */
|
2010-01-26 18:40:08 +07:00
|
|
|
tmp = lec_arp_find(priv, src);
|
|
|
|
if (tmp) {
|
2006-09-30 07:14:27 +07:00
|
|
|
lec_arp_remove(priv, tmp);
|
2006-09-30 07:16:48 +07:00
|
|
|
lec_arp_put(tmp);
|
2006-09-30 07:14:27 +07:00
|
|
|
}
|
|
|
|
hlist_del(&entry->next);
|
|
|
|
lec_arp_add(priv, entry);
|
|
|
|
goto out;
|
2006-09-30 07:11:47 +07:00
|
|
|
}
|
|
|
|
}
|
2007-08-29 05:22:09 +07:00
|
|
|
pr_debug("LEC_ARP: Arp_check_empties: entry not found!\n");
|
2005-04-17 05:20:36 +07:00
|
|
|
out:
|
|
|
|
spin_unlock_irqrestore(&priv->lec_arp_lock, flags);
|
|
|
|
}
|
2006-09-30 07:11:47 +07:00
|
|
|
|
2005-04-17 05:20:36 +07:00
|
|
|
MODULE_LICENSE("GPL");
|