clip.c 23.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4
/* net/atm/clip.c - RFC1577 Classical IP over ATM */

/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */

5 6
#define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__

L
Linus Torvalds 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/kernel.h> /* for UINT_MAX */
#include <linux/module.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/wait.h>
#include <linux/timer.h>
#include <linux/if_arp.h> /* for some manifest constants */
#include <linux/notifier.h>
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/atmclip.h>
#include <linux/atmarp.h>
22
#include <linux/capability.h>
L
Linus Torvalds 已提交
23 24 25 26 27
#include <linux/ip.h> /* for net/route.h */
#include <linux/in.h> /* for struct sockaddr_in */
#include <linux/if.h> /* for IFF_UP */
#include <linux/inetdevice.h>
#include <linux/bitops.h>
R
Randy Dunlap 已提交
28
#include <linux/poison.h>
L
Linus Torvalds 已提交
29 30 31 32
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/rcupdate.h>
#include <linux/jhash.h>
33
#include <linux/slab.h>
L
Linus Torvalds 已提交
34 35
#include <net/route.h> /* for struct rtable and routing */
#include <net/icmp.h> /* icmp_send */
36 37
#include <linux/param.h> /* for HZ */
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
38 39
#include <asm/byteorder.h> /* for htons etc. */
#include <asm/system.h> /* save/restore_flags */
A
Arun Sharma 已提交
40
#include <linux/atomic.h>
L
Linus Torvalds 已提交
41 42 43 44 45 46 47 48 49 50

#include "common.h"
#include "resources.h"
#include <net/atmclip.h>

static struct net_device *clip_devs;
static struct atm_vcc *atmarpd;
static struct neigh_table clip_tbl;
static struct timer_list idle_timer;

A
Al Viro 已提交
51
static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
L
Linus Torvalds 已提交
52 53 54 55 56
{
	struct sock *sk;
	struct atmarp_ctrl *ctrl;
	struct sk_buff *skb;

57
	pr_debug("(%d)\n", type);
58 59
	if (!atmarpd)
		return -EUNATCH;
60
	skb = alloc_skb(sizeof(struct atmarp_ctrl), GFP_ATOMIC);
61 62
	if (!skb)
		return -ENOMEM;
63
	ctrl = (struct atmarp_ctrl *)skb_put(skb, sizeof(struct atmarp_ctrl));
L
Linus Torvalds 已提交
64 65 66
	ctrl->type = type;
	ctrl->itf_num = itf;
	ctrl->ip = ip;
67
	atm_force_charge(atmarpd, skb->truesize);
L
Linus Torvalds 已提交
68 69 70 71 72 73 74

	sk = sk_atm(atmarpd);
	skb_queue_tail(&sk->sk_receive_queue, skb);
	sk->sk_data_ready(sk, skb->len);
	return 0;
}

75
static void link_vcc(struct clip_vcc *clip_vcc, struct atmarp_entry *entry)
L
Linus Torvalds 已提交
76
{
77
	pr_debug("%p to entry %p (neigh %p)\n", clip_vcc, entry, entry->neigh);
L
Linus Torvalds 已提交
78
	clip_vcc->entry = entry;
79
	clip_vcc->xoff = 0;	/* @@@ may overrun buffer by one packet */
L
Linus Torvalds 已提交
80 81 82 83 84 85 86 87 88 89 90
	clip_vcc->next = entry->vccs;
	entry->vccs = clip_vcc;
	entry->neigh->used = jiffies;
}

static void unlink_clip_vcc(struct clip_vcc *clip_vcc)
{
	struct atmarp_entry *entry = clip_vcc->entry;
	struct clip_vcc **walk;

	if (!entry) {
91
		pr_crit("!clip_vcc->entry (clip_vcc %p)\n", clip_vcc);
L
Linus Torvalds 已提交
92 93
		return;
	}
H
Herbert Xu 已提交
94
	netif_tx_lock_bh(entry->neigh->dev);	/* block clip_start_xmit() */
L
Linus Torvalds 已提交
95 96 97 98 99
	entry->neigh->used = jiffies;
	for (walk = &entry->vccs; *walk; walk = &(*walk)->next)
		if (*walk == clip_vcc) {
			int error;

100
			*walk = clip_vcc->next;	/* atomic */
L
Linus Torvalds 已提交
101 102 103 104 105
			clip_vcc->entry = NULL;
			if (clip_vcc->xoff)
				netif_wake_queue(entry->neigh->dev);
			if (entry->vccs)
				goto out;
106 107
			entry->expires = jiffies - 1;
			/* force resolution or expiration */
L
Linus Torvalds 已提交
108 109 110
			error = neigh_update(entry->neigh, NULL, NUD_NONE,
					     NEIGH_UPDATE_F_ADMIN);
			if (error)
111
				pr_crit("neigh_update failed with %d\n", error);
L
Linus Torvalds 已提交
112 113
			goto out;
		}
114
	pr_crit("ATMARP: failed (entry %p, vcc 0x%p)\n", entry, clip_vcc);
115
out:
H
Herbert Xu 已提交
116
	netif_tx_unlock_bh(entry->neigh->dev);
L
Linus Torvalds 已提交
117 118 119 120 121 122 123 124 125 126 127 128
}

