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