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>
8 #include <linux/bitops.h>
9 #include <linux/capability.h>
13 #include <linux/if_ether.h>
14 #include <linux/netdevice.h>
20 #include <asm/byteorder.h>
27 #include <linux/atmdev.h>
31 #include <linux/module.h>
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)
77 static void set_mpc_ctrl_addr_rcvd(
struct k_message *mesg,
79 static void set_mps_mac_addr_rcvd(
struct k_message *mesg,
88 static void send_set_mps_ctrl_addr(
const char *
addr,
struct mpoa_client *mpc);
95 static int mpoa_event_listener(
struct notifier_block *mpoa_notifier,
97 static void mpc_timer_refresh(
void);
98 static void mpc_cache_check(
unsigned long checking_time);
110 static struct llc_snap_hdr llc_snap_mpoa_data_tagged = {
127 static struct mpoa_client *find_mpc_by_itfnum(
int itf)
132 while (mpc !=
NULL) {
146 while (mpc !=
NULL) {
160 while (mpc !=
NULL) {
188 pr_info(
"mpoa: out of memory\n");
195 entry->
next = qos_head;
207 if (qos->
ipaddr == dst_ip)
224 if (entry == qos_head) {
225 qos_head = qos_head->
next;
231 while (curr !=
NULL) {
232 if (curr->
next == entry) {
249 seq_printf(m,
"QoS entries for shortcuts:\n");
250 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");
252 while (qos !=
NULL) {
253 seq_printf(m,
"%pI4\n %-7d %-7d %-7d %-7d %-7d\n %-7d %-7d %-7d %-7d %-7d\n",
255 qos->
qos.txtp.max_pcr,
257 qos->
qos.txtp.min_pcr,
258 qos->
qos.txtp.max_cdv,
259 qos->
qos.txtp.max_sdu,
260 qos->
qos.rxtp.max_pcr,
262 qos->
qos.rxtp.min_pcr,
263 qos->
qos.rxtp.max_cdv,
264 qos->
qos.rxtp.max_sdu);
269 static struct net_device *find_lec_by_itfnum(
int itf)
320 mpc->
new_ops.ndo_start_xmit = mpc_send_packet;
345 static const char *mpoa_device_type_string(
char type)
349 return "non-MPOA device";
355 return "both MPS and MPC";
358 return "unspecified (non-MPOA) device";
375 const u8 *tlvs,
u32 sizeoftlvs)
382 mpoa_device_type = number_of_mps_macs = 0;
384 dprintk(
"total length of all TLVs %d\n", sizeoftlvs);
385 mpc = find_mpc_by_lec(dev);
390 end_of_tlvs = tlvs + sizeoftlvs;
391 while (end_of_tlvs - tlvs >= 5) {
392 type = ((tlvs[0] << 24) | (tlvs[1] << 16) |
393 (tlvs[2] << 8) | tlvs[3]);
396 dprintk(
" type 0x%x length %02x\n", type, length);
397 if (tlvs + length > end_of_tlvs) {
398 pr_info(
"TLV value extends past its buffer, aborting parse\n");
403 pr_info(
"mpoa: (%s) TLV type was 0, returning\n",
412 mpoa_device_type = *tlvs++;
413 number_of_mps_macs = *tlvs++;
414 dprintk(
"(%s) MPOA device type '%s', ",
415 dev->
name, mpoa_device_type_string(mpoa_device_type));
417 length < (42 + number_of_mps_macs*
ETH_ALEN)) {
418 pr_info(
"(%s) short MPOA Device Type TLV\n",
422 if ((mpoa_device_type ==
MPS || mpoa_device_type ==
MPC) &&
423 length < 22 + number_of_mps_macs*ETH_ALEN) {
424 pr_info(
"(%s) short MPOA Device Type TLV\n", dev->
name);
427 if (mpoa_device_type !=
MPS &&
429 dprintk(
"ignoring non-MPS device ");
430 if (mpoa_device_type ==
MPC)
434 if (number_of_mps_macs == 0 &&
436 pr_info(
"(%s) MPS_AND_MPC has zero MACs\n", dev->
name);
446 send_set_mps_ctrl_addr(tlvs, mpc);
448 tlvs = copy_macs(mpc, mac_addr, tlvs,
449 number_of_mps_macs, mpoa_device_type);
453 if (end_of_tlvs - tlvs != 0)
454 pr_info(
"(%s) ignoring %Zd bytes of trailing TLV garbage\n",
455 dev->
name, end_of_tlvs - tlvs);
469 num_macs = (mps_macs > 1) ? mps_macs : 1;
482 tlvs += 20;
if (device_type ==
MPS_AND_MPC) tlvs += 20;
501 } tagged_llc_snap_hdr = {
502 {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}, {0x88, 0x4c}},
506 buff = skb->
data + mpc->
dev->hard_header_len;
507 iph = (
struct iphdr *)buff;
511 mpc->
dev->name, ipaddr);
513 entry = mpc->
in_ops->get(ipaddr, mpc);
515 entry = mpc->
in_ops->add_entry(ipaddr, mpc);
521 if (mpc->
in_ops->cache_hit(entry, mpc) !=
OPEN) {
522 ddprintk(
"(%s) cache_hit: returns != OPEN\n",
532 ddprintk(
"(%s) IP ttl = %u, using LANE\n",
533 mpc->
dev->name, iph->
ttl);
544 tagged_llc_snap_hdr.tag = entry->
ctrl_info.tag;
546 skb_push(skb,
sizeof(tagged_llc_snap_hdr));
548 skb_copy_to_linear_data(skb, &tagged_llc_snap_hdr,
549 sizeof(tagged_llc_snap_hdr));
554 skb_copy_to_linear_data(skb, &llc_snap_mpoa_data,
577 mpc = find_mpc_by_lec(dev);
590 skb_set_network_header(skb,
ETH_HLEN);
591 if (skb->
len <
ETH_HLEN + ip_hdr(skb)->ihl * 4 || ip_hdr(skb)->ihl < 5)
594 while (i < mpc->number_of_mps_macs) {
596 if (send_via_shortcut(skb, mpc) == 0)
602 return mpc->
old_ops->ndo_start_xmit(skb, dev);
605 static int atm_mpoa_vcc_attach(
struct atm_vcc *vcc,
void __user *
arg)
614 if (bytes_left != 0) {
615 pr_info(
"mpoa:Short read (missed %d bytes) from userland\n",
619 ipaddr = ioc_data.ipaddr;
620 if (ioc_data.dev_num < 0 || ioc_data.dev_num >=
MAX_LEC_ITF)
623 mpc = find_mpc_by_itfnum(ioc_data.dev_num);
628 in_entry = mpc->
in_ops->get(ipaddr, mpc);
629 if (in_entry ==
NULL ||
631 pr_info(
"(%s) did not find RESOLVED entry from ingress cache\n",
633 if (in_entry !=
NULL)
634 mpc->
in_ops->put(in_entry);
637 pr_info(
"(%s) attaching ingress SVC, entry = %pI4\n",
638 mpc->
dev->name, &in_entry->ctrl_info.in_dst_ip);
639 in_entry->shortcut =
vcc;
640 mpc->
in_ops->put(in_entry);
642 pr_info(
"(%s) attaching egress SVC\n", mpc->
dev->name);
646 vcc->
push = mpc_push;
660 mpc = find_mpc_by_lec(dev);
662 pr_info(
"(%s) close for unknown MPC\n", dev->
name);
667 in_entry = mpc->
in_ops->get_by_vcc(vcc, mpc);
669 dprintk(
"(%s) ingress SVC closed ip = %pI4\n",
672 mpc->
in_ops->put(in_entry);
674 eg_entry = mpc->
eg_ops->get_by_vcc(vcc, mpc);
676 dprintk(
"(%s) egress SVC closed\n", mpc->
dev->name);
678 mpc->
eg_ops->put(eg_entry);
681 if (in_entry ==
NULL && eg_entry ==
NULL)
696 dprintk(
"(%s) null skb, closing VCC\n", dev->
name);
697 mpc_vcc_close(vcc, dev);
704 struct sock *
sk = sk_atm(vcc);
706 dprintk(
"(%s) control packet arrived\n", dev->
name);
716 mpc = find_mpc_by_lec(dev);
722 if (
memcmp(skb->
data, &llc_snap_mpoa_data_tagged,
724 ddprintk(
"(%s) tagged data packet arrived\n", dev->
name);
726 }
else if (
memcmp(skb->
data, &llc_snap_mpoa_data,
728 pr_info(
"(%s) Unsupported non-tagged data packet arrived. Purging\n",
733 pr_info(
"(%s) garbage arrived, purging\n", dev->
name);
743 pr_info(
"mpoa: (%s) Didn't find egress cache entry, tag = %u\n",
745 purge_egress_shortcut(vcc,
NULL);
754 if (eg->shortcut ==
NULL) {
764 if (new_skb ==
NULL) {
768 skb_push(new_skb, eg->ctrl_info.DH_length);
769 skb_copy_to_linear_data(new_skb, eg->ctrl_info.DLL_header,
770 eg->ctrl_info.DH_length);
772 skb_reset_network_header(new_skb);
774 eg->latest_ip_addr = ip_hdr(new_skb)->saddr;
783 .close = mpoad_close,
784 .send = msg_from_mpoad
787 static struct atm_dev mpc_dev = {
795 static int atm_mpoa_mpoad_attach(
struct atm_vcc *vcc,
int arg)
813 mpc = find_mpc_by_itfnum(arg);
815 dprintk(
"allocating new mpc for itf %d\n", arg);
820 mpc->
dev = find_lec_by_itfnum(arg);
824 pr_info(
"mpoad is already present for itf %d\n", arg);
829 priv = netdev_priv(mpc->
dev);
834 priv->
lane2_ops->associate_indicator = lane2_assoc_ind;
847 start_mpc(mpc, mpc->
dev);
859 static void send_set_mps_ctrl_addr(
const char *
addr,
struct mpoa_client *mpc)
870 static void mpoad_close(
struct atm_vcc *vcc)
875 mpc = find_mpc_by_vcc(vcc);
881 pr_info(
"close for non-present mpoad\n");
893 mpc->
in_ops->destroy_cache(mpc);
894 mpc->
eg_ops->destroy_cache(mpc);
896 while ((skb =
skb_dequeue(&sk_atm(vcc)->sk_receive_queue))) {
902 (mpc->
dev) ? mpc->
dev->name :
"<unknown>");
909 static int msg_from_mpoad(
struct atm_vcc *vcc,
struct sk_buff *skb)
921 switch (mesg->
type) {
924 MPOA_res_reply_rcvd(mesg, mpc);
928 MPOA_trigger_rcvd(mesg, mpc);
932 ingress_purge_rcvd(mesg, mpc);
936 egress_purge_rcvd(mesg, mpc);
940 mps_death(mesg, mpc);
944 MPOA_cache_impos_rcvd(mesg, mpc);
948 set_mpc_ctrl_addr_rcvd(mesg, mpc);
952 set_mps_mac_addr_rcvd(mesg, mpc);
956 clean_up(mesg, mpc,
DIE);
960 clean_up(mesg, mpc,
RELOAD);
982 pr_info(
"mesg %d to a non-existent mpoad\n", mesg->
type);
990 skb_copy_to_linear_data(skb, mesg,
sizeof(*mesg));
1000 static int mpoa_event_listener(
struct notifier_block *mpoa_notifier,
1001 unsigned long event,
void *dev_ptr)
1009 if (!net_eq(dev_net(dev), &
init_net))
1017 priv = netdev_priv(dev);
1020 priv->
lane2_ops->associate_indicator = lane2_assoc_ind;
1021 mpc = find_mpc_by_itfnum(priv->
itfnum);
1023 dprintk(
"allocating new mpc for %s\n", dev->
name);
1037 mpc = find_mpc_by_lec(dev);
1040 dprintk(
"device (%s) was deallocated\n", dev->
name);
1047 mpc = find_mpc_by_lec(dev);
1051 start_mpc(mpc, dev);
1058 mpc = find_mpc_by_lec(dev);
1088 entry = mpc->
in_ops->get(dst_ip, mpc);
1089 if (entry ==
NULL) {
1090 entry = mpc->
in_ops->add_entry(dst_ip, mpc);
1110 pr_info(
"(%s) entry already in resolving state\n",
1111 (mpc->
dev) ? mpc->
dev->name :
"<unknown>");
1119 static void check_qos_and_open_shortcut(
struct k_message *msg,
1127 if (eg_entry && eg_entry->
shortcut) {
1128 if (eg_entry->
shortcut->qos.txtp.traffic_class &
1129 msg->
qos.txtp.traffic_class &
1133 else if (eg_entry->
shortcut->qos.txtp.max_pcr > 0)
1137 dprintk(
"(%s) using egress SVC to reach %pI4\n",
1138 client->
dev->name, &dst_ip);
1139 client->
eg_ops->put(eg_entry);
1143 if (eg_entry !=
NULL)
1144 client->
eg_ops->put(eg_entry);
1149 (qos->
qos.txtp.traffic_class == msg->
qos.txtp.traffic_class)) {
1151 pr_info(
"(%s) trying to get a CBR shortcut\n",
1164 mpc->
dev->name, &dst_ip);
1166 mpc->
dev->name, entry);
1167 if (entry ==
NULL) {
1168 pr_info(
"(%s) ARGH, received res. reply for an entry that doesn't exist.\n",
1175 pr_info(
"(%s) RESOLVED entry!\n", mpc->
dev->name);
1194 pr_info(
"(%s) entry->shortcut != NULL, impossible!\n",
1200 check_qos_and_open_shortcut(msg, mpc, entry);
1214 if (entry ==
NULL) {
1215 pr_info(
"(%s) purge for a non-existing entry, ip = %pI4\n",
1216 mpc->
dev->name, &dst_ip);
1221 dprintk(
"(%s) removing an ingress entry, ip = %pI4\n",
1222 mpc->
dev->name, &dst_ip);
1224 mpc->
in_ops->remove_entry(entry, mpc);
1227 entry = mpc->
in_ops->get_with_mask(dst_ip, mpc, mask);
1228 }
while (entry !=
NULL);
1236 if (entry ==
NULL) {
1237 dprintk(
"(%s) purge for a non-existing entry\n",
1243 mpc->
eg_ops->remove_entry(entry, mpc);
1274 atm_force_charge(vcc, skb->
truesize);
1300 while (entry !=
NULL) {
1301 purge_egress_shortcut(entry->
shortcut, entry);
1302 entry = entry->
next;
1306 mpc->
in_ops->destroy_cache(mpc);
1307 mpc->
eg_ops->destroy_cache(mpc);
1310 static void MPOA_cache_impos_rcvd(
struct k_message *msg,
1317 dprintk(
"(%s) entry = %p, holding_time = %u\n",
1318 mpc->
dev->name, entry, holding_time);
1319 if (entry ==
NULL && holding_time) {
1320 entry = mpc->
eg_ops->add_entry(msg, mpc);
1325 mpc->
eg_ops->update(entry, holding_time);
1330 mpc->
eg_ops->remove_entry(entry, mpc);
1336 static void set_mpc_ctrl_addr_rcvd(
struct k_message *mesg,
1344 tlv[0] = 00; tlv[1] = 0xa0; tlv[2] = 0x3e; tlv[3] = 0x2a;
1352 dprintk(
"(%s) setting MPC ctrl ATM address to",
1353 mpc->
dev ? mpc->
dev->name :
"<unknown>");
1354 for (i = 7; i <
sizeof(tlv); i++)
1359 priv = netdev_priv(mpc->
dev);
1364 pr_info(
"(%s) MPOA device type TLV association failed\n",
1368 pr_info(
"(%s) targetless LE_ARP request failed\n",
1373 static void set_mps_mac_addr_rcvd(
struct k_message *msg,
1401 while (entry !=
NULL) {
1405 entry = entry->
next;
1413 static void mpc_timer_refresh(
void)
1416 mpc_timer.data = mpc_timer.expires;
1417 mpc_timer.function = mpc_cache_check;
1421 static void mpc_cache_check(
unsigned long checking_time)
1424 static unsigned long previous_resolving_check_time;
1425 static unsigned long previous_refresh_time;
1427 while (mpc !=
NULL) {
1428 mpc->
in_ops->clear_count(mpc);
1429 mpc->
eg_ops->clear_expired(mpc);
1430 if (checking_time - previous_resolving_check_time >
1432 mpc->
in_ops->check_resolving(mpc);
1433 previous_resolving_check_time = checking_time;
1435 if (checking_time - previous_refresh_time >
1437 mpc->
in_ops->refresh(mpc);
1438 previous_refresh_time = checking_time;
1442 mpc_timer_refresh();
1445 static int atm_mpoa_ioctl(
struct socket *
sock,
unsigned int cmd,
1449 struct atm_vcc *vcc = ATM_SD(sock);
1459 err = atm_mpoa_mpoad_attach(vcc, (
int)arg);
1464 err = atm_mpoa_vcc_attach(vcc, (
void __user *)arg);
1472 static struct atm_ioctl atm_ioctl_ops = {
1474 .ioctl = atm_mpoa_ioctl,
1477 static __init int atm_mpoa_init(
void)
1482 pr_info(
"failed to initialize /proc/mpoa\n");
1484 pr_info(
"mpc.c: initialized\n");
1489 static void __exit atm_mpoa_cleanup(
void)
1503 while (mpc !=
NULL) {
1507 priv = netdev_priv(mpc->
dev);
1511 ddprintk(
"about to clear caches\n");
1512 mpc->
in_ops->destroy_cache(mpc);
1513 mpc->
eg_ops->destroy_cache(mpc);
1517 ddprintk(
"about to kfree %p\n", mpc);
1519 ddprintk(
"next mpc is at %p\n", tmp);
1525 while (qos !=
NULL) {
1526 nextqos = qos->
next;
1527 dprintk(
"freeing qos entry %p\n", qos);