/* The neighbour entry n->lock is held. */
static int neigh_check_cb(struct neighbour *n)
{
	struct atmarp_entry *entry = NEIGH2ENTRY(n);
	struct clip_vcc *cv;

	for (cv = entry->vccs; cv; cv = cv->next) {
		unsigned long exp = cv->last_use + cv->idle_timeout;

		if (cv->idle_timeout && time_after(jiffies, exp)) {
129
			pr_debug("releasing vcc %p->%p of entry %p\n",
130
				 cv, cv->vcc, entry);
L
Linus Torvalds 已提交
131 132 133 134 135 136 137 138 139 140
			vcc_release_async(cv->vcc, -ETIMEDOUT);
		}
	}

	if (entry->vccs || time_before(jiffies, entry->expires))
		return 0;

	if (atomic_read(&n->refcnt) > 1) {
		struct sk_buff *skb;

141
		pr_debug("destruction postponed with ref %d\n",
142
			 atomic_read(&n->refcnt));
L
Linus Torvalds 已提交
143

144
		while ((skb = skb_dequeue(&n->arp_queue)) != NULL)
L
Linus Torvalds 已提交
145 146 147 148 149
			dev_kfree_skb(skb);

		return 0;
	}

150
	pr_debug("expired neigh %p\n", n);
L
Linus Torvalds 已提交
151 152 153 154 155 156 157
	return 1;
}

static void idle_timer_check(unsigned long dummy)
{
	write_lock(&clip_tbl.lock);
	__neigh_for_each_release(&clip_tbl, neigh_check_cb);
158
	mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
L
Linus Torvalds 已提交
159 160 161 162 163 164 165
	write_unlock(&clip_tbl.lock);
}

static int clip_arp_rcv(struct sk_buff *skb)
{
	struct atm_vcc *vcc;

166
	pr_debug("\n");
L
Linus Torvalds 已提交
167
	vcc = ATM_SKB(skb)->vcc;
168
	if (!vcc || !atm_charge(vcc, skb->truesize)) {
L
Linus Torvalds 已提交
169 170 171
		dev_kfree_skb_any(skb);
		return 0;
	}
172 173
	pr_debug("pushing to %p\n", vcc);
	pr_debug("using %p\n", CLIP_VCC(vcc)->old_push);
174
	CLIP_VCC(vcc)->old_push(vcc, skb);
L
Linus Torvalds 已提交
175 176 177 178 179 180 181 182 183
	return 0;
}

static const unsigned char llc_oui[] = {
	0xaa,	/* DSAP: non-ISO */
	0xaa,	/* SSAP: non-ISO */
	0x03,	/* Ctrl: Unnumbered Information Command PDU */
	0x00,	/* OUI: EtherType */
	0x00,
184 185
	0x00
};
L
Linus Torvalds 已提交
186

187
static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb)
L
Linus Torvalds 已提交
188 189 190
{
	struct clip_vcc *clip_vcc = CLIP_VCC(vcc);

191
	pr_debug("\n");
192 193 194 195 196 197 198

	if (!clip_devs) {
		atm_return(vcc, skb->truesize);
		kfree_skb(skb);
		return;
	}

L
Linus Torvalds 已提交
199
	if (!skb) {
200
		pr_debug("removing VCC %p\n", clip_vcc);
201 202 203
		if (clip_vcc->entry)
			unlink_clip_vcc(clip_vcc);
		clip_vcc->old_push(vcc, NULL);	/* pass on the bad news */
L
Linus Torvalds 已提交
204 205 206
		kfree(clip_vcc);
		return;
	}
207
	atm_return(vcc, skb->truesize);
L
Linus Torvalds 已提交
208
	skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs;
209
	/* clip_vcc->entry == NULL if we don't have an IP address yet */
L
Linus Torvalds 已提交
210 211 212 213 214
	if (!skb->dev) {
		dev_kfree_skb_any(skb);
		return;
	}
	ATM_SKB(skb)->vcc = vcc;
215
	skb_reset_mac_header(skb);
216 217 218
	if (!clip_vcc->encap ||
	    skb->len < RFC1483LLC_LEN ||
	    memcmp(skb->data, llc_oui, sizeof(llc_oui)))
219
		skb->protocol = htons(ETH_P_IP);
L
Linus Torvalds 已提交
220
	else {
221
		skb->protocol = ((__be16 *)skb->data)[3];
222
		skb_pull(skb, RFC1483LLC_LEN);
L
Linus Torvalds 已提交
223
		if (skb->protocol == htons(ETH_P_ARP)) {
224 225
			skb->dev->stats.rx_packets++;
			skb->dev->stats.rx_bytes += skb->len;
L
Linus Torvalds 已提交
226 227 228 229 230
			clip_arp_rcv(skb);
			return;
		}
	}
	clip_vcc->last_use = jiffies;
231 232
	skb->dev->stats.rx_packets++;
	skb->dev->stats.rx_bytes += skb->len;
L
Linus Torvalds 已提交
233 234 235 236 237 238 239 240 241
	memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
	netif_rx(skb);
}

/*
 * Note: these spinlocks _must_not_ block on non-SMP. The only goal is that
 * clip_pop is atomic with respect to the critical section in clip_start_xmit.
 */

