1 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
3 #include <linux/kernel.h>
4 #include <linux/string.h>
5 #include <linux/slab.h>
6 #include <linux/timer.h>
7 #include <linux/init.h>
8 #include <linux/bitops.h>
9 #include <linux/capability.h>
10 #include <linux/seq_file.h>
12 /* We are an ethernet device */
13 #include <linux/if_ether.h>
14 #include <linux/netdevice.h>
15 #include <linux/etherdevice.h>
17 #include <linux/skbuff.h>
19 #include <linux/uaccess.h>
20 #include <asm/byteorder.h>
21 #include <net/checksum.h> /* for ip_fast_csum() */
24 #include <linux/proc_fs.h>
27 #include <linux/atmdev.h>
28 #include <linux/atmlec.h>
29 #include <linux/atmmpc.h>
31 #include <linux/module.h>
35 #include "resources.h"
38 * mpc.c: Implementation of MPOA client kernel part
42 #define dprintk(format, args...) \
43 printk(KERN_DEBUG "mpoa:%s: " format, __func__, ##args)
44 #define dprintk_cont(format, args...) printk(KERN_CONT format, ##args)
46 #define dprintk(format, args...) \
48 printk(KERN_DEBUG "mpoa:%s: " format, __func__, ##args);\
50 #define dprintk_cont(format, args...) \
51 do { if (0) printk(KERN_CONT format, ##args); } while (0)
55 #define ddprintk(format, args...) \
56 printk(KERN_DEBUG "mpoa:%s: " format, __func__, ##args)
57 #define ddprintk_cont(format, args...) printk(KERN_CONT format, ##args)
59 #define ddprintk(format, args...) \
61 printk(KERN_DEBUG "mpoa:%s: " format, __func__, ##args);\
63 #define ddprintk_cont(format, args...) \
64 do { if (0) printk(KERN_CONT format, ##args); } while (0)
67 #define MPOA_TAG_LEN 4
69 /* mpc_daemon -> kernel */
70 static void MPOA_trigger_rcvd(struct k_message
*msg
, struct mpoa_client
*mpc
);
71 static void MPOA_res_reply_rcvd(struct k_message
*msg
, struct mpoa_client
*mpc
);
72 static void ingress_purge_rcvd(struct k_message
*msg
, struct mpoa_client
*mpc
);
73 static void egress_purge_rcvd(struct k_message
*msg
, struct mpoa_client
*mpc
);
74 static void mps_death(struct k_message
*msg
, struct mpoa_client
*mpc
);
75 static void clean_up(struct k_message
*msg
, struct mpoa_client
*mpc
,
77 static void MPOA_cache_impos_rcvd(struct k_message
*msg
,
78 struct mpoa_client
*mpc
);
79 static void set_mpc_ctrl_addr_rcvd(struct k_message
*mesg
,
80 struct mpoa_client
*mpc
);
81 static void set_mps_mac_addr_rcvd(struct k_message
*mesg
,
82 struct mpoa_client
*mpc
);
84 static const uint8_t *copy_macs(struct mpoa_client
*mpc
,
85 const uint8_t *router_mac
,
86 const uint8_t *tlvs
, uint8_t mps_macs
,
88 static void purge_egress_shortcut(struct atm_vcc
*vcc
, eg_cache_entry
*entry
);
90 static void send_set_mps_ctrl_addr(const char *addr
, struct mpoa_client
*mpc
);
91 static void mpoad_close(struct atm_vcc
*vcc
);
92 static int msg_from_mpoad(struct atm_vcc
*vcc
, struct sk_buff
*skb
);
94 static void mpc_push(struct atm_vcc
*vcc
, struct sk_buff
*skb
);
95 static netdev_tx_t
mpc_send_packet(struct sk_buff
*skb
,
96 struct net_device
*dev
);
97 static int mpoa_event_listener(struct notifier_block
*mpoa_notifier
,
98 unsigned long event
, void *dev
);
99 static void mpc_timer_refresh(void);
100 static void mpc_cache_check(unsigned long checking_time
);
102 static struct llc_snap_hdr llc_snap_mpoa_ctrl
= {
105 {0x00, 0x03} /* For MPOA control PDUs */
107 static struct llc_snap_hdr llc_snap_mpoa_data
= {
110 {0x08, 0x00} /* This is for IP PDUs only */
112 static struct llc_snap_hdr llc_snap_mpoa_data_tagged
= {
115 {0x88, 0x4c} /* This is for tagged data PDUs */
118 static struct notifier_block mpoa_notifier
= {
124 struct mpoa_client
*mpcs
= NULL
; /* FIXME */
125 static struct atm_mpoa_qos
*qos_head
= NULL
;
126 static DEFINE_TIMER(mpc_timer
, NULL
, 0, 0);
129 static struct mpoa_client
*find_mpc_by_itfnum(int itf
)
131 struct mpoa_client
*mpc
;
133 mpc
= mpcs
; /* our global linked list */
134 while (mpc
!= NULL
) {
135 if (mpc
->dev_num
== itf
)
140 return NULL
; /* not found */
143 static struct mpoa_client
*find_mpc_by_vcc(struct atm_vcc
*vcc
)
145 struct mpoa_client
*mpc
;
147 mpc
= mpcs
; /* our global linked list */
148 while (mpc
!= NULL
) {
149 if (mpc
->mpoad_vcc
== vcc
)
154 return NULL
; /* not found */
157 static struct mpoa_client
*find_mpc_by_lec(struct net_device
*dev
)
159 struct mpoa_client
*mpc
;
161 mpc
= mpcs
; /* our global linked list */
162 while (mpc
!= NULL
) {
168 return NULL
; /* not found */
172 * Functions for managing QoS list
176 * Overwrites the old entry or makes a new one.
178 struct atm_mpoa_qos
*atm_mpoa_add_qos(__be32 dst_ip
, struct atm_qos
*qos
)
180 struct atm_mpoa_qos
*entry
;
182 entry
= atm_mpoa_search_qos(dst_ip
);
188 entry
= kmalloc(sizeof(struct atm_mpoa_qos
), GFP_KERNEL
);
190 pr_info("mpoa: out of memory\n");
194 entry
->ipaddr
= dst_ip
;
197 entry
->next
= qos_head
;
203 struct atm_mpoa_qos
*atm_mpoa_search_qos(__be32 dst_ip
)
205 struct atm_mpoa_qos
*qos
;
209 if (qos
->ipaddr
== dst_ip
)
218 * Returns 0 for failure
220 int atm_mpoa_delete_qos(struct atm_mpoa_qos
*entry
)
222 struct atm_mpoa_qos
*curr
;
226 if (entry
== qos_head
) {
227 qos_head
= qos_head
->next
;
233 while (curr
!= NULL
) {
234 if (curr
->next
== entry
) {
235 curr
->next
= entry
->next
;
245 /* this is buggered - we need locking for qos_head */
246 void atm_mpoa_disp_qos(struct seq_file
*m
)
248 struct atm_mpoa_qos
*qos
;
251 seq_printf(m
, "QoS entries for shortcuts:\n");
252 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");
254 while (qos
!= NULL
) {
255 seq_printf(m
, "%pI4\n %-7d %-7d %-7d %-7d %-7d\n %-7d %-7d %-7d %-7d %-7d\n",
257 qos
->qos
.txtp
.max_pcr
,
259 qos
->qos
.txtp
.min_pcr
,
260 qos
->qos
.txtp
.max_cdv
,
261 qos
->qos
.txtp
.max_sdu
,
262 qos
->qos
.rxtp
.max_pcr
,
264 qos
->qos
.rxtp
.min_pcr
,
265 qos
->qos
.rxtp
.max_cdv
,
266 qos
->qos
.rxtp
.max_sdu
);
271 static struct net_device
*find_lec_by_itfnum(int itf
)
273 struct net_device
*dev
;
276 sprintf(name
, "lec%d", itf
);
277 dev
= dev_get_by_name(&init_net
, name
);
282 static struct mpoa_client
*alloc_mpc(void)
284 struct mpoa_client
*mpc
;
286 mpc
= kzalloc(sizeof(struct mpoa_client
), GFP_KERNEL
);
289 rwlock_init(&mpc
->ingress_lock
);
290 rwlock_init(&mpc
->egress_lock
);
292 atm_mpoa_init_cache(mpc
);
294 mpc
->parameters
.mpc_p1
= MPC_P1
;
295 mpc
->parameters
.mpc_p2
= MPC_P2
;
296 memset(mpc
->parameters
.mpc_p3
, 0, sizeof(mpc
->parameters
.mpc_p3
));
297 mpc
->parameters
.mpc_p4
= MPC_P4
;
298 mpc
->parameters
.mpc_p5
= MPC_P5
;
299 mpc
->parameters
.mpc_p6
= MPC_P6
;
308 * start_mpc() puts the MPC on line. All the packets destined
309 * to the lec underneath us are now being monitored and
310 * shortcuts will be established.
313 static void start_mpc(struct mpoa_client
*mpc
, struct net_device
*dev
)
316 dprintk("(%s)\n", mpc
->dev
->name
);
317 if (!dev
->netdev_ops
)
318 pr_info("(%s) not starting\n", dev
->name
);
320 mpc
->old_ops
= dev
->netdev_ops
;
321 mpc
->new_ops
= *mpc
->old_ops
;
322 mpc
->new_ops
.ndo_start_xmit
= mpc_send_packet
;
323 dev
->netdev_ops
= &mpc
->new_ops
;
327 static void stop_mpc(struct mpoa_client
*mpc
)
329 struct net_device
*dev
= mpc
->dev
;
330 dprintk("(%s)", mpc
->dev
->name
);
332 /* Lets not nullify lec device's dev->hard_start_xmit */
333 if (dev
->netdev_ops
!= &mpc
->new_ops
) {
334 dprintk_cont(" mpc already stopped, not fatal\n");
339 dev
->netdev_ops
= mpc
->old_ops
;
342 /* close_shortcuts(mpc); ??? FIXME */
345 static const char *mpoa_device_type_string(char type
) __attribute__ ((unused
));
347 static const char *mpoa_device_type_string(char type
)
351 return "non-MPOA device";
357 return "both MPS and MPC";
360 return "unspecified (non-MPOA) device";
364 * lec device calls this via its netdev_priv(dev)->lane2_ops
365 * ->associate_indicator() when it sees a TLV in LE_ARP packet.
366 * We fill in the pointer above when we see a LANE2 lec initializing
367 * See LANE2 spec 3.1.5
369 * Quite a big and ugly function but when you look at it
370 * all it does is to try to locate and parse MPOA Device
372 * We give our lec a pointer to this function and when the
373 * lec sees a TLV it uses the pointer to call this function.
376 static void lane2_assoc_ind(struct net_device
*dev
, const u8
*mac_addr
,
377 const u8
*tlvs
, u32 sizeoftlvs
)
380 uint8_t length
, mpoa_device_type
, number_of_mps_macs
;
381 const uint8_t *end_of_tlvs
;
382 struct mpoa_client
*mpc
;
384 mpoa_device_type
= number_of_mps_macs
= 0; /* silence gcc */
385 dprintk("(%s) received TLV(s), ", dev
->name
);
386 dprintk("total length of all TLVs %d\n", sizeoftlvs
);
387 mpc
= find_mpc_by_lec(dev
); /* Sampo-Fix: moved here from below */
389 pr_info("(%s) no mpc\n", dev
->name
);
392 end_of_tlvs
= tlvs
+ sizeoftlvs
;
393 while (end_of_tlvs
- tlvs
>= 5) {
394 type
= ((tlvs
[0] << 24) | (tlvs
[1] << 16) |
395 (tlvs
[2] << 8) | tlvs
[3]);
398 dprintk(" type 0x%x length %02x\n", type
, length
);
399 if (tlvs
+ length
> end_of_tlvs
) {
400 pr_info("TLV value extends past its buffer, aborting parse\n");
405 pr_info("mpoa: (%s) TLV type was 0, returning\n",
410 if (type
!= TLV_MPOA_DEVICE_TYPE
) {
412 continue; /* skip other TLVs */
414 mpoa_device_type
= *tlvs
++;
415 number_of_mps_macs
= *tlvs
++;
416 dprintk("(%s) MPOA device type '%s', ",
417 dev
->name
, mpoa_device_type_string(mpoa_device_type
));
418 if (mpoa_device_type
== MPS_AND_MPC
&&
419 length
< (42 + number_of_mps_macs
*ETH_ALEN
)) { /* :) */
420 pr_info("(%s) short MPOA Device Type TLV\n",
424 if ((mpoa_device_type
== MPS
|| mpoa_device_type
== MPC
) &&
425 length
< 22 + number_of_mps_macs
*ETH_ALEN
) {
426 pr_info("(%s) short MPOA Device Type TLV\n", dev
->name
);
429 if (mpoa_device_type
!= MPS
&&
430 mpoa_device_type
!= MPS_AND_MPC
) {
431 dprintk("ignoring non-MPS device ");
432 if (mpoa_device_type
== MPC
)
434 continue; /* we are only interested in MPSs */
436 if (number_of_mps_macs
== 0 &&
437 mpoa_device_type
== MPS_AND_MPC
) {
438 pr_info("(%s) MPS_AND_MPC has zero MACs\n", dev
->name
);
439 continue; /* someone should read the spec */
441 dprintk_cont("this MPS has %d MAC addresses\n",
445 * ok, now we can go and tell our daemon
446 * the control address of MPS
448 send_set_mps_ctrl_addr(tlvs
, mpc
);
450 tlvs
= copy_macs(mpc
, mac_addr
, tlvs
,
451 number_of_mps_macs
, mpoa_device_type
);
455 if (end_of_tlvs
- tlvs
!= 0)
456 pr_info("(%s) ignoring %Zd bytes of trailing TLV garbage\n",
457 dev
->name
, end_of_tlvs
- tlvs
);
461 * Store at least advertizing router's MAC address
462 * plus the possible MAC address(es) to mpc->mps_macs.
463 * For a freshly allocated MPOA client mpc->mps_macs == 0.
465 static const uint8_t *copy_macs(struct mpoa_client
*mpc
,
466 const uint8_t *router_mac
,
467 const uint8_t *tlvs
, uint8_t mps_macs
,
471 num_macs
= (mps_macs
> 1) ? mps_macs
: 1;
473 if (mpc
->number_of_mps_macs
!= num_macs
) { /* need to reallocate? */
474 if (mpc
->number_of_mps_macs
!= 0)
475 kfree(mpc
->mps_macs
);
476 mpc
->number_of_mps_macs
= 0;
477 mpc
->mps_macs
= kmalloc(num_macs
* ETH_ALEN
, GFP_KERNEL
);
478 if (mpc
->mps_macs
== NULL
) {
479 pr_info("(%s) out of mem\n", mpc
->dev
->name
);
483 memcpy(mpc
->mps_macs
, router_mac
, ETH_ALEN
);
484 tlvs
+= 20; if (device_type
== MPS_AND_MPC
) tlvs
+= 20;
486 memcpy(mpc
->mps_macs
, tlvs
, mps_macs
*ETH_ALEN
);
487 tlvs
+= mps_macs
*ETH_ALEN
;
488 mpc
->number_of_mps_macs
= num_macs
;
493 static int send_via_shortcut(struct sk_buff
*skb
, struct mpoa_client
*mpc
)
495 in_cache_entry
*entry
;
501 struct llc_snap_hdr hdr
;
503 } tagged_llc_snap_hdr
= {
504 {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}, {0x88, 0x4c}},
508 buff
= skb
->data
+ mpc
->dev
->hard_header_len
;
509 iph
= (struct iphdr
*)buff
;
512 ddprintk("(%s) ipaddr 0x%x\n",
513 mpc
->dev
->name
, ipaddr
);
515 entry
= mpc
->in_ops
->get(ipaddr
, mpc
);
517 entry
= mpc
->in_ops
->add_entry(ipaddr
, mpc
);
519 mpc
->in_ops
->put(entry
);
522 /* threshold not exceeded or VCC not ready */
523 if (mpc
->in_ops
->cache_hit(entry
, mpc
) != OPEN
) {
524 ddprintk("(%s) cache_hit: returns != OPEN\n",
526 mpc
->in_ops
->put(entry
);
530 ddprintk("(%s) using shortcut\n",
532 /* MPOA spec A.1.4, MPOA client must decrement IP ttl at least by one */
534 ddprintk("(%s) IP ttl = %u, using LANE\n",
535 mpc
->dev
->name
, iph
->ttl
);
536 mpc
->in_ops
->put(entry
);
541 iph
->check
= ip_fast_csum((unsigned char *)iph
, iph
->ihl
);
543 if (entry
->ctrl_info
.tag
!= 0) {
544 ddprintk("(%s) adding tag 0x%x\n",
545 mpc
->dev
->name
, entry
->ctrl_info
.tag
);
546 tagged_llc_snap_hdr
.tag
= entry
->ctrl_info
.tag
;
547 skb_pull(skb
, ETH_HLEN
); /* get rid of Eth header */
548 skb_push(skb
, sizeof(tagged_llc_snap_hdr
));
549 /* add LLC/SNAP header */
550 skb_copy_to_linear_data(skb
, &tagged_llc_snap_hdr
,
551 sizeof(tagged_llc_snap_hdr
));
553 skb_pull(skb
, ETH_HLEN
); /* get rid of Eth header */
554 skb_push(skb
, sizeof(struct llc_snap_hdr
));
555 /* add LLC/SNAP header + tag */
556 skb_copy_to_linear_data(skb
, &llc_snap_mpoa_data
,
557 sizeof(struct llc_snap_hdr
));
560 atomic_add(skb
->truesize
, &sk_atm(entry
->shortcut
)->sk_wmem_alloc
);
561 ATM_SKB(skb
)->atm_options
= entry
->shortcut
->atm_options
;
562 entry
->shortcut
->send(entry
->shortcut
, skb
);
563 entry
->packets_fwded
++;
564 mpc
->in_ops
->put(entry
);
570 * Probably needs some error checks and locking, not sure...
572 static netdev_tx_t
mpc_send_packet(struct sk_buff
*skb
,
573 struct net_device
*dev
)
575 struct mpoa_client
*mpc
;
579 mpc
= find_mpc_by_lec(dev
); /* this should NEVER fail */
581 pr_info("(%s) no MPC found\n", dev
->name
);
585 eth
= (struct ethhdr
*)skb
->data
;
586 if (eth
->h_proto
!= htons(ETH_P_IP
))
587 goto non_ip
; /* Multi-Protocol Over ATM :-) */
589 /* Weed out funny packets (e.g., AF_PACKET or raw). */
590 if (skb
->len
< ETH_HLEN
+ sizeof(struct iphdr
))
592 skb_set_network_header(skb
, ETH_HLEN
);
593 if (skb
->len
< ETH_HLEN
+ ip_hdr(skb
)->ihl
* 4 || ip_hdr(skb
)->ihl
< 5)
596 while (i
< mpc
->number_of_mps_macs
) {
597 if (!compare_ether_addr(eth
->h_dest
,
598 (mpc
->mps_macs
+ i
*ETH_ALEN
)))
599 if (send_via_shortcut(skb
, mpc
) == 0) /* try shortcut */
605 return mpc
->old_ops
->ndo_start_xmit(skb
, dev
);
608 static int atm_mpoa_vcc_attach(struct atm_vcc
*vcc
, void __user
*arg
)
611 struct mpoa_client
*mpc
;
612 struct atmmpc_ioc ioc_data
;
613 in_cache_entry
*in_entry
;
616 bytes_left
= copy_from_user(&ioc_data
, arg
, sizeof(struct atmmpc_ioc
));
617 if (bytes_left
!= 0) {
618 pr_info("mpoa:Short read (missed %d bytes) from userland\n",
622 ipaddr
= ioc_data
.ipaddr
;
623 if (ioc_data
.dev_num
< 0 || ioc_data
.dev_num
>= MAX_LEC_ITF
)
626 mpc
= find_mpc_by_itfnum(ioc_data
.dev_num
);
630 if (ioc_data
.type
== MPC_SOCKET_INGRESS
) {
631 in_entry
= mpc
->in_ops
->get(ipaddr
, mpc
);
632 if (in_entry
== NULL
||
633 in_entry
->entry_state
< INGRESS_RESOLVED
) {
634 pr_info("(%s) did not find RESOLVED entry from ingress cache\n",
636 if (in_entry
!= NULL
)
637 mpc
->in_ops
->put(in_entry
);
640 pr_info("(%s) attaching ingress SVC, entry = %pI4\n",
641 mpc
->dev
->name
, &in_entry
->ctrl_info
.in_dst_ip
);
642 in_entry
->shortcut
= vcc
;
643 mpc
->in_ops
->put(in_entry
);
645 pr_info("(%s) attaching egress SVC\n", mpc
->dev
->name
);
648 vcc
->proto_data
= mpc
->dev
;
649 vcc
->push
= mpc_push
;
657 static void mpc_vcc_close(struct atm_vcc
*vcc
, struct net_device
*dev
)
659 struct mpoa_client
*mpc
;
660 in_cache_entry
*in_entry
;
661 eg_cache_entry
*eg_entry
;
663 mpc
= find_mpc_by_lec(dev
);
665 pr_info("(%s) close for unknown MPC\n", dev
->name
);
669 dprintk("(%s)\n", dev
->name
);
670 in_entry
= mpc
->in_ops
->get_by_vcc(vcc
, mpc
);
672 dprintk("(%s) ingress SVC closed ip = %pI4\n",
673 mpc
->dev
->name
, &in_entry
->ctrl_info
.in_dst_ip
);
674 in_entry
->shortcut
= NULL
;
675 mpc
->in_ops
->put(in_entry
);
677 eg_entry
= mpc
->eg_ops
->get_by_vcc(vcc
, mpc
);
679 dprintk("(%s) egress SVC closed\n", mpc
->dev
->name
);
680 eg_entry
->shortcut
= NULL
;
681 mpc
->eg_ops
->put(eg_entry
);
684 if (in_entry
== NULL
&& eg_entry
== NULL
)
685 dprintk("(%s) unused vcc closed\n", dev
->name
);
688 static void mpc_push(struct atm_vcc
*vcc
, struct sk_buff
*skb
)
690 struct net_device
*dev
= (struct net_device
*)vcc
->proto_data
;
691 struct sk_buff
*new_skb
;
693 struct mpoa_client
*mpc
;
697 ddprintk("(%s)\n", dev
->name
);
699 dprintk("(%s) null skb, closing VCC\n", dev
->name
);
700 mpc_vcc_close(vcc
, dev
);
705 if (memcmp(skb
->data
, &llc_snap_mpoa_ctrl
,
706 sizeof(struct llc_snap_hdr
)) == 0) {
707 struct sock
*sk
= sk_atm(vcc
);
709 dprintk("(%s) control packet arrived\n", dev
->name
);
710 /* Pass control packets to daemon */
711 skb_queue_tail(&sk
->sk_receive_queue
, skb
);
712 sk
->sk_data_ready(sk
, skb
->len
);
716 /* data coming over the shortcut */
717 atm_return(vcc
, skb
->truesize
);
719 mpc
= find_mpc_by_lec(dev
);
721 pr_info("(%s) unknown MPC\n", dev
->name
);
725 if (memcmp(skb
->data
, &llc_snap_mpoa_data_tagged
,
726 sizeof(struct llc_snap_hdr
)) == 0) { /* MPOA tagged data */
727 ddprintk("(%s) tagged data packet arrived\n", dev
->name
);
729 } else if (memcmp(skb
->data
, &llc_snap_mpoa_data
,
730 sizeof(struct llc_snap_hdr
)) == 0) { /* MPOA data */
731 pr_info("(%s) Unsupported non-tagged data packet arrived. Purging\n",
733 dev_kfree_skb_any(skb
);
736 pr_info("(%s) garbage arrived, purging\n", dev
->name
);
737 dev_kfree_skb_any(skb
);
741 tmp
= skb
->data
+ sizeof(struct llc_snap_hdr
);
742 tag
= *(__be32
*)tmp
;
744 eg
= mpc
->eg_ops
->get_by_tag(tag
, mpc
);
746 pr_info("mpoa: (%s) Didn't find egress cache entry, tag = %u\n",
748 purge_egress_shortcut(vcc
, NULL
);
749 dev_kfree_skb_any(skb
);
754 * See if ingress MPC is using shortcut we opened as a return channel.
755 * This means we have a bi-directional vcc opened by us.
757 if (eg
->shortcut
== NULL
) {
759 pr_info("(%s) egress SVC in use\n", dev
->name
);
762 skb_pull(skb
, sizeof(struct llc_snap_hdr
) + sizeof(tag
));
763 /* get rid of LLC/SNAP header */
764 new_skb
= skb_realloc_headroom(skb
, eg
->ctrl_info
.DH_length
);
765 /* LLC/SNAP is shorter than MAC header :( */
766 dev_kfree_skb_any(skb
);
767 if (new_skb
== NULL
) {
768 mpc
->eg_ops
->put(eg
);
771 skb_push(new_skb
, eg
->ctrl_info
.DH_length
); /* add MAC header */
772 skb_copy_to_linear_data(new_skb
, eg
->ctrl_info
.DLL_header
,
773 eg
->ctrl_info
.DH_length
);
774 new_skb
->protocol
= eth_type_trans(new_skb
, dev
);
775 skb_reset_network_header(new_skb
);
777 eg
->latest_ip_addr
= ip_hdr(new_skb
)->saddr
;
779 mpc
->eg_ops
->put(eg
);
781 memset(ATM_SKB(new_skb
), 0, sizeof(struct atm_skb_data
));
785 static struct atmdev_ops mpc_ops
= { /* only send is required */
786 .close
= mpoad_close
,
787 .send
= msg_from_mpoad
790 static struct atm_dev mpc_dev
= {
794 .lock
= __SPIN_LOCK_UNLOCKED(mpc_dev
.lock
)
795 /* members not explicitly initialised will be 0 */
798 static int atm_mpoa_mpoad_attach(struct atm_vcc
*vcc
, int arg
)
800 struct mpoa_client
*mpc
;
801 struct lec_priv
*priv
;
805 init_timer(&mpc_timer
);
808 /* This lets us now how our LECs are doing */
809 err
= register_netdevice_notifier(&mpoa_notifier
);
811 del_timer(&mpc_timer
);
816 mpc
= find_mpc_by_itfnum(arg
);
818 dprintk("allocating new mpc for itf %d\n", arg
);
823 mpc
->dev
= find_lec_by_itfnum(arg
);
824 /* NULL if there was no lec */
826 if (mpc
->mpoad_vcc
) {
827 pr_info("mpoad is already present for itf %d\n", arg
);
831 if (mpc
->dev
) { /* check if the lec is LANE2 capable */
832 priv
= netdev_priv(mpc
->dev
);
833 if (priv
->lane_version
< 2) {
837 priv
->lane2_ops
->associate_indicator
= lane2_assoc_ind
;
840 mpc
->mpoad_vcc
= vcc
;
842 vcc_insert_socket(sk_atm(vcc
));
843 set_bit(ATM_VF_META
, &vcc
->flags
);
844 set_bit(ATM_VF_READY
, &vcc
->flags
);
847 char empty
[ATM_ESA_LEN
];
848 memset(empty
, 0, ATM_ESA_LEN
);
850 start_mpc(mpc
, mpc
->dev
);
851 /* set address if mpcd e.g. gets killed and restarted.
852 * If we do not do it now we have to wait for the next LE_ARP
854 if (memcmp(mpc
->mps_ctrl_addr
, empty
, ATM_ESA_LEN
) != 0)
855 send_set_mps_ctrl_addr(mpc
->mps_ctrl_addr
, mpc
);
858 __module_get(THIS_MODULE
);
862 static void send_set_mps_ctrl_addr(const char *addr
, struct mpoa_client
*mpc
)
864 struct k_message mesg
;
866 memcpy(mpc
->mps_ctrl_addr
, addr
, ATM_ESA_LEN
);
868 mesg
.type
= SET_MPS_CTRL_ADDR
;
869 memcpy(mesg
.MPS_ctrl
, addr
, ATM_ESA_LEN
);
870 msg_to_mpoad(&mesg
, mpc
);
873 static void mpoad_close(struct atm_vcc
*vcc
)
875 struct mpoa_client
*mpc
;
878 mpc
= find_mpc_by_vcc(vcc
);
880 pr_info("did not find MPC\n");
883 if (!mpc
->mpoad_vcc
) {
884 pr_info("close for non-present mpoad\n");
888 mpc
->mpoad_vcc
= NULL
;
890 struct lec_priv
*priv
= netdev_priv(mpc
->dev
);
891 priv
->lane2_ops
->associate_indicator
= NULL
;
896 mpc
->in_ops
->destroy_cache(mpc
);
897 mpc
->eg_ops
->destroy_cache(mpc
);
899 while ((skb
= skb_dequeue(&sk_atm(vcc
)->sk_receive_queue
))) {
900 atm_return(vcc
, skb
->truesize
);
904 pr_info("(%s) going down\n",
905 (mpc
->dev
) ? mpc
->dev
->name
: "<unknown>");
906 module_put(THIS_MODULE
);
912 static int msg_from_mpoad(struct atm_vcc
*vcc
, struct sk_buff
*skb
)
915 struct mpoa_client
*mpc
= find_mpc_by_vcc(vcc
);
916 struct k_message
*mesg
= (struct k_message
*)skb
->data
;
917 atomic_sub(skb
->truesize
, &sk_atm(vcc
)->sk_wmem_alloc
);
920 pr_info("no mpc found\n");
923 dprintk("(%s)", mpc
->dev
? mpc
->dev
->name
: "<unknown>");
924 switch (mesg
->type
) {
925 case MPOA_RES_REPLY_RCVD
:
926 dprintk_cont("mpoa_res_reply_rcvd\n");
927 MPOA_res_reply_rcvd(mesg
, mpc
);
929 case MPOA_TRIGGER_RCVD
:
930 dprintk_cont("mpoa_trigger_rcvd\n");
931 MPOA_trigger_rcvd(mesg
, mpc
);
933 case INGRESS_PURGE_RCVD
:
934 dprintk_cont("nhrp_purge_rcvd\n");
935 ingress_purge_rcvd(mesg
, mpc
);
937 case EGRESS_PURGE_RCVD
:
938 dprintk_cont("egress_purge_reply_rcvd\n");
939 egress_purge_rcvd(mesg
, mpc
);
942 dprintk_cont("mps_death\n");
943 mps_death(mesg
, mpc
);
945 case CACHE_IMPOS_RCVD
:
946 dprintk_cont("cache_impos_rcvd\n");
947 MPOA_cache_impos_rcvd(mesg
, mpc
);
949 case SET_MPC_CTRL_ADDR
:
950 dprintk_cont("set_mpc_ctrl_addr\n");
951 set_mpc_ctrl_addr_rcvd(mesg
, mpc
);
953 case SET_MPS_MAC_ADDR
:
954 dprintk_cont("set_mps_mac_addr\n");
955 set_mps_mac_addr_rcvd(mesg
, mpc
);
957 case CLEAN_UP_AND_EXIT
:
958 dprintk_cont("clean_up_and_exit\n");
959 clean_up(mesg
, mpc
, DIE
);
962 dprintk_cont("reload\n");
963 clean_up(mesg
, mpc
, RELOAD
);
966 dprintk_cont("set_mpc_params\n");
967 mpc
->parameters
= mesg
->content
.params
;
970 dprintk_cont("unknown message %d\n", mesg
->type
);
978 /* Remember that this function may not do things that sleep */
979 int msg_to_mpoad(struct k_message
*mesg
, struct mpoa_client
*mpc
)
984 if (mpc
== NULL
|| !mpc
->mpoad_vcc
) {
985 pr_info("mesg %d to a non-existent mpoad\n", mesg
->type
);
989 skb
= alloc_skb(sizeof(struct k_message
), GFP_ATOMIC
);
992 skb_put(skb
, sizeof(struct k_message
));
993 skb_copy_to_linear_data(skb
, mesg
, sizeof(*mesg
));
994 atm_force_charge(mpc
->mpoad_vcc
, skb
->truesize
);
996 sk
= sk_atm(mpc
->mpoad_vcc
);
997 skb_queue_tail(&sk
->sk_receive_queue
, skb
);
998 sk
->sk_data_ready(sk
, skb
->len
);
1003 static int mpoa_event_listener(struct notifier_block
*mpoa_notifier
,
1004 unsigned long event
, void *dev_ptr
)
1006 struct net_device
*dev
;
1007 struct mpoa_client
*mpc
;
1008 struct lec_priv
*priv
;
1010 dev
= (struct net_device
*)dev_ptr
;
1012 if (!net_eq(dev_net(dev
), &init_net
))
1015 if (dev
->name
== NULL
|| strncmp(dev
->name
, "lec", 3))
1016 return NOTIFY_DONE
; /* we are only interested in lec:s */
1019 case NETDEV_REGISTER
: /* a new lec device was allocated */
1020 priv
= netdev_priv(dev
);
1021 if (priv
->lane_version
< 2)
1023 priv
->lane2_ops
->associate_indicator
= lane2_assoc_ind
;
1024 mpc
= find_mpc_by_itfnum(priv
->itfnum
);
1026 dprintk("allocating new mpc for %s\n", dev
->name
);
1029 pr_info("no new mpc");
1033 mpc
->dev_num
= priv
->itfnum
;
1036 dprintk("(%s) was initialized\n", dev
->name
);
1038 case NETDEV_UNREGISTER
:
1039 /* the lec device was deallocated */
1040 mpc
= find_mpc_by_lec(dev
);
1043 dprintk("device (%s) was deallocated\n", dev
->name
);
1049 /* the dev was ifconfig'ed up */
1050 mpc
= find_mpc_by_lec(dev
);
1053 if (mpc
->mpoad_vcc
!= NULL
)
1054 start_mpc(mpc
, dev
);
1057 /* the dev was ifconfig'ed down */
1058 /* this means that the flow of packets from the
1061 mpc
= find_mpc_by_lec(dev
);
1064 if (mpc
->mpoad_vcc
!= NULL
)
1069 case NETDEV_CHANGEMTU
:
1070 case NETDEV_CHANGEADDR
:
1071 case NETDEV_GOING_DOWN
:
1081 * Functions which are called after a message is received from mpcd.
1082 * Msg is reused on purpose.
1086 static void MPOA_trigger_rcvd(struct k_message
*msg
, struct mpoa_client
*mpc
)
1088 __be32 dst_ip
= msg
->content
.in_info
.in_dst_ip
;
1089 in_cache_entry
*entry
;
1091 entry
= mpc
->in_ops
->get(dst_ip
, mpc
);
1092 if (entry
== NULL
) {
1093 entry
= mpc
->in_ops
->add_entry(dst_ip
, mpc
);
1094 entry
->entry_state
= INGRESS_RESOLVING
;
1095 msg
->type
= SND_MPOA_RES_RQST
;
1096 msg
->content
.in_info
= entry
->ctrl_info
;
1097 msg_to_mpoad(msg
, mpc
);
1098 do_gettimeofday(&(entry
->reply_wait
));
1099 mpc
->in_ops
->put(entry
);
1103 if (entry
->entry_state
== INGRESS_INVALID
) {
1104 entry
->entry_state
= INGRESS_RESOLVING
;
1105 msg
->type
= SND_MPOA_RES_RQST
;
1106 msg
->content
.in_info
= entry
->ctrl_info
;
1107 msg_to_mpoad(msg
, mpc
);
1108 do_gettimeofday(&(entry
->reply_wait
));
1109 mpc
->in_ops
->put(entry
);
1113 pr_info("(%s) entry already in resolving state\n",
1114 (mpc
->dev
) ? mpc
->dev
->name
: "<unknown>");
1115 mpc
->in_ops
->put(entry
);
1119 * Things get complicated because we have to check if there's an egress
1120 * shortcut with suitable traffic parameters we could use.
1122 static void check_qos_and_open_shortcut(struct k_message
*msg
,
1123 struct mpoa_client
*client
,
1124 in_cache_entry
*entry
)
1126 __be32 dst_ip
= msg
->content
.in_info
.in_dst_ip
;
1127 struct atm_mpoa_qos
*qos
= atm_mpoa_search_qos(dst_ip
);
1128 eg_cache_entry
*eg_entry
= client
->eg_ops
->get_by_src_ip(dst_ip
, client
);
1130 if (eg_entry
&& eg_entry
->shortcut
) {
1131 if (eg_entry
->shortcut
->qos
.txtp
.traffic_class
&
1132 msg
->qos
.txtp
.traffic_class
&
1133 (qos
? qos
->qos
.txtp
.traffic_class
: ATM_UBR
| ATM_CBR
)) {
1134 if (eg_entry
->shortcut
->qos
.txtp
.traffic_class
== ATM_UBR
)
1135 entry
->shortcut
= eg_entry
->shortcut
;
1136 else if (eg_entry
->shortcut
->qos
.txtp
.max_pcr
> 0)
1137 entry
->shortcut
= eg_entry
->shortcut
;
1139 if (entry
->shortcut
) {
1140 dprintk("(%s) using egress SVC to reach %pI4\n",
1141 client
->dev
->name
, &dst_ip
);
1142 client
->eg_ops
->put(eg_entry
);
1146 if (eg_entry
!= NULL
)
1147 client
->eg_ops
->put(eg_entry
);
1149 /* No luck in the egress cache we must open an ingress SVC */
1150 msg
->type
= OPEN_INGRESS_SVC
;
1152 (qos
->qos
.txtp
.traffic_class
== msg
->qos
.txtp
.traffic_class
)) {
1153 msg
->qos
= qos
->qos
;
1154 pr_info("(%s) trying to get a CBR shortcut\n",
1157 memset(&msg
->qos
, 0, sizeof(struct atm_qos
));
1158 msg_to_mpoad(msg
, client
);
1161 static void MPOA_res_reply_rcvd(struct k_message
*msg
, struct mpoa_client
*mpc
)
1163 __be32 dst_ip
= msg
->content
.in_info
.in_dst_ip
;
1164 in_cache_entry
*entry
= mpc
->in_ops
->get(dst_ip
, mpc
);
1166 dprintk("(%s) ip %pI4\n",
1167 mpc
->dev
->name
, &dst_ip
);
1168 ddprintk("(%s) entry = %p",
1169 mpc
->dev
->name
, entry
);
1170 if (entry
== NULL
) {
1171 pr_info("(%s) ARGH, received res. reply for an entry that doesn't exist.\n",
1175 ddprintk_cont(" entry_state = %d ", entry
->entry_state
);
1177 if (entry
->entry_state
== INGRESS_RESOLVED
) {
1178 pr_info("(%s) RESOLVED entry!\n", mpc
->dev
->name
);
1179 mpc
->in_ops
->put(entry
);
1183 entry
->ctrl_info
= msg
->content
.in_info
;
1184 do_gettimeofday(&(entry
->tv
));
1185 do_gettimeofday(&(entry
->reply_wait
)); /* Used in refreshing func from now on */
1186 entry
->refresh_time
= 0;
1187 ddprintk_cont("entry->shortcut = %p\n", entry
->shortcut
);
1189 if (entry
->entry_state
== INGRESS_RESOLVING
&&
1190 entry
->shortcut
!= NULL
) {
1191 entry
->entry_state
= INGRESS_RESOLVED
;
1192 mpc
->in_ops
->put(entry
);
1193 return; /* Shortcut already open... */
1196 if (entry
->shortcut
!= NULL
) {
1197 pr_info("(%s) entry->shortcut != NULL, impossible!\n",
1199 mpc
->in_ops
->put(entry
);
1203 check_qos_and_open_shortcut(msg
, mpc
, entry
);
1204 entry
->entry_state
= INGRESS_RESOLVED
;
1205 mpc
->in_ops
->put(entry
);
1211 static void ingress_purge_rcvd(struct k_message
*msg
, struct mpoa_client
*mpc
)
1213 __be32 dst_ip
= msg
->content
.in_info
.in_dst_ip
;
1214 __be32 mask
= msg
->ip_mask
;
1215 in_cache_entry
*entry
= mpc
->in_ops
->get_with_mask(dst_ip
, mpc
, mask
);
1217 if (entry
== NULL
) {
1218 pr_info("(%s) purge for a non-existing entry, ip = %pI4\n",
1219 mpc
->dev
->name
, &dst_ip
);
1224 dprintk("(%s) removing an ingress entry, ip = %pI4\n",
1225 mpc
->dev
->name
, &dst_ip
);
1226 write_lock_bh(&mpc
->ingress_lock
);
1227 mpc
->in_ops
->remove_entry(entry
, mpc
);
1228 write_unlock_bh(&mpc
->ingress_lock
);
1229 mpc
->in_ops
->put(entry
);
1230 entry
= mpc
->in_ops
->get_with_mask(dst_ip
, mpc
, mask
);
1231 } while (entry
!= NULL
);
1234 static void egress_purge_rcvd(struct k_message
*msg
, struct mpoa_client
*mpc
)
1236 __be32 cache_id
= msg
->content
.eg_info
.cache_id
;
1237 eg_cache_entry
*entry
= mpc
->eg_ops
->get_by_cache_id(cache_id
, mpc
);
1239 if (entry
== NULL
) {
1240 dprintk("(%s) purge for a non-existing entry\n",
1245 write_lock_irq(&mpc
->egress_lock
);
1246 mpc
->eg_ops
->remove_entry(entry
, mpc
);
1247 write_unlock_irq(&mpc
->egress_lock
);
1249 mpc
->eg_ops
->put(entry
);
1252 static void purge_egress_shortcut(struct atm_vcc
*vcc
, eg_cache_entry
*entry
)
1255 struct k_message
*purge_msg
;
1256 struct sk_buff
*skb
;
1258 dprintk("entering\n");
1260 pr_info("vcc == NULL\n");
1264 skb
= alloc_skb(sizeof(struct k_message
), GFP_ATOMIC
);
1266 pr_info("out of memory\n");
1270 skb_put(skb
, sizeof(struct k_message
));
1271 memset(skb
->data
, 0, sizeof(struct k_message
));
1272 purge_msg
= (struct k_message
*)skb
->data
;
1273 purge_msg
->type
= DATA_PLANE_PURGE
;
1275 purge_msg
->content
.eg_info
= entry
->ctrl_info
;
1277 atm_force_charge(vcc
, skb
->truesize
);
1280 skb_queue_tail(&sk
->sk_receive_queue
, skb
);
1281 sk
->sk_data_ready(sk
, skb
->len
);
1282 dprintk("exiting\n");
1286 * Our MPS died. Tell our daemon to send NHRP data plane purge to each
1287 * of the egress shortcuts we have.
1289 static void mps_death(struct k_message
*msg
, struct mpoa_client
*mpc
)
1291 eg_cache_entry
*entry
;
1293 dprintk("(%s)\n", mpc
->dev
->name
);
1295 if (memcmp(msg
->MPS_ctrl
, mpc
->mps_ctrl_addr
, ATM_ESA_LEN
)) {
1296 pr_info("(%s) wrong MPS\n", mpc
->dev
->name
);
1300 /* FIXME: This knows too much of the cache structure */
1301 read_lock_irq(&mpc
->egress_lock
);
1302 entry
= mpc
->eg_cache
;
1303 while (entry
!= NULL
) {
1304 purge_egress_shortcut(entry
->shortcut
, entry
);
1305 entry
= entry
->next
;
1307 read_unlock_irq(&mpc
->egress_lock
);
1309 mpc
->in_ops
->destroy_cache(mpc
);
1310 mpc
->eg_ops
->destroy_cache(mpc
);
1313 static void MPOA_cache_impos_rcvd(struct k_message
*msg
,
1314 struct mpoa_client
*mpc
)
1316 uint16_t holding_time
;
1317 eg_cache_entry
*entry
= mpc
->eg_ops
->get_by_cache_id(msg
->content
.eg_info
.cache_id
, mpc
);
1319 holding_time
= msg
->content
.eg_info
.holding_time
;
1320 dprintk("(%s) entry = %p, holding_time = %u\n",
1321 mpc
->dev
->name
, entry
, holding_time
);
1322 if (entry
== NULL
&& holding_time
) {
1323 entry
= mpc
->eg_ops
->add_entry(msg
, mpc
);
1324 mpc
->eg_ops
->put(entry
);
1328 mpc
->eg_ops
->update(entry
, holding_time
);
1332 write_lock_irq(&mpc
->egress_lock
);
1333 mpc
->eg_ops
->remove_entry(entry
, mpc
);
1334 write_unlock_irq(&mpc
->egress_lock
);
1336 mpc
->eg_ops
->put(entry
);
1339 static void set_mpc_ctrl_addr_rcvd(struct k_message
*mesg
,
1340 struct mpoa_client
*mpc
)
1342 struct lec_priv
*priv
;
1345 uint8_t tlv
[4 + 1 + 1 + 1 + ATM_ESA_LEN
];
1347 tlv
[0] = 00; tlv
[1] = 0xa0; tlv
[2] = 0x3e; tlv
[3] = 0x2a; /* type */
1348 tlv
[4] = 1 + 1 + ATM_ESA_LEN
; /* length */
1349 tlv
[5] = 0x02; /* MPOA client */
1350 tlv
[6] = 0x00; /* number of MPS MAC addresses */
1352 memcpy(&tlv
[7], mesg
->MPS_ctrl
, ATM_ESA_LEN
); /* MPC ctrl ATM addr */
1353 memcpy(mpc
->our_ctrl_addr
, mesg
->MPS_ctrl
, ATM_ESA_LEN
);
1355 dprintk("(%s) setting MPC ctrl ATM address to",
1356 mpc
->dev
? mpc
->dev
->name
: "<unknown>");
1357 for (i
= 7; i
< sizeof(tlv
); i
++)
1358 dprintk_cont(" %02x", tlv
[i
]);
1362 priv
= netdev_priv(mpc
->dev
);
1363 retval
= priv
->lane2_ops
->associate_req(mpc
->dev
,
1367 pr_info("(%s) MPOA device type TLV association failed\n",
1369 retval
= priv
->lane2_ops
->resolve(mpc
->dev
, NULL
, 1, NULL
, NULL
);
1371 pr_info("(%s) targetless LE_ARP request failed\n",
1376 static void set_mps_mac_addr_rcvd(struct k_message
*msg
,
1377 struct mpoa_client
*client
)
1380 if (client
->number_of_mps_macs
)
1381 kfree(client
->mps_macs
);
1382 client
->number_of_mps_macs
= 0;
1383 client
->mps_macs
= kmemdup(msg
->MPS_ctrl
, ETH_ALEN
, GFP_KERNEL
);
1384 if (client
->mps_macs
== NULL
) {
1385 pr_info("out of memory\n");
1388 client
->number_of_mps_macs
= 1;
1392 * purge egress cache and tell daemon to 'action' (DIE, RELOAD)
1394 static void clean_up(struct k_message
*msg
, struct mpoa_client
*mpc
, int action
)
1397 eg_cache_entry
*entry
;
1398 msg
->type
= SND_EGRESS_PURGE
;
1401 /* FIXME: This knows too much of the cache structure */
1402 read_lock_irq(&mpc
->egress_lock
);
1403 entry
= mpc
->eg_cache
;
1404 while (entry
!= NULL
) {
1405 msg
->content
.eg_info
= entry
->ctrl_info
;
1406 dprintk("cache_id %u\n", entry
->ctrl_info
.cache_id
);
1407 msg_to_mpoad(msg
, mpc
);
1408 entry
= entry
->next
;
1410 read_unlock_irq(&mpc
->egress_lock
);
1413 msg_to_mpoad(msg
, mpc
);
1416 static void mpc_timer_refresh(void)
1418 mpc_timer
.expires
= jiffies
+ (MPC_P2
* HZ
);
1419 mpc_timer
.data
= mpc_timer
.expires
;
1420 mpc_timer
.function
= mpc_cache_check
;
1421 add_timer(&mpc_timer
);
1424 static void mpc_cache_check(unsigned long checking_time
)
1426 struct mpoa_client
*mpc
= mpcs
;
1427 static unsigned long previous_resolving_check_time
;
1428 static unsigned long previous_refresh_time
;
1430 while (mpc
!= NULL
) {
1431 mpc
->in_ops
->clear_count(mpc
);
1432 mpc
->eg_ops
->clear_expired(mpc
);
1433 if (checking_time
- previous_resolving_check_time
>
1434 mpc
->parameters
.mpc_p4
* HZ
) {
1435 mpc
->in_ops
->check_resolving(mpc
);
1436 previous_resolving_check_time
= checking_time
;
1438 if (checking_time
- previous_refresh_time
>
1439 mpc
->parameters
.mpc_p5
* HZ
) {
1440 mpc
->in_ops
->refresh(mpc
);
1441 previous_refresh_time
= checking_time
;
1445 mpc_timer_refresh();
1448 static int atm_mpoa_ioctl(struct socket
*sock
, unsigned int cmd
,
1452 struct atm_vcc
*vcc
= ATM_SD(sock
);
1454 if (cmd
!= ATMMPC_CTRL
&& cmd
!= ATMMPC_DATA
)
1455 return -ENOIOCTLCMD
;
1457 if (!capable(CAP_NET_ADMIN
))
1462 err
= atm_mpoa_mpoad_attach(vcc
, (int)arg
);
1464 sock
->state
= SS_CONNECTED
;
1467 err
= atm_mpoa_vcc_attach(vcc
, (void __user
*)arg
);
1475 static struct atm_ioctl atm_ioctl_ops
= {
1476 .owner
= THIS_MODULE
,
1477 .ioctl
= atm_mpoa_ioctl
,
1480 static __init
int atm_mpoa_init(void)
1482 register_atm_ioctl(&atm_ioctl_ops
);
1484 if (mpc_proc_init() != 0)
1485 pr_info("failed to initialize /proc/mpoa\n");
1487 pr_info("mpc.c: " __DATE__
" " __TIME__
" initialized\n");
1492 static void __exit
atm_mpoa_cleanup(void)
1494 struct mpoa_client
*mpc
, *tmp
;
1495 struct atm_mpoa_qos
*qos
, *nextqos
;
1496 struct lec_priv
*priv
;
1500 del_timer(&mpc_timer
);
1501 unregister_netdevice_notifier(&mpoa_notifier
);
1502 deregister_atm_ioctl(&atm_ioctl_ops
);
1506 while (mpc
!= NULL
) {
1508 if (mpc
->dev
!= NULL
) {
1510 priv
= netdev_priv(mpc
->dev
);
1511 if (priv
->lane2_ops
!= NULL
)
1512 priv
->lane2_ops
->associate_indicator
= NULL
;
1514 ddprintk("about to clear caches\n");
1515 mpc
->in_ops
->destroy_cache(mpc
);
1516 mpc
->eg_ops
->destroy_cache(mpc
);
1517 ddprintk("caches cleared\n");
1518 kfree(mpc
->mps_macs
);
1519 memset(mpc
, 0, sizeof(struct mpoa_client
));
1520 ddprintk("about to kfree %p\n", mpc
);
1522 ddprintk("next mpc is at %p\n", tmp
);
1528 while (qos
!= NULL
) {
1529 nextqos
= qos
->next
;
1530 dprintk("freeing qos entry %p\n", qos
);
1536 module_init(atm_mpoa_init
);
1537 module_exit(atm_mpoa_cleanup
);
1539 MODULE_LICENSE("GPL");