mpc.c revision ec634fe328182a1a098585bfc7b69e5042bdb08d
1#include <linux/kernel.h>
2#include <linux/string.h>
3#include <linux/timer.h>
4#include <linux/init.h>
5#include <linux/bitops.h>
6#include <linux/capability.h>
7#include <linux/seq_file.h>
8
9/* We are an ethernet device */
10#include <linux/if_ether.h>
11#include <linux/netdevice.h>
12#include <linux/etherdevice.h>
13#include <net/sock.h>
14#include <linux/skbuff.h>
15#include <linux/ip.h>
16#include <asm/byteorder.h>
17#include <asm/uaccess.h>
18#include <net/checksum.h>   /* for ip_fast_csum() */
19#include <net/arp.h>
20#include <net/dst.h>
21#include <linux/proc_fs.h>
22
23/* And atm device */
24#include <linux/atmdev.h>
25#include <linux/atmlec.h>
26#include <linux/atmmpc.h>
27/* Modular too */
28#include <linux/module.h>
29
30#include "lec.h"
31#include "mpc.h"
32#include "resources.h"
33
34/*
35 * mpc.c: Implementation of MPOA client kernel part
36 */
37
38#if 0
39#define dprintk printk   /* debug */
40#else
41#define dprintk(format,args...)
42#endif
43
44#if 0
45#define ddprintk printk  /* more debug */
46#else
47#define ddprintk(format,args...)
48#endif
49
50
51
52#define MPOA_TAG_LEN 4
53
54/* mpc_daemon -> kernel */
55static void MPOA_trigger_rcvd (struct k_message *msg, struct mpoa_client *mpc);
56static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc);
57static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc);
58static void egress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc);
59static void mps_death(struct k_message *msg, struct mpoa_client *mpc);
60static void clean_up(struct k_message *msg, struct mpoa_client *mpc, int action);
61static void MPOA_cache_impos_rcvd(struct k_message *msg, struct mpoa_client *mpc);
62static void set_mpc_ctrl_addr_rcvd(struct k_message *mesg, struct mpoa_client *mpc);
63static void set_mps_mac_addr_rcvd(struct k_message *mesg, struct mpoa_client *mpc);
64
65static const uint8_t *copy_macs(struct mpoa_client *mpc,
66				const uint8_t *router_mac,
67				const uint8_t *tlvs, uint8_t mps_macs,
68				uint8_t device_type);
69static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry);
70
71static void send_set_mps_ctrl_addr(const char *addr, struct mpoa_client *mpc);
72static void mpoad_close(struct atm_vcc *vcc);
73static int msg_from_mpoad(struct atm_vcc *vcc, struct sk_buff *skb);
74
75static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb);
76static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev);
77static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned long event, void *dev);
78static void mpc_timer_refresh(void);
79static void mpc_cache_check( unsigned long checking_time  );
80
81static struct llc_snap_hdr llc_snap_mpoa_ctrl = {
82	0xaa, 0xaa, 0x03,
83	{0x00, 0x00, 0x5e},
84	{0x00, 0x03}         /* For MPOA control PDUs */
85};
86static struct llc_snap_hdr llc_snap_mpoa_data = {
87	0xaa, 0xaa, 0x03,
88	{0x00, 0x00, 0x00},
89	{0x08, 0x00}         /* This is for IP PDUs only */
90};
91static struct llc_snap_hdr llc_snap_mpoa_data_tagged = {
92	0xaa, 0xaa, 0x03,
93	{0x00, 0x00, 0x00},
94	{0x88, 0x4c}         /* This is for tagged data PDUs */
95};
96
97static struct notifier_block mpoa_notifier = {
98	mpoa_event_listener,
99	NULL,
100	0
101};
102
103struct mpoa_client *mpcs = NULL; /* FIXME */
104static struct atm_mpoa_qos *qos_head = NULL;
105static DEFINE_TIMER(mpc_timer, NULL, 0, 0);
106
107
108static struct mpoa_client *find_mpc_by_itfnum(int itf)
109{
110	struct mpoa_client *mpc;
111
112	mpc = mpcs;  /* our global linked list */
113	while (mpc != NULL) {
114		if (mpc->dev_num == itf)
115			return mpc;
116		mpc = mpc->next;
117	}
118
119	return NULL;   /* not found */
120}
121
122static struct mpoa_client *find_mpc_by_vcc(struct atm_vcc *vcc)
123{
124	struct mpoa_client *mpc;
125
126	mpc = mpcs;  /* our global linked list */
127	while (mpc != NULL) {
128		if (mpc->mpoad_vcc == vcc)
129			return mpc;
130		mpc = mpc->next;
131	}
132
133	return NULL;   /* not found */
134}
135
136static struct mpoa_client *find_mpc_by_lec(struct net_device *dev)
137{
138	struct mpoa_client *mpc;
139
140	mpc = mpcs;  /* our global linked list */
141	while (mpc != NULL) {
142		if (mpc->dev == dev)
143			return mpc;
144		mpc = mpc->next;
145	}
146
147	return NULL;   /* not found */
148}
149
150/*
151 * Functions for managing QoS list
152 */
153
154/*
155 * Overwrites the old entry or makes a new one.
156 */
157struct atm_mpoa_qos *atm_mpoa_add_qos(__be32 dst_ip, struct atm_qos *qos)
158{
159	struct atm_mpoa_qos *entry;
160
161	entry = atm_mpoa_search_qos(dst_ip);
162	if (entry != NULL) {
163		entry->qos = *qos;
164		return entry;
165	}
166
167	entry = kmalloc(sizeof(struct atm_mpoa_qos), GFP_KERNEL);
168	if (entry == NULL) {
169		printk("mpoa: atm_mpoa_add_qos: out of memory\n");
170		return entry;
171	}
172
173	entry->ipaddr = dst_ip;
174	entry->qos = *qos;
175
176	entry->next = qos_head;
177	qos_head = entry;
178
179	return entry;
180}
181
182struct atm_mpoa_qos *atm_mpoa_search_qos(__be32 dst_ip)
183{
184	struct atm_mpoa_qos *qos;
185
186	qos = qos_head;
187	while( qos != NULL ){
188		if(qos->ipaddr == dst_ip) {
189			break;
190		}
191		qos = qos->next;
192	}
193
194	return qos;
195}
196
197/*
198 * Returns 0 for failure
199 */
200int atm_mpoa_delete_qos(struct atm_mpoa_qos *entry)
201{
202
203	struct atm_mpoa_qos *curr;
204
205	if (entry == NULL) return 0;
206	if (entry == qos_head) {
207		qos_head = qos_head->next;
208		kfree(entry);
209		return 1;
210	}
211
212	curr = qos_head;
213	while (curr != NULL) {
214		if (curr->next == entry) {
215			curr->next = entry->next;
216			kfree(entry);
217			return 1;
218		}
219		curr = curr->next;
220	}
221
222	return 0;
223}
224
225/* this is buggered - we need locking for qos_head */
226void atm_mpoa_disp_qos(struct seq_file *m)
227{
228	struct atm_mpoa_qos *qos;
229
230	qos = qos_head;
231	seq_printf(m, "QoS entries for shortcuts:\n");
232	seq_printf(m, "IP address\n  TX:max_pcr pcr     min_pcr max_cdv max_sdu\n  RX:max_pcr pcr     min_pcr max_cdv max_sdu\n");
233
234	while (qos != NULL) {
235		seq_printf(m, "%pI4\n     %-7d %-7d %-7d %-7d %-7d\n     %-7d %-7d %-7d %-7d %-7d\n",
236				&qos->ipaddr,
237				qos->qos.txtp.max_pcr, qos->qos.txtp.pcr, qos->qos.txtp.min_pcr, qos->qos.txtp.max_cdv, qos->qos.txtp.max_sdu,
238				qos->qos.rxtp.max_pcr, qos->qos.rxtp.pcr, qos->qos.rxtp.min_pcr, qos->qos.rxtp.max_cdv, qos->qos.rxtp.max_sdu);
239		qos = qos->next;
240	}
241}
242
243static struct net_device *find_lec_by_itfnum(int itf)
244{
245	struct net_device *dev;
246	char name[IFNAMSIZ];
247
248	sprintf(name, "lec%d", itf);
249	dev = dev_get_by_name(&init_net, name);
250
251	return dev;
252}
253
254static struct mpoa_client *alloc_mpc(void)
255{
256	struct mpoa_client *mpc;
257
258	mpc = kzalloc(sizeof (struct mpoa_client), GFP_KERNEL);
259	if (mpc == NULL)
260		return NULL;
261	rwlock_init(&mpc->ingress_lock);
262	rwlock_init(&mpc->egress_lock);
263	mpc->next = mpcs;
264	atm_mpoa_init_cache(mpc);
265
266	mpc->parameters.mpc_p1 = MPC_P1;
267	mpc->parameters.mpc_p2 = MPC_P2;
268	memset(mpc->parameters.mpc_p3,0,sizeof(mpc->parameters.mpc_p3));
269	mpc->parameters.mpc_p4 = MPC_P4;
270	mpc->parameters.mpc_p5 = MPC_P5;
271	mpc->parameters.mpc_p6 = MPC_P6;
272
273	mpcs = mpc;
274
275	return mpc;
276}
277
278/*
279 *
280 * start_mpc() puts the MPC on line. All the packets destined
281 * to the lec underneath us are now being monitored and
282 * shortcuts will be established.
283 *
284 */
285static void start_mpc(struct mpoa_client *mpc, struct net_device *dev)
286{
287
288	dprintk("mpoa: (%s) start_mpc:\n", mpc->dev->name);
289	if (!dev->netdev_ops)
290		printk("mpoa: (%s) start_mpc  not starting\n", dev->name);
291	else {
292		mpc->old_ops = dev->netdev_ops;
293		mpc->new_ops = *mpc->old_ops;
294		mpc->new_ops.ndo_start_xmit = mpc_send_packet;
295		dev->netdev_ops = &mpc->new_ops;
296	}
297}
298
299static void stop_mpc(struct mpoa_client *mpc)
300{
301	struct net_device *dev = mpc->dev;
302	dprintk("mpoa: (%s) stop_mpc:", mpc->dev->name);
303
304	/* Lets not nullify lec device's dev->hard_start_xmit */
305	if (dev->netdev_ops != &mpc->new_ops) {
306		dprintk(" mpc already stopped, not fatal\n");
307		return;
308	}
309	dprintk("\n");
310
311	dev->netdev_ops = mpc->old_ops;
312	mpc->old_ops = NULL;
313
314	/* close_shortcuts(mpc);    ??? FIXME */
315}
316
317static const char *mpoa_device_type_string(char type) __attribute__ ((unused));
318
319static const char *mpoa_device_type_string(char type)
320{
321	switch(type) {
322	case NON_MPOA:
323		return "non-MPOA device";
324		break;
325	case MPS:
326		return "MPS";
327		break;
328	case MPC:
329		return "MPC";
330		break;
331	case MPS_AND_MPC:
332		return "both MPS and MPC";
333		break;
334	default:
335		return "unspecified (non-MPOA) device";
336		break;
337	}
338
339	return ""; /* not reached */
340}
341
342/*
343 * lec device calls this via its netdev_priv(dev)->lane2_ops
344 * ->associate_indicator() when it sees a TLV in LE_ARP packet.
345 * We fill in the pointer above when we see a LANE2 lec initializing
346 * See LANE2 spec 3.1.5
347 *
348 * Quite a big and ugly function but when you look at it
349 * all it does is to try to locate and parse MPOA Device
350 * Type TLV.
351 * We give our lec a pointer to this function and when the
352 * lec sees a TLV it uses the pointer to call this function.
353 *
354 */
355static void lane2_assoc_ind(struct net_device *dev, const u8 *mac_addr,
356			    const u8 *tlvs, u32 sizeoftlvs)
357{
358	uint32_t type;
359	uint8_t length, mpoa_device_type, number_of_mps_macs;
360	const uint8_t *end_of_tlvs;
361	struct mpoa_client *mpc;
362
363	mpoa_device_type = number_of_mps_macs = 0; /* silence gcc */
364	dprintk("mpoa: (%s) lane2_assoc_ind: received TLV(s), ", dev->name);
365	dprintk("total length of all TLVs %d\n", sizeoftlvs);
366	mpc = find_mpc_by_lec(dev); /* Sampo-Fix: moved here from below */
367	if (mpc == NULL) {
368		printk("mpoa: (%s) lane2_assoc_ind: no mpc\n", dev->name);
369		return;
370	}
371	end_of_tlvs = tlvs + sizeoftlvs;
372	while (end_of_tlvs - tlvs >= 5) {
373		type = (tlvs[0] << 24) | (tlvs[1] << 16) | (tlvs[2] << 8) | tlvs[3];
374		length = tlvs[4];
375		tlvs += 5;
376		dprintk("    type 0x%x length %02x\n", type, length);
377		if (tlvs + length > end_of_tlvs) {
378			printk("TLV value extends past its buffer, aborting parse\n");
379			return;
380		}
381
382		if (type == 0) {
383			printk("mpoa: (%s) lane2_assoc_ind: TLV type was 0, returning\n", dev->name);
384			return;
385		}
386
387		if (type != TLV_MPOA_DEVICE_TYPE) {
388			tlvs += length;
389			continue;  /* skip other TLVs */
390		}
391		mpoa_device_type = *tlvs++;
392		number_of_mps_macs = *tlvs++;
393		dprintk("mpoa: (%s) MPOA device type '%s', ", dev->name, mpoa_device_type_string(mpoa_device_type));
394		if (mpoa_device_type == MPS_AND_MPC &&
395		    length < (42 + number_of_mps_macs*ETH_ALEN)) { /* :) */
396			printk("\nmpoa: (%s) lane2_assoc_ind: short MPOA Device Type TLV\n",
397			       dev->name);
398			continue;
399		}
400		if ((mpoa_device_type == MPS || mpoa_device_type == MPC)
401		    && length < 22 + number_of_mps_macs*ETH_ALEN) {
402			printk("\nmpoa: (%s) lane2_assoc_ind: short MPOA Device Type TLV\n",
403				dev->name);
404			continue;
405		}
406		if (mpoa_device_type != MPS && mpoa_device_type != MPS_AND_MPC) {
407			dprintk("ignoring non-MPS device\n");
408			if (mpoa_device_type == MPC) tlvs += 20;
409			continue;  /* we are only interested in MPSs */
410		}
411		if (number_of_mps_macs == 0 && mpoa_device_type == MPS_AND_MPC) {
412			printk("\nmpoa: (%s) lane2_assoc_ind: MPS_AND_MPC has zero MACs\n", dev->name);
413			continue;  /* someone should read the spec */
414		}
415		dprintk("this MPS has %d MAC addresses\n", number_of_mps_macs);
416
417		/* ok, now we can go and tell our daemon the control address of MPS */
418		send_set_mps_ctrl_addr(tlvs, mpc);
419
420		tlvs = copy_macs(mpc, mac_addr, tlvs, number_of_mps_macs, mpoa_device_type);
421		if (tlvs == NULL) return;
422	}
423	if (end_of_tlvs - tlvs != 0)
424		printk("mpoa: (%s) lane2_assoc_ind: ignoring %Zd bytes of trailing TLV carbage\n",
425		       dev->name, end_of_tlvs - tlvs);
426	return;
427}
428
429/*
430 * Store at least advertizing router's MAC address
431 * plus the possible MAC address(es) to mpc->mps_macs.
432 * For a freshly allocated MPOA client mpc->mps_macs == 0.
433 */
434static const uint8_t *copy_macs(struct mpoa_client *mpc,
435				const uint8_t *router_mac,
436				const uint8_t *tlvs, uint8_t mps_macs,
437				uint8_t device_type)
438{
439	int num_macs;
440	num_macs = (mps_macs > 1) ? mps_macs : 1;
441
442	if (mpc->number_of_mps_macs != num_macs) { /* need to reallocate? */
443		if (mpc->number_of_mps_macs != 0) kfree(mpc->mps_macs);
444		mpc->number_of_mps_macs = 0;
445		mpc->mps_macs = kmalloc(num_macs*ETH_ALEN, GFP_KERNEL);
446		if (mpc->mps_macs == NULL) {
447			printk("mpoa: (%s) copy_macs: out of mem\n", mpc->dev->name);
448			return NULL;
449		}
450	}
451	memcpy(mpc->mps_macs, router_mac, ETH_ALEN);
452	tlvs += 20; if (device_type == MPS_AND_MPC) tlvs += 20;
453	if (mps_macs > 0)
454		memcpy(mpc->mps_macs, tlvs, mps_macs*ETH_ALEN);
455	tlvs += mps_macs*ETH_ALEN;
456	mpc->number_of_mps_macs = num_macs;
457
458	return tlvs;
459}
460
461static int send_via_shortcut(struct sk_buff *skb, struct mpoa_client *mpc)
462{
463	in_cache_entry *entry;
464	struct iphdr *iph;
465	char *buff;
466	__be32 ipaddr = 0;
467
468	static struct {
469		struct llc_snap_hdr hdr;
470		__be32 tag;
471	} tagged_llc_snap_hdr = {
472		{0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}, {0x88, 0x4c}},
473		0
474	};
475
476	buff = skb->data + mpc->dev->hard_header_len;
477	iph = (struct iphdr *)buff;
478	ipaddr = iph->daddr;
479
480	ddprintk("mpoa: (%s) send_via_shortcut: ipaddr 0x%x\n", mpc->dev->name, ipaddr);
481
482	entry = mpc->in_ops->get(ipaddr, mpc);
483	if (entry == NULL) {
484		entry = mpc->in_ops->add_entry(ipaddr, mpc);
485		if (entry != NULL) mpc->in_ops->put(entry);
486		return 1;
487	}
488	if (mpc->in_ops->cache_hit(entry, mpc) != OPEN){   /* threshold not exceeded or VCC not ready */
489		ddprintk("mpoa: (%s) send_via_shortcut: cache_hit: returns != OPEN\n", mpc->dev->name);
490		mpc->in_ops->put(entry);
491		return 1;
492	}
493
494	ddprintk("mpoa: (%s) send_via_shortcut: using shortcut\n", mpc->dev->name);
495	/* MPOA spec A.1.4, MPOA client must decrement IP ttl at least by one */
496	if (iph->ttl <= 1) {
497		ddprintk("mpoa: (%s) send_via_shortcut: IP ttl = %u, using LANE\n", mpc->dev->name, iph->ttl);
498		mpc->in_ops->put(entry);
499		return 1;
500	}
501	iph->ttl--;
502	iph->check = 0;
503	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
504
505	if (entry->ctrl_info.tag != 0) {
506		ddprintk("mpoa: (%s) send_via_shortcut: adding tag 0x%x\n", mpc->dev->name, entry->ctrl_info.tag);
507		tagged_llc_snap_hdr.tag = entry->ctrl_info.tag;
508		skb_pull(skb, ETH_HLEN);                       /* get rid of Eth header */
509		skb_push(skb, sizeof(tagged_llc_snap_hdr));    /* add LLC/SNAP header   */
510		skb_copy_to_linear_data(skb, &tagged_llc_snap_hdr,
511					sizeof(tagged_llc_snap_hdr));
512	} else {
513		skb_pull(skb, ETH_HLEN);                        /* get rid of Eth header */
514		skb_push(skb, sizeof(struct llc_snap_hdr));     /* add LLC/SNAP header + tag  */
515		skb_copy_to_linear_data(skb, &llc_snap_mpoa_data,
516					sizeof(struct llc_snap_hdr));
517	}
518
519	atomic_add(skb->truesize, &sk_atm(entry->shortcut)->sk_wmem_alloc);
520	ATM_SKB(skb)->atm_options = entry->shortcut->atm_options;
521	entry->shortcut->send(entry->shortcut, skb);
522	entry->packets_fwded++;
523	mpc->in_ops->put(entry);
524
525	return 0;
526}
527
528/*
529 * Probably needs some error checks and locking, not sure...
530 */
531static int mpc_send_packet(struct sk_buff *skb, struct net_device *dev)
532{
533	struct mpoa_client *mpc;
534	struct ethhdr *eth;
535	int i = 0;
536
537	mpc = find_mpc_by_lec(dev); /* this should NEVER fail */
538	if(mpc == NULL) {
539		printk("mpoa: (%s) mpc_send_packet: no MPC found\n", dev->name);
540		goto non_ip;
541	}
542
543	eth = (struct ethhdr *)skb->data;
544	if (eth->h_proto != htons(ETH_P_IP))
545		goto non_ip; /* Multi-Protocol Over ATM :-) */
546
547	/* Weed out funny packets (e.g., AF_PACKET or raw). */
548	if (skb->len < ETH_HLEN + sizeof(struct iphdr))
549		goto non_ip;
550	skb_set_network_header(skb, ETH_HLEN);
551	if (skb->len < ETH_HLEN + ip_hdr(skb)->ihl * 4 || ip_hdr(skb)->ihl < 5)
552		goto non_ip;
553
554	while (i < mpc->number_of_mps_macs) {
555		if (!compare_ether_addr(eth->h_dest, (mpc->mps_macs + i*ETH_ALEN)))
556			if ( send_via_shortcut(skb, mpc) == 0 )           /* try shortcut */
557				return NETDEV_TX_OK;                      /* success!     */
558		i++;
559	}
560
561 non_ip:
562	return mpc->old_ops->ndo_start_xmit(skb,dev);
563}
564
565static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
566{
567	int bytes_left;
568	struct mpoa_client *mpc;
569	struct atmmpc_ioc ioc_data;
570	in_cache_entry *in_entry;
571	__be32  ipaddr;
572
573	bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmmpc_ioc));
574	if (bytes_left != 0) {
575		printk("mpoa: mpc_vcc_attach: Short read (missed %d bytes) from userland\n", bytes_left);
576		return -EFAULT;
577	}
578	ipaddr = ioc_data.ipaddr;
579	if (ioc_data.dev_num < 0 || ioc_data.dev_num >= MAX_LEC_ITF)
580		return -EINVAL;
581
582	mpc = find_mpc_by_itfnum(ioc_data.dev_num);
583	if (mpc == NULL)
584		return -EINVAL;
585
586	if (ioc_data.type == MPC_SOCKET_INGRESS) {
587		in_entry = mpc->in_ops->get(ipaddr, mpc);
588		if (in_entry == NULL || in_entry->entry_state < INGRESS_RESOLVED) {
589			printk("mpoa: (%s) mpc_vcc_attach: did not find RESOLVED entry from ingress cache\n",
590				mpc->dev->name);
591			if (in_entry != NULL) mpc->in_ops->put(in_entry);
592			return -EINVAL;
593		}
594		printk("mpoa: (%s) mpc_vcc_attach: attaching ingress SVC, entry = %pI4\n",
595		       mpc->dev->name, &in_entry->ctrl_info.in_dst_ip);
596		in_entry->shortcut = vcc;
597		mpc->in_ops->put(in_entry);
598	} else {
599		printk("mpoa: (%s) mpc_vcc_attach: attaching egress SVC\n", mpc->dev->name);
600	}
601
602	vcc->proto_data = mpc->dev;
603	vcc->push = mpc_push;
604
605	return 0;
606}
607
608/*
609 *
610 */
611static void mpc_vcc_close(struct atm_vcc *vcc, struct net_device *dev)
612{
613	struct mpoa_client *mpc;
614	in_cache_entry *in_entry;
615	eg_cache_entry *eg_entry;
616
617	mpc = find_mpc_by_lec(dev);
618	if (mpc == NULL) {
619		printk("mpoa: (%s) mpc_vcc_close: close for unknown MPC\n", dev->name);
620		return;
621	}
622
623	dprintk("mpoa: (%s) mpc_vcc_close:\n", dev->name);
624	in_entry = mpc->in_ops->get_by_vcc(vcc, mpc);
625	if (in_entry) {
626		dprintk("mpoa: (%s) mpc_vcc_close: ingress SVC closed ip = %pI4\n",
627		       mpc->dev->name, &in_entry->ctrl_info.in_dst_ip);
628		in_entry->shortcut = NULL;
629		mpc->in_ops->put(in_entry);
630	}
631	eg_entry = mpc->eg_ops->get_by_vcc(vcc, mpc);
632	if (eg_entry) {
633		dprintk("mpoa: (%s) mpc_vcc_close: egress SVC closed\n", mpc->dev->name);
634		eg_entry->shortcut = NULL;
635		mpc->eg_ops->put(eg_entry);
636	}
637
638	if (in_entry == NULL && eg_entry == NULL)
639		dprintk("mpoa: (%s) mpc_vcc_close:  unused vcc closed\n", dev->name);
640
641	return;
642}
643
644static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb)
645{
646	struct net_device *dev = (struct net_device *)vcc->proto_data;
647	struct sk_buff *new_skb;
648	eg_cache_entry *eg;
649	struct mpoa_client *mpc;
650	__be32 tag;
651	char *tmp;
652
653	ddprintk("mpoa: (%s) mpc_push:\n", dev->name);
654	if (skb == NULL) {
655		dprintk("mpoa: (%s) mpc_push: null skb, closing VCC\n", dev->name);
656		mpc_vcc_close(vcc, dev);
657		return;
658	}
659
660	skb->dev = dev;
661	if (memcmp(skb->data, &llc_snap_mpoa_ctrl, sizeof(struct llc_snap_hdr)) == 0) {
662		struct sock *sk = sk_atm(vcc);
663
664		dprintk("mpoa: (%s) mpc_push: control packet arrived\n", dev->name);
665		/* Pass control packets to daemon */
666		skb_queue_tail(&sk->sk_receive_queue, skb);
667		sk->sk_data_ready(sk, skb->len);
668		return;
669	}
670
671	/* data coming over the shortcut */
672	atm_return(vcc, skb->truesize);
673
674	mpc = find_mpc_by_lec(dev);
675	if (mpc == NULL) {
676		printk("mpoa: (%s) mpc_push: unknown MPC\n", dev->name);
677		return;
678	}
679
680	if (memcmp(skb->data, &llc_snap_mpoa_data_tagged, sizeof(struct llc_snap_hdr)) == 0) { /* MPOA tagged data */
681		ddprintk("mpoa: (%s) mpc_push: tagged data packet arrived\n", dev->name);
682
683	} else if (memcmp(skb->data, &llc_snap_mpoa_data, sizeof(struct llc_snap_hdr)) == 0) { /* MPOA data */
684		printk("mpoa: (%s) mpc_push: non-tagged data packet arrived\n", dev->name);
685		printk("           mpc_push: non-tagged data unsupported, purging\n");
686		dev_kfree_skb_any(skb);
687		return;
688	} else {
689		printk("mpoa: (%s) mpc_push: garbage arrived, purging\n", dev->name);
690		dev_kfree_skb_any(skb);
691		return;
692	}
693
694	tmp = skb->data + sizeof(struct llc_snap_hdr);
695	tag = *(__be32 *)tmp;
696
697	eg = mpc->eg_ops->get_by_tag(tag, mpc);
698	if (eg == NULL) {
699		printk("mpoa: (%s) mpc_push: Didn't find egress cache entry, tag = %u\n",
700		       dev->name,tag);
701		purge_egress_shortcut(vcc, NULL);
702		dev_kfree_skb_any(skb);
703		return;
704	}
705
706	/*
707	 * See if ingress MPC is using shortcut we opened as a return channel.
708	 * This means we have a bi-directional vcc opened by us.
709	 */
710	if (eg->shortcut == NULL) {
711		eg->shortcut = vcc;
712		printk("mpoa: (%s) mpc_push: egress SVC in use\n", dev->name);
713	}
714
715	skb_pull(skb, sizeof(struct llc_snap_hdr) + sizeof(tag)); /* get rid of LLC/SNAP header */
716	new_skb = skb_realloc_headroom(skb, eg->ctrl_info.DH_length); /* LLC/SNAP is shorter than MAC header :( */
717	dev_kfree_skb_any(skb);
718	if (new_skb == NULL){
719		mpc->eg_ops->put(eg);
720		return;
721	}
722	skb_push(new_skb, eg->ctrl_info.DH_length);     /* add MAC header */
723	skb_copy_to_linear_data(new_skb, eg->ctrl_info.DLL_header,
724				eg->ctrl_info.DH_length);
725	new_skb->protocol = eth_type_trans(new_skb, dev);
726	skb_reset_network_header(new_skb);
727
728	eg->latest_ip_addr = ip_hdr(new_skb)->saddr;
729	eg->packets_rcvd++;
730	mpc->eg_ops->put(eg);
731
732	memset(ATM_SKB(skb), 0, sizeof(struct atm_skb_data));
733	netif_rx(new_skb);
734
735	return;
736}
737
738static struct atmdev_ops mpc_ops = { /* only send is required */
739	.close	= mpoad_close,
740	.send	= msg_from_mpoad
741};
742
743static struct atm_dev mpc_dev = {
744	.ops	= &mpc_ops,
745	.type	= "mpc",
746	.number	= 42,
747	.lock	= __SPIN_LOCK_UNLOCKED(mpc_dev.lock)
748	/* members not explicitly initialised will be 0 */
749};
750
751static int atm_mpoa_mpoad_attach (struct atm_vcc *vcc, int arg)
752{
753	struct mpoa_client *mpc;
754	struct lec_priv *priv;
755	int err;
756
757	if (mpcs == NULL) {
758		init_timer(&mpc_timer);
759		mpc_timer_refresh();
760
761		/* This lets us now how our LECs are doing */
762		err = register_netdevice_notifier(&mpoa_notifier);
763		if (err < 0) {
764			del_timer(&mpc_timer);
765			return err;
766		}
767	}
768
769	mpc = find_mpc_by_itfnum(arg);
770	if (mpc == NULL) {
771		dprintk("mpoa: mpoad_attach: allocating new mpc for itf %d\n", arg);
772		mpc = alloc_mpc();
773		if (mpc == NULL)
774			return -ENOMEM;
775		mpc->dev_num = arg;
776		mpc->dev = find_lec_by_itfnum(arg); /* NULL if there was no lec */
777	}
778	if (mpc->mpoad_vcc) {
779		printk("mpoa: mpoad_attach: mpoad is already present for itf %d\n", arg);
780		return -EADDRINUSE;
781	}
782
783	if (mpc->dev) { /* check if the lec is LANE2 capable */
784		priv = netdev_priv(mpc->dev);
785		if (priv->lane_version < 2) {
786			dev_put(mpc->dev);
787			mpc->dev = NULL;
788		} else
789			priv->lane2_ops->associate_indicator = lane2_assoc_ind;
790	}
791
792	mpc->mpoad_vcc = vcc;
793	vcc->dev = &mpc_dev;
794	vcc_insert_socket(sk_atm(vcc));
795	set_bit(ATM_VF_META,&vcc->flags);
796	set_bit(ATM_VF_READY,&vcc->flags);
797
798	if (mpc->dev) {
799		char empty[ATM_ESA_LEN];
800		memset(empty, 0, ATM_ESA_LEN);
801
802		start_mpc(mpc, mpc->dev);
803		/* set address if mpcd e.g. gets killed and restarted.
804		 * If we do not do it now we have to wait for the next LE_ARP
805		 */
806		if ( memcmp(mpc->mps_ctrl_addr, empty, ATM_ESA_LEN) != 0 )
807			send_set_mps_ctrl_addr(mpc->mps_ctrl_addr, mpc);
808	}
809
810	__module_get(THIS_MODULE);
811	return arg;
812}
813
814static void send_set_mps_ctrl_addr(const char *addr, struct mpoa_client *mpc)
815{
816	struct k_message mesg;
817
818	memcpy (mpc->mps_ctrl_addr, addr, ATM_ESA_LEN);
819
820	mesg.type = SET_MPS_CTRL_ADDR;
821	memcpy(mesg.MPS_ctrl, addr, ATM_ESA_LEN);
822	msg_to_mpoad(&mesg, mpc);
823
824	return;
825}
826
827static void mpoad_close(struct atm_vcc *vcc)
828{
829	struct mpoa_client *mpc;
830	struct sk_buff *skb;
831
832	mpc = find_mpc_by_vcc(vcc);
833	if (mpc == NULL) {
834		printk("mpoa: mpoad_close: did not find MPC\n");
835		return;
836	}
837	if (!mpc->mpoad_vcc) {
838		printk("mpoa: mpoad_close: close for non-present mpoad\n");
839		return;
840	}
841
842	mpc->mpoad_vcc = NULL;
843	if (mpc->dev) {
844		struct lec_priv *priv = netdev_priv(mpc->dev);
845		priv->lane2_ops->associate_indicator = NULL;
846		stop_mpc(mpc);
847		dev_put(mpc->dev);
848	}
849
850	mpc->in_ops->destroy_cache(mpc);
851	mpc->eg_ops->destroy_cache(mpc);
852
853	while ((skb = skb_dequeue(&sk_atm(vcc)->sk_receive_queue))) {
854		atm_return(vcc, skb->truesize);
855		kfree_skb(skb);
856	}
857
858	printk("mpoa: (%s) going down\n",
859		(mpc->dev) ? mpc->dev->name : "<unknown>");
860	module_put(THIS_MODULE);
861
862	return;
863}
864
865/*
866 *
867 */
868static int msg_from_mpoad(struct atm_vcc *vcc, struct sk_buff *skb)
869{
870
871	struct mpoa_client *mpc = find_mpc_by_vcc(vcc);
872	struct k_message *mesg = (struct k_message*)skb->data;
873	atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
874
875	if (mpc == NULL) {
876		printk("mpoa: msg_from_mpoad: no mpc found\n");
877		return 0;
878	}
879	dprintk("mpoa: (%s) msg_from_mpoad:", (mpc->dev) ? mpc->dev->name : "<unknown>");
880	switch(mesg->type) {
881	case MPOA_RES_REPLY_RCVD:
882		dprintk(" mpoa_res_reply_rcvd\n");
883		MPOA_res_reply_rcvd(mesg, mpc);
884		break;
885	case MPOA_TRIGGER_RCVD:
886		dprintk(" mpoa_trigger_rcvd\n");
887		MPOA_trigger_rcvd(mesg, mpc);
888		break;
889	case INGRESS_PURGE_RCVD:
890		dprintk(" nhrp_purge_rcvd\n");
891		ingress_purge_rcvd(mesg, mpc);
892		break;
893	case EGRESS_PURGE_RCVD:
894		dprintk(" egress_purge_reply_rcvd\n");
895		egress_purge_rcvd(mesg, mpc);
896		break;
897	case MPS_DEATH:
898		dprintk(" mps_death\n");
899		mps_death(mesg, mpc);
900		break;
901	case CACHE_IMPOS_RCVD:
902		dprintk(" cache_impos_rcvd\n");
903		MPOA_cache_impos_rcvd(mesg, mpc);
904		break;
905	case SET_MPC_CTRL_ADDR:
906		dprintk(" set_mpc_ctrl_addr\n");
907		set_mpc_ctrl_addr_rcvd(mesg, mpc);
908		break;
909	case SET_MPS_MAC_ADDR:
910		dprintk(" set_mps_mac_addr\n");
911		set_mps_mac_addr_rcvd(mesg, mpc);
912		break;
913	case CLEAN_UP_AND_EXIT:
914		dprintk(" clean_up_and_exit\n");
915		clean_up(mesg, mpc, DIE);
916		break;
917	case RELOAD:
918		dprintk(" reload\n");
919		clean_up(mesg, mpc, RELOAD);
920		break;
921	case SET_MPC_PARAMS:
922		dprintk(" set_mpc_params\n");
923		mpc->parameters = mesg->content.params;
924		break;
925	default:
926		dprintk(" unknown message %d\n", mesg->type);
927		break;
928	}
929	kfree_skb(skb);
930
931	return 0;
932}
933
934/* Remember that this function may not do things that sleep */
935int msg_to_mpoad(struct k_message *mesg, struct mpoa_client *mpc)
936{
937	struct sk_buff *skb;
938	struct sock *sk;
939
940	if (mpc == NULL || !mpc->mpoad_vcc) {
941		printk("mpoa: msg_to_mpoad: mesg %d to a non-existent mpoad\n", mesg->type);
942		return -ENXIO;
943	}
944
945	skb = alloc_skb(sizeof(struct k_message), GFP_ATOMIC);
946	if (skb == NULL)
947		return -ENOMEM;
948	skb_put(skb, sizeof(struct k_message));
949	skb_copy_to_linear_data(skb, mesg, sizeof(*mesg));
950	atm_force_charge(mpc->mpoad_vcc, skb->truesize);
951
952	sk = sk_atm(mpc->mpoad_vcc);
953	skb_queue_tail(&sk->sk_receive_queue, skb);
954	sk->sk_data_ready(sk, skb->len);
955
956	return 0;
957}
958
959static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned long event, void *dev_ptr)
960{
961	struct net_device *dev;
962	struct mpoa_client *mpc;
963	struct lec_priv *priv;
964
965	dev = (struct net_device *)dev_ptr;
966
967	if (!net_eq(dev_net(dev), &init_net))
968		return NOTIFY_DONE;
969
970	if (dev->name == NULL || strncmp(dev->name, "lec", 3))
971		return NOTIFY_DONE; /* we are only interested in lec:s */
972
973	switch (event) {
974	case NETDEV_REGISTER:       /* a new lec device was allocated */
975		priv = netdev_priv(dev);
976		if (priv->lane_version < 2)
977			break;
978		priv->lane2_ops->associate_indicator = lane2_assoc_ind;
979		mpc = find_mpc_by_itfnum(priv->itfnum);
980		if (mpc == NULL) {
981			dprintk("mpoa: mpoa_event_listener: allocating new mpc for %s\n",
982			       dev->name);
983			mpc = alloc_mpc();
984			if (mpc == NULL) {
985				printk("mpoa: mpoa_event_listener: no new mpc");
986				break;
987			}
988		}
989		mpc->dev_num = priv->itfnum;
990		mpc->dev = dev;
991		dev_hold(dev);
992		dprintk("mpoa: (%s) was initialized\n", dev->name);
993		break;
994	case NETDEV_UNREGISTER:
995		/* the lec device was deallocated */
996		mpc = find_mpc_by_lec(dev);
997		if (mpc == NULL)
998			break;
999		dprintk("mpoa: device (%s) was deallocated\n", dev->name);
1000		stop_mpc(mpc);
1001		dev_put(mpc->dev);
1002		mpc->dev = NULL;
1003		break;
1004	case NETDEV_UP:
1005		/* the dev was ifconfig'ed up */
1006		mpc = find_mpc_by_lec(dev);
1007		if (mpc == NULL)
1008			break;
1009		if (mpc->mpoad_vcc != NULL) {
1010			start_mpc(mpc, dev);
1011		}
1012		break;
1013	case NETDEV_DOWN:
1014		/* the dev was ifconfig'ed down */
1015		/* this means that the flow of packets from the
1016		 * upper layer stops
1017		 */
1018		mpc = find_mpc_by_lec(dev);
1019		if (mpc == NULL)
1020			break;
1021		if (mpc->mpoad_vcc != NULL) {
1022			stop_mpc(mpc);
1023		}
1024		break;
1025	case NETDEV_REBOOT:
1026	case NETDEV_CHANGE:
1027	case NETDEV_CHANGEMTU:
1028	case NETDEV_CHANGEADDR:
1029	case NETDEV_GOING_DOWN:
1030		break;
1031	default:
1032		break;
1033	}
1034
1035	return NOTIFY_DONE;
1036}
1037
1038/*
1039 * Functions which are called after a message is received from mpcd.
1040 * Msg is reused on purpose.
1041 */
1042
1043
1044static void MPOA_trigger_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1045{
1046	__be32 dst_ip = msg->content.in_info.in_dst_ip;
1047	in_cache_entry *entry;
1048
1049	entry = mpc->in_ops->get(dst_ip, mpc);
1050	if(entry == NULL){
1051		entry = mpc->in_ops->add_entry(dst_ip, mpc);
1052		entry->entry_state = INGRESS_RESOLVING;
1053		msg->type = SND_MPOA_RES_RQST;
1054		msg->content.in_info = entry->ctrl_info;
1055		msg_to_mpoad(msg, mpc);
1056		do_gettimeofday(&(entry->reply_wait));
1057		mpc->in_ops->put(entry);
1058		return;
1059	}
1060
1061	if(entry->entry_state == INGRESS_INVALID){
1062		entry->entry_state = INGRESS_RESOLVING;
1063		msg->type = SND_MPOA_RES_RQST;
1064		msg->content.in_info = entry->ctrl_info;
1065		msg_to_mpoad(msg, mpc);
1066		do_gettimeofday(&(entry->reply_wait));
1067		mpc->in_ops->put(entry);
1068		return;
1069	}
1070
1071	printk("mpoa: (%s) MPOA_trigger_rcvd: entry already in resolving state\n",
1072		(mpc->dev) ? mpc->dev->name : "<unknown>");
1073	mpc->in_ops->put(entry);
1074	return;
1075}
1076
1077/*
1078 * Things get complicated because we have to check if there's an egress
1079 * shortcut with suitable traffic parameters we could use.
1080 */
1081static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_client *client, in_cache_entry *entry)
1082{
1083	__be32 dst_ip = msg->content.in_info.in_dst_ip;
1084	struct atm_mpoa_qos *qos = atm_mpoa_search_qos(dst_ip);
1085	eg_cache_entry *eg_entry = client->eg_ops->get_by_src_ip(dst_ip, client);
1086
1087	if(eg_entry && eg_entry->shortcut){
1088		if(eg_entry->shortcut->qos.txtp.traffic_class &
1089		   msg->qos.txtp.traffic_class &
1090		   (qos ? qos->qos.txtp.traffic_class : ATM_UBR | ATM_CBR)){
1091			    if(eg_entry->shortcut->qos.txtp.traffic_class == ATM_UBR)
1092				    entry->shortcut = eg_entry->shortcut;
1093			    else if(eg_entry->shortcut->qos.txtp.max_pcr > 0)
1094				    entry->shortcut = eg_entry->shortcut;
1095		}
1096		if(entry->shortcut){
1097			dprintk("mpoa: (%s) using egress SVC to reach %pI4\n",
1098				client->dev->name, &dst_ip);
1099			client->eg_ops->put(eg_entry);
1100			return;
1101		}
1102	}
1103	if (eg_entry != NULL)
1104		client->eg_ops->put(eg_entry);
1105
1106	/* No luck in the egress cache we must open an ingress SVC */
1107	msg->type = OPEN_INGRESS_SVC;
1108	if (qos && (qos->qos.txtp.traffic_class == msg->qos.txtp.traffic_class))
1109	{
1110		msg->qos = qos->qos;
1111		printk("mpoa: (%s) trying to get a CBR shortcut\n",client->dev->name);
1112	}
1113	else memset(&msg->qos,0,sizeof(struct atm_qos));
1114	msg_to_mpoad(msg, client);
1115	return;
1116}
1117
1118static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1119{
1120	__be32 dst_ip = msg->content.in_info.in_dst_ip;
1121	in_cache_entry *entry = mpc->in_ops->get(dst_ip, mpc);
1122
1123	dprintk("mpoa: (%s) MPOA_res_reply_rcvd: ip %pI4\n",
1124		mpc->dev->name, &dst_ip);
1125	ddprintk("mpoa: (%s) MPOA_res_reply_rcvd() entry = %p", mpc->dev->name, entry);
1126	if(entry == NULL){
1127		printk("\nmpoa: (%s) ARGH, received res. reply for an entry that doesn't exist.\n", mpc->dev->name);
1128		return;
1129	}
1130	ddprintk(" entry_state = %d ", entry->entry_state);
1131
1132	if (entry->entry_state == INGRESS_RESOLVED) {
1133		printk("\nmpoa: (%s) MPOA_res_reply_rcvd for RESOLVED entry!\n", mpc->dev->name);
1134		mpc->in_ops->put(entry);
1135		return;
1136	}
1137
1138	entry->ctrl_info = msg->content.in_info;
1139	do_gettimeofday(&(entry->tv));
1140	do_gettimeofday(&(entry->reply_wait)); /* Used in refreshing func from now on */
1141	entry->refresh_time = 0;
1142	ddprintk("entry->shortcut = %p\n", entry->shortcut);
1143
1144	if(entry->entry_state == INGRESS_RESOLVING && entry->shortcut != NULL){
1145		entry->entry_state = INGRESS_RESOLVED;
1146		mpc->in_ops->put(entry);
1147		return; /* Shortcut already open... */
1148	}
1149
1150	if (entry->shortcut != NULL) {
1151		printk("mpoa: (%s) MPOA_res_reply_rcvd: entry->shortcut != NULL, impossible!\n",
1152		       mpc->dev->name);
1153		mpc->in_ops->put(entry);
1154		return;
1155	}
1156
1157	check_qos_and_open_shortcut(msg, mpc, entry);
1158	entry->entry_state = INGRESS_RESOLVED;
1159	mpc->in_ops->put(entry);
1160
1161	return;
1162
1163}
1164
1165static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1166{
1167	__be32 dst_ip = msg->content.in_info.in_dst_ip;
1168	__be32 mask = msg->ip_mask;
1169	in_cache_entry *entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask);
1170
1171	if(entry == NULL){
1172		printk("mpoa: (%s) ingress_purge_rcvd: purge for a non-existing entry, ip = %pI4\n",
1173		       mpc->dev->name, &dst_ip);
1174		return;
1175	}
1176
1177	do {
1178		dprintk("mpoa: (%s) ingress_purge_rcvd: removing an ingress entry, ip = %pI4\n",
1179			mpc->dev->name, &dst_ip);
1180		write_lock_bh(&mpc->ingress_lock);
1181		mpc->in_ops->remove_entry(entry, mpc);
1182		write_unlock_bh(&mpc->ingress_lock);
1183		mpc->in_ops->put(entry);
1184		entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask);
1185	} while (entry != NULL);
1186
1187	return;
1188}
1189
1190static void egress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1191{
1192	__be32 cache_id = msg->content.eg_info.cache_id;
1193	eg_cache_entry *entry = mpc->eg_ops->get_by_cache_id(cache_id, mpc);
1194
1195	if (entry == NULL) {
1196		dprintk("mpoa: (%s) egress_purge_rcvd: purge for a non-existing entry\n", mpc->dev->name);
1197		return;
1198	}
1199
1200	write_lock_irq(&mpc->egress_lock);
1201	mpc->eg_ops->remove_entry(entry, mpc);
1202	write_unlock_irq(&mpc->egress_lock);
1203
1204	mpc->eg_ops->put(entry);
1205
1206	return;
1207}
1208
1209static void purge_egress_shortcut(struct atm_vcc *vcc, eg_cache_entry *entry)
1210{
1211	struct sock *sk;
1212	struct k_message *purge_msg;
1213	struct sk_buff *skb;
1214
1215	dprintk("mpoa: purge_egress_shortcut: entering\n");
1216	if (vcc == NULL) {
1217		printk("mpoa: purge_egress_shortcut: vcc == NULL\n");
1218		return;
1219	}
1220
1221	skb = alloc_skb(sizeof(struct k_message), GFP_ATOMIC);
1222	if (skb == NULL) {
1223		 printk("mpoa: purge_egress_shortcut: out of memory\n");
1224		return;
1225	}
1226
1227	skb_put(skb, sizeof(struct k_message));
1228	memset(skb->data, 0, sizeof(struct k_message));
1229	purge_msg = (struct k_message *)skb->data;
1230	purge_msg->type = DATA_PLANE_PURGE;
1231	if (entry != NULL)
1232		purge_msg->content.eg_info = entry->ctrl_info;
1233
1234	atm_force_charge(vcc, skb->truesize);
1235
1236	sk = sk_atm(vcc);
1237	skb_queue_tail(&sk->sk_receive_queue, skb);
1238	sk->sk_data_ready(sk, skb->len);
1239	dprintk("mpoa: purge_egress_shortcut: exiting:\n");
1240
1241	return;
1242}
1243
1244/*
1245 * Our MPS died. Tell our daemon to send NHRP data plane purge to each
1246 * of the egress shortcuts we have.
1247 */
1248static void mps_death( struct k_message * msg, struct mpoa_client * mpc )
1249{
1250	eg_cache_entry *entry;
1251
1252	dprintk("mpoa: (%s) mps_death:\n", mpc->dev->name);
1253
1254	if(memcmp(msg->MPS_ctrl, mpc->mps_ctrl_addr, ATM_ESA_LEN)){
1255		printk("mpoa: (%s) mps_death: wrong MPS\n", mpc->dev->name);
1256		return;
1257	}
1258
1259	/* FIXME: This knows too much of the cache structure */
1260	read_lock_irq(&mpc->egress_lock);
1261	entry = mpc->eg_cache;
1262	while (entry != NULL) {
1263		purge_egress_shortcut(entry->shortcut, entry);
1264		entry = entry->next;
1265	}
1266	read_unlock_irq(&mpc->egress_lock);
1267
1268	mpc->in_ops->destroy_cache(mpc);
1269	mpc->eg_ops->destroy_cache(mpc);
1270
1271	return;
1272}
1273
1274static void MPOA_cache_impos_rcvd( struct k_message * msg, struct mpoa_client * mpc)
1275{
1276	uint16_t holding_time;
1277	eg_cache_entry *entry = mpc->eg_ops->get_by_cache_id(msg->content.eg_info.cache_id, mpc);
1278
1279	holding_time = msg->content.eg_info.holding_time;
1280	dprintk("mpoa: (%s) MPOA_cache_impos_rcvd: entry = %p, holding_time = %u\n",
1281	       mpc->dev->name, entry, holding_time);
1282	if(entry == NULL && holding_time) {
1283		entry = mpc->eg_ops->add_entry(msg, mpc);
1284		mpc->eg_ops->put(entry);
1285		return;
1286	}
1287	if(holding_time){
1288		mpc->eg_ops->update(entry, holding_time);
1289		return;
1290	}
1291
1292	write_lock_irq(&mpc->egress_lock);
1293	mpc->eg_ops->remove_entry(entry, mpc);
1294	write_unlock_irq(&mpc->egress_lock);
1295
1296	mpc->eg_ops->put(entry);
1297
1298	return;
1299}
1300
1301static void set_mpc_ctrl_addr_rcvd(struct k_message *mesg, struct mpoa_client *mpc)
1302{
1303	struct lec_priv *priv;
1304	int i, retval ;
1305
1306	uint8_t tlv[4 + 1 + 1 + 1 + ATM_ESA_LEN];
1307
1308	tlv[0] = 00; tlv[1] = 0xa0; tlv[2] = 0x3e; tlv[3] = 0x2a; /* type  */
1309	tlv[4] = 1 + 1 + ATM_ESA_LEN;  /* length                           */
1310	tlv[5] = 0x02;                 /* MPOA client                      */
1311	tlv[6] = 0x00;                 /* number of MPS MAC addresses      */
1312
1313	memcpy(&tlv[7], mesg->MPS_ctrl, ATM_ESA_LEN); /* MPC ctrl ATM addr */
1314	memcpy(mpc->our_ctrl_addr, mesg->MPS_ctrl, ATM_ESA_LEN);
1315
1316	dprintk("mpoa: (%s) setting MPC ctrl ATM address to ",
1317	       (mpc->dev) ? mpc->dev->name : "<unknown>");
1318	for (i = 7; i < sizeof(tlv); i++)
1319		dprintk("%02x ", tlv[i]);
1320	dprintk("\n");
1321
1322	if (mpc->dev) {
1323		priv = netdev_priv(mpc->dev);
1324		retval = priv->lane2_ops->associate_req(mpc->dev, mpc->dev->dev_addr, tlv, sizeof(tlv));
1325		if (retval == 0)
1326			printk("mpoa: (%s) MPOA device type TLV association failed\n", mpc->dev->name);
1327		retval = priv->lane2_ops->resolve(mpc->dev, NULL, 1, NULL, NULL);
1328		if (retval < 0)
1329			printk("mpoa: (%s) targetless LE_ARP request failed\n", mpc->dev->name);
1330	}
1331
1332	return;
1333}
1334
1335static void set_mps_mac_addr_rcvd(struct k_message *msg, struct mpoa_client *client)
1336{
1337
1338	if(client->number_of_mps_macs)
1339		kfree(client->mps_macs);
1340	client->number_of_mps_macs = 0;
1341	client->mps_macs = kmemdup(msg->MPS_ctrl, ETH_ALEN, GFP_KERNEL);
1342	if (client->mps_macs == NULL) {
1343		printk("mpoa: set_mps_mac_addr_rcvd: out of memory\n");
1344		return;
1345	}
1346	client->number_of_mps_macs = 1;
1347
1348	return;
1349}
1350
1351/*
1352 * purge egress cache and tell daemon to 'action' (DIE, RELOAD)
1353 */
1354static void clean_up(struct k_message *msg, struct mpoa_client *mpc, int action)
1355{
1356
1357	eg_cache_entry *entry;
1358	msg->type = SND_EGRESS_PURGE;
1359
1360
1361	/* FIXME: This knows too much of the cache structure */
1362	read_lock_irq(&mpc->egress_lock);
1363	entry = mpc->eg_cache;
1364	while (entry != NULL){
1365		    msg->content.eg_info = entry->ctrl_info;
1366		    dprintk("mpoa: cache_id %u\n", entry->ctrl_info.cache_id);
1367		    msg_to_mpoad(msg, mpc);
1368		    entry = entry->next;
1369	}
1370	read_unlock_irq(&mpc->egress_lock);
1371
1372	msg->type = action;
1373	msg_to_mpoad(msg, mpc);
1374	return;
1375}
1376
1377static void mpc_timer_refresh(void)
1378{
1379	mpc_timer.expires = jiffies + (MPC_P2 * HZ);
1380	mpc_timer.data = mpc_timer.expires;
1381	mpc_timer.function = mpc_cache_check;
1382	add_timer(&mpc_timer);
1383
1384	return;
1385}
1386
1387static void mpc_cache_check( unsigned long checking_time  )
1388{
1389	struct mpoa_client *mpc = mpcs;
1390	static unsigned long previous_resolving_check_time;
1391	static unsigned long previous_refresh_time;
1392
1393	while( mpc != NULL ){
1394		mpc->in_ops->clear_count(mpc);
1395		mpc->eg_ops->clear_expired(mpc);
1396		if(checking_time - previous_resolving_check_time > mpc->parameters.mpc_p4 * HZ ){
1397			mpc->in_ops->check_resolving(mpc);
1398			previous_resolving_check_time = checking_time;
1399		}
1400		if(checking_time - previous_refresh_time > mpc->parameters.mpc_p5 * HZ ){
1401			mpc->in_ops->refresh(mpc);
1402			previous_refresh_time = checking_time;
1403		}
1404		mpc = mpc->next;
1405	}
1406	mpc_timer_refresh();
1407
1408	return;
1409}
1410
1411static int atm_mpoa_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1412{
1413	int err = 0;
1414	struct atm_vcc *vcc = ATM_SD(sock);
1415
1416	if (cmd != ATMMPC_CTRL && cmd != ATMMPC_DATA)
1417		return -ENOIOCTLCMD;
1418
1419	if (!capable(CAP_NET_ADMIN))
1420		return -EPERM;
1421
1422	switch (cmd) {
1423		case ATMMPC_CTRL:
1424			err = atm_mpoa_mpoad_attach(vcc, (int)arg);
1425			if (err >= 0)
1426				sock->state = SS_CONNECTED;
1427			break;
1428		case ATMMPC_DATA:
1429			err = atm_mpoa_vcc_attach(vcc, (void __user *)arg);
1430			break;
1431		default:
1432			break;
1433	}
1434	return err;
1435}
1436
1437
1438static struct atm_ioctl atm_ioctl_ops = {
1439	.owner	= THIS_MODULE,
1440	.ioctl	= atm_mpoa_ioctl,
1441};
1442
1443static __init int atm_mpoa_init(void)
1444{
1445	register_atm_ioctl(&atm_ioctl_ops);
1446
1447	if (mpc_proc_init() != 0)
1448		printk(KERN_INFO "mpoa: failed to initialize /proc/mpoa\n");
1449
1450	printk("mpc.c: " __DATE__ " " __TIME__ " initialized\n");
1451
1452	return 0;
1453}
1454
1455static void __exit atm_mpoa_cleanup(void)
1456{
1457	struct mpoa_client *mpc, *tmp;
1458	struct atm_mpoa_qos *qos, *nextqos;
1459	struct lec_priv *priv;
1460
1461	mpc_proc_clean();
1462
1463	del_timer(&mpc_timer);
1464	unregister_netdevice_notifier(&mpoa_notifier);
1465	deregister_atm_ioctl(&atm_ioctl_ops);
1466
1467	mpc = mpcs;
1468	mpcs = NULL;
1469	while (mpc != NULL) {
1470		tmp = mpc->next;
1471		if (mpc->dev != NULL) {
1472			stop_mpc(mpc);
1473			priv = netdev_priv(mpc->dev);
1474			if (priv->lane2_ops != NULL)
1475				priv->lane2_ops->associate_indicator = NULL;
1476		}
1477		ddprintk("mpoa: cleanup_module: about to clear caches\n");
1478		mpc->in_ops->destroy_cache(mpc);
1479		mpc->eg_ops->destroy_cache(mpc);
1480		ddprintk("mpoa: cleanup_module: caches cleared\n");
1481		kfree(mpc->mps_macs);
1482		memset(mpc, 0, sizeof(struct mpoa_client));
1483		ddprintk("mpoa: cleanup_module: about to kfree %p\n", mpc);
1484		kfree(mpc);
1485		ddprintk("mpoa: cleanup_module: next mpc is at %p\n", tmp);
1486		mpc = tmp;
1487	}
1488
1489	qos = qos_head;
1490	qos_head = NULL;
1491	while (qos != NULL) {
1492		nextqos = qos->next;
1493		dprintk("mpoa: cleanup_module: freeing qos entry %p\n", qos);
1494		kfree(qos);
1495		qos = nextqos;
1496	}
1497
1498	return;
1499}
1500
1501module_init(atm_mpoa_init);
1502module_exit(atm_mpoa_cleanup);
1503
1504MODULE_LICENSE("GPL");
1505