242
static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb)
L
Linus Torvalds 已提交
243 244 245 246 247 248
{
	struct clip_vcc *clip_vcc = CLIP_VCC(vcc);
	struct net_device *dev = skb->dev;
	int old;
	unsigned long flags;

249
	pr_debug("(vcc %p)\n", vcc);
250
	clip_vcc->old_pop(vcc, skb);
L
Linus Torvalds 已提交
251
	/* skb->dev == NULL in outbound ARP packets */
252 253 254 255 256 257 258
	if (!dev)
		return;
	spin_lock_irqsave(&PRIV(dev)->xoff_lock, flags);
	if (atm_may_send(vcc, 0)) {
		old = xchg(&clip_vcc->xoff, 0);
		if (old)
			netif_wake_queue(dev);
L
Linus Torvalds 已提交
259
	}
260
	spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags);
L
Linus Torvalds 已提交
261 262
}

263
static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb)
L
Linus Torvalds 已提交
264
{
265
	pr_debug("(neigh %p, skb %p)\n", neigh, skb);
266
	to_atmarpd(act_need, PRIV(neigh->dev)->number, NEIGH2ENTRY(neigh)->ip);
L
Linus Torvalds 已提交
267 268
}

269
static void clip_neigh_error(struct neighbour *neigh, struct sk_buff *skb)
L
Linus Torvalds 已提交
270 271
{
#ifndef CONFIG_ATM_CLIP_NO_ICMP
272
	icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
L
Linus Torvalds 已提交
273 274 275 276
#endif
	kfree_skb(skb);
}

S
Stephen Hemminger 已提交
277
static const struct neigh_ops clip_neigh_ops = {
L
Linus Torvalds 已提交
278 279 280
	.family =		AF_INET,
	.solicit =		clip_neigh_solicit,
	.error_report =		clip_neigh_error,
281 282
	.output =		neigh_direct_output,
	.connected_output =	neigh_direct_output,
L
Linus Torvalds 已提交
283 284 285 286 287 288 289 290 291
};

static int clip_constructor(struct neighbour *neigh)
{
	struct atmarp_entry *entry = NEIGH2ENTRY(neigh);
	struct net_device *dev = neigh->dev;
	struct in_device *in_dev;
	struct neigh_parms *parms;

292
	pr_debug("(neigh %p, entry %p)\n", neigh, entry);
293
	neigh->type = inet_addr_type(&init_net, entry->ip);
294 295
	if (neigh->type != RTN_UNICAST)
		return -EINVAL;
L
Linus Torvalds 已提交
296 297

	rcu_read_lock();
298
	in_dev = __in_dev_get_rcu(dev);
L
Linus Torvalds 已提交
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
	if (!in_dev) {
		rcu_read_unlock();
		return -EINVAL;
	}

	parms = in_dev->arp_parms;
	__neigh_parms_put(neigh->parms);
	neigh->parms = neigh_parms_clone(parms);
	rcu_read_unlock();

	neigh->ops = &clip_neigh_ops;
	neigh->output = neigh->nud_state & NUD_VALID ?
	    neigh->ops->connected_output : neigh->ops->output;
	entry->neigh = neigh;
	entry->vccs = NULL;
314
	entry->expires = jiffies - 1;
L
Linus Torvalds 已提交
315 316 317
	return 0;
}

318
static u32 clip_hash(const void *pkey, const struct net_device *dev, __u32 rnd)
L
Linus Torvalds 已提交
319
{
320
	return jhash_2words(*(u32 *) pkey, dev->ifindex, rnd);
L
Linus Torvalds 已提交
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
}

static struct neigh_table clip_tbl = {
	.family 	= AF_INET,
	.entry_size 	= sizeof(struct neighbour)+sizeof(struct atmarp_entry),
	.key_len 	= 4,
	.hash 		= clip_hash,
	.constructor 	= clip_constructor,
	.id 		= "clip_arp_cache",

	/* parameters are copied from ARP ... */
	.parms = {
		.tbl 			= &clip_tbl,
		.base_reachable_time 	= 30 * HZ,
		.retrans_time 		= 1 * HZ,
		.gc_staletime 		= 60 * HZ,
		.reachable_time 	= 30 * HZ,
		.delay_probe_time 	= 5 * HZ,
E
Eric Dumazet 已提交
339
		.queue_len_bytes 	= 64 * 1024,
L
Linus Torvalds 已提交
340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
		.ucast_probes 		= 3,
		.mcast_probes 		= 3,
		.anycast_delay 		= 1 * HZ,
		.proxy_delay 		= (8 * HZ) / 10,
		.proxy_qlen 		= 64,
		.locktime 		= 1 * HZ,
	},
	.gc_interval 	= 30 * HZ,
	.gc_thresh1 	= 128,
	.gc_thresh2 	= 512,
	.gc_thresh3 	= 1024,
};

/* @@@ copy bh locking from arp.c -- need to bh-enable atm code before */

/*
 * We play with the resolve flag: 0 and 1 have the usual meaning, but -1 means
 * to allocate the neighbour entry but not to ask atmarpd for resolution. Also,
 * don't increment the usage count. This is used to create entries in
 * clip_setentry.
 */

362
static int clip_encap(struct atm_vcc *vcc, int mode)
L
Linus Torvalds 已提交
363 364 365 366 367
{
	CLIP_VCC(vcc)->encap = mode;
	return 0;
}

368 369
static netdev_tx_t clip_start_xmit(struct sk_buff *skb,
				   struct net_device *dev)
