Blame view
net/atm/lec.c
58.2 KB
09c434b8a treewide: Add SPD... |
1 |
// SPDX-License-Identifier: GPL-2.0-only |
1da177e4c Linux-2.6.12-rc2 |
2 |
/* |
f7d57453d [NET] ATM: Fix wh... |
3 |
* lec.c: Lan Emulation driver |
1da177e4c Linux-2.6.12-rc2 |
4 |
* |
d44f77466 [ATM]: [lec] inde... |
5 |
* Marko Kiiskila <mkiiskila@yahoo.com> |
1da177e4c Linux-2.6.12-rc2 |
6 |
*/ |
99824461e net/atm: Convert ... |
7 |
#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__ |
5a0e3ad6a include cleanup: ... |
8 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
9 10 |
#include <linux/kernel.h> #include <linux/bitops.h> |
4fc268d24 [PATCH] capable/c... |
11 |
#include <linux/capability.h> |
1da177e4c Linux-2.6.12-rc2 |
12 13 14 15 16 17 18 19 20 |
/* 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> |
c48192a70 net/atm/lec.c: ch... |
21 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
22 23 24 25 |
#include <net/arp.h> #include <net/dst.h> #include <linux/proc_fs.h> #include <linux/spinlock.h> |
1da177e4c Linux-2.6.12-rc2 |
26 |
#include <linux/seq_file.h> |
1da177e4c Linux-2.6.12-rc2 |
27 28 29 30 31 |
/* And atm device */ #include <linux/atmdev.h> #include <linux/atmlec.h> /* Proxy LEC knows about bridging */ |
9a81c34ac lec: use IS_ENABL... |
32 |
#if IS_ENABLED(CONFIG_BRIDGE) |
1da177e4c Linux-2.6.12-rc2 |
33 |
#include "../bridge/br_private.h" |
d44f77466 [ATM]: [lec] inde... |
34 |
static unsigned char bridge_ula_lec[] = { 0x01, 0x80, 0xc2, 0x00, 0x00 }; |
1da177e4c Linux-2.6.12-rc2 |
35 36 37 38 39 |
#endif /* Modular too */ #include <linux/module.h> #include <linux/init.h> |
acf784bd0 net: atm: Fix pot... |
40 41 |
/* Hardening for Spectre-v1 */ #include <linux/nospec.h> |
1da177e4c Linux-2.6.12-rc2 |
42 43 44 |
#include "lec.h" #include "lec_arpc.h" #include "resources.h" |
d44f77466 [ATM]: [lec] inde... |
45 46 47 48 49 |
#define DUMP_PACKETS 0 /* * 0 = None, * 1 = 30 first bytes * 2 = Whole packet */ |
1da177e4c Linux-2.6.12-rc2 |
50 |
|
d44f77466 [ATM]: [lec] inde... |
51 52 53 54 |
#define LEC_UNRES_QUE_LEN 8 /* * number of tx packets to queue for a * single destination while waiting for SVC */ |
1da177e4c Linux-2.6.12-rc2 |
55 56 |
static int lec_open(struct net_device *dev); |
3c805a22a convert ATM drive... |
57 58 |
static netdev_tx_t lec_start_xmit(struct sk_buff *skb, struct net_device *dev); |
1da177e4c Linux-2.6.12-rc2 |
59 |
static int lec_close(struct net_device *dev); |
d44f77466 [ATM]: [lec] inde... |
60 |
static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, |
61c33e012 atm: use const wh... |
61 |
const unsigned char *mac_addr); |
1da177e4c Linux-2.6.12-rc2 |
62 |
static int lec_arp_remove(struct lec_priv *priv, |
d44f77466 [ATM]: [lec] inde... |
63 |
struct lec_arp_table *to_remove); |
1da177e4c Linux-2.6.12-rc2 |
64 |
/* LANE2 functions */ |
61c33e012 atm: use const wh... |
65 66 67 |
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, |
d44f77466 [ATM]: [lec] inde... |
68 |
u8 **tlvs, u32 *sizeoftlvs); |
61c33e012 atm: use const wh... |
69 70 |
static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst, const u8 *tlvs, u32 sizeoftlvs); |
1da177e4c Linux-2.6.12-rc2 |
71 |
|
61c33e012 atm: use const wh... |
72 |
static int lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr, |
1da177e4c Linux-2.6.12-rc2 |
73 74 75 76 77 |
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); |
d44f77466 [ATM]: [lec] inde... |
78 |
static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, |
61c33e012 atm: use const wh... |
79 |
const unsigned char *mac_to_find, |
1da177e4c Linux-2.6.12-rc2 |
80 81 |
int is_rdesc, struct lec_arp_table **ret_entry); |
61c33e012 atm: use const wh... |
82 |
static void lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr, |
c48192a70 net/atm/lec.c: ch... |
83 84 |
const unsigned char *atm_addr, unsigned long remoteflag, |
1da177e4c Linux-2.6.12-rc2 |
85 86 87 88 |
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, |
61c33e012 atm: use const wh... |
89 |
const unsigned char *atm_addr, |
1da177e4c Linux-2.6.12-rc2 |
90 |
unsigned long tran_id); |
c48192a70 net/atm/lec.c: ch... |
91 92 |
static void lec_vcc_added(struct lec_priv *priv, const struct atmlec_ioc *ioc_data, |
1da177e4c Linux-2.6.12-rc2 |
93 |
struct atm_vcc *vcc, |
c48192a70 net/atm/lec.c: ch... |
94 95 |
void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb)); |
1da177e4c Linux-2.6.12-rc2 |
96 |
static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc); |
33a9c2d4b [ATM]: [lec] add ... |
97 98 99 |
/* must be done under lec_arp_lock */ static inline void lec_arp_hold(struct lec_arp_table *entry) { |
788936641 net, atm: convert... |
100 |
refcount_inc(&entry->usage); |
33a9c2d4b [ATM]: [lec] add ... |
101 102 103 104 |
} static inline void lec_arp_put(struct lec_arp_table *entry) { |
788936641 net, atm: convert... |
105 |
if (refcount_dec_and_test(&entry->usage)) |
33a9c2d4b [ATM]: [lec] add ... |
106 107 |
kfree(entry); } |
1da177e4c Linux-2.6.12-rc2 |
108 |
static struct lane2_ops lane2_ops = { |
99a5e178b ATM: use designat... |
109 110 111 |
.resolve = lane2_resolve, /* spec 3.1.3 */ .associate_req = lane2_associate_req, /* spec 3.1.4 */ .associate_indicator = NULL /* spec 3.1.5 */ |
1da177e4c Linux-2.6.12-rc2 |
112 |
}; |
d44f77466 [ATM]: [lec] inde... |
113 |
static unsigned char bus_mac[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; |
1da177e4c Linux-2.6.12-rc2 |
114 115 116 |
/* Device structures */ static struct net_device *dev_lec[MAX_LEC_ITF]; |
9a81c34ac lec: use IS_ENABL... |
117 |
#if IS_ENABLED(CONFIG_BRIDGE) |
1da177e4c Linux-2.6.12-rc2 |
118 119 |
static void lec_handle_bridge(struct sk_buff *skb, struct net_device *dev) { |
d44f77466 [ATM]: [lec] inde... |
120 121 122 123 124 125 126 127 |
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 */ |
d44f77466 [ATM]: [lec] inde... |
128 129 |
buff = skb->data + skb->dev->hard_header_len; if (*buff++ == 0x42 && *buff++ == 0x42 && *buff++ == 0x03) { |
1da177e4c Linux-2.6.12-rc2 |
130 |
struct sock *sk; |
d44f77466 [ATM]: [lec] inde... |
131 132 133 134 135 136 137 138 139 140 |
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; |
c48192a70 net/atm/lec.c: ch... |
141 142 |
mesg->content.normal.flag = *buff & 0x01; /* 0x01 is topology change */ |
d44f77466 [ATM]: [lec] inde... |
143 |
|
524ad0a79 netdevice: safe c... |
144 |
priv = netdev_priv(dev); |
d44f77466 [ATM]: [lec] inde... |
145 |
atm_force_charge(priv->lecd, skb2->truesize); |
1da177e4c Linux-2.6.12-rc2 |
146 |
sk = sk_atm(priv->lecd); |
d44f77466 [ATM]: [lec] inde... |
147 |
skb_queue_tail(&sk->sk_receive_queue, skb2); |
676d23690 net: Fix use afte... |
148 |
sk->sk_data_ready(sk); |
d44f77466 [ATM]: [lec] inde... |
149 |
} |
1da177e4c Linux-2.6.12-rc2 |
150 |
} |
9a81c34ac lec: use IS_ENABL... |
151 |
#endif /* IS_ENABLED(CONFIG_BRIDGE) */ |
1da177e4c Linux-2.6.12-rc2 |
152 153 |
/* |
1da177e4c Linux-2.6.12-rc2 |
154 155 156 157 158 159 160 |
* 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. */ |
d44f77466 [ATM]: [lec] inde... |
161 |
static int lec_open(struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
162 |
{ |
1da177e4c Linux-2.6.12-rc2 |
163 |
netif_start_queue(dev); |
d44f77466 [ATM]: [lec] inde... |
164 165 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
166 |
} |
162619e59 lec: convert to i... |
167 168 |
static void lec_send(struct atm_vcc *vcc, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
169 |
{ |
162619e59 lec: convert to i... |
170 |
struct net_device *dev = skb->dev; |
1da177e4c Linux-2.6.12-rc2 |
171 |
ATM_SKB(skb)->vcc = vcc; |
9bbe60a67 atm: Preserve val... |
172 |
atm_account_tx(vcc, skb); |
1da177e4c Linux-2.6.12-rc2 |
173 |
|
1da177e4c Linux-2.6.12-rc2 |
174 |
if (vcc->send(vcc, skb) < 0) { |
162619e59 lec: convert to i... |
175 |
dev->stats.tx_dropped++; |
1da177e4c Linux-2.6.12-rc2 |
176 177 |
return; } |
162619e59 lec: convert to i... |
178 179 |
dev->stats.tx_packets++; dev->stats.tx_bytes += skb->len; |
1da177e4c Linux-2.6.12-rc2 |
180 |
} |
0290bd291 netdev: pass the ... |
181 |
static void lec_tx_timeout(struct net_device *dev, unsigned int txqueue) |
1da177e4c Linux-2.6.12-rc2 |
182 |
{ |
99824461e net/atm: Convert ... |
183 184 |
pr_info("%s ", dev->name); |
860e9538a treewide: replace... |
185 |
netif_trans_update(dev); |
1da177e4c Linux-2.6.12-rc2 |
186 187 |
netif_wake_queue(dev); } |
3c805a22a convert ATM drive... |
188 189 |
static netdev_tx_t lec_start_xmit(struct sk_buff *skb, struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
190 |
{ |
d44f77466 [ATM]: [lec] inde... |
191 |
struct sk_buff *skb2; |
524ad0a79 netdevice: safe c... |
192 |
struct lec_priv *priv = netdev_priv(dev); |
d44f77466 [ATM]: [lec] inde... |
193 194 |
struct lecdatahdr_8023 *lec_h; struct atm_vcc *vcc; |
1da177e4c Linux-2.6.12-rc2 |
195 |
struct lec_arp_table *entry; |
d44f77466 [ATM]: [lec] inde... |
196 |
unsigned char *dst; |
1da177e4c Linux-2.6.12-rc2 |
197 |
int min_frame_size; |
d44f77466 [ATM]: [lec] inde... |
198 |
int is_rdesc; |
d44f77466 [ATM]: [lec] inde... |
199 |
|
99824461e net/atm: Convert ... |
200 201 |
pr_debug("called "); |
d44f77466 [ATM]: [lec] inde... |
202 |
if (!priv->lecd) { |
c48192a70 net/atm/lec.c: ch... |
203 204 |
pr_info("%s:No lecd attached ", dev->name); |
162619e59 lec: convert to i... |
205 |
dev->stats.tx_errors++; |
d44f77466 [ATM]: [lec] inde... |
206 |
netif_stop_queue(dev); |
81fbbf604 net: fix network ... |
207 208 |
kfree_skb(skb); return NETDEV_TX_OK; |
d44f77466 [ATM]: [lec] inde... |
209 |
} |
522400623 [ATM]: Replace DP... |
210 211 |
pr_debug("skbuff head:%lx data:%lx tail:%lx end:%lx ", |
99824461e net/atm: Convert ... |
212 213 |
(long)skb->head, (long)skb->data, (long)skb_tail_pointer(skb), (long)skb_end_pointer(skb)); |
9a81c34ac lec: use IS_ENABL... |
214 |
#if IS_ENABLED(CONFIG_BRIDGE) |
d44f77466 [ATM]: [lec] inde... |
215 216 |
if (memcmp(skb->data, bridge_ula_lec, sizeof(bridge_ula_lec)) == 0) lec_handle_bridge(skb, dev); |
1da177e4c Linux-2.6.12-rc2 |
217 |
#endif |
d44f77466 [ATM]: [lec] inde... |
218 219 |
/* Make sure we have room for lec_id */ if (skb_headroom(skb) < 2) { |
99824461e net/atm: Convert ... |
220 221 |
pr_debug("reallocating skb "); |
d44f77466 [ATM]: [lec] inde... |
222 |
skb2 = skb_realloc_headroom(skb, LEC_HEADER_LEN); |
5d0ba55b6 net: use consume_... |
223 224 |
if (unlikely(!skb2)) { kfree_skb(skb); |
6ed106549 net: use NETDEV_T... |
225 |
return NETDEV_TX_OK; |
5d0ba55b6 net: use consume_... |
226 227 |
} consume_skb(skb); |
d44f77466 [ATM]: [lec] inde... |
228 229 230 |
skb = skb2; } skb_push(skb, 2); |
1da177e4c Linux-2.6.12-rc2 |
231 |
|
60eea6cf2 atm: remove the c... |
232 |
/* Put le header to place */ |
d44f77466 [ATM]: [lec] inde... |
233 234 |
lec_h = (struct lecdatahdr_8023 *)skb->data; lec_h->le_header = htons(priv->lecid); |
1da177e4c Linux-2.6.12-rc2 |
235 |
|
1da177e4c Linux-2.6.12-rc2 |
236 |
#if DUMP_PACKETS >= 2 |
c48192a70 net/atm/lec.c: ch... |
237 |
#define MAX_DUMP_SKB 99 |
1da177e4c Linux-2.6.12-rc2 |
238 |
#elif DUMP_PACKETS >= 1 |
c48192a70 net/atm/lec.c: ch... |
239 240 241 242 243 244 245 246 |
#define MAX_DUMP_SKB 30 #endif #if DUMP_PACKETS >= 1 printk(KERN_DEBUG "%s: send datalen:%ld lecid:%4.4x ", dev->name, skb->len, priv->lecid); print_hex_dump(KERN_DEBUG, "", DUMP_OFFSET, 16, 1, skb->data, min(skb->len, MAX_DUMP_SKB), true); |
1da177e4c Linux-2.6.12-rc2 |
247 |
#endif /* DUMP_PACKETS >= 1 */ |
1da177e4c Linux-2.6.12-rc2 |
248 |
|
d44f77466 [ATM]: [lec] inde... |
249 |
/* Minimum ethernet-frame size */ |
60eea6cf2 atm: remove the c... |
250 |
min_frame_size = LEC_MINIMUM_8023_SIZE; |
d44f77466 [ATM]: [lec] inde... |
251 252 253 254 255 256 257 |
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) { |
162619e59 lec: convert to i... |
258 |
dev->stats.tx_dropped++; |
6ed106549 net: use NETDEV_T... |
259 |
return NETDEV_TX_OK; |
d44f77466 [ATM]: [lec] inde... |
260 261 262 |
} skb = skb2; } |
1da177e4c Linux-2.6.12-rc2 |
263 |
skb_put(skb, min_frame_size - skb->len); |
d44f77466 [ATM]: [lec] inde... |
264 265 266 267 268 |
} /* Send to right vcc */ is_rdesc = 0; dst = lec_h->h_dest; |
d44f77466 [ATM]: [lec] inde... |
269 270 |
entry = NULL; vcc = lec_arp_resolve(priv, dst, is_rdesc, &entry); |
99824461e net/atm: Convert ... |
271 272 273 |
pr_debug("%s:vcc:%p vcc_flags:%lx, entry:%p ", dev->name, vcc, vcc ? vcc->flags : 0, entry); |
d44f77466 [ATM]: [lec] inde... |
274 275 |
if (!vcc || !test_bit(ATM_VF_READY, &vcc->flags)) { if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) { |
99824461e net/atm: Convert ... |
276 277 278 |
pr_debug("%s:queuing packet, MAC address %pM ", dev->name, lec_h->h_dest); |
d44f77466 [ATM]: [lec] inde... |
279 280 |
skb_queue_tail(&entry->tx_wait, skb); } else { |
99824461e net/atm: Convert ... |
281 282 283 |
pr_debug("%s:tx queue full or no arp entry, dropping, MAC address: %pM ", dev->name, lec_h->h_dest); |
162619e59 lec: convert to i... |
284 |
dev->stats.tx_dropped++; |
d44f77466 [ATM]: [lec] inde... |
285 286 |
dev_kfree_skb(skb); } |
6656e3c4c [ATM]: [lec] use ... |
287 |
goto out; |
d44f77466 [ATM]: [lec] inde... |
288 289 |
} #if DUMP_PACKETS > 0 |
c48192a70 net/atm/lec.c: ch... |
290 291 292 |
printk(KERN_DEBUG "%s:sending to vpi:%d vci:%d ", dev->name, vcc->vpi, vcc->vci); |
1da177e4c Linux-2.6.12-rc2 |
293 |
#endif /* DUMP_PACKETS > 0 */ |
d44f77466 [ATM]: [lec] inde... |
294 295 |
while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) { |
99824461e net/atm: Convert ... |
296 297 |
pr_debug("emptying tx queue, MAC address %pM ", lec_h->h_dest); |
162619e59 lec: convert to i... |
298 |
lec_send(vcc, skb2); |
d44f77466 [ATM]: [lec] inde... |
299 |
} |
1da177e4c Linux-2.6.12-rc2 |
300 |
|
162619e59 lec: convert to i... |
301 |
lec_send(vcc, skb); |
1da177e4c Linux-2.6.12-rc2 |
302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
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); } |
6656e3c4c [ATM]: [lec] use ... |
318 319 320 |
out: if (entry) lec_arp_put(entry); |
860e9538a treewide: replace... |
321 |
netif_trans_update(dev); |
6ed106549 net: use NETDEV_T... |
322 |
return NETDEV_TX_OK; |
1da177e4c Linux-2.6.12-rc2 |
323 324 325 |
} /* The inverse routine to net_open(). */ |
d44f77466 [ATM]: [lec] inde... |
326 |
static int lec_close(struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
327 |
{ |
d44f77466 [ATM]: [lec] inde... |
328 329 |
netif_stop_queue(dev); return 0; |
1da177e4c Linux-2.6.12-rc2 |
330 |
} |
d44f77466 [ATM]: [lec] inde... |
331 |
static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
332 333 |
{ unsigned long flags; |
d44f77466 [ATM]: [lec] inde... |
334 |
struct net_device *dev = (struct net_device *)vcc->proto_data; |
524ad0a79 netdevice: safe c... |
335 |
struct lec_priv *priv = netdev_priv(dev); |
d44f77466 [ATM]: [lec] inde... |
336 337 338 339 |
struct atmlec_msg *mesg; struct lec_arp_table *entry; int i; char *tmp; /* FIXME */ |
1da177e4c Linux-2.6.12-rc2 |
340 |
|
14afee4b6 net: convert sock... |
341 |
WARN_ON(refcount_sub_and_test(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc)); |
d44f77466 [ATM]: [lec] inde... |
342 343 344 |
mesg = (struct atmlec_msg *)skb->data; tmp = skb->data; tmp += sizeof(struct atmlec_msg); |
522400623 [ATM]: Replace DP... |
345 346 |
pr_debug("%s: msg from zeppelin:%d ", dev->name, mesg->type); |
d44f77466 [ATM]: [lec] inde... |
347 348 |
switch (mesg->type) { case l_set_mac_addr: |
c48192a70 net/atm/lec.c: ch... |
349 |
for (i = 0; i < 6; i++) |
d44f77466 [ATM]: [lec] inde... |
350 |
dev->dev_addr[i] = mesg->content.normal.mac_addr[i]; |
d44f77466 [ATM]: [lec] inde... |
351 352 |
break; case l_del_mac_addr: |
c48192a70 net/atm/lec.c: ch... |
353 |
for (i = 0; i < 6; i++) |
d44f77466 [ATM]: [lec] inde... |
354 |
dev->dev_addr[i] = 0; |
d44f77466 [ATM]: [lec] inde... |
355 356 357 358 359 360 361 362 363 364 365 366 |
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 */ |
1da177e4c Linux-2.6.12-rc2 |
367 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
d44f77466 [ATM]: [lec] inde... |
368 369 |
entry = lec_arp_find(priv, mesg->content.normal.mac_addr); lec_arp_remove(priv, entry); |
1da177e4c Linux-2.6.12-rc2 |
370 |
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
d44f77466 [ATM]: [lec] inde... |
371 372 |
if (mesg->content.normal.no_source_le_narp) break; |
df561f668 treewide: Use fal... |
373 |
fallthrough; |
d44f77466 [ATM]: [lec] inde... |
374 375 376 377 378 |
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); |
99824461e net/atm: Convert ... |
379 380 |
pr_debug("in l_arp_update "); |
d44f77466 [ATM]: [lec] inde... |
381 |
if (mesg->sizeoftlvs != 0) { /* LANE2 3.1.5 */ |
99824461e net/atm: Convert ... |
382 383 384 |
pr_debug("LANE2 3.1.5, got tlvs, size %d ", mesg->sizeoftlvs); |
d44f77466 [ATM]: [lec] inde... |
385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 |
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); |
c48192a70 net/atm/lec.c: ch... |
403 404 |
priv->lane_version = mesg->content.config.lane_version; /* LANE2 */ |
1da177e4c Linux-2.6.12-rc2 |
405 406 407 |
priv->lane2_ops = NULL; if (priv->lane_version > 1) priv->lane2_ops = &lane2_ops; |
6df378d2d lec: Use rtnl loc... |
408 |
rtnl_lock(); |
1f1900f93 atm: lec use dev_... |
409 |
if (dev_set_mtu(dev, mesg->content.config.mtu)) |
c48192a70 net/atm/lec.c: ch... |
410 411 412 |
pr_info("%s: change_mtu to %d failed ", dev->name, mesg->content.config.mtu); |
6df378d2d lec: Use rtnl loc... |
413 |
rtnl_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
414 |
priv->is_proxy = mesg->content.config.is_proxy; |
d44f77466 [ATM]: [lec] inde... |
415 416 417 418 419 420 421 422 423 424 |
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: |
9a81c34ac lec: use IS_ENABL... |
425 |
#if IS_ENABLED(CONFIG_BRIDGE) |
b4c84ec0f net/atm/lec.c: Ad... |
426 427 428 429 |
{ pr_debug("%s: bridge zeppelin asks about %pM ", dev->name, mesg->content.proxy.mac_addr); |
d44f77466 [ATM]: [lec] inde... |
430 |
|
b4c84ec0f net/atm/lec.c: Ad... |
431 432 |
if (br_fdb_test_addr_hook == NULL) break; |
d44f77466 [ATM]: [lec] inde... |
433 |
|
b4c84ec0f net/atm/lec.c: Ad... |
434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
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 ", 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); |
676d23690 net: Fix use afte... |
450 |
sk->sk_data_ready(sk); |
d44f77466 [ATM]: [lec] inde... |
451 |
} |
b4c84ec0f net/atm/lec.c: Ad... |
452 |
} |
9a81c34ac lec: use IS_ENABL... |
453 |
#endif /* IS_ENABLED(CONFIG_BRIDGE) */ |
d44f77466 [ATM]: [lec] inde... |
454 455 |
break; default: |
c48192a70 net/atm/lec.c: ch... |
456 457 |
pr_info("%s: Unknown message type %d ", dev->name, mesg->type); |
d44f77466 [ATM]: [lec] inde... |
458 459 460 461 462 |
dev_kfree_skb(skb); return -EINVAL; } dev_kfree_skb(skb); return 0; |
1da177e4c Linux-2.6.12-rc2 |
463 |
} |
d44f77466 [ATM]: [lec] inde... |
464 |
static void lec_atm_close(struct atm_vcc *vcc) |
1da177e4c Linux-2.6.12-rc2 |
465 |
{ |
d44f77466 [ATM]: [lec] inde... |
466 467 |
struct sk_buff *skb; struct net_device *dev = (struct net_device *)vcc->proto_data; |
524ad0a79 netdevice: safe c... |
468 |
struct lec_priv *priv = netdev_priv(dev); |
1da177e4c Linux-2.6.12-rc2 |
469 |
|
d44f77466 [ATM]: [lec] inde... |
470 471 |
priv->lecd = NULL; /* Do something needful? */ |
1da177e4c Linux-2.6.12-rc2 |
472 |
|
d44f77466 [ATM]: [lec] inde... |
473 474 |
netif_stop_queue(dev); lec_arp_destroy(priv); |
1da177e4c Linux-2.6.12-rc2 |
475 |
|
d44f77466 [ATM]: [lec] inde... |
476 |
if (skb_peek(&sk_atm(vcc)->sk_receive_queue)) |
c48192a70 net/atm/lec.c: ch... |
477 478 |
pr_info("%s closing with messages pending ", dev->name); |
b4c84ec0f net/atm/lec.c: Ad... |
479 |
while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue))) { |
d44f77466 [ATM]: [lec] inde... |
480 |
atm_return(vcc, skb->truesize); |
1da177e4c Linux-2.6.12-rc2 |
481 |
dev_kfree_skb(skb); |
d44f77466 [ATM]: [lec] inde... |
482 |
} |
c48192a70 net/atm/lec.c: ch... |
483 484 |
pr_info("%s: Shut down! ", dev->name); |
d44f77466 [ATM]: [lec] inde... |
485 |
module_put(THIS_MODULE); |
1da177e4c Linux-2.6.12-rc2 |
486 |
} |
800bb47e7 net: atm: make at... |
487 |
static const struct atmdev_ops lecdev_ops = { |
d44f77466 [ATM]: [lec] inde... |
488 489 |
.close = lec_atm_close, .send = lec_atm_send |
1da177e4c Linux-2.6.12-rc2 |
490 491 492 |
}; static struct atm_dev lecatm_dev = { |
d44f77466 [ATM]: [lec] inde... |
493 494 495 |
.ops = &lecdev_ops, .type = "lec", .number = 999, /* dummy device number */ |
4ef8d0aea [NET]: SPIN_LOCK_... |
496 |
.lock = __SPIN_LOCK_UNLOCKED(lecatm_dev.lock) |
1da177e4c Linux-2.6.12-rc2 |
497 498 499 500 501 502 |
}; /* * LANE2: new argument struct sk_buff *data contains * the LE_ARP based TLVs introduced in the LANE2 spec */ |
d44f77466 [ATM]: [lec] inde... |
503 504 |
static int send_to_lecd(struct lec_priv *priv, atmlec_msg_type type, |
61c33e012 atm: use const wh... |
505 |
const unsigned char *mac_addr, const unsigned char *atm_addr, |
d44f77466 [ATM]: [lec] inde... |
506 |
struct sk_buff *data) |
1da177e4c Linux-2.6.12-rc2 |
507 508 509 510 |
{ struct sock *sk; struct sk_buff *skb; struct atmlec_msg *mesg; |
c48192a70 net/atm/lec.c: ch... |
511 |
if (!priv || !priv->lecd) |
1da177e4c Linux-2.6.12-rc2 |
512 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
513 514 515 516 517 |
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; |
d44f77466 [ATM]: [lec] inde... |
518 |
memset(mesg, 0, sizeof(struct atmlec_msg)); |
1da177e4c Linux-2.6.12-rc2 |
519 |
mesg->type = type; |
d44f77466 [ATM]: [lec] inde... |
520 521 |
if (data != NULL) mesg->sizeoftlvs = data->len; |
1da177e4c Linux-2.6.12-rc2 |
522 |
if (mac_addr) |
9be68c1ae net: Fix some fal... |
523 |
ether_addr_copy(mesg->content.normal.mac_addr, mac_addr); |
d44f77466 [ATM]: [lec] inde... |
524 525 |
else mesg->content.normal.targetless_le_arp = 1; |
1da177e4c Linux-2.6.12-rc2 |
526 527 |
if (atm_addr) memcpy(&mesg->content.normal.atm_addr, atm_addr, ATM_ESA_LEN); |
d44f77466 [ATM]: [lec] inde... |
528 |
atm_force_charge(priv->lecd, skb->truesize); |
1da177e4c Linux-2.6.12-rc2 |
529 530 |
sk = sk_atm(priv->lecd); skb_queue_tail(&sk->sk_receive_queue, skb); |
676d23690 net: Fix use afte... |
531 |
sk->sk_data_ready(sk); |
1da177e4c Linux-2.6.12-rc2 |
532 |
|
d44f77466 [ATM]: [lec] inde... |
533 |
if (data != NULL) { |
99824461e net/atm: Convert ... |
534 535 |
pr_debug("about to send %d bytes of data ", data->len); |
d44f77466 [ATM]: [lec] inde... |
536 537 |
atm_force_charge(priv->lecd, data->truesize); skb_queue_tail(&sk->sk_receive_queue, data); |
676d23690 net: Fix use afte... |
538 |
sk->sk_data_ready(sk); |
d44f77466 [ATM]: [lec] inde... |
539 |
} |
1da177e4c Linux-2.6.12-rc2 |
540 |
|
d44f77466 [ATM]: [lec] inde... |
541 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
542 |
} |
1da177e4c Linux-2.6.12-rc2 |
543 544 |
static void lec_set_multicast_list(struct net_device *dev) { |
d44f77466 [ATM]: [lec] inde... |
545 546 547 548 |
/* * by default, all multicast frames arrive over the bus. * eventually support selective multicast service */ |
1da177e4c Linux-2.6.12-rc2 |
549 |
} |
004b3225c lec: convert to n... |
550 551 552 553 |
static const struct net_device_ops lec_netdev_ops = { .ndo_open = lec_open, .ndo_stop = lec_close, .ndo_start_xmit = lec_start_xmit, |
004b3225c lec: convert to n... |
554 |
.ndo_tx_timeout = lec_tx_timeout, |
afc4b13df net: remove use o... |
555 |
.ndo_set_rx_mode = lec_set_multicast_list, |
004b3225c lec: convert to n... |
556 |
}; |
61c33e012 atm: use const wh... |
557 |
static const unsigned char lec_ctrl_magic[] = { |
d44f77466 [ATM]: [lec] inde... |
558 559 560 561 562 |
0xff, 0x00, 0x01, 0x01 }; |
1da177e4c Linux-2.6.12-rc2 |
563 |
|
4a7097fcc [ATM]: [lec] atte... |
564 565 566 567 |
#define LEC_DATA_DIRECT_8023 2 #define LEC_DATA_DIRECT_8025 3 static int lec_is_data_direct(struct atm_vcc *vcc) |
d44f77466 [ATM]: [lec] inde... |
568 |
{ |
4a7097fcc [ATM]: [lec] atte... |
569 570 |
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)); |
d44f77466 [ATM]: [lec] inde... |
571 |
} |
4a7097fcc [ATM]: [lec] atte... |
572 |
|
d44f77466 [ATM]: [lec] inde... |
573 |
static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
574 |
{ |
4a7097fcc [ATM]: [lec] atte... |
575 |
unsigned long flags; |
d44f77466 [ATM]: [lec] inde... |
576 |
struct net_device *dev = (struct net_device *)vcc->proto_data; |
524ad0a79 netdevice: safe c... |
577 |
struct lec_priv *priv = netdev_priv(dev); |
1da177e4c Linux-2.6.12-rc2 |
578 |
|
c48192a70 net/atm/lec.c: ch... |
579 |
#if DUMP_PACKETS > 0 |
99824461e net/atm: Convert ... |
580 581 582 |
printk(KERN_DEBUG "%s: vcc vpi:%d vci:%d ", dev->name, vcc->vpi, vcc->vci); |
1da177e4c Linux-2.6.12-rc2 |
583 |
#endif |
d44f77466 [ATM]: [lec] inde... |
584 |
if (!skb) { |
522400623 [ATM]: Replace DP... |
585 586 |
pr_debug("%s: null skb ", dev->name); |
d44f77466 [ATM]: [lec] inde... |
587 588 589 |
lec_vcc_close(priv, vcc); return; } |
1da177e4c Linux-2.6.12-rc2 |
590 |
#if DUMP_PACKETS >= 2 |
99824461e net/atm: Convert ... |
591 |
#define MAX_SKB_DUMP 99 |
1da177e4c Linux-2.6.12-rc2 |
592 |
#elif DUMP_PACKETS >= 1 |
99824461e net/atm: Convert ... |
593 594 595 596 597 598 599 600 |
#define MAX_SKB_DUMP 30 #endif #if DUMP_PACKETS > 0 printk(KERN_DEBUG "%s: rcv datalen:%ld lecid:%4.4x ", dev->name, skb->len, priv->lecid); print_hex_dump(KERN_DEBUG, "", DUMP_OFFSET, 16, 1, skb->data, min(MAX_SKB_DUMP, skb->len), true); |
1da177e4c Linux-2.6.12-rc2 |
601 |
#endif /* DUMP_PACKETS > 0 */ |
99824461e net/atm: Convert ... |
602 603 |
if (memcmp(skb->data, lec_ctrl_magic, 4) == 0) { /* Control frame, to daemon */ |
1da177e4c Linux-2.6.12-rc2 |
604 |
struct sock *sk = sk_atm(vcc); |
522400623 [ATM]: Replace DP... |
605 606 |
pr_debug("%s: To daemon ", dev->name); |
d44f77466 [ATM]: [lec] inde... |
607 |
skb_queue_tail(&sk->sk_receive_queue, skb); |
676d23690 net: Fix use afte... |
608 |
sk->sk_data_ready(sk); |
d44f77466 [ATM]: [lec] inde... |
609 |
} else { /* Data frame, queue to protocol handlers */ |
4a7097fcc [ATM]: [lec] atte... |
610 |
struct lec_arp_table *entry; |
d44f77466 [ATM]: [lec] inde... |
611 612 613 |
unsigned char *src, *dst; atm_return(vcc, skb->truesize); |
30d492da7 [ATM]: Annotations. |
614 |
if (*(__be16 *) skb->data == htons(priv->lecid) || |
d44f77466 [ATM]: [lec] inde... |
615 616 617 618 619 |
!priv->lecd || !(dev->flags & IFF_UP)) { /* * Probably looping back, or if lecd is missing, * lecd has gone down */ |
522400623 [ATM]: Replace DP... |
620 621 |
pr_debug("Ignoring frame... "); |
d44f77466 [ATM]: [lec] inde... |
622 623 624 |
dev_kfree_skb(skb); return; } |
60eea6cf2 atm: remove the c... |
625 |
dst = ((struct lecdatahdr_8023 *)skb->data)->h_dest; |
4a7097fcc [ATM]: [lec] atte... |
626 |
|
d44f77466 [ATM]: [lec] inde... |
627 628 |
/* * If this is a Data Direct VCC, and the VCC does not match |
4a7097fcc [ATM]: [lec] atte... |
629 630 631 632 |
* 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)) { |
60eea6cf2 atm: remove the c... |
633 |
src = ((struct lecdatahdr_8023 *)skb->data)->h_source; |
4a7097fcc [ATM]: [lec] atte... |
634 635 636 |
entry = lec_arp_find(priv, src); if (entry && entry->vcc != vcc) { lec_arp_remove(priv, entry); |
33a9c2d4b [ATM]: [lec] add ... |
637 |
lec_arp_put(entry); |
4a7097fcc [ATM]: [lec] atte... |
638 639 640 |
} } spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
641 |
|
d44f77466 [ATM]: [lec] inde... |
642 643 |
if (!(dst[0] & 0x01) && /* Never filter Multi/Broadcast */ !priv->is_proxy && /* Proxy wants all the packets */ |
1da177e4c Linux-2.6.12-rc2 |
644 |
memcmp(dst, dev->dev_addr, dev->addr_len)) { |
d44f77466 [ATM]: [lec] inde... |
645 646 647 |
dev_kfree_skb(skb); return; } |
c48192a70 net/atm/lec.c: ch... |
648 |
if (!hlist_empty(&priv->lec_arp_empty_ones)) |
d44f77466 [ATM]: [lec] inde... |
649 |
lec_arp_check_empties(priv, vcc, skb); |
d44f77466 [ATM]: [lec] inde... |
650 |
skb_pull(skb, 2); /* skip lec_id */ |
60eea6cf2 atm: remove the c... |
651 |
skb->protocol = eth_type_trans(skb, dev); |
162619e59 lec: convert to i... |
652 653 |
dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; |
d44f77466 [ATM]: [lec] inde... |
654 655 656 |
memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data)); netif_rx(skb); } |
1da177e4c Linux-2.6.12-rc2 |
657 |
} |
d44f77466 [ATM]: [lec] inde... |
658 |
static void lec_pop(struct atm_vcc *vcc, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
659 660 661 662 663 |
{ struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); struct net_device *dev = skb->dev; if (vpriv == NULL) { |
99824461e net/atm: Convert ... |
664 665 |
pr_info("vpriv = NULL!?!?!? "); |
1da177e4c Linux-2.6.12-rc2 |
666 667 668 669 670 671 672 673 674 675 676 |
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); } } |
d44f77466 [ATM]: [lec] inde... |
677 |
static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg) |
1da177e4c Linux-2.6.12-rc2 |
678 679 |
{ struct lec_vcc_priv *vpriv; |
d44f77466 [ATM]: [lec] inde... |
680 681 682 683 684 |
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)); |
99824461e net/atm: Convert ... |
685 686 687 |
if (bytes_left != 0) pr_info("copy from user failed for %d bytes ", bytes_left); |
acf784bd0 net: atm: Fix pot... |
688 689 690 691 |
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]) |
d44f77466 [ATM]: [lec] inde... |
692 |
return -EINVAL; |
c48192a70 net/atm/lec.c: ch... |
693 694 |
vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL); if (!vpriv) |
1da177e4c Linux-2.6.12-rc2 |
695 696 697 698 699 |
return -ENOMEM; vpriv->xoff = 0; vpriv->old_pop = vcc->pop; vcc->user_back = vpriv; vcc->pop = lec_pop; |
524ad0a79 netdevice: safe c... |
700 |
lec_vcc_added(netdev_priv(dev_lec[ioc_data.dev_num]), |
d44f77466 [ATM]: [lec] inde... |
701 702 703 704 |
&ioc_data, vcc, vcc->push); vcc->proto_data = dev_lec[ioc_data.dev_num]; vcc->push = lec_push; return 0; |
1da177e4c Linux-2.6.12-rc2 |
705 |
} |
d44f77466 [ATM]: [lec] inde... |
706 |
static int lec_mcast_attach(struct atm_vcc *vcc, int arg) |
1da177e4c Linux-2.6.12-rc2 |
707 |
{ |
899537b73 net: atm: Fix pot... |
708 709 710 711 |
if (arg < 0 || arg >= MAX_LEC_ITF) return -EINVAL; arg = array_index_nospec(arg, MAX_LEC_ITF); if (!dev_lec[arg]) |
d44f77466 [ATM]: [lec] inde... |
712 713 |
return -EINVAL; vcc->proto_data = dev_lec[arg]; |
37d668004 net/atm: Remove u... |
714 |
return lec_mcast_make(netdev_priv(dev_lec[arg]), vcc); |
1da177e4c Linux-2.6.12-rc2 |
715 716 717 |
} /* Initialize device. */ |
d44f77466 [ATM]: [lec] inde... |
718 719 720 721 722 723 |
static int lecd_attach(struct atm_vcc *vcc, int arg) { int i; struct lec_priv *priv; if (arg < 0) |
fdd1a8103 net: atm: clean u... |
724 |
arg = 0; |
d44f77466 [ATM]: [lec] inde... |
725 726 |
if (arg >= MAX_LEC_ITF) return -EINVAL; |
899537b73 net: atm: Fix pot... |
727 |
i = array_index_nospec(arg, MAX_LEC_ITF); |
d44f77466 [ATM]: [lec] inde... |
728 |
if (!dev_lec[i]) { |
60eea6cf2 atm: remove the c... |
729 |
int size; |
1da177e4c Linux-2.6.12-rc2 |
730 |
|
d44f77466 [ATM]: [lec] inde... |
731 |
size = sizeof(struct lec_priv); |
60eea6cf2 atm: remove the c... |
732 |
dev_lec[i] = alloc_etherdev(size); |
d44f77466 [ATM]: [lec] inde... |
733 734 |
if (!dev_lec[i]) return -ENOMEM; |
eb0445887 atm: [lec] initia... |
735 |
dev_lec[i]->netdev_ops = &lec_netdev_ops; |
8b6b4135e net: use core MTU... |
736 |
dev_lec[i]->max_mtu = 18190; |
d44f77466 [ATM]: [lec] inde... |
737 738 739 740 741 |
snprintf(dev_lec[i]->name, IFNAMSIZ, "lec%d", i); if (register_netdev(dev_lec[i])) { free_netdev(dev_lec[i]); return -EINVAL; } |
524ad0a79 netdevice: safe c... |
742 |
priv = netdev_priv(dev_lec[i]); |
d44f77466 [ATM]: [lec] inde... |
743 |
} else { |
524ad0a79 netdevice: safe c... |
744 |
priv = netdev_priv(dev_lec[i]); |
d44f77466 [ATM]: [lec] inde... |
745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 |
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); |
c48192a70 net/atm/lec.c: ch... |
769 |
if (dev_lec[i]->flags & IFF_UP) |
d44f77466 [ATM]: [lec] inde... |
770 |
netif_start_queue(dev_lec[i]); |
d44f77466 [ATM]: [lec] inde... |
771 772 |
__module_get(THIS_MODULE); return i; |
1da177e4c Linux-2.6.12-rc2 |
773 774 775 |
} #ifdef CONFIG_PROC_FS |
36cbd3dcc net: mark read-on... |
776 |
static const char *lec_arp_get_status_string(unsigned char status) |
1da177e4c Linux-2.6.12-rc2 |
777 |
{ |
36cbd3dcc net: mark read-on... |
778 |
static const char *const lec_arp_status_string[] = { |
1da177e4c Linux-2.6.12-rc2 |
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 |
"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) { |
79ac52240 net: atm: use %*p... |
794 795 796 |
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), |
1da177e4c Linux-2.6.12-rc2 |
797 798 799 800 |
entry->flags & 0xffff); if (entry->vcc) seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci); else |
d44f77466 [ATM]: [lec] inde... |
801 |
seq_printf(seq, " "); |
1da177e4c Linux-2.6.12-rc2 |
802 803 804 |
if (entry->recv_vcc) { seq_printf(seq, " %3d %3d", entry->recv_vcc->vpi, entry->recv_vcc->vci); |
d44f77466 [ATM]: [lec] inde... |
805 806 807 |
} seq_putc(seq, ' '); |
1da177e4c Linux-2.6.12-rc2 |
808 |
} |
1da177e4c Linux-2.6.12-rc2 |
809 810 811 |
struct lec_state { unsigned long flags; struct lec_priv *locked; |
d0732f649 [ATM]: [lec] conv... |
812 |
struct hlist_node *node; |
1da177e4c Linux-2.6.12-rc2 |
813 814 815 816 817 |
struct net_device *dev; int itf; int arp_table; int misc_table; }; |
d0732f649 [ATM]: [lec] conv... |
818 |
static void *lec_tbl_walk(struct lec_state *state, struct hlist_head *tbl, |
1da177e4c Linux-2.6.12-rc2 |
819 820 |
loff_t *l) { |
d0732f649 [ATM]: [lec] conv... |
821 |
struct hlist_node *e = state->node; |
1da177e4c Linux-2.6.12-rc2 |
822 823 |
if (!e) |
d0732f649 [ATM]: [lec] conv... |
824 |
e = tbl->first; |
2e1e9848a [ATM]: Use SEQ_ST... |
825 |
if (e == SEQ_START_TOKEN) { |
d0732f649 [ATM]: [lec] conv... |
826 |
e = tbl->first; |
1da177e4c Linux-2.6.12-rc2 |
827 828 |
--*l; } |
d0732f649 [ATM]: [lec] conv... |
829 |
|
8356f9d56 lec: Fix bug intr... |
830 |
for (; e; e = e->next) { |
1da177e4c Linux-2.6.12-rc2 |
831 832 833 |
if (--*l < 0) break; } |
d0732f649 [ATM]: [lec] conv... |
834 |
state->node = e; |
1da177e4c Linux-2.6.12-rc2 |
835 836 837 838 |
return (*l < 0) ? state : NULL; } static void *lec_arp_walk(struct lec_state *state, loff_t *l, |
d44f77466 [ATM]: [lec] inde... |
839 |
struct lec_priv *priv) |
1da177e4c Linux-2.6.12-rc2 |
840 841 842 843 844 |
{ void *v = NULL; int p; for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) { |
d0732f649 [ATM]: [lec] conv... |
845 |
v = lec_tbl_walk(state, &priv->lec_arp_tables[p], l); |
1da177e4c Linux-2.6.12-rc2 |
846 847 848 849 850 851 852 853 854 855 |
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) { |
d0732f649 [ATM]: [lec] conv... |
856 857 858 859 |
struct hlist_head *lec_misc_tables[] = { &priv->lec_arp_empty_ones, &priv->lec_no_forward, &priv->mcast_fwds |
1da177e4c Linux-2.6.12-rc2 |
860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 |
}; 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); } |
d44f77466 [ATM]: [lec] inde... |
880 |
if (!lec_arp_walk(state, l, priv) && !lec_misc_walk(state, l, priv)) { |
1da177e4c Linux-2.6.12-rc2 |
881 882 883 884 885 886 887 888 889 890 891 892 893 894 |
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]; |
524ad0a79 netdevice: safe c... |
895 896 |
v = (dev && netdev_priv(dev)) ? lec_priv_walk(state, l, netdev_priv(dev)) : NULL; |
1da177e4c Linux-2.6.12-rc2 |
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 |
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; } |
d44f77466 [ATM]: [lec] inde... |
915 |
return v; |
1da177e4c Linux-2.6.12-rc2 |
916 917 918 919 920 921 922 923 924 925 926 |
} 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; |
2e1e9848a [ATM]: Use SEQ_ST... |
927 |
state->node = SEQ_START_TOKEN; |
1da177e4c Linux-2.6.12-rc2 |
928 |
|
2e1e9848a [ATM]: Use SEQ_ST... |
929 |
return *pos ? lec_get_idx(state, *pos) : SEQ_START_TOKEN; |
1da177e4c Linux-2.6.12-rc2 |
930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 |
} 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; |
2f71e0061 net: atm: fix upd... |
946 947 |
++*pos; return lec_get_idx(state, 1); |
1da177e4c Linux-2.6.12-rc2 |
948 949 950 951 |
} static int lec_seq_show(struct seq_file *seq, void *v) { |
36cbd3dcc net: mark read-on... |
952 953 |
static const char lec_banner[] = "Itf MAC ATM destination" |
d44f77466 [ATM]: [lec] inde... |
954 955 956 |
" Status Flags " "VPI/VCI Recv VPI/VCI "; |
1da177e4c Linux-2.6.12-rc2 |
957 |
|
2e1e9848a [ATM]: Use SEQ_ST... |
958 |
if (v == SEQ_START_TOKEN) |
1da177e4c Linux-2.6.12-rc2 |
959 960 961 |
seq_puts(seq, lec_banner); else { struct lec_state *state = seq->private; |
d44f77466 [ATM]: [lec] inde... |
962 |
struct net_device *dev = state->dev; |
c48192a70 net/atm/lec.c: ch... |
963 964 965 |
struct lec_arp_table *entry = hlist_entry(state->node, struct lec_arp_table, next); |
1da177e4c Linux-2.6.12-rc2 |
966 967 |
seq_printf(seq, "%s ", dev->name); |
d0732f649 [ATM]: [lec] conv... |
968 |
lec_info(seq, entry); |
1da177e4c Linux-2.6.12-rc2 |
969 970 971 |
} return 0; } |
56b3d975b [NET]: Make all i... |
972 |
static const struct seq_operations lec_seq_ops = { |
d44f77466 [ATM]: [lec] inde... |
973 974 975 976 |
.start = lec_seq_start, .next = lec_seq_next, .stop = lec_seq_stop, .show = lec_seq_show, |
1da177e4c Linux-2.6.12-rc2 |
977 |
}; |
1da177e4c Linux-2.6.12-rc2 |
978 979 980 981 982 983 |
#endif static int lane_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct atm_vcc *vcc = ATM_SD(sock); int err = 0; |
d44f77466 [ATM]: [lec] inde... |
984 |
|
1da177e4c Linux-2.6.12-rc2 |
985 |
switch (cmd) { |
d44f77466 [ATM]: [lec] inde... |
986 987 988 989 990 991 992 993 |
case ATMLEC_CTRL: case ATMLEC_MCAST: case ATMLEC_DATA: if (!capable(CAP_NET_ADMIN)) return -EPERM; break; default: return -ENOIOCTLCMD; |
1da177e4c Linux-2.6.12-rc2 |
994 995 996 |
} switch (cmd) { |
d44f77466 [ATM]: [lec] inde... |
997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 |
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; |
1da177e4c Linux-2.6.12-rc2 |
1008 1009 1010 1011 1012 1013 |
} return err; } static struct atm_ioctl lane_ioctl_ops = { |
d44f77466 [ATM]: [lec] inde... |
1014 1015 |
.owner = THIS_MODULE, .ioctl = lane_ioctl, |
1da177e4c Linux-2.6.12-rc2 |
1016 1017 1018 1019 1020 1021 |
}; static int __init lane_module_init(void) { #ifdef CONFIG_PROC_FS struct proc_dir_entry *p; |
44414d82c proc: introduce p... |
1022 1023 |
p = proc_create_seq_private("lec", 0444, atm_proc_root, &lec_seq_ops, sizeof(struct lec_state), NULL); |
dbee0d3f4 [ATM]: When proc_... |
1024 |
if (!p) { |
99824461e net/atm: Convert ... |
1025 1026 |
pr_err("Unable to initialize /proc/net/atm/lec "); |
dbee0d3f4 [ATM]: When proc_... |
1027 1028 |
return -ENOMEM; } |
1da177e4c Linux-2.6.12-rc2 |
1029 1030 1031 |
#endif register_atm_ioctl(&lane_ioctl_ops); |
36a9f77e5 atm: Drop __TIME_... |
1032 1033 |
pr_info("lec.c: initialized "); |
d44f77466 [ATM]: [lec] inde... |
1034 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1035 1036 1037 1038 |
} static void __exit lane_module_cleanup(void) { |
d44f77466 [ATM]: [lec] inde... |
1039 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
1040 |
|
9dd0f896d net: atm: Fix war... |
1041 |
#ifdef CONFIG_PROC_FS |
1da177e4c Linux-2.6.12-rc2 |
1042 |
remove_proc_entry("lec", atm_proc_root); |
9dd0f896d net: atm: Fix war... |
1043 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
1044 1045 |
deregister_atm_ioctl(&lane_ioctl_ops); |
d44f77466 [ATM]: [lec] inde... |
1046 1047 |
for (i = 0; i < MAX_LEC_ITF; i++) { if (dev_lec[i] != NULL) { |
1da177e4c Linux-2.6.12-rc2 |
1048 |
unregister_netdev(dev_lec[i]); |
d44f77466 [ATM]: [lec] inde... |
1049 1050 1051 1052 |
free_netdev(dev_lec[i]); dev_lec[i] = NULL; } } |
1da177e4c Linux-2.6.12-rc2 |
1053 1054 1055 1056 1057 1058 1059 1060 |
} 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. |
563f63e39 net: atm: delete ... |
1061 |
* If sizeoftlvs == NULL the default TLVs associated with this |
1da177e4c Linux-2.6.12-rc2 |
1062 1063 1064 |
* lec will be used. * If dst_mac == NULL, targetless LE_ARP will be sent */ |
61c33e012 atm: use const wh... |
1065 |
static int lane2_resolve(struct net_device *dev, const u8 *dst_mac, int force, |
d44f77466 [ATM]: [lec] inde... |
1066 |
u8 **tlvs, u32 *sizeoftlvs) |
1da177e4c Linux-2.6.12-rc2 |
1067 1068 |
{ unsigned long flags; |
524ad0a79 netdevice: safe c... |
1069 |
struct lec_priv *priv = netdev_priv(dev); |
d44f77466 [ATM]: [lec] inde... |
1070 1071 1072 |
struct lec_arp_table *table; struct sk_buff *skb; int retval; |
1da177e4c Linux-2.6.12-rc2 |
1073 |
|
d44f77466 [ATM]: [lec] inde... |
1074 |
if (force == 0) { |
1da177e4c Linux-2.6.12-rc2 |
1075 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
d44f77466 [ATM]: [lec] inde... |
1076 |
table = lec_arp_find(priv, dst_mac); |
1da177e4c Linux-2.6.12-rc2 |
1077 |
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
d44f77466 [ATM]: [lec] inde... |
1078 1079 |
if (table == NULL) return -1; |
2afe37cdf [ATM]: Use kmemdu... |
1080 |
*tlvs = kmemdup(table->tlvs, table->sizeoftlvs, GFP_ATOMIC); |
d44f77466 [ATM]: [lec] inde... |
1081 1082 |
if (*tlvs == NULL) return -1; |
d44f77466 [ATM]: [lec] inde... |
1083 1084 1085 1086 |
*sizeoftlvs = table->sizeoftlvs; return 0; } |
1da177e4c Linux-2.6.12-rc2 |
1087 1088 1089 |
if (sizeoftlvs == NULL) retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, NULL); |
d44f77466 [ATM]: [lec] inde... |
1090 |
|
1da177e4c Linux-2.6.12-rc2 |
1091 1092 1093 1094 1095 |
else { skb = alloc_skb(*sizeoftlvs, GFP_ATOMIC); if (skb == NULL) return -1; skb->len = *sizeoftlvs; |
27d7ff46a [SK_BUFF]: Introd... |
1096 |
skb_copy_to_linear_data(skb, *tlvs, *sizeoftlvs); |
1da177e4c Linux-2.6.12-rc2 |
1097 1098 |
retval = send_to_lecd(priv, l_arp_xmt, dst_mac, NULL, skb); } |
d44f77466 [ATM]: [lec] inde... |
1099 1100 |
return retval; } |
1da177e4c Linux-2.6.12-rc2 |
1101 1102 1103 1104 1105 1106 1107 1108 |
/* * 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) * */ |
61c33e012 atm: use const wh... |
1109 1110 |
static int lane2_associate_req(struct net_device *dev, const u8 *lan_dst, const u8 *tlvs, u32 sizeoftlvs) |
1da177e4c Linux-2.6.12-rc2 |
1111 |
{ |
d44f77466 [ATM]: [lec] inde... |
1112 1113 |
int retval; struct sk_buff *skb; |
524ad0a79 netdevice: safe c... |
1114 |
struct lec_priv *priv = netdev_priv(dev); |
d44f77466 [ATM]: [lec] inde... |
1115 |
|
150238ebb atm: Convert comp... |
1116 |
if (!ether_addr_equal(lan_dst, dev->dev_addr)) |
c48192a70 net/atm/lec.c: ch... |
1117 |
return 0; /* not our mac address */ |
d44f77466 [ATM]: [lec] inde... |
1118 1119 |
kfree(priv->tlvs); /* NULL if there was no previous association */ |
2afe37cdf [ATM]: Use kmemdu... |
1120 |
priv->tlvs = kmemdup(tlvs, sizeoftlvs, GFP_KERNEL); |
d44f77466 [ATM]: [lec] inde... |
1121 |
if (priv->tlvs == NULL) |
c48192a70 net/atm/lec.c: ch... |
1122 |
return 0; |
d44f77466 [ATM]: [lec] inde... |
1123 |
priv->sizeoftlvs = sizeoftlvs; |
d44f77466 [ATM]: [lec] inde... |
1124 1125 1126 1127 1128 |
skb = alloc_skb(sizeoftlvs, GFP_ATOMIC); if (skb == NULL) return 0; skb->len = sizeoftlvs; |
27d7ff46a [SK_BUFF]: Introd... |
1129 |
skb_copy_to_linear_data(skb, tlvs, sizeoftlvs); |
d44f77466 [ATM]: [lec] inde... |
1130 1131 |
retval = send_to_lecd(priv, l_associate_req, NULL, NULL, skb); if (retval != 0) |
c48192a70 net/atm/lec.c: ch... |
1132 1133 |
pr_info("lec.c: lane2_associate_req() failed "); |
d44f77466 [ATM]: [lec] inde... |
1134 1135 1136 1137 |
/* * If the previous association has changed we must * somehow notify other LANE entities about the change */ |
c48192a70 net/atm/lec.c: ch... |
1138 |
return 1; |
1da177e4c Linux-2.6.12-rc2 |
1139 1140 1141 1142 1143 1144 |
} /* * LANE2: 3.1.5, LE_ASSOCIATE.indication * */ |
61c33e012 atm: use const wh... |
1145 1146 |
static void lane2_associate_ind(struct net_device *dev, const u8 *mac_addr, const u8 *tlvs, u32 sizeoftlvs) |
1da177e4c Linux-2.6.12-rc2 |
1147 1148 |
{ #if 0 |
d44f77466 [ATM]: [lec] inde... |
1149 |
int i = 0; |
1da177e4c Linux-2.6.12-rc2 |
1150 |
#endif |
524ad0a79 netdevice: safe c... |
1151 |
struct lec_priv *priv = netdev_priv(dev); |
d44f77466 [ATM]: [lec] inde... |
1152 1153 1154 1155 1156 1157 1158 |
#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); |
1da177e4c Linux-2.6.12-rc2 |
1159 |
|
d44f77466 [ATM]: [lec] inde... |
1160 1161 |
if (entry == NULL) return; /* should not happen */ |
1da177e4c Linux-2.6.12-rc2 |
1162 |
|
d44f77466 [ATM]: [lec] inde... |
1163 |
kfree(entry->tlvs); |
1da177e4c Linux-2.6.12-rc2 |
1164 |
|
2afe37cdf [ATM]: Use kmemdu... |
1165 |
entry->tlvs = kmemdup(tlvs, sizeoftlvs, GFP_KERNEL); |
d44f77466 [ATM]: [lec] inde... |
1166 1167 |
if (entry->tlvs == NULL) return; |
d44f77466 [ATM]: [lec] inde... |
1168 |
entry->sizeoftlvs = sizeoftlvs; |
1da177e4c Linux-2.6.12-rc2 |
1169 1170 |
#endif #if 0 |
c48192a70 net/atm/lec.c: ch... |
1171 1172 1173 1174 |
pr_info(" "); pr_info("dump of tlvs, sizeoftlvs=%d ", sizeoftlvs); |
d44f77466 [ATM]: [lec] inde... |
1175 |
while (i < sizeoftlvs) |
c48192a70 net/atm/lec.c: ch... |
1176 |
pr_cont("%02x ", tlvs[i++]); |
d44f77466 [ATM]: [lec] inde... |
1177 |
|
c48192a70 net/atm/lec.c: ch... |
1178 1179 |
pr_cont(" "); |
1da177e4c Linux-2.6.12-rc2 |
1180 |
#endif |
d44f77466 [ATM]: [lec] inde... |
1181 1182 1183 1184 1185 |
/* 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); } |
1da177e4c Linux-2.6.12-rc2 |
1186 1187 1188 1189 1190 1191 1192 |
} /* * Here starts what used to lec_arpc.c * * lec_arpc.c was added here when making * lane client modular. October 1997 |
1da177e4c Linux-2.6.12-rc2 |
1193 1194 1195 |
*/ #include <linux/types.h> |
1da177e4c Linux-2.6.12-rc2 |
1196 |
#include <linux/timer.h> |
c48192a70 net/atm/lec.c: ch... |
1197 |
#include <linux/param.h> |
60063497a atomic: use <linu... |
1198 |
#include <linux/atomic.h> |
1da177e4c Linux-2.6.12-rc2 |
1199 1200 |
#include <linux/inetdevice.h> #include <net/route.h> |
1da177e4c Linux-2.6.12-rc2 |
1201 |
#if 0 |
c48192a70 net/atm/lec.c: ch... |
1202 |
#define pr_debug(format, args...) |
1da177e4c Linux-2.6.12-rc2 |
1203 |
/* |
99824461e net/atm: Convert ... |
1204 |
#define pr_debug printk |
1da177e4c Linux-2.6.12-rc2 |
1205 1206 1207 1208 1209 |
*/ #endif #define DEBUG_ARP_TABLE 0 #define LEC_ARP_REFRESH_INTERVAL (3*HZ) |
c4028958b WorkStruct: make ... |
1210 |
static void lec_arp_check_expire(struct work_struct *work); |
ba4217935 net: atm: Convert... |
1211 |
static void lec_arp_expire_arp(struct timer_list *t); |
1da177e4c Linux-2.6.12-rc2 |
1212 |
|
f7d57453d [NET] ATM: Fix wh... |
1213 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1214 1215 |
* Arp table funcs */ |
c48192a70 net/atm/lec.c: ch... |
1216 |
#define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE - 1)) |
1da177e4c Linux-2.6.12-rc2 |
1217 1218 1219 1220 |
/* * Initialization of arp-cache */ |
1fa9961d6 [ATM]: [lec] inde... |
1221 |
static void lec_arp_init(struct lec_priv *priv) |
1da177e4c Linux-2.6.12-rc2 |
1222 |
{ |
1fa9961d6 [ATM]: [lec] inde... |
1223 |
unsigned short i; |
1da177e4c Linux-2.6.12-rc2 |
1224 |
|
c48192a70 net/atm/lec.c: ch... |
1225 |
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) |
d0732f649 [ATM]: [lec] conv... |
1226 |
INIT_HLIST_HEAD(&priv->lec_arp_tables[i]); |
f7d57453d [NET] ATM: Fix wh... |
1227 1228 1229 |
INIT_HLIST_HEAD(&priv->lec_arp_empty_ones); INIT_HLIST_HEAD(&priv->lec_no_forward); INIT_HLIST_HEAD(&priv->mcast_fwds); |
1da177e4c Linux-2.6.12-rc2 |
1230 |
spin_lock_init(&priv->lec_arp_lock); |
c4028958b WorkStruct: make ... |
1231 |
INIT_DELAYED_WORK(&priv->lec_arp_work, lec_arp_check_expire); |
987e46bdf [ATM]: [lec] use ... |
1232 |
schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL); |
1da177e4c Linux-2.6.12-rc2 |
1233 |
} |
1fa9961d6 [ATM]: [lec] inde... |
1234 |
static void lec_arp_clear_vccs(struct lec_arp_table *entry) |
1da177e4c Linux-2.6.12-rc2 |
1235 |
{ |
1fa9961d6 [ATM]: [lec] inde... |
1236 |
if (entry->vcc) { |
1da177e4c Linux-2.6.12-rc2 |
1237 1238 |
struct atm_vcc *vcc = entry->vcc; struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); |
1fa9961d6 [ATM]: [lec] inde... |
1239 |
struct net_device *dev = (struct net_device *)vcc->proto_data; |
1da177e4c Linux-2.6.12-rc2 |
1240 |
|
1fa9961d6 [ATM]: [lec] inde... |
1241 |
vcc->pop = vpriv->old_pop; |
1da177e4c Linux-2.6.12-rc2 |
1242 1243 1244 1245 |
if (vpriv->xoff) netif_wake_queue(dev); kfree(vpriv); vcc->user_back = NULL; |
1fa9961d6 [ATM]: [lec] inde... |
1246 |
vcc->push = entry->old_push; |
1da177e4c Linux-2.6.12-rc2 |
1247 |
vcc_release_async(vcc, -EPIPE); |
d0732f649 [ATM]: [lec] conv... |
1248 |
entry->vcc = NULL; |
1fa9961d6 [ATM]: [lec] inde... |
1249 1250 |
} if (entry->recv_vcc) { |
8d9f73c0a atm: fix a memory... |
1251 1252 1253 1254 1255 |
struct atm_vcc *vcc = entry->recv_vcc; struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); kfree(vpriv); vcc->user_back = NULL; |
1fa9961d6 [ATM]: [lec] inde... |
1256 |
entry->recv_vcc->push = entry->old_recv_push; |
1da177e4c Linux-2.6.12-rc2 |
1257 |
vcc_release_async(entry->recv_vcc, -EPIPE); |
1fa9961d6 [ATM]: [lec] inde... |
1258 1259 |
entry->recv_vcc = NULL; } |
1da177e4c Linux-2.6.12-rc2 |
1260 1261 1262 1263 1264 1265 |
} /* * Insert entry to lec_arp_table * LANE2: Add to the end of the list to satisfy 8.1.13 */ |
1fa9961d6 [ATM]: [lec] inde... |
1266 |
static inline void |
d0732f649 [ATM]: [lec] conv... |
1267 |
lec_arp_add(struct lec_priv *priv, struct lec_arp_table *entry) |
1da177e4c Linux-2.6.12-rc2 |
1268 |
{ |
d0732f649 [ATM]: [lec] conv... |
1269 |
struct hlist_head *tmp; |
1fa9961d6 [ATM]: [lec] inde... |
1270 |
|
d0732f649 [ATM]: [lec] conv... |
1271 1272 |
tmp = &priv->lec_arp_tables[HASH(entry->mac_addr[ETH_ALEN - 1])]; hlist_add_head(&entry->next, tmp); |
1fa9961d6 [ATM]: [lec] inde... |
1273 |
|
99824461e net/atm: Convert ... |
1274 1275 |
pr_debug("Added entry:%pM ", entry->mac_addr); |
1da177e4c Linux-2.6.12-rc2 |
1276 1277 1278 1279 1280 |
} /* * Remove entry from lec_arp_table */ |
1fa9961d6 [ATM]: [lec] inde... |
1281 1282 |
static int lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove) |
1da177e4c Linux-2.6.12-rc2 |
1283 |
{ |
d0732f649 [ATM]: [lec] conv... |
1284 1285 |
struct lec_arp_table *entry; int i, remove_vcc = 1; |
1fa9961d6 [ATM]: [lec] inde... |
1286 |
|
c48192a70 net/atm/lec.c: ch... |
1287 |
if (!to_remove) |
1fa9961d6 [ATM]: [lec] inde... |
1288 |
return -1; |
d0732f649 [ATM]: [lec] conv... |
1289 1290 |
hlist_del(&to_remove->next); |
1fa9961d6 [ATM]: [lec] inde... |
1291 |
del_timer(&to_remove->timer); |
c48192a70 net/atm/lec.c: ch... |
1292 1293 1294 1295 |
/* * If this is the only MAC connected to this VCC, * also tear down the VCC */ |
1fa9961d6 [ATM]: [lec] inde... |
1296 1297 1298 1299 |
if (to_remove->status >= ESI_FLUSH_PENDING) { /* * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT */ |
d0732f649 [ATM]: [lec] conv... |
1300 |
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
b67bfe0d4 hlist: drop the n... |
1301 |
hlist_for_each_entry(entry, |
c48192a70 net/atm/lec.c: ch... |
1302 |
&priv->lec_arp_tables[i], next) { |
d0732f649 [ATM]: [lec] conv... |
1303 1304 |
if (memcmp(to_remove->atm_addr, entry->atm_addr, ATM_ESA_LEN) == 0) { |
1fa9961d6 [ATM]: [lec] inde... |
1305 1306 1307 1308 1309 1310 1311 1312 1313 |
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? */ |
99824461e net/atm: Convert ... |
1314 1315 |
pr_debug("Removed entry:%pM ", to_remove->mac_addr); |
1fa9961d6 [ATM]: [lec] inde... |
1316 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1317 1318 1319 |
} #if DEBUG_ARP_TABLE |
36cbd3dcc net: mark read-on... |
1320 |
static const char *get_status_string(unsigned char st) |
1da177e4c Linux-2.6.12-rc2 |
1321 |
{ |
1fa9961d6 [ATM]: [lec] inde... |
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 |
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"; |
1fa9961d6 [ATM]: [lec] inde... |
1333 |
} |
c48192a70 net/atm/lec.c: ch... |
1334 |
return "<UNKNOWN>"; |
1da177e4c Linux-2.6.12-rc2 |
1335 |
} |
1da177e4c Linux-2.6.12-rc2 |
1336 |
|
1fa9961d6 [ATM]: [lec] inde... |
1337 |
static void dump_arp_table(struct lec_priv *priv) |
1da177e4c Linux-2.6.12-rc2 |
1338 |
{ |
1fa9961d6 [ATM]: [lec] inde... |
1339 |
struct lec_arp_table *rulla; |
d0732f649 [ATM]: [lec] conv... |
1340 |
char buf[256]; |
79ac52240 net: atm: use %*p... |
1341 |
int i, offset; |
1fa9961d6 [ATM]: [lec] inde... |
1342 |
|
c48192a70 net/atm/lec.c: ch... |
1343 1344 |
pr_info("Dump %p: ", priv); |
1fa9961d6 [ATM]: [lec] inde... |
1345 |
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
b67bfe0d4 hlist: drop the n... |
1346 |
hlist_for_each_entry(rulla, |
c48192a70 net/atm/lec.c: ch... |
1347 |
&priv->lec_arp_tables[i], next) { |
d0732f649 [ATM]: [lec] conv... |
1348 1349 1350 |
offset = 0; offset += sprintf(buf, "%d: %p ", i, rulla); |
79ac52240 net: atm: use %*p... |
1351 |
offset += sprintf(buf + offset, "Mac: %pM ", |
c48192a70 net/atm/lec.c: ch... |
1352 |
rulla->mac_addr); |
79ac52240 net: atm: use %*p... |
1353 1354 |
offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN, rulla->atm_addr); |
1fa9961d6 [ATM]: [lec] inde... |
1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 |
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)); |
c48192a70 net/atm/lec.c: ch... |
1369 1370 |
pr_info("%s ", buf); |
1fa9961d6 [ATM]: [lec] inde... |
1371 |
} |
1fa9961d6 [ATM]: [lec] inde... |
1372 |
} |
d0732f649 [ATM]: [lec] conv... |
1373 1374 |
if (!hlist_empty(&priv->lec_no_forward)) |
c48192a70 net/atm/lec.c: ch... |
1375 1376 |
pr_info("No forward "); |
b67bfe0d4 hlist: drop the n... |
1377 |
hlist_for_each_entry(rulla, &priv->lec_no_forward, next) { |
1fa9961d6 [ATM]: [lec] inde... |
1378 |
offset = 0; |
79ac52240 net: atm: use %*p... |
1379 1380 1381 |
offset += sprintf(buf + offset, "Mac: %pM ", rulla->mac_addr); offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN, rulla->atm_addr); |
1fa9961d6 [ATM]: [lec] inde... |
1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 |
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)); |
c48192a70 net/atm/lec.c: ch... |
1394 1395 |
pr_info("%s ", buf); |
1fa9961d6 [ATM]: [lec] inde... |
1396 |
} |
d0732f649 [ATM]: [lec] conv... |
1397 1398 |
if (!hlist_empty(&priv->lec_arp_empty_ones)) |
c48192a70 net/atm/lec.c: ch... |
1399 1400 |
pr_info("Empty ones "); |
b67bfe0d4 hlist: drop the n... |
1401 |
hlist_for_each_entry(rulla, &priv->lec_arp_empty_ones, next) { |
1fa9961d6 [ATM]: [lec] inde... |
1402 |
offset = 0; |
79ac52240 net: atm: use %*p... |
1403 1404 1405 |
offset += sprintf(buf + offset, "Mac: %pM ", rulla->mac_addr); offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN, rulla->atm_addr); |
1fa9961d6 [ATM]: [lec] inde... |
1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 |
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)); |
c48192a70 net/atm/lec.c: ch... |
1418 |
pr_info("%s", buf); |
1fa9961d6 [ATM]: [lec] inde... |
1419 |
} |
d0732f649 [ATM]: [lec] conv... |
1420 |
if (!hlist_empty(&priv->mcast_fwds)) |
c48192a70 net/atm/lec.c: ch... |
1421 1422 |
pr_info("Multicast Forward VCCs "); |
b67bfe0d4 hlist: drop the n... |
1423 |
hlist_for_each_entry(rulla, &priv->mcast_fwds, next) { |
1fa9961d6 [ATM]: [lec] inde... |
1424 |
offset = 0; |
79ac52240 net: atm: use %*p... |
1425 1426 1427 |
offset += sprintf(buf + offset, "Mac: %pM ", rulla->mac_addr); offset += sprintf(buf + offset, "Atm: %*ph ", ATM_ESA_LEN, rulla->atm_addr); |
1fa9961d6 [ATM]: [lec] inde... |
1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 |
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)); |
c48192a70 net/atm/lec.c: ch... |
1440 1441 |
pr_info("%s ", buf); |
1fa9961d6 [ATM]: [lec] inde... |
1442 |
} |
1da177e4c Linux-2.6.12-rc2 |
1443 |
|
1da177e4c Linux-2.6.12-rc2 |
1444 |
} |
d0732f649 [ATM]: [lec] conv... |
1445 1446 1447 |
#else #define dump_arp_table(priv) do { } while (0) #endif |
1da177e4c Linux-2.6.12-rc2 |
1448 1449 1450 1451 |
/* * Destruction of arp-cache */ |
1fa9961d6 [ATM]: [lec] inde... |
1452 |
static void lec_arp_destroy(struct lec_priv *priv) |
1da177e4c Linux-2.6.12-rc2 |
1453 1454 |
{ unsigned long flags; |
b67bfe0d4 hlist: drop the n... |
1455 |
struct hlist_node *next; |
d0732f649 [ATM]: [lec] conv... |
1456 |
struct lec_arp_table *entry; |
1fa9961d6 [ATM]: [lec] inde... |
1457 |
int i; |
afe2c511f workqueue: conver... |
1458 |
cancel_delayed_work_sync(&priv->lec_arp_work); |
1da177e4c Linux-2.6.12-rc2 |
1459 |
|
1fa9961d6 [ATM]: [lec] inde... |
1460 1461 1462 |
/* * Remove all entries */ |
1da177e4c Linux-2.6.12-rc2 |
1463 1464 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
1465 |
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
b67bfe0d4 hlist: drop the n... |
1466 |
hlist_for_each_entry_safe(entry, next, |
c48192a70 net/atm/lec.c: ch... |
1467 |
&priv->lec_arp_tables[i], next) { |
1fa9961d6 [ATM]: [lec] inde... |
1468 |
lec_arp_remove(priv, entry); |
33a9c2d4b [ATM]: [lec] add ... |
1469 |
lec_arp_put(entry); |
1fa9961d6 [ATM]: [lec] inde... |
1470 |
} |
d0732f649 [ATM]: [lec] conv... |
1471 |
INIT_HLIST_HEAD(&priv->lec_arp_tables[i]); |
1fa9961d6 [ATM]: [lec] inde... |
1472 |
} |
d0732f649 [ATM]: [lec] conv... |
1473 |
|
b67bfe0d4 hlist: drop the n... |
1474 |
hlist_for_each_entry_safe(entry, next, |
c48192a70 net/atm/lec.c: ch... |
1475 |
&priv->lec_arp_empty_ones, next) { |
1fa9961d6 [ATM]: [lec] inde... |
1476 1477 |
del_timer_sync(&entry->timer); lec_arp_clear_vccs(entry); |
d0732f649 [ATM]: [lec] conv... |
1478 |
hlist_del(&entry->next); |
33a9c2d4b [ATM]: [lec] add ... |
1479 |
lec_arp_put(entry); |
1fa9961d6 [ATM]: [lec] inde... |
1480 |
} |
d0732f649 [ATM]: [lec] conv... |
1481 |
INIT_HLIST_HEAD(&priv->lec_arp_empty_ones); |
b67bfe0d4 hlist: drop the n... |
1482 |
hlist_for_each_entry_safe(entry, next, |
c48192a70 net/atm/lec.c: ch... |
1483 |
&priv->lec_no_forward, next) { |
1fa9961d6 [ATM]: [lec] inde... |
1484 1485 |
del_timer_sync(&entry->timer); lec_arp_clear_vccs(entry); |
d0732f649 [ATM]: [lec] conv... |
1486 |
hlist_del(&entry->next); |
33a9c2d4b [ATM]: [lec] add ... |
1487 |
lec_arp_put(entry); |
1fa9961d6 [ATM]: [lec] inde... |
1488 |
} |
d0732f649 [ATM]: [lec] conv... |
1489 |
INIT_HLIST_HEAD(&priv->lec_no_forward); |
b67bfe0d4 hlist: drop the n... |
1490 |
hlist_for_each_entry_safe(entry, next, &priv->mcast_fwds, next) { |
1fa9961d6 [ATM]: [lec] inde... |
1491 1492 |
/* No timer, LANEv2 7.1.20 and 2.3.5.3 */ lec_arp_clear_vccs(entry); |
d0732f649 [ATM]: [lec] conv... |
1493 |
hlist_del(&entry->next); |
33a9c2d4b [ATM]: [lec] add ... |
1494 |
lec_arp_put(entry); |
1fa9961d6 [ATM]: [lec] inde... |
1495 |
} |
d0732f649 [ATM]: [lec] conv... |
1496 |
INIT_HLIST_HEAD(&priv->mcast_fwds); |
1fa9961d6 [ATM]: [lec] inde... |
1497 |
priv->mcast_vcc = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1498 1499 |
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); } |
f7d57453d [NET] ATM: Fix wh... |
1500 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1501 1502 |
* Find entry by mac_address */ |
1fa9961d6 [ATM]: [lec] inde... |
1503 |
static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, |
61c33e012 atm: use const wh... |
1504 |
const unsigned char *mac_addr) |
1da177e4c Linux-2.6.12-rc2 |
1505 |
{ |
d0732f649 [ATM]: [lec] conv... |
1506 1507 |
struct hlist_head *head; struct lec_arp_table *entry; |
1fa9961d6 [ATM]: [lec] inde... |
1508 |
|
99824461e net/atm: Convert ... |
1509 1510 |
pr_debug("%pM ", mac_addr); |
1fa9961d6 [ATM]: [lec] inde... |
1511 |
|
d0732f649 [ATM]: [lec] conv... |
1512 |
head = &priv->lec_arp_tables[HASH(mac_addr[ETH_ALEN - 1])]; |
b67bfe0d4 hlist: drop the n... |
1513 |
hlist_for_each_entry(entry, head, next) { |
150238ebb atm: Convert comp... |
1514 |
if (ether_addr_equal(mac_addr, entry->mac_addr)) |
d0732f649 [ATM]: [lec] conv... |
1515 |
return entry; |
1fa9961d6 [ATM]: [lec] inde... |
1516 1517 |
} return NULL; |
1da177e4c Linux-2.6.12-rc2 |
1518 |
} |
1fa9961d6 [ATM]: [lec] inde... |
1519 |
static struct lec_arp_table *make_entry(struct lec_priv *priv, |
61c33e012 atm: use const wh... |
1520 |
const unsigned char *mac_addr) |
1da177e4c Linux-2.6.12-rc2 |
1521 |
{ |
1fa9961d6 [ATM]: [lec] inde... |
1522 1523 1524 |
struct lec_arp_table *to_return; to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); |
bf97bac9d net: atm: Remove ... |
1525 |
if (!to_return) |
1fa9961d6 [ATM]: [lec] inde... |
1526 |
return NULL; |
116e853f7 atm: Use ether_ad... |
1527 |
ether_addr_copy(to_return->mac_addr, mac_addr); |
d0732f649 [ATM]: [lec] conv... |
1528 |
INIT_HLIST_NODE(&to_return->next); |
ba4217935 net: atm: Convert... |
1529 |
timer_setup(&to_return->timer, lec_arp_expire_arp, 0); |
1fa9961d6 [ATM]: [lec] inde... |
1530 1531 1532 |
to_return->last_used = jiffies; to_return->priv = priv; skb_queue_head_init(&to_return->tx_wait); |
788936641 net, atm: convert... |
1533 |
refcount_set(&to_return->usage, 1); |
1fa9961d6 [ATM]: [lec] inde... |
1534 |
return to_return; |
1da177e4c Linux-2.6.12-rc2 |
1535 |
} |
1fa9961d6 [ATM]: [lec] inde... |
1536 |
/* Arp sent timer expired */ |
ba4217935 net: atm: Convert... |
1537 |
static void lec_arp_expire_arp(struct timer_list *t) |
1da177e4c Linux-2.6.12-rc2 |
1538 |
{ |
1fa9961d6 [ATM]: [lec] inde... |
1539 |
struct lec_arp_table *entry; |
ba4217935 net: atm: Convert... |
1540 |
entry = from_timer(entry, t, timer); |
1fa9961d6 [ATM]: [lec] inde... |
1541 |
|
99824461e net/atm: Convert ... |
1542 1543 |
pr_debug(" "); |
1fa9961d6 [ATM]: [lec] inde... |
1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 |
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)); } |
1da177e4c Linux-2.6.12-rc2 |
1556 |
} |
1fa9961d6 [ATM]: [lec] inde... |
1557 |
/* Unknown/unused vcc expire, remove associated entry */ |
ba4217935 net: atm: Convert... |
1558 |
static void lec_arp_expire_vcc(struct timer_list *t) |
1da177e4c Linux-2.6.12-rc2 |
1559 1560 |
{ unsigned long flags; |
ba4217935 net: atm: Convert... |
1561 |
struct lec_arp_table *to_remove = from_timer(to_remove, t, timer); |
e3192690a net: Remove casts... |
1562 |
struct lec_priv *priv = to_remove->priv; |
1da177e4c Linux-2.6.12-rc2 |
1563 |
|
1fa9961d6 [ATM]: [lec] inde... |
1564 |
del_timer(&to_remove->timer); |
1da177e4c Linux-2.6.12-rc2 |
1565 |
|
99824461e net/atm: Convert ... |
1566 1567 1568 1569 1570 |
pr_debug("%p %p: vpi:%d vci:%d ", to_remove, priv, to_remove->vcc ? to_remove->recv_vcc->vpi : 0, to_remove->vcc ? to_remove->recv_vcc->vci : 0); |
1da177e4c Linux-2.6.12-rc2 |
1571 1572 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
d0732f649 [ATM]: [lec] conv... |
1573 |
hlist_del(&to_remove->next); |
1da177e4c Linux-2.6.12-rc2 |
1574 |
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
1575 |
lec_arp_clear_vccs(to_remove); |
33a9c2d4b [ATM]: [lec] add ... |
1576 |
lec_arp_put(to_remove); |
1da177e4c Linux-2.6.12-rc2 |
1577 |
} |
b4c84ec0f net/atm/lec.c: Ad... |
1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 |
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 ", 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 "); 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; } |
1da177e4c Linux-2.6.12-rc2 |
1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 |
/* * 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. */ |
c4028958b WorkStruct: make ... |
1640 |
static void lec_arp_check_expire(struct work_struct *work) |
1da177e4c Linux-2.6.12-rc2 |
1641 1642 |
{ unsigned long flags; |
c4028958b WorkStruct: make ... |
1643 1644 |
struct lec_priv *priv = container_of(work, struct lec_priv, lec_arp_work.work); |
b67bfe0d4 hlist: drop the n... |
1645 |
struct hlist_node *next; |
d0732f649 [ATM]: [lec] conv... |
1646 |
struct lec_arp_table *entry; |
1fa9961d6 [ATM]: [lec] inde... |
1647 |
unsigned long now; |
1fa9961d6 [ATM]: [lec] inde... |
1648 |
int i; |
99824461e net/atm: Convert ... |
1649 1650 |
pr_debug("%p ", priv); |
1da177e4c Linux-2.6.12-rc2 |
1651 |
now = jiffies; |
6656e3c4c [ATM]: [lec] use ... |
1652 |
restart: |
1da177e4c Linux-2.6.12-rc2 |
1653 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
1654 |
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
b67bfe0d4 hlist: drop the n... |
1655 |
hlist_for_each_entry_safe(entry, next, |
c48192a70 net/atm/lec.c: ch... |
1656 |
&priv->lec_arp_tables[i], next) { |
b4c84ec0f net/atm/lec.c: Ad... |
1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 |
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; |
33a9c2d4b [ATM]: [lec] add ... |
1667 |
lec_arp_put(entry); |
b4c84ec0f net/atm/lec.c: Ad... |
1668 1669 |
goto restart; |
1da177e4c Linux-2.6.12-rc2 |
1670 1671 1672 1673 |
} } } spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
987e46bdf [ATM]: [lec] use ... |
1674 |
schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL); |
1da177e4c Linux-2.6.12-rc2 |
1675 |
} |
1fa9961d6 [ATM]: [lec] inde... |
1676 |
|
1da177e4c Linux-2.6.12-rc2 |
1677 1678 |
/* * Try to find vcc where mac_address is attached. |
f7d57453d [NET] ATM: Fix wh... |
1679 |
* |
1da177e4c Linux-2.6.12-rc2 |
1680 |
*/ |
1fa9961d6 [ATM]: [lec] inde... |
1681 |
static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, |
c48192a70 net/atm/lec.c: ch... |
1682 1683 |
const unsigned char *mac_to_find, int is_rdesc, |
1fa9961d6 [ATM]: [lec] inde... |
1684 |
struct lec_arp_table **ret_entry) |
1da177e4c Linux-2.6.12-rc2 |
1685 1686 |
{ unsigned long flags; |
1fa9961d6 [ATM]: [lec] inde... |
1687 |
struct lec_arp_table *entry; |
1da177e4c Linux-2.6.12-rc2 |
1688 |
struct atm_vcc *found; |
1fa9961d6 [ATM]: [lec] inde... |
1689 1690 1691 1692 |
if (mac_to_find[0] & 0x01) { switch (priv->lane_version) { case 1: return priv->mcast_vcc; |
1fa9961d6 [ATM]: [lec] inde... |
1693 |
case 2: /* LANE2 wants arp for multicast addresses */ |
150238ebb atm: Convert comp... |
1694 |
if (ether_addr_equal(mac_to_find, bus_mac)) |
1fa9961d6 [ATM]: [lec] inde... |
1695 1696 1697 1698 1699 1700 |
return priv->mcast_vcc; break; default: break; } } |
1da177e4c Linux-2.6.12-rc2 |
1701 1702 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
1703 1704 1705 1706 1707 1708 |
entry = lec_arp_find(priv, mac_to_find); if (entry) { if (entry->status == ESI_FORWARD_DIRECT) { /* Connection Ok */ entry->last_used = jiffies; |
6656e3c4c [ATM]: [lec] use ... |
1709 |
lec_arp_hold(entry); |
1fa9961d6 [ATM]: [lec] inde... |
1710 1711 |
*ret_entry = entry; found = entry->vcc; |
1da177e4c Linux-2.6.12-rc2 |
1712 |
goto out; |
1fa9961d6 [ATM]: [lec] inde... |
1713 1714 1715 |
} /* * If the LE_ARP cache entry is still pending, reset count to 0 |
75b895c15 [ATM]: [lec] rese... |
1716 1717 |
* so another LE_ARP request can be made for this frame. */ |
c48192a70 net/atm/lec.c: ch... |
1718 |
if (entry->status == ESI_ARP_PENDING) |
75b895c15 [ATM]: [lec] rese... |
1719 |
entry->no_tries = 0; |
1fa9961d6 [ATM]: [lec] inde... |
1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 |
/* * 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++; |
99824461e net/atm: Convert ... |
1730 1731 |
pr_debug("Flooding.. "); |
1fa9961d6 [ATM]: [lec] inde... |
1732 |
found = priv->mcast_vcc; |
1da177e4c Linux-2.6.12-rc2 |
1733 |
goto out; |
1fa9961d6 [ATM]: [lec] inde... |
1734 1735 1736 |
} /* * We got here because entry->status == ESI_FLUSH_PENDING |
1da177e4c Linux-2.6.12-rc2 |
1737 1738 1739 |
* or BUS flood limit was reached for an entry which is * in ESI_ARP_PENDING or ESI_VC_PENDING state. */ |
6656e3c4c [ATM]: [lec] use ... |
1740 |
lec_arp_hold(entry); |
1fa9961d6 [ATM]: [lec] inde... |
1741 |
*ret_entry = entry; |
99824461e net/atm: Convert ... |
1742 1743 1744 |
pr_debug("entry->status %d entry->vcc %p ", entry->status, entry->vcc); |
1fa9961d6 [ATM]: [lec] inde... |
1745 1746 1747 1748 |
found = NULL; } else { /* No matching entry was found */ entry = make_entry(priv, mac_to_find); |
99824461e net/atm: Convert ... |
1749 1750 |
pr_debug("Making entry "); |
1fa9961d6 [ATM]: [lec] inde... |
1751 1752 |
if (!entry) { found = priv->mcast_vcc; |
1da177e4c Linux-2.6.12-rc2 |
1753 |
goto out; |
1fa9961d6 [ATM]: [lec] inde... |
1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 |
} 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); |
841b86f32 treewide: Remove ... |
1768 |
entry->timer.function = lec_arp_expire_arp; |
1fa9961d6 [ATM]: [lec] inde... |
1769 1770 1771 |
add_timer(&entry->timer); found = priv->mcast_vcc; } |
1da177e4c Linux-2.6.12-rc2 |
1772 1773 1774 1775 1776 1777 1778 |
out: spin_unlock_irqrestore(&priv->lec_arp_lock, flags); return found; } static int |
61c33e012 atm: use const wh... |
1779 |
lec_addr_delete(struct lec_priv *priv, const unsigned char *atm_addr, |
1fa9961d6 [ATM]: [lec] inde... |
1780 |
unsigned long permanent) |
1da177e4c Linux-2.6.12-rc2 |
1781 1782 |
{ unsigned long flags; |
b67bfe0d4 hlist: drop the n... |
1783 |
struct hlist_node *next; |
d0732f649 [ATM]: [lec] conv... |
1784 |
struct lec_arp_table *entry; |
1fa9961d6 [ATM]: [lec] inde... |
1785 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
1786 |
|
99824461e net/atm: Convert ... |
1787 1788 |
pr_debug(" "); |
1da177e4c Linux-2.6.12-rc2 |
1789 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
1790 |
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
b67bfe0d4 hlist: drop the n... |
1791 |
hlist_for_each_entry_safe(entry, next, |
c48192a70 net/atm/lec.c: ch... |
1792 1793 1794 1795 |
&priv->lec_arp_tables[i], next) { if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN) && (permanent || !(entry->flags & LEC_PERMANENT_FLAG))) { |
1da177e4c Linux-2.6.12-rc2 |
1796 |
lec_arp_remove(priv, entry); |
33a9c2d4b [ATM]: [lec] add ... |
1797 |
lec_arp_put(entry); |
1fa9961d6 [ATM]: [lec] inde... |
1798 |
} |
1da177e4c Linux-2.6.12-rc2 |
1799 |
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
1800 1801 1802 |
return 0; } } |
1da177e4c Linux-2.6.12-rc2 |
1803 |
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
1804 |
return -1; |
1da177e4c Linux-2.6.12-rc2 |
1805 1806 1807 |
} /* |
f7d57453d [NET] ATM: Fix wh... |
1808 |
* Notifies: Response to arp_request (atm_addr != NULL) |
1da177e4c Linux-2.6.12-rc2 |
1809 1810 |
*/ static void |
61c33e012 atm: use const wh... |
1811 1812 |
lec_arp_update(struct lec_priv *priv, const unsigned char *mac_addr, const unsigned char *atm_addr, unsigned long remoteflag, |
1fa9961d6 [ATM]: [lec] inde... |
1813 |
unsigned int targetless_le_arp) |
1da177e4c Linux-2.6.12-rc2 |
1814 1815 |
{ unsigned long flags; |
b67bfe0d4 hlist: drop the n... |
1816 |
struct hlist_node *next; |
1fa9961d6 [ATM]: [lec] inde... |
1817 1818 |
struct lec_arp_table *entry, *tmp; int i; |
1da177e4c Linux-2.6.12-rc2 |
1819 |
|
99824461e net/atm: Convert ... |
1820 1821 1822 |
pr_debug("%smac:%pM ", (targetless_le_arp) ? "targetless " : "", mac_addr); |
1da177e4c Linux-2.6.12-rc2 |
1823 1824 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
1825 1826 1827 1828 1829 1830 |
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 */ |
d0732f649 [ATM]: [lec] conv... |
1831 |
if (!hlist_empty(&priv->lec_arp_empty_ones)) { |
b67bfe0d4 hlist: drop the n... |
1832 |
hlist_for_each_entry_safe(entry, next, |
c48192a70 net/atm/lec.c: ch... |
1833 |
&priv->lec_arp_empty_ones, next) { |
d0732f649 [ATM]: [lec] conv... |
1834 1835 |
if (memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN) == 0) { hlist_del(&entry->next); |
1fa9961d6 [ATM]: [lec] inde... |
1836 |
del_timer(&entry->timer); |
d0732f649 [ATM]: [lec] conv... |
1837 1838 1839 1840 1841 1842 1843 1844 1845 |
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); |
33a9c2d4b [ATM]: [lec] add ... |
1846 |
lec_arp_put(entry); |
d0732f649 [ATM]: [lec] conv... |
1847 1848 1849 |
entry = tmp; } else { entry->status = ESI_FORWARD_DIRECT; |
116e853f7 atm: Use ether_ad... |
1850 1851 |
ether_addr_copy(entry->mac_addr, mac_addr); |
d0732f649 [ATM]: [lec] conv... |
1852 1853 1854 1855 1856 1857 1858 |
entry->last_used = jiffies; lec_arp_add(priv, entry); } if (remoteflag) entry->flags |= LEC_REMOTE_FLAG; else entry->flags &= ~LEC_REMOTE_FLAG; |
522400623 [ATM]: Replace DP... |
1859 1860 |
pr_debug("After update "); |
d0732f649 [ATM]: [lec] conv... |
1861 1862 |
dump_arp_table(priv); goto out; |
1fa9961d6 [ATM]: [lec] inde... |
1863 |
} |
1fa9961d6 [ATM]: [lec] inde... |
1864 1865 |
} } |
d0732f649 [ATM]: [lec] conv... |
1866 |
|
1fa9961d6 [ATM]: [lec] inde... |
1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 |
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++) { |
b67bfe0d4 hlist: drop the n... |
1879 |
hlist_for_each_entry(tmp, |
c48192a70 net/atm/lec.c: ch... |
1880 |
&priv->lec_arp_tables[i], next) { |
1fa9961d6 [ATM]: [lec] inde... |
1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 |
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; |
d0732f649 [ATM]: [lec] conv... |
1903 |
send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL); |
1fa9961d6 [ATM]: [lec] inde... |
1904 |
} |
522400623 [ATM]: Replace DP... |
1905 1906 |
pr_debug("After update2 "); |
1fa9961d6 [ATM]: [lec] inde... |
1907 |
dump_arp_table(priv); |
1da177e4c Linux-2.6.12-rc2 |
1908 1909 1910 1911 1912 |
out: spin_unlock_irqrestore(&priv->lec_arp_lock, flags); } /* |
f7d57453d [NET] ATM: Fix wh... |
1913 |
* Notifies: Vcc setup ready |
1da177e4c Linux-2.6.12-rc2 |
1914 1915 |
*/ static void |
61c33e012 atm: use const wh... |
1916 |
lec_vcc_added(struct lec_priv *priv, const struct atmlec_ioc *ioc_data, |
1fa9961d6 [ATM]: [lec] inde... |
1917 1918 |
struct atm_vcc *vcc, void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb)) |
1da177e4c Linux-2.6.12-rc2 |
1919 1920 |
{ unsigned long flags; |
1fa9961d6 [ATM]: [lec] inde... |
1921 1922 |
struct lec_arp_table *entry; int i, found_entry = 0; |
1da177e4c Linux-2.6.12-rc2 |
1923 1924 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
c48192a70 net/atm/lec.c: ch... |
1925 |
/* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */ |
1fa9961d6 [ATM]: [lec] inde... |
1926 |
if (ioc_data->receive == 2) { |
522400623 [ATM]: Replace DP... |
1927 1928 |
pr_debug("LEC_ARP: Attaching mcast forward "); |
1da177e4c Linux-2.6.12-rc2 |
1929 |
#if 0 |
1fa9961d6 [ATM]: [lec] inde... |
1930 1931 |
entry = lec_arp_find(priv, bus_mac); if (!entry) { |
c48192a70 net/atm/lec.c: ch... |
1932 1933 |
pr_info("LEC_ARP: Multicast entry not found! "); |
1da177e4c Linux-2.6.12-rc2 |
1934 |
goto out; |
1fa9961d6 [ATM]: [lec] inde... |
1935 1936 1937 1938 |
} memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); entry->recv_vcc = vcc; entry->old_recv_push = old_push; |
1da177e4c Linux-2.6.12-rc2 |
1939 |
#endif |
1fa9961d6 [ATM]: [lec] inde... |
1940 1941 |
entry = make_entry(priv, bus_mac); if (entry == NULL) |
1da177e4c Linux-2.6.12-rc2 |
1942 |
goto out; |
1fa9961d6 [ATM]: [lec] inde... |
1943 1944 1945 1946 |
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; |
d0732f649 [ATM]: [lec] conv... |
1947 |
hlist_add_head(&entry->next, &priv->mcast_fwds); |
1fa9961d6 [ATM]: [lec] inde... |
1948 1949 1950 1951 1952 1953 |
goto out; } else if (ioc_data->receive == 1) { /* * Vcc which we don't want to make default vcc, * attach it anyway. */ |
79ac52240 net: atm: use %*p... |
1954 1955 1956 |
pr_debug("LEC_ARP:Attaching data direct, not default: %*phN ", ATM_ESA_LEN, ioc_data->atm_addr); |
1fa9961d6 [ATM]: [lec] inde... |
1957 1958 |
entry = make_entry(priv, bus_mac); if (entry == NULL) |
1da177e4c Linux-2.6.12-rc2 |
1959 |
goto out; |
1fa9961d6 [ATM]: [lec] inde... |
1960 |
memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); |
19ffa562e atm: Use eth_<foo... |
1961 |
eth_zero_addr(entry->mac_addr); |
1fa9961d6 [ATM]: [lec] inde... |
1962 1963 1964 1965 |
entry->recv_vcc = vcc; entry->old_recv_push = old_push; entry->status = ESI_UNKNOWN; entry->timer.expires = jiffies + priv->vcc_timeout_period; |
841b86f32 treewide: Remove ... |
1966 |
entry->timer.function = lec_arp_expire_vcc; |
d0732f649 [ATM]: [lec] conv... |
1967 |
hlist_add_head(&entry->next, &priv->lec_no_forward); |
1fa9961d6 [ATM]: [lec] inde... |
1968 |
add_timer(&entry->timer); |
1da177e4c Linux-2.6.12-rc2 |
1969 1970 |
dump_arp_table(priv); goto out; |
1fa9961d6 [ATM]: [lec] inde... |
1971 |
} |
79ac52240 net: atm: use %*p... |
1972 1973 1974 |
pr_debug("LEC_ARP:Attaching data direct, default: %*phN ", ATM_ESA_LEN, ioc_data->atm_addr); |
1fa9961d6 [ATM]: [lec] inde... |
1975 |
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
b67bfe0d4 hlist: drop the n... |
1976 |
hlist_for_each_entry(entry, |
c48192a70 net/atm/lec.c: ch... |
1977 |
&priv->lec_arp_tables[i], next) { |
1fa9961d6 [ATM]: [lec] inde... |
1978 1979 1980 |
if (memcmp (ioc_data->atm_addr, entry->atm_addr, ATM_ESA_LEN) == 0) { |
522400623 [ATM]: Replace DP... |
1981 1982 1983 1984 |
pr_debug("LEC_ARP: Attaching data direct "); pr_debug("Currently -> Vcc: %d, Rvcc:%d ", |
99824461e net/atm: Convert ... |
1985 1986 1987 |
entry->vcc ? entry->vcc->vci : 0, entry->recv_vcc ? entry->recv_vcc-> vci : 0); |
1fa9961d6 [ATM]: [lec] inde... |
1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 |
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; |
1da177e4c Linux-2.6.12-rc2 |
2001 |
#if 0 |
1fa9961d6 [ATM]: [lec] inde... |
2002 2003 2004 2005 |
send_to_lecd(priv, l_flush_xmt, NULL, entry->atm_addr, NULL); |
1da177e4c Linux-2.6.12-rc2 |
2006 |
#endif |
1fa9961d6 [ATM]: [lec] inde... |
2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 |
} } 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) { |
522400623 [ATM]: Replace DP... |
2026 2027 |
pr_debug("After vcc was added "); |
1fa9961d6 [ATM]: [lec] inde... |
2028 |
dump_arp_table(priv); |
1da177e4c Linux-2.6.12-rc2 |
2029 |
goto out; |
1fa9961d6 [ATM]: [lec] inde... |
2030 2031 2032 2033 2034 2035 2036 |
} /* * Not found, snatch address from first data packet that arrives * from this vcc */ entry = make_entry(priv, bus_mac); if (!entry) |
1da177e4c Linux-2.6.12-rc2 |
2037 |
goto out; |
1fa9961d6 [ATM]: [lec] inde... |
2038 2039 2040 |
entry->vcc = vcc; entry->old_push = old_push; memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); |
19ffa562e atm: Use eth_<foo... |
2041 |
eth_zero_addr(entry->mac_addr); |
1fa9961d6 [ATM]: [lec] inde... |
2042 |
entry->status = ESI_UNKNOWN; |
d0732f649 [ATM]: [lec] conv... |
2043 |
hlist_add_head(&entry->next, &priv->lec_arp_empty_ones); |
1fa9961d6 [ATM]: [lec] inde... |
2044 |
entry->timer.expires = jiffies + priv->vcc_timeout_period; |
841b86f32 treewide: Remove ... |
2045 |
entry->timer.function = lec_arp_expire_vcc; |
1fa9961d6 [ATM]: [lec] inde... |
2046 |
add_timer(&entry->timer); |
522400623 [ATM]: Replace DP... |
2047 2048 |
pr_debug("After vcc was added "); |
1da177e4c Linux-2.6.12-rc2 |
2049 2050 2051 2052 |
dump_arp_table(priv); out: spin_unlock_irqrestore(&priv->lec_arp_lock, flags); } |
1fa9961d6 [ATM]: [lec] inde... |
2053 |
static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id) |
1da177e4c Linux-2.6.12-rc2 |
2054 2055 |
{ unsigned long flags; |
1fa9961d6 [ATM]: [lec] inde... |
2056 2057 |
struct lec_arp_table *entry; int i; |
1da177e4c Linux-2.6.12-rc2 |
2058 |
|
99824461e net/atm: Convert ... |
2059 2060 |
pr_debug("%lx ", tran_id); |
6656e3c4c [ATM]: [lec] use ... |
2061 |
restart: |
1fa9961d6 [ATM]: [lec] inde... |
2062 2063 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
b67bfe0d4 hlist: drop the n... |
2064 |
hlist_for_each_entry(entry, |
c48192a70 net/atm/lec.c: ch... |
2065 2066 2067 |
&priv->lec_arp_tables[i], next) { if (entry->flush_tran_id == tran_id && entry->status == ESI_FLUSH_PENDING) { |
1fa9961d6 [ATM]: [lec] inde... |
2068 |
struct sk_buff *skb; |
6656e3c4c [ATM]: [lec] use ... |
2069 |
struct atm_vcc *vcc = entry->vcc; |
1fa9961d6 [ATM]: [lec] inde... |
2070 |
|
6656e3c4c [ATM]: [lec] use ... |
2071 |
lec_arp_hold(entry); |
c48192a70 net/atm/lec.c: ch... |
2072 2073 |
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
b4c84ec0f net/atm/lec.c: Ad... |
2074 |
while ((skb = skb_dequeue(&entry->tx_wait))) |
162619e59 lec: convert to i... |
2075 |
lec_send(vcc, skb); |
6656e3c4c [ATM]: [lec] use ... |
2076 |
entry->last_used = jiffies; |
1fa9961d6 [ATM]: [lec] inde... |
2077 |
entry->status = ESI_FORWARD_DIRECT; |
6656e3c4c [ATM]: [lec] use ... |
2078 |
lec_arp_put(entry); |
522400623 [ATM]: Replace DP... |
2079 2080 |
pr_debug("LEC_ARP: Flushed "); |
6656e3c4c [ATM]: [lec] use ... |
2081 |
goto restart; |
1fa9961d6 [ATM]: [lec] inde... |
2082 2083 2084 |
} } } |
1da177e4c Linux-2.6.12-rc2 |
2085 |
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
2086 |
dump_arp_table(priv); |
1da177e4c Linux-2.6.12-rc2 |
2087 2088 2089 2090 |
} static void lec_set_flush_tran_id(struct lec_priv *priv, |
61c33e012 atm: use const wh... |
2091 |
const unsigned char *atm_addr, unsigned long tran_id) |
1da177e4c Linux-2.6.12-rc2 |
2092 2093 |
{ unsigned long flags; |
1fa9961d6 [ATM]: [lec] inde... |
2094 2095 |
struct lec_arp_table *entry; int i; |
1da177e4c Linux-2.6.12-rc2 |
2096 2097 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
2098 |
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) |
b67bfe0d4 hlist: drop the n... |
2099 |
hlist_for_each_entry(entry, |
c48192a70 net/atm/lec.c: ch... |
2100 |
&priv->lec_arp_tables[i], next) { |
1fa9961d6 [ATM]: [lec] inde... |
2101 2102 |
if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) { entry->flush_tran_id = tran_id; |
522400623 [ATM]: Replace DP... |
2103 2104 |
pr_debug("Set flush transaction id to %lx for %p ", |
99824461e net/atm: Convert ... |
2105 |
tran_id, entry); |
1fa9961d6 [ATM]: [lec] inde... |
2106 |
} |
d0732f649 [ATM]: [lec] conv... |
2107 |
} |
1da177e4c Linux-2.6.12-rc2 |
2108 2109 |
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); } |
1fa9961d6 [ATM]: [lec] inde... |
2110 |
static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc) |
1da177e4c Linux-2.6.12-rc2 |
2111 2112 |
{ unsigned long flags; |
1fa9961d6 [ATM]: [lec] inde... |
2113 2114 2115 2116 |
unsigned char mac_addr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; struct lec_arp_table *to_add; |
1da177e4c Linux-2.6.12-rc2 |
2117 2118 |
struct lec_vcc_priv *vpriv; int err = 0; |
1fa9961d6 [ATM]: [lec] inde... |
2119 |
|
c48192a70 net/atm/lec.c: ch... |
2120 2121 |
vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL); if (!vpriv) |
1da177e4c Linux-2.6.12-rc2 |
2122 2123 2124 2125 |
return -ENOMEM; vpriv->xoff = 0; vpriv->old_pop = vcc->pop; vcc->user_back = vpriv; |
1fa9961d6 [ATM]: [lec] inde... |
2126 |
vcc->pop = lec_pop; |
1da177e4c Linux-2.6.12-rc2 |
2127 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
2128 2129 |
to_add = make_entry(priv, mac_addr); if (!to_add) { |
1da177e4c Linux-2.6.12-rc2 |
2130 2131 |
vcc->pop = vpriv->old_pop; kfree(vpriv); |
1fa9961d6 [ATM]: [lec] inde... |
2132 |
err = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
2133 |
goto out; |
1fa9961d6 [ATM]: [lec] inde... |
2134 2135 2136 2137 2138 2139 2140 2141 2142 |
} 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); |
1da177e4c Linux-2.6.12-rc2 |
2143 2144 |
out: spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
1fa9961d6 [ATM]: [lec] inde... |
2145 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
2146 |
} |
1fa9961d6 [ATM]: [lec] inde... |
2147 |
static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc) |
1da177e4c Linux-2.6.12-rc2 |
2148 2149 |
{ unsigned long flags; |
b67bfe0d4 hlist: drop the n... |
2150 |
struct hlist_node *next; |
d0732f649 [ATM]: [lec] conv... |
2151 |
struct lec_arp_table *entry; |
1fa9961d6 [ATM]: [lec] inde... |
2152 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
2153 |
|
522400623 [ATM]: Replace DP... |
2154 2155 |
pr_debug("LEC_ARP: lec_vcc_close vpi:%d vci:%d ", vcc->vpi, vcc->vci); |
1fa9961d6 [ATM]: [lec] inde... |
2156 |
dump_arp_table(priv); |
d0732f649 [ATM]: [lec] conv... |
2157 |
|
1da177e4c Linux-2.6.12-rc2 |
2158 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
d0732f649 [ATM]: [lec] conv... |
2159 |
|
1fa9961d6 [ATM]: [lec] inde... |
2160 |
for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
b67bfe0d4 hlist: drop the n... |
2161 |
hlist_for_each_entry_safe(entry, next, |
c48192a70 net/atm/lec.c: ch... |
2162 |
&priv->lec_arp_tables[i], next) { |
1fa9961d6 [ATM]: [lec] inde... |
2163 2164 |
if (vcc == entry->vcc) { lec_arp_remove(priv, entry); |
33a9c2d4b [ATM]: [lec] add ... |
2165 |
lec_arp_put(entry); |
c48192a70 net/atm/lec.c: ch... |
2166 |
if (priv->mcast_vcc == vcc) |
1fa9961d6 [ATM]: [lec] inde... |
2167 |
priv->mcast_vcc = NULL; |
1fa9961d6 [ATM]: [lec] inde... |
2168 2169 2170 |
} } } |
b67bfe0d4 hlist: drop the n... |
2171 |
hlist_for_each_entry_safe(entry, next, |
c48192a70 net/atm/lec.c: ch... |
2172 |
&priv->lec_arp_empty_ones, next) { |
d0732f649 [ATM]: [lec] conv... |
2173 |
if (entry->vcc == vcc) { |
1fa9961d6 [ATM]: [lec] inde... |
2174 2175 |
lec_arp_clear_vccs(entry); del_timer(&entry->timer); |
d0732f649 [ATM]: [lec] conv... |
2176 |
hlist_del(&entry->next); |
33a9c2d4b [ATM]: [lec] add ... |
2177 |
lec_arp_put(entry); |
1fa9961d6 [ATM]: [lec] inde... |
2178 |
} |
1fa9961d6 [ATM]: [lec] inde... |
2179 |
} |
b67bfe0d4 hlist: drop the n... |
2180 |
hlist_for_each_entry_safe(entry, next, |
c48192a70 net/atm/lec.c: ch... |
2181 |
&priv->lec_no_forward, next) { |
1fa9961d6 [ATM]: [lec] inde... |
2182 2183 2184 |
if (entry->recv_vcc == vcc) { lec_arp_clear_vccs(entry); del_timer(&entry->timer); |
d0732f649 [ATM]: [lec] conv... |
2185 |
hlist_del(&entry->next); |
33a9c2d4b [ATM]: [lec] add ... |
2186 |
lec_arp_put(entry); |
1fa9961d6 [ATM]: [lec] inde... |
2187 |
} |
1fa9961d6 [ATM]: [lec] inde... |
2188 |
} |
b67bfe0d4 hlist: drop the n... |
2189 |
hlist_for_each_entry_safe(entry, next, &priv->mcast_fwds, next) { |
1fa9961d6 [ATM]: [lec] inde... |
2190 2191 2192 |
if (entry->recv_vcc == vcc) { lec_arp_clear_vccs(entry); /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ |
d0732f649 [ATM]: [lec] conv... |
2193 |
hlist_del(&entry->next); |
33a9c2d4b [ATM]: [lec] add ... |
2194 |
lec_arp_put(entry); |
1fa9961d6 [ATM]: [lec] inde... |
2195 |
} |
1fa9961d6 [ATM]: [lec] inde... |
2196 |
} |
1da177e4c Linux-2.6.12-rc2 |
2197 2198 2199 2200 2201 2202 2203 |
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); dump_arp_table(priv); } static void lec_arp_check_empties(struct lec_priv *priv, |
1fa9961d6 [ATM]: [lec] inde... |
2204 |
struct atm_vcc *vcc, struct sk_buff *skb) |
1da177e4c Linux-2.6.12-rc2 |
2205 |
{ |
1fa9961d6 [ATM]: [lec] inde... |
2206 |
unsigned long flags; |
b67bfe0d4 hlist: drop the n... |
2207 |
struct hlist_node *next; |
d0732f649 [ATM]: [lec] conv... |
2208 |
struct lec_arp_table *entry, *tmp; |
1fa9961d6 [ATM]: [lec] inde... |
2209 |
struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data; |
60eea6cf2 atm: remove the c... |
2210 |
unsigned char *src = hdr->h_source; |
1da177e4c Linux-2.6.12-rc2 |
2211 2212 |
spin_lock_irqsave(&priv->lec_arp_lock, flags); |
b67bfe0d4 hlist: drop the n... |
2213 |
hlist_for_each_entry_safe(entry, next, |
c48192a70 net/atm/lec.c: ch... |
2214 |
&priv->lec_arp_empty_ones, next) { |
d0732f649 [ATM]: [lec] conv... |
2215 2216 |
if (vcc == entry->vcc) { del_timer(&entry->timer); |
116e853f7 atm: Use ether_ad... |
2217 |
ether_addr_copy(entry->mac_addr, src); |
d0732f649 [ATM]: [lec] conv... |
2218 2219 2220 |
entry->status = ESI_FORWARD_DIRECT; entry->last_used = jiffies; /* We might have got an entry */ |
c48192a70 net/atm/lec.c: ch... |
2221 2222 |
tmp = lec_arp_find(priv, src); if (tmp) { |
d0732f649 [ATM]: [lec] conv... |
2223 |
lec_arp_remove(priv, tmp); |
33a9c2d4b [ATM]: [lec] add ... |
2224 |
lec_arp_put(tmp); |
d0732f649 [ATM]: [lec] conv... |
2225 2226 2227 2228 |
} hlist_del(&entry->next); lec_arp_add(priv, entry); goto out; |
1fa9961d6 [ATM]: [lec] inde... |
2229 |
} |
1fa9961d6 [ATM]: [lec] inde... |
2230 |
} |
522400623 [ATM]: Replace DP... |
2231 2232 |
pr_debug("LEC_ARP: Arp_check_empties: entry not found! "); |
1da177e4c Linux-2.6.12-rc2 |
2233 2234 2235 |
out: spin_unlock_irqrestore(&priv->lec_arp_lock, flags); } |
1fa9961d6 [ATM]: [lec] inde... |
2236 |
|
1da177e4c Linux-2.6.12-rc2 |
2237 |
MODULE_LICENSE("GPL"); |