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