L
Linus Torvalds 已提交
370 371
{
	struct clip_priv *clip_priv = PRIV(dev);
372
	struct dst_entry *dst = skb_dst(skb);
L
Linus Torvalds 已提交
373
	struct atmarp_entry *entry;
374
	struct neighbour *n;
L
Linus Torvalds 已提交
375 376 377 378
	struct atm_vcc *vcc;
	int old;
	unsigned long flags;

379
	pr_debug("(skb %p)\n", skb);
380
	if (!dst) {
381
		pr_err("skb_dst(skb) == NULL\n");
L
Linus Torvalds 已提交
382
		dev_kfree_skb(skb);
383
		dev->stats.tx_dropped++;
384
		return NETDEV_TX_OK;
L
Linus Torvalds 已提交
385
	}
386 387
	n = dst_get_neighbour(dst);
	if (!n) {
L
Linus Torvalds 已提交
388
#if 0
389 390
		n = clip_find_neighbour(skb_dst(skb), 1);
		if (!n) {
391
			dev_kfree_skb(skb);	/* lost that one */
392
			dev->stats.tx_dropped++;
L
Linus Torvalds 已提交
393 394
			return 0;
		}
395
		dst_set_neighbour(dst, n);
L
Linus Torvalds 已提交
396
#endif
397
		pr_err("NO NEIGHBOUR !\n");
L
Linus Torvalds 已提交
398
		dev_kfree_skb(skb);
399
		dev->stats.tx_dropped++;
400
		return NETDEV_TX_OK;
L
Linus Torvalds 已提交
401
	}
402
	entry = NEIGH2ENTRY(n);
L
Linus Torvalds 已提交
403 404 405
	if (!entry->vccs) {
		if (time_after(jiffies, entry->expires)) {
			/* should be resolved */
406 407
			entry->expires = jiffies + ATMARP_RETRY_DELAY * HZ;
			to_atmarpd(act_need, PRIV(dev)->number, entry->ip);
L
Linus Torvalds 已提交
408 409
		}
		if (entry->neigh->arp_queue.qlen < ATMARP_MAX_UNRES_PACKETS)
410
			skb_queue_tail(&entry->neigh->arp_queue, skb);
L
Linus Torvalds 已提交
411 412
		else {
			dev_kfree_skb(skb);
413
			dev->stats.tx_dropped++;
L
Linus Torvalds 已提交
414
		}
415
		return NETDEV_TX_OK;
L
Linus Torvalds 已提交
416
	}
417
	pr_debug("neigh %p, vccs %p\n", entry, entry->vccs);
L
Linus Torvalds 已提交
418
	ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
419
	pr_debug("using neighbour %p, vcc %p\n", n, vcc);
L
Linus Torvalds 已提交
420 421 422
	if (entry->vccs->encap) {
		void *here;

423 424
		here = skb_push(skb, RFC1483LLC_LEN);
		memcpy(here, llc_oui, sizeof(llc_oui));
A
Al Viro 已提交
425
		((__be16 *) here)[3] = skb->protocol;
L
Linus Torvalds 已提交
426 427 428 429
	}
	atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
	ATM_SKB(skb)->atm_options = vcc->atm_options;
	entry->vccs->last_use = jiffies;
430
	pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, vcc, vcc->dev);
431
	old = xchg(&entry->vccs->xoff, 1);	/* assume XOFF ... */
L
Linus Torvalds 已提交
432
	if (old) {
433
		pr_warning("XOFF->XOFF transition\n");
434
		return NETDEV_TX_OK;
L
Linus Torvalds 已提交
435
	}
436 437
	dev->stats.tx_packets++;
	dev->stats.tx_bytes += skb->len;
438
	vcc->send(vcc, skb);
439
	if (atm_may_send(vcc, 0)) {
L
Linus Torvalds 已提交
440
		entry->vccs->xoff = 0;
441
		return NETDEV_TX_OK;
L
Linus Torvalds 已提交
442
	}
443 444
	spin_lock_irqsave(&clip_priv->xoff_lock, flags);
	netif_stop_queue(dev);	/* XOFF -> throttle immediately */
L
Linus Torvalds 已提交
445 446 447
	barrier();
	if (!entry->vccs->xoff)
		netif_start_queue(dev);
448 449 450 451 452
	/* Oh, we just raced with clip_pop. netif_start_queue should be
	   good enough, because nothing should really be asleep because
	   of the brief netif_stop_queue. If this isn't true or if it
	   changes, use netif_wake_queue instead. */
	spin_unlock_irqrestore(&clip_priv->xoff_lock, flags);
453
	return NETDEV_TX_OK;
L
Linus Torvalds 已提交
454 455
}

456
static int clip_mkip(struct atm_vcc *vcc, int timeout)
L
Linus Torvalds 已提交
457
{
458
	struct sk_buff_head *rq, queue;
L
Linus Torvalds 已提交
459
	struct clip_vcc *clip_vcc;
460
	struct sk_buff *skb, *tmp;
D
David S. Miller 已提交
461
	unsigned long flags;
L
Linus Torvalds 已提交
462

463 464 465 466 467
	if (!vcc->push)
		return -EBADFD;
	clip_vcc = kmalloc(sizeof(struct clip_vcc), GFP_KERNEL);
	if (!clip_vcc)
		return -ENOMEM;
468
	pr_debug("%p vcc %p\n", clip_vcc, vcc);
L
Linus Torvalds 已提交
469 470 471 472 473 474 475
	clip_vcc->vcc = vcc;
	vcc->user_back = clip_vcc;
	set_bit(ATM_VF_IS_CLIP, &vcc->flags);
	clip_vcc->entry = NULL;
	clip_vcc->xoff = 0;
	clip_vcc->encap = 1;
	clip_vcc->last_use = jiffies;
476
	clip_vcc->idle_timeout = timeout * HZ;
L
Linus Torvalds 已提交
477 478 479 480
	clip_vcc->old_push = vcc->push;
	clip_vcc->old_pop = vcc->pop;
	vcc->push = clip_push;
	vcc->pop = clip_pop;
D
David S. Miller 已提交
481

482
	__skb_queue_head_init(&queue);
D
David S. Miller 已提交
483 484 485
	rq = &sk_atm(vcc)->sk_receive_queue;

	spin_lock_irqsave(&rq->lock, flags);
486
	skb_queue_splice_init(rq, &queue);
D
David S. Miller 已提交
487 488
	spin_unlock_irqrestore(&rq->lock, flags);

L
Linus Torvalds 已提交
489
	/* re-process everything received between connection setup and MKIP */
490 491 492
	skb_queue_walk_safe(&queue, skb, tmp)
		clip_push(vcc, skb);

L
Linus Torvalds 已提交
493 494 495
	return 0;
}

A
Al Viro 已提交
496
static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
L
Linus Torvalds 已提交
497 498 499 500 501 502 503 504
{
	struct neighbour *neigh;
	struct atmarp_entry *entry;
	int error;
	struct clip_vcc *clip_vcc;
	struct rtable *rt;

	if (vcc->push != clip_push) {
505
		pr_warning("non-CLIP VCC\n");
L
Linus Torvalds 已提交
506 507 508 509 510
		return -EBADF;
	}
	clip_vcc = CLIP_VCC(vcc);
	if (!ip) {
		if (!clip_vcc->entry) {
511
			pr_err("hiding hidden ATMARP entry\n");
L
Linus Torvalds 已提交
512 513
			return 0;
		}
514
		pr_debug("remove\n");
L
Linus Torvalds 已提交
515 516 517
		unlink_clip_vcc(clip_vcc);
		return 0;
	}
518
	rt = ip_route_output(&init_net, ip, 0, 1, 0);
519 520
	if (IS_ERR(rt))
		return PTR_ERR(rt);
521
	neigh = __neigh_lookup(&clip_tbl, &ip, rt->dst.dev, 1);
L
Linus Torvalds 已提交
522 523 524 525 526
	ip_rt_put(rt);
	if (!neigh)
		return -ENOMEM;
	entry = NEIGH2ENTRY(neigh);
	if (entry != clip_vcc->entry) {
527
		if (!clip_vcc->entry)
528
			pr_debug("add\n");
L
Linus Torvalds 已提交
529
		else {
530
			pr_debug("update\n");
L
Linus Torvalds 已提交
531 532
			unlink_clip_vcc(clip_vcc);
		}
533
		link_vcc(clip_vcc, entry);
L
Linus Torvalds 已提交
534
	}
535 536
	error = neigh_update(neigh, llc_oui, NUD_PERMANENT,
			     NEIGH_UPDATE_F_OVERRIDE | NEIGH_UPDATE_F_ADMIN);
L
Linus Torvalds 已提交
537 538 539 540
	neigh_release(neigh);
	return error;
}

541 542 543 544
static const struct net_device_ops clip_netdev_ops = {
	.ndo_start_xmit = clip_start_xmit,
};

L
Linus Torvalds 已提交
545 546
static void clip_setup(struct net_device *dev)
{
547
	dev->netdev_ops = &clip_netdev_ops;
L
Linus Torvalds 已提交
548 549 550
	dev->type = ARPHRD_ATM;
	dev->hard_header_len = RFC1483LLC_LEN;
	dev->mtu = RFC1626_MTU;
551 552 553 554 555 556
	dev->tx_queue_len = 100;	/* "normal" queue (packets) */
	/* When using a "real" qdisc, the qdisc determines the queue */
	/* length. tx_queue_len is only used for the default case, */
	/* without any more elaborate queuing. 100 is a reasonable */
	/* compromise between decent burst-tolerance and protection */
	/* against memory hogs. */
557
	dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
L
Linus Torvalds 已提交
558 559 560 561 562 563 564 565 566 567
}

static int clip_create(int number)
{
	struct net_device *dev;
	struct clip_priv *clip_priv;
	int error;

	if (number != -1) {
		for (dev = clip_devs; dev; dev = PRIV(dev)->next)
568 569 570
			if (PRIV(dev)->number == number)
				return -EEXIST;
	} else {
L
Linus Torvalds 已提交
571 572 573
		number = 0;
		for (dev = clip_devs; dev; dev = PRIV(dev)->next)
			if (PRIV(dev)->number >= number)
574
				number = PRIV(dev)->number + 1;
L
Linus Torvalds 已提交
575 576 577 578 579
	}
	dev = alloc_netdev(sizeof(struct clip_priv), "", clip_setup);
	if (!dev)
		return -ENOMEM;
	clip_priv = PRIV(dev);
580
	sprintf(dev->name, "atm%d", number);
L
Linus Torvalds 已提交
581 582 583 584 585 586 587 588 589
	spin_lock_init(&clip_priv->xoff_lock);
	clip_priv->number = number;
	error = register_netdev(dev);
	if (error) {
		free_netdev(dev);
		return error;
	}
	clip_priv->next = clip_devs;
	clip_devs = dev;
590
	pr_debug("registered (net:%s)\n", dev->name);
L
Linus Torvalds 已提交
591 592 593
	return number;
}

594
static int clip_device_event(struct notifier_block *this, unsigned long event,
595
			     void *arg)
L
Linus Torvalds 已提交
596
{
597 598
	struct net_device *dev = arg;

599
	if (!net_eq(dev_net(dev), &init_net))
600 601
		return NOTIFY_DONE;

602 603 604 605 606
	if (event == NETDEV_UNREGISTER) {
		neigh_ifdown(&clip_tbl, dev);
		return NOTIFY_DONE;
	}

L
Linus Torvalds 已提交
607
	/* ignore non-CLIP devices */
608
	if (dev->type != ARPHRD_ATM || dev->netdev_ops != &clip_netdev_ops)
L
Linus Torvalds 已提交
609
		return NOTIFY_DONE;
610

L
Linus Torvalds 已提交
611
	switch (event) {
612
	case NETDEV_UP:
613
		pr_debug("NETDEV_UP\n");
614
		to_atmarpd(act_up, PRIV(dev)->number, 0);
615 616
		break;
	case NETDEV_GOING_DOWN:
617
		pr_debug("NETDEV_DOWN\n");
618
		to_atmarpd(act_down, PRIV(dev)->number, 0);
619 620 621
		break;
	case NETDEV_CHANGE:
	case NETDEV_CHANGEMTU:
622
		pr_debug("NETDEV_CHANGE*\n");
623
		to_atmarpd(act_change, PRIV(dev)->number, 0);
624
		break;
L
Linus Torvalds 已提交
625 626 627 628
	}
	return NOTIFY_DONE;
}

629 630
static int clip_inet_event(struct notifier_block *this, unsigned long event,
			   void *ifa)
L
Linus Torvalds 已提交
631 632 633
{
	struct in_device *in_dev;

634
	in_dev = ((struct in_ifaddr *)ifa)->ifa_dev;
L
Linus Torvalds 已提交
635 636 637 638
	/*
	 * Transitions are of the down-change-up type, so it's sufficient to
	 * handle the change on up.
	 */
639 640 641
	if (event != NETDEV_UP)
		return NOTIFY_DONE;
	return clip_device_event(this, NETDEV_CHANGE, in_dev->dev);
L
Linus Torvalds 已提交
642 643 644
}

static struct notifier_block clip_dev_notifier = {
645
	.notifier_call = clip_device_event,
L
Linus Torvalds 已提交
646 647 648 649 650
};



static struct notifier_block clip_inet_notifier = {
651
	.notifier_call = clip_inet_event,
L
Linus Torvalds 已提交
652 653 654 655 656 657
};



static void atmarpd_close(struct atm_vcc *vcc)
{
658
	pr_debug("\n");
659 660 661

	rtnl_lock();
	atmarpd = NULL;
L
Linus Torvalds 已提交
662
	skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
663 664
	rtnl_unlock();

665
	pr_debug("(done)\n");
L
Linus Torvalds 已提交
666 667 668 669 670 671 672 673 674 675 676 677
	module_put(THIS_MODULE);
}

static struct atmdev_ops atmarpd_dev_ops = {
	.close = atmarpd_close
};


static struct atm_dev atmarpd_dev = {
	.ops =			&atmarpd_dev_ops,
	.type =			"arpd",
	.number = 		999,
678
	.lock =			__SPIN_LOCK_UNLOCKED(atmarpd_dev.lock)
L
Linus Torvalds 已提交
679 680 681 682 683
};


static int atm_init_atmarp(struct atm_vcc *vcc)
{
684 685 686 687 688 689
	rtnl_lock();
	if (atmarpd) {
		rtnl_unlock();
		return -EADDRINUSE;
	}

690
	mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
S
Stephen Hemminger 已提交
691

L
Linus Torvalds 已提交
692
	atmarpd = vcc;
693 694
	set_bit(ATM_VF_META, &vcc->flags);
	set_bit(ATM_VF_READY, &vcc->flags);
L
Linus Torvalds 已提交
695 696 697 698 699 700
	    /* allow replies and avoid getting closed if signaling dies */
	vcc->dev = &atmarpd_dev;
	vcc_insert_socket(sk_atm(vcc));
	vcc->push = NULL;
	vcc->pop = NULL; /* crash */
	vcc->push_oam = NULL; /* crash */
701
	rtnl_unlock();
L
Linus Torvalds 已提交
702 703 704 705 706 707 708 709 710
	return 0;
}

static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
	struct atm_vcc *vcc = ATM_SD(sock);
	int err = 0;

	switch (cmd) {
711 712 713 714 715 716 717 718 719 720
	case SIOCMKCLIP:
	case ATMARPD_CTRL:
	case ATMARP_MKIP:
	case ATMARP_SETENTRY:
	case ATMARP_ENCAP:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
		break;
	default:
		return -ENOIOCTLCMD;
L
Linus Torvalds 已提交
721 722 723
	}

	switch (cmd) {
724 725 726 727 728 729 730 731 732 733 734 735 736 737
	case SIOCMKCLIP:
		err = clip_create(arg);
		break;
	case ATMARPD_CTRL:
		err = atm_init_atmarp(vcc);
		if (!err) {
			sock->state = SS_CONNECTED;
			__module_get(THIS_MODULE);
		}
		break;
	case ATMARP_MKIP:
		err = clip_mkip(vcc, arg);
		break;
	case ATMARP_SETENTRY:
A
Al Viro 已提交
738
		err = clip_setentry(vcc, (__force __be32)arg);
739 740 741 742
		break;
	case ATMARP_ENCAP:
		err = clip_encap(vcc, arg);
		break;
L
Linus Torvalds 已提交
743 744 745 746 747
	}
	return err;
}

static struct atm_ioctl clip_ioctl_ops = {
748 749
	.owner = THIS_MODULE,
	.ioctl = clip_ioctl,
L
Linus Torvalds 已提交
750 751 752 753 754 755
};

#ifdef CONFIG_PROC_FS

static void svc_addr(struct seq_file *seq, struct sockaddr_atmsvc *addr)
{
756 757
	static int code[] = { 1, 2, 10, 6, 1, 0 };
	static int e164[] = { 1, 8, 4, 6, 1, 0 };
L
Linus Torvalds 已提交
758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775

	if (*addr->sas_addr.pub) {
		seq_printf(seq, "%s", addr->sas_addr.pub);
		if (*addr->sas_addr.prv)
			seq_putc(seq, '+');
	} else if (!*addr->sas_addr.prv) {
		seq_printf(seq, "%s", "(none)");
		return;
	}
	if (*addr->sas_addr.prv) {
		unsigned char *prv = addr->sas_addr.prv;
		int *fields;
		int i, j;

		fields = *prv == ATM_AFI_E164 ? e164 : code;
		for (i = 0; fields[i]; i++) {
			for (j = fields[i]; j; j--)
				seq_printf(seq, "%02X", *prv++);
776
			if (fields[i + 1])
L
Linus Torvalds 已提交
777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
				seq_putc(seq, '.');
		}
	}
}

/* This means the neighbour entry has no attached VCC objects. */
#define SEQ_NO_VCC_TOKEN	((void *) 2)

static void atmarp_info(struct seq_file *seq, struct net_device *dev,
			struct atmarp_entry *entry, struct clip_vcc *clip_vcc)
{
	unsigned long exp;
	char buf[17];
	int svc, llc, off;

	svc = ((clip_vcc == SEQ_NO_VCC_TOKEN) ||
	       (sk_atm(clip_vcc->vcc)->sk_family == AF_ATMSVC));

795
	llc = ((clip_vcc == SEQ_NO_VCC_TOKEN) || clip_vcc->encap);
L
Linus Torvalds 已提交
796 797 798 799 800 801 802 803 804

	if (clip_vcc == SEQ_NO_VCC_TOKEN)
		exp = entry->neigh->used;
	else
		exp = clip_vcc->last_use;

	exp = (jiffies - exp) / HZ;

	seq_printf(seq, "%-6s%-4s%-4s%5ld ",
805
		   dev->name, svc ? "SVC" : "PVC", llc ? "LLC" : "NULL", exp);
L
Linus Torvalds 已提交
806

H
Harvey Harrison 已提交
807 808
	off = scnprintf(buf, sizeof(buf) - 1, "%pI4",
			&entry->ip);
L
Linus Torvalds 已提交
809 810 811 812 813 814 815 816 817 818 819 820 821 822
	while (off < 16)
		buf[off++] = ' ';
	buf[off] = '\0';
	seq_printf(seq, "%s", buf);

	if (clip_vcc == SEQ_NO_VCC_TOKEN) {
		if (time_before(jiffies, entry->expires))
			seq_printf(seq, "(resolving)\n");
		else
			seq_printf(seq, "(expired, ref %d)\n",
				   atomic_read(&entry->neigh->refcnt));
	} else if (!svc) {
		seq_printf(seq, "%d.%d.%d\n",
			   clip_vcc->vcc->dev->number,
823
			   clip_vcc->vcc->vpi, clip_vcc->vcc->vci);
L
Linus Torvalds 已提交
824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855
	} else {
		svc_addr(seq, &clip_vcc->vcc->remote);
		seq_putc(seq, '\n');
	}
}

struct clip_seq_state {
	/* This member must be first. */
	struct neigh_seq_state ns;

	/* Local to clip specific iteration. */
	struct clip_vcc *vcc;
};

static struct clip_vcc *clip_seq_next_vcc(struct atmarp_entry *e,
					  struct clip_vcc *curr)
{
	if (!curr) {
		curr = e->vccs;
		if (!curr)
			return SEQ_NO_VCC_TOKEN;
		return curr;
	}
	if (curr == SEQ_NO_VCC_TOKEN)
		return NULL;

	curr = curr->next;

	return curr;
}

static void *clip_seq_vcc_walk(struct clip_seq_state *state,
856
			       struct atmarp_entry *e, loff_t * pos)
L
Linus Torvalds 已提交
857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872
{
	struct clip_vcc *vcc = state->vcc;

	vcc = clip_seq_next_vcc(e, vcc);
	if (vcc && pos != NULL) {
		while (*pos) {
			vcc = clip_seq_next_vcc(e, vcc);
			if (!vcc)
				break;
			--(*pos);
		}
	}
	state->vcc = vcc;

	return vcc;
}
873

L
Linus Torvalds 已提交
874
static void *clip_seq_sub_iter(struct neigh_seq_state *_state,
875
			       struct neighbour *n, loff_t * pos)
L
Linus Torvalds 已提交
876
{
877
	struct clip_seq_state *state = (struct clip_seq_state *)_state;
L
Linus Torvalds 已提交
878 879 880 881

	return clip_seq_vcc_walk(state, NEIGH2ENTRY(n), pos);
}

882
static void *clip_seq_start(struct seq_file *seq, loff_t * pos)
L
Linus Torvalds 已提交
883
{
884 885
	struct clip_seq_state *state = seq->private;
	state->ns.neigh_sub_iter = clip_seq_sub_iter;
L
Linus Torvalds 已提交
886 887 888 889 890
	return neigh_seq_start(seq, pos, &clip_tbl, NEIGH_SEQ_NEIGH_ONLY);
}

static int clip_seq_show(struct seq_file *seq, void *v)
{
891 892
	static char atm_arp_banner[] =
	    "IPitf TypeEncp Idle IP address      ATM address\n";
L
Linus Torvalds 已提交
893 894 895 896 897 898 899 900 901 902

	if (v == SEQ_START_TOKEN) {
		seq_puts(seq, atm_arp_banner);
	} else {
		struct clip_seq_state *state = seq->private;
		struct neighbour *n = v;
		struct clip_vcc *vcc = state->vcc;

		atmarp_info(seq, n->dev, NEIGH2ENTRY(n), vcc);
	}
903
	return 0;
L
Linus Torvalds 已提交
904 905
}

906
static const struct seq_operations arp_seq_ops = {
L
Linus Torvalds 已提交
907 908 909 910 911 912 913 914
	.start	= clip_seq_start,
	.next	= neigh_seq_next,
	.stop	= neigh_seq_stop,
	.show	= clip_seq_show,
};

static int arp_seq_open(struct inode *inode, struct file *file)
{
915 916
	return seq_open_net(inode, file, &arp_seq_ops,
			    sizeof(struct clip_seq_state));
917 918
}

919
static const struct file_operations arp_seq_fops = {
L
Linus Torvalds 已提交
920 921 922
	.open		= arp_seq_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
923
	.release	= seq_release_net,
L
Linus Torvalds 已提交
924 925 926 927
	.owner		= THIS_MODULE
};
#endif

928 929
static void atm_clip_exit_noproc(void);

L
Linus Torvalds 已提交
930 931
static int __init atm_clip_init(void)
{
932
	neigh_table_init_no_netlink(&clip_tbl);
L
Linus Torvalds 已提交
933 934 935

	clip_tbl_hook = &clip_tbl;
	register_atm_ioctl(&clip_ioctl_ops);
936 937
	register_netdevice_notifier(&clip_dev_notifier);
	register_inetaddr_notifier(&clip_inet_notifier);
L
Linus Torvalds 已提交
938

S
Stephen Hemminger 已提交
939 940
	setup_timer(&idle_timer, idle_timer_check, 0);

941 942 943 944
#ifdef CONFIG_PROC_FS
	{
		struct proc_dir_entry *p;

945
		p = proc_create("arp", S_IRUGO, atm_proc_root, &arp_seq_fops);
946
		if (!p) {
947
			pr_err("Unable to initialize /proc/net/atm/arp\n");
948 949 950
			atm_clip_exit_noproc();
			return -ENOMEM;
		}
951 952
	}
#endif
L
Linus Torvalds 已提交
953 954 955 956

	return 0;
}

957
static void atm_clip_exit_noproc(void)
L
Linus Torvalds 已提交
958 959 960
{
	struct net_device *dev, *next;

961 962 963
	unregister_inetaddr_notifier(&clip_inet_notifier);
	unregister_netdevice_notifier(&clip_dev_notifier);

L
Linus Torvalds 已提交
964 965 966 967 968
	deregister_atm_ioctl(&clip_ioctl_ops);

	/* First, stop the idle timer, so it stops banging
	 * on the table.
	 */
S
Stephen Hemminger 已提交
969
	del_timer_sync(&idle_timer);
L
Linus Torvalds 已提交
970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990

	/* Next, purge the table, so that the device
	 * unregister loop below does not hang due to
	 * device references remaining in the table.
	 */
	neigh_ifdown(&clip_tbl, NULL);

	dev = clip_devs;
	while (dev) {
		next = PRIV(dev)->next;
		unregister_netdev(dev);
		free_netdev(dev);
		dev = next;
	}

	/* Now it is safe to fully shutdown whole table. */
	neigh_table_clear(&clip_tbl);

	clip_tbl_hook = NULL;
}

991 992 993 994 995 996 997
static void __exit atm_clip_exit(void)
{
	remove_proc_entry("arp", atm_proc_root);

	atm_clip_exit_noproc();
}

L
Linus Torvalds 已提交
998 999
module_init(atm_clip_init);
module_exit(atm_clip_exit);
S
Stephen Hemminger 已提交
1000 1001
MODULE_AUTHOR("Werner Almesberger");
MODULE_DESCRIPTION("Classical/IP over ATM interface");
L
Linus Torvalds 已提交
1002
MODULE_LICENSE("GPL");