1/* 2 * Linux IPv6 multicast routing support for BSD pim6sd 3 * 4 * (c) 2004 Mickael Hoerdt, <hoerdt@clarinet.u-strasbg.fr> 5 * LSIIT Laboratory, Strasbourg, France 6 * (c) 2004 Jean-Philippe Andriot, <jean-philippe.andriot@6WIND.com> 7 * 6WIND, Paris, France 8 * 9 * This program is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation; either version 12 * 2 of the License, or (at your option) any later version. 13 * 14 * Version: $Id: ip6mr.c,v 1.9 2004/10/18 08:46:04 hoerdt Exp $ 15 * 16 * Fixes: 17 * Michael Chastain : Incorrect size of copying. 18 * Alan Cox : Added the cache manager code 19 * Alan Cox : Fixed the clone/copy bug and device race. 20 * Mike McLagan : Routing by source 21 * Malcolm Beattie : Buffer handling fixes. 22 * Alexey Kuznetsov : Double buffer free and other fixes. 23 * SVR Anand : Fixed several multicast bugs and problems. 24 * Alexey Kuznetsov : Status, optimisations and more. 25 * Brad Parker : Better behaviour on mrouted upcall 26 * overflow. 27 * Carlos Picoto : PIMv1 Support 28 * Pavlin Ivanov Radoslavov: PIMv2 Registers must checksum only PIM header 29 * Relax this requirement to work with older peers. 30 * Mickael Hoerdt and : IPv6 support based on linux/net/ipv4/ipmr.c [Linux 2.x] 31 * Jean-Philippe Andriot on netinet/ip6_mroute.c [*BSD] 32 * 33 */ 34 35#include <asm/system.h> 36#include <asm/uaccess.h> 37#include <linux/types.h> 38#include <linux/sched.h> 39#include <linux/errno.h> 40#include <linux/timer.h> 41#include <linux/mm.h> 42#include <linux/kernel.h> 43#include <linux/fcntl.h> 44#include <linux/stat.h> 45#include <linux/socket.h> 46#include <linux/in.h> 47#include <linux/inet.h> 48#include <linux/netdevice.h> 49#include <linux/inetdevice.h> 50#include <linux/igmp.h> 51#include <linux/proc_fs.h> 52#include <linux/seq_file.h> 53#include <linux/mroute.h> 54#include <linux/init.h> 55#include <net/ip.h> 56#include <net/protocol.h> 57#include <linux/skbuff.h> 58#include <net/route.h> 59#include <net/sock.h> 60#include <net/icmp.h> 61#include <net/udp.h> 62#include <net/raw.h> 63#include <linux/notifier.h> 64#include <linux/if_arp.h> 65#include <linux/netfilter_ipv4.h> 66#include <net/ipip.h> 67#include <net/checksum.h> 68 69 70#include <net/ipv6.h> 71#include <net/ip6_route.h> 72#include <linux/mroute6.h> 73#include <net/addrconf.h> 74#include <linux/netfilter_ipv6.h> 75 76 77struct sock *mroute6_socket; 78 79 80/* Big lock, protecting vif table, mrt cache and mroute socket state. 81 Note that the changes are semaphored via rtnl_lock. 82 */ 83 84static rwlock_t mrt_lock = RW_LOCK_UNLOCKED; 85 86/* 87 * Multicast router control variables 88 */ 89 90static struct mif_device vif6_table[MAXMIFS]; /* Devices */ 91static int maxvif; 92 93#define MIF_EXISTS(idx) (vif6_table[idx].dev != NULL) 94 95static int mroute_do_assert; /* Set in PIM assert */ 96static int mroute_do_pim; 97 98static struct mfc6_cache *mfc6_cache_array[MFC_LINES]; /* Forwarding cache */ 99 100static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */ 101static atomic_t cache_resolve_queue_len; /* Size of unresolved */ 102 103/* Special spinlock for queue of unresolved entries */ 104static spinlock_t mfc_unres_lock = SPIN_LOCK_UNLOCKED; 105 106/* We return to original Alan's scheme. Hash table of resolved 107 entries is changed only in process context and protected 108 with weak lock mrt_lock. Queue of unresolved entries is protected 109 with strong spinlock mfc_unres_lock. 110 111 In this case data path is free of exclusive locks at all. 112 */ 113 114static kmem_cache_t *mrt_cachep; 115 116static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache, int local); 117static int ip6mr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); 118static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm); 119 120static struct inet6_protocol pim6_protocol; 121 122static struct timer_list ipmr_expire_timer; 123 124 125#ifdef CONFIG_PROC_FS 126 127struct ipmr_mfc_iter { 128 struct mfc6_cache **cache; 129 int ct; 130}; 131 132 133static struct mfc6_cache *ipmr_mfc_seq_idx(struct ipmr_mfc_iter *it, loff_t pos) 134{ 135 struct mfc6_cache *mfc; 136 137 it->cache = mfc6_cache_array; 138 read_lock(&mrt_lock); 139 for (it->ct = 0; it->ct < MFC_LINES; it->ct++) { 140 for(mfc = mfc6_cache_array[it->ct]; mfc; mfc = mfc->next) { 141 if (pos-- == 0) { 142 return mfc; 143 } 144 } 145 } 146 read_unlock(&mrt_lock); 147 148 it->cache = &mfc_unres_queue; 149 spin_lock_bh(&mfc_unres_lock); 150 for(mfc = mfc_unres_queue; mfc; mfc = mfc->next) { 151 if (pos-- == 0) { 152 return mfc; 153 } 154 } 155 spin_unlock_bh(&mfc_unres_lock); 156 157 it->cache = NULL; 158 return NULL; 159} 160 161 162 163 164/* 165 * The /proc interfaces to multicast routing /proc/ip6_mr_cache /proc/ip6_mr_vif 166 */ 167 168struct ipmr_vif_iter { 169 int ct; 170}; 171 172static struct mif_device *ip6mr_vif_seq_idx(struct ipmr_vif_iter *iter, 173 loff_t pos) 174{ 175 for (iter->ct = 0; iter->ct < maxvif; ++iter->ct) { 176 if(!MIF_EXISTS(iter->ct)) { 177 continue; 178 } 179 if (pos-- == 0) { 180 return &vif6_table[iter->ct]; 181 } 182 } 183 return NULL; 184} 185 186static void *ip6mr_vif_seq_start(struct seq_file *seq, loff_t *pos) 187{ 188 read_lock(&mrt_lock); 189 return *pos ? ip6mr_vif_seq_idx(seq->private, *pos - 1) 190 : SEQ_START_TOKEN; 191} 192 193static void *ip6mr_vif_seq_next(struct seq_file *seq, void *v, loff_t *pos) 194{ 195 struct ipmr_vif_iter *iter = seq->private; 196 197 ++*pos; 198 if (v == SEQ_START_TOKEN) 199 return ip6mr_vif_seq_idx(iter, 0); 200 201 while (++iter->ct < maxvif) { 202 if(!MIF_EXISTS(iter->ct)) 203 continue; 204 return &vif6_table[iter->ct]; 205 } 206 return NULL; 207} 208 209static void ip6mr_vif_seq_stop(struct seq_file *seq, void *v) 210{ 211 read_unlock(&mrt_lock); 212} 213 214static int ip6mr_vif_seq_show(struct seq_file *seq, void *v) 215{ 216 if (v == SEQ_START_TOKEN) { 217 seq_puts(seq, 218 "Interface BytesIn PktsIn BytesOut PktsOut Flags\n"); 219 } else { 220 const struct mif_device *vif = v; 221 const char *name = vif->dev ? vif->dev->name : "none"; 222 223 seq_printf(seq, 224 "%2Zd %-10s %8ld %7ld %8ld %7ld %05X\n", 225 vif - vif6_table, 226 name, vif->bytes_in, vif->pkt_in, 227 vif->bytes_out, vif->pkt_out, 228 vif->flags); 229 } 230 return 0; 231} 232 233static struct seq_operations ip6mr_vif_seq_ops = { 234 .start = ip6mr_vif_seq_start, 235 .next = ip6mr_vif_seq_next, 236 .stop = ip6mr_vif_seq_stop, 237 .show = ip6mr_vif_seq_show, 238}; 239 240static int ip6mr_vif_open(struct inode *inode, struct file *file) 241{ 242 struct seq_file *seq; 243 int rc = -ENOMEM; 244 struct ipmr_vif_iter *s = kmalloc(sizeof(*s), GFP_KERNEL); 245 246 if (!s) 247 goto out; 248 249 rc = seq_open(file, &ip6mr_vif_seq_ops); 250 if (rc) 251 goto out_kfree; 252 253 s->ct = 0; 254 seq = file->private_data; 255 seq->private = s; 256out: 257 return rc; 258out_kfree: 259 kfree(s); 260 goto out; 261 262} 263 264static struct file_operations ip6mr_vif_fops = { 265 .owner = THIS_MODULE, 266 .open = ip6mr_vif_open, 267 .read = seq_read, 268 .llseek = seq_lseek, 269 .release = seq_release, 270}; 271 272static void *ipmr_mfc_seq_start(struct seq_file *seq, loff_t *pos) 273{ 274 return *pos ? ipmr_mfc_seq_idx(seq->private, *pos - 1) 275 : SEQ_START_TOKEN; 276} 277 278static void *ipmr_mfc_seq_next(struct seq_file *seq, void *v, loff_t *pos) 279{ 280 struct mfc6_cache *mfc = v; 281 struct ipmr_mfc_iter *it = seq->private; 282 283 ++*pos; 284 285 if (v == SEQ_START_TOKEN) { 286 return ipmr_mfc_seq_idx(seq->private, 0); 287 } 288 289 if (mfc->next) { 290 return mfc->next; 291 } 292 293 if (it->cache == &mfc_unres_queue) { 294 goto end_of_list; 295 } 296 297 BUG_ON(it->cache != mfc6_cache_array); 298 299 while (++it->ct < MFC_LINES) { 300 mfc = mfc6_cache_array[it->ct]; 301 if (mfc) 302 return mfc; 303 } 304 305 /* exhausted cache_array, show unresolved */ 306 read_unlock(&mrt_lock); 307 it->cache = &mfc_unres_queue; 308 it->ct = 0; 309 310 spin_lock_bh(&mfc_unres_lock); 311 mfc = mfc_unres_queue; 312 if (mfc) 313 return mfc; 314 315 end_of_list: 316 spin_unlock_bh(&mfc_unres_lock); 317 it->cache = NULL; 318 319 return NULL; 320} 321 322static void ipmr_mfc_seq_stop(struct seq_file *seq, void *v) 323{ 324 struct ipmr_mfc_iter *it = seq->private; 325 326 if (it->cache == &mfc_unres_queue) 327 spin_unlock_bh(&mfc_unres_lock); 328 else if (it->cache == mfc6_cache_array) 329 read_unlock(&mrt_lock); 330} 331 332static int ipmr_mfc_seq_show(struct seq_file *seq, void *v) 333{ 334 int n; 335 336 337 if (v == SEQ_START_TOKEN) { 338 seq_puts(seq, 339 "Group Origin Iif Pkts Bytes Wrong Oifs\n"); 340 } else { 341 const struct mfc6_cache *mfc = v; 342 const struct ipmr_mfc_iter *it = seq->private; 343 int i; 344 345 for(i=0;i<16;i++) { 346 seq_printf(seq,"%02x",mfc->mf6c_mcastgrp.s6_addr[i]); 347 } 348 seq_printf(seq," "); 349 for(i=0;i<16;i++) { 350 seq_printf(seq,"%02x",mfc->mf6c_origin.s6_addr[i]); 351 } 352 seq_printf(seq," "); 353 354 seq_printf(seq, "%-3d %8ld %8ld %8ld", 355 mfc->mf6c_parent, 356 mfc->mfc_un.res.pkt, 357 mfc->mfc_un.res.bytes, 358 mfc->mfc_un.res.wrong_if); 359 360 if (it->cache != &mfc_unres_queue) { 361 for(n = mfc->mfc_un.res.minvif; 362 n < mfc->mfc_un.res.maxvif; n++ ) { 363 if(MIF_EXISTS(n) 364 && mfc->mfc_un.res.ttls[n] < 255) 365 seq_printf(seq, 366 " %2d:%-3d", 367 n, mfc->mfc_un.res.ttls[n]); 368 } 369 } 370 seq_putc(seq, '\n'); 371 } 372 return 0; 373} 374 375static struct seq_operations ipmr_mfc_seq_ops = { 376 .start = ipmr_mfc_seq_start, 377 .next = ipmr_mfc_seq_next, 378 .stop = ipmr_mfc_seq_stop, 379 .show = ipmr_mfc_seq_show, 380}; 381 382static int ipmr_mfc_open(struct inode *inode, struct file *file) 383{ 384 struct seq_file *seq; 385 int rc = -ENOMEM; 386 struct ipmr_mfc_iter *s = kmalloc(sizeof(*s), GFP_KERNEL); 387 388 if (!s) 389 goto out; 390 391 rc = seq_open(file, &ipmr_mfc_seq_ops); 392 if (rc) 393 goto out_kfree; 394 395 memset(s, 0, sizeof(*s)); 396 seq = file->private_data; 397 seq->private = s; 398out: 399 return rc; 400out_kfree: 401 kfree(s); 402 goto out; 403 404} 405 406static struct file_operations ip6mr_mfc_fops = { 407 .owner = THIS_MODULE, 408 .open = ipmr_mfc_open, 409 .read = seq_read, 410 .llseek = seq_lseek, 411 .release = seq_release, 412}; 413#endif 414 415#ifdef CONFIG_IPV6_PIMSM_V2 416static int reg_vif_num = -1; 417 418static int pim6_rcv(struct sk_buff **pskb,unsigned int *nhoffp) 419{ 420 struct pimreghdr *pim; 421 struct ipv6hdr *encap; 422 struct sk_buff *skb = *pskb; 423 struct net_device *reg_dev = NULL; 424 425 if (!pskb_may_pull(skb, sizeof(*pim) + sizeof(*encap))) 426 goto drop; 427 428 //pim = (struct pimreghdr*)skb->h.raw; 429 pim = (struct pimreghdr *)skb_transport_header(skb); 430 if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) || 431 (pim->flags&PIM_NULL_REGISTER) || 432 (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && 433 (u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))) 434 goto drop; 435 436 /* check if the inner packet is destined to mcast group */ 437 //encap = (struct ipv6hdr*)(skb->h.raw + sizeof(struct pimreghdr)); 438 encap = (struct ipv6hdr *)(skb_transport_header(skb) + sizeof(*pim)); 439 440 if(!(ipv6_addr_type(&encap->daddr)&IPV6_ADDR_MULTICAST) || 441 encap->payload_len == 0 || 442 ntohs(encap->payload_len) + sizeof(*pim) > skb->len) 443 goto drop; 444 445 read_lock(&mrt_lock); 446 if (reg_vif_num >= 0) 447 reg_dev = vif6_table[reg_vif_num].dev; 448 if (reg_dev) 449 dev_hold(reg_dev); 450 read_unlock(&mrt_lock); 451 452 if (reg_dev == NULL) 453 goto drop; 454 455 //skb->mac.raw = skb->nh.raw; 456 skb->mac_header = skb->network_header; 457 skb_pull(skb, (u8*)encap - skb->data); 458 //skb->nh.ipv6h = (struct ipv6hdr *)skb->data; 459 skb_reset_network_header(skb); 460 skb->dev = reg_dev; 461 skb->protocol = htons(ETH_P_IP); 462 skb->ip_summed = 0; 463 skb->pkt_type = PACKET_HOST; 464 dst_release(skb->dst); 465 ((struct net_device_stats*)reg_dev->priv)->rx_bytes += skb->len; 466 ((struct net_device_stats*)reg_dev->priv)->rx_packets++; 467 skb->dst = NULL; 468#ifdef CONFIG_NETFILTER 469 //nf_conntrack_put(skb->nfct); 470 //skb->nfct = NULL; 471 nf_reset(skb); 472#endif 473 netif_rx(skb); 474 dev_put(reg_dev); 475 return 0; 476 drop: 477 kfree_skb(skb); 478 return 0; 479} 480 481static struct inet6_protocol pim6_protocol = { 482 .handler = pim6_rcv, 483}; 484#endif 485 486/* Service routines creating virtual interfaces: PIMREG */ 487#ifdef CONFIG_IPV6_PIMSM_V2 488 489 490static int reg_vif_xmit(struct sk_buff *skb, struct net_device *dev) 491{ 492 read_lock(&mrt_lock); 493 ((struct net_device_stats*)dev->priv)->tx_bytes += skb->len; 494 ((struct net_device_stats*)dev->priv)->tx_packets++; 495 ip6mr_cache_report(skb, reg_vif_num, MRT6MSG_WHOLEPKT); 496 read_unlock(&mrt_lock); 497 kfree_skb(skb); 498 return 0; 499} 500 501static struct net_device_stats *reg_vif_get_stats(struct net_device *dev) 502{ 503 return (struct net_device_stats*)dev->priv; 504} 505 506static void reg_vif_setup(struct net_device *dev) 507{ 508 dev->type = ARPHRD_PIMREG; 509 dev->mtu = 1500 - sizeof(struct ipv6hdr) - 8; 510 dev->flags = IFF_NOARP; 511 dev->hard_start_xmit = reg_vif_xmit; 512 dev->get_stats = reg_vif_get_stats; 513 dev->destructor = free_netdev; 514} 515 516static struct net_device *ip6mr_reg_vif(void) 517{ 518 struct net_device *dev; 519 struct inet6_dev *in_dev; 520 521 dev = alloc_netdev(sizeof(struct net_device_stats), "pim6reg", 522 reg_vif_setup); 523 524 if (dev == NULL) 525 return NULL; 526 527 if (register_netdevice(dev)) { 528 free_netdev(dev); 529 return NULL; 530 } 531 dev->iflink = 0; 532 533 if ((in_dev = ipv6_find_idev(dev)) == NULL) { 534 goto failure; 535 } 536 537/* 538 * if ((in_dev = __in6_dev_get(dev)) == NULL) 539 goto failure; 540*/ 541 //in_dev->cnf.rp_filter = 0; 542 543 if (dev_open(dev)) 544 goto failure; 545 546 return dev; 547 548failure: 549 /* allow the register to be completed before unregistering. */ 550 rtnl_unlock(); 551 rtnl_lock(); 552 553 unregister_netdevice(dev); 554 return NULL; 555} 556#endif 557 558/* 559 * Delete a VIF entry 560 */ 561 562static int mif6_delete(int vifi) 563{ 564 struct mif_device *v; 565 struct net_device *dev; 566 struct inet6_dev *in_dev; 567 568 if (vifi < 0 || vifi >= maxvif) 569 return -EADDRNOTAVAIL; 570 571 v = &vif6_table[vifi]; 572 573 write_lock_bh(&mrt_lock); 574 dev = v->dev; 575 v->dev = NULL; 576 577 if (!dev) { 578 write_unlock_bh(&mrt_lock); 579 return -EADDRNOTAVAIL; 580 } 581 582#ifdef CONFIG_IPV6_PIMSM_V2 583 if (vifi == reg_vif_num) 584 reg_vif_num = -1; 585#endif 586 587 if (vifi+1 == maxvif) { 588 int tmp; 589 for (tmp=vifi-1; tmp>=0; tmp--) { 590 if (MIF_EXISTS(tmp)) 591 break; 592 } 593 maxvif = tmp+1; 594 } 595 596 write_unlock_bh(&mrt_lock); 597 598 dev_set_allmulti(dev, -1); 599 600 if ((in_dev = __in6_dev_get(dev)) != NULL) { 601 in_dev->cnf.mc_forwarding--; 602 } 603 604 if (v->flags&(MIFF_REGISTER)) 605 unregister_netdevice(dev); 606 607 dev_put(dev); 608 return 0; 609} 610 611/* Destroy an unresolved cache entry, killing queued skbs 612 and reporting error to netlink readers. 613 */ 614 615static void ip6mr_destroy_unres(struct mfc6_cache *c) 616{ 617 struct sk_buff *skb; 618 619 atomic_dec(&cache_resolve_queue_len); 620 621 while((skb=skb_dequeue(&c->mfc_un.unres.unresolved))) { 622 //if (skb->nh.ipv6h->version == 0) { //bob modified 623 if (ipv6_hdr(skb)->version == 0) { 624 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr)); 625 nlh->nlmsg_type = NLMSG_ERROR; 626 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); 627 skb_trim(skb, nlh->nlmsg_len); 628 ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -ETIMEDOUT; 629#if 0 630 netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); 631#endif 632 rtnl_unicast(skb, NETLINK_CB(skb).pid); 633 } else 634 kfree_skb(skb); 635 } 636 637 kmem_cache_free(mrt_cachep, c); 638} 639 640 641/* Single timer process for all the unresolved queue. */ 642 643static void ipmr_expire_process(unsigned long dummy) 644{ 645 unsigned long now; 646 unsigned long expires; 647 struct mfc6_cache *c, **cp; 648 649 if (!spin_trylock(&mfc_unres_lock)) { 650 mod_timer(&ipmr_expire_timer, jiffies+HZ/10); 651 return; 652 } 653 654 if (atomic_read(&cache_resolve_queue_len) == 0) 655 goto out; 656 657 now = jiffies; 658 expires = 10*HZ; 659 cp = &mfc_unres_queue; 660 661 while ((c=*cp) != NULL) { 662 if (time_after(c->mfc_un.unres.expires, now)) { 663 unsigned long interval = c->mfc_un.unres.expires - now; 664 if (interval < expires) 665 expires = interval; 666 cp = &c->next; 667 continue; 668 } 669 670 *cp = c->next; 671 672 ip6mr_destroy_unres(c); 673 } 674 675 if (atomic_read(&cache_resolve_queue_len)) 676 mod_timer(&ipmr_expire_timer, jiffies + expires); 677 678out: 679 spin_unlock(&mfc_unres_lock); 680} 681 682/* Fill oifs list. It is called under write locked mrt_lock. */ 683 684static void ip6mr_update_threshoulds(struct mfc6_cache *cache, unsigned char *ttls) 685{ 686 int vifi; 687 688 cache->mfc_un.res.minvif = MAXVIFS; 689 cache->mfc_un.res.maxvif = 0; 690 memset(cache->mfc_un.res.ttls, 255, MAXVIFS); 691 692 for (vifi=0; vifi<maxvif; vifi++) { 693 if (MIF_EXISTS(vifi) && ttls[vifi] && ttls[vifi] < 255) { 694 cache->mfc_un.res.ttls[vifi] = ttls[vifi]; 695 if (cache->mfc_un.res.minvif > vifi) { 696 cache->mfc_un.res.minvif = vifi; 697 } 698 if (cache->mfc_un.res.maxvif <= vifi) { 699 cache->mfc_un.res.maxvif = vifi + 1; 700 } 701 } 702 } 703} 704 705static int mif6_add(struct mif6ctl *vifc, int mrtsock) 706{ 707 int vifi = vifc->mif6c_mifi; 708 struct mif_device *v = &vif6_table[vifi]; 709 struct net_device *dev; 710 struct inet6_dev *in_dev; 711 712 /* Is vif busy ? */ 713 if (MIF_EXISTS(vifi)) 714 return -EADDRINUSE; 715 716 switch (vifc->mif6c_flags) { 717#ifdef CONFIG_IPV6_PIMSM_V2 718 case MIFF_REGISTER: 719 /* 720 * Special Purpose VIF in PIM 721 * All the packets will be sent to the daemon 722 */ 723 if (reg_vif_num >= 0) 724 return -EADDRINUSE; 725 dev = ip6mr_reg_vif(); 726 if (!dev) 727 return -ENOBUFS; 728 break; 729#endif 730 case 0: 731 dev=dev_get_by_index(vifc->mif6c_pifi); 732 if (!dev) 733 return -EADDRNOTAVAIL; 734 dev_put(dev); 735 break; 736 default: 737 return -EINVAL; 738 } 739 740 if ((in_dev = __in6_dev_get(dev)) == NULL) 741 return -EADDRNOTAVAIL; 742 in_dev->cnf.mc_forwarding++; 743 dev_set_allmulti(dev, +1); 744 745 /* 746 * Fill in the VIF structures 747 */ 748 v->rate_limit=vifc->vifc_rate_limit; 749 v->flags=vifc->mif6c_flags; 750 if(!mrtsock) 751 v->flags |= VIFF_STATIC; 752 v->threshold=vifc->vifc_threshold; 753 v->bytes_in = 0; 754 v->bytes_out = 0; 755 v->pkt_in = 0; 756 v->pkt_out = 0; 757 v->link = dev->ifindex; 758 if (v->flags&(MIFF_REGISTER)) 759 v->link = dev->iflink; 760 761 /* And finish update writing critical data */ 762 write_lock_bh(&mrt_lock); 763 dev_hold(dev); 764 v->dev=dev; 765#ifdef CONFIG_IPV6_PIMSM_V2 766 if (v->flags&MIFF_REGISTER) 767 reg_vif_num = vifi; 768#endif 769 if (vifi+1 > maxvif) 770 maxvif = vifi+1; 771 write_unlock_bh(&mrt_lock); 772 return 0; 773} 774 775static struct mfc6_cache *ip6mr_cache_find(struct in6_addr origin,struct in6_addr mcastgrp) 776{ 777 int line=MFC6_HASH(mcastgrp,origin); 778 struct mfc6_cache *c; 779 780 for (c=mfc6_cache_array[line]; c; c = c->next) { 781 if (IN6_ARE_ADDR_EQUAL(&c->mf6c_origin,&origin) && 782 IN6_ARE_ADDR_EQUAL(&c->mf6c_mcastgrp,&mcastgrp)) 783 break; 784 } 785 786#if defined(CONFIG_MIPS_BRCM) 787 if(c == NULL) { 788 for (c=mfc6_cache_array[line]; c; c = c->next) { 789 if (IN6_ARE_ADDR_EQUAL(&c->mf6c_mcastgrp,&mcastgrp)) 790 break; 791 } 792 } 793#endif /* CONFIG_MIPS_BRCM */ 794 return c; 795} 796 797/* 798 * Allocate a multicast cache entry 799 */ 800static struct mfc6_cache *ip6mr_cache_alloc(void) 801{ 802 struct mfc6_cache *c=kmem_cache_alloc(mrt_cachep, GFP_KERNEL); 803 if(c==NULL) 804 return NULL; 805 memset(c, 0, sizeof(*c)); 806 c->mfc_un.res.minvif = MAXVIFS; 807 return c; 808} 809 810static struct mfc6_cache *ip6mr_cache_alloc_unres(void) 811{ 812 struct mfc6_cache *c=kmem_cache_alloc(mrt_cachep, GFP_ATOMIC); 813 if(c==NULL) 814 return NULL; 815 memset(c, 0, sizeof(*c)); 816 skb_queue_head_init(&c->mfc_un.unres.unresolved); 817 c->mfc_un.unres.expires = jiffies + 10*HZ; 818 return c; 819} 820 821/* 822 * A cache entry has gone into a resolved state from queued 823 */ 824 825static void ip6mr_cache_resolve(struct mfc6_cache *uc, struct mfc6_cache *c) 826{ 827 struct sk_buff *skb; 828 829 /* 830 * Play the pending entries through our router 831 */ 832 833 while((skb=__skb_dequeue(&uc->mfc_un.unres.unresolved))) { 834 //if (skb->nh.ipv6h->version == 0) { //bob modified 835 if (ipv6_hdr(skb)->version == 0) { 836 int err; 837 struct nlmsghdr *nlh = (struct nlmsghdr *)skb_pull(skb, sizeof(struct ipv6hdr)); 838 839 if (ip6mr_fill_mroute(skb, c, NLMSG_DATA(nlh)) > 0) { 840 nlh->nlmsg_len = skb->tail - (u8*)nlh; 841 } else { 842 nlh->nlmsg_type = NLMSG_ERROR; 843 nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); 844 skb_trim(skb, nlh->nlmsg_len); 845 ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -EMSGSIZE; 846 } 847#if 0 848 err = netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); 849#endif 850 err = rtnl_unicast(skb, NETLINK_CB(skb).pid); 851 } else 852 ip6_mr_forward(skb, c, 0); 853 } 854} 855 856/* 857 * Bounce a cache query up to pim6sd. We could use netlink for this but pim6sd 858 * expects the following bizarre scheme. 859 * 860 * Called under mrt_lock. 861 */ 862 863static int ip6mr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert) 864{ 865 struct sk_buff *skb; 866 struct mrt6msg *msg; 867 int ret; 868 869#ifdef CONFIG_IPV6_PIMSM_V2 870 if (assert == MRT6MSG_WHOLEPKT) 871 skb = skb_realloc_headroom(pkt, sizeof(struct ipv6hdr)); 872 else 873#endif 874 skb = alloc_skb(128, GFP_ATOMIC); 875 876 if(!skb) 877 return -ENOBUFS; 878 879 /* I suppose that internal messages 880 * do not require checksums */ 881 882 skb->ip_summed = CHECKSUM_UNNECESSARY; 883 884#ifdef CONFIG_IPV6_PIMSM_V2 885 if (assert == MRT6MSG_WHOLEPKT) { 886 /* Ugly, but we have no choice with this interface. 887 Duplicate old header, fix length etc. 888 And all this only to mangle msg->im6_msgtype and 889 to set msg->im6_mbz to "mbz" :-) 890 */ 891 skb_push(skb, -skb_network_offset(pkt)); 892 893 skb_push(skb, sizeof(*msg)); 894 skb_reset_transport_header(skb); 895 msg = (struct mrt6msg *)skb_transport_header(skb); 896 msg->im6_mbz = 0; 897 msg->im6_msgtype = MRT6MSG_WHOLEPKT; 898 msg->im6_mif = reg_vif_num; 899 msg->im6_pad = 0; 900 ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr); 901 ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr); 902 903 skb->ip_summed = CHECKSUM_UNNECESSARY; 904 } else 905#endif 906 { 907 908 /* 909 * Copy the IP header 910 */ 911#if 0 //bob modified 912 skb->nh.ipv6h = (struct ipv6hdr *)skb_put(skb, sizeof(struct ipv6hdr)); 913 memcpy(skb->data,pkt->data,sizeof(struct ipv6hdr)); 914 915 msg = (struct mrt6msg*)skb->nh.ipv6h; 916 skb->dst = dst_clone(pkt->dst); 917#endif 918 skb_put(skb, sizeof(struct ipv6hdr)); 919 skb_reset_network_header(skb); 920 skb_copy_to_linear_data(skb, ipv6_hdr(pkt), sizeof(struct ipv6hdr)); 921 /* 922 * Add our header 923 */ 924 925#if 0 926 msg->im6_msgtype = assert; 927 msg->im6_mbz = 0; 928 msg->im6_mif = vifi; 929 skb->h.raw = skb->nh.raw; 930 } 931 932 if (mroute6_socket == NULL) { 933 kfree_skb(skb); 934 return -EINVAL; 935 } 936#endif 937 skb_put(skb, sizeof(*msg)); 938 skb_reset_transport_header(skb); 939 msg = (struct mrt6msg *)skb_transport_header(skb); 940 941 msg->im6_mbz = 0; 942 msg->im6_msgtype = assert; 943 msg->im6_mif = vifi; 944 msg->im6_pad = 0; 945 ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr); 946 ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr); 947 948 skb->dst = dst_clone(pkt->dst); 949 skb->ip_summed = CHECKSUM_UNNECESSARY; 950 951 skb_pull(skb, sizeof(struct ipv6hdr)); 952 } 953 954 if (mroute6_socket == NULL) { 955 kfree_skb(skb); 956 return -EINVAL; 957 } 958 /* 959 * Deliver to user space multicast routing algorithms 960 */ 961 if ((ret=sock_queue_rcv_skb(mroute6_socket,skb))<0) { 962 if (net_ratelimit()) 963 printk(KERN_WARNING "mroute6: pending queue full, dropping entries.\n"); 964 kfree_skb(skb); 965 } 966 967 return ret; 968} 969 970/* 971 * Queue a packet for resolution. It gets locked cache entry! 972 */ 973 974static int 975ip6mr_cache_unresolved(vifi_t vifi, struct sk_buff *skb) 976{ 977 int err; 978 struct mfc6_cache *c; 979 980 spin_lock_bh(&mfc_unres_lock); 981 for (c=mfc_unres_queue; c; c=c->next) { 982 //if (IN6_ARE_ADDR_EQUAL(&c->mf6c_mcastgrp,&skb->nh.ipv6h->daddr) && 983 // IN6_ARE_ADDR_EQUAL(&c->mf6c_origin,&skb->nh.ipv6h->saddr)) 984 if (ipv6_addr_equal(&c->mf6c_mcastgrp, &ipv6_hdr(skb)->daddr) && //bob modified 985 ipv6_addr_equal(&c->mf6c_origin, &ipv6_hdr(skb)->saddr)) 986 break; 987 } 988 989 if (c == NULL) { 990 /* 991 * Create a new entry if allowable 992 */ 993 994 if (atomic_read(&cache_resolve_queue_len)>=10 || 995 (c=ip6mr_cache_alloc_unres())==NULL) { 996 spin_unlock_bh(&mfc_unres_lock); 997 998 kfree_skb(skb); 999 return -ENOBUFS; 1000 } 1001 1002 /* 1003 * Fill in the new cache entry 1004 */ 1005 c->mf6c_parent=-1; 1006 //c->mf6c_origin=skb->nh.ipv6h->saddr; //bob modifed 1007 c->mf6c_origin = ipv6_hdr(skb)->saddr; 1008 //c->mf6c_mcastgrp=skb->nh.ipv6h->daddr; 1009 c->mf6c_mcastgrp = ipv6_hdr(skb)->daddr; 1010 1011 /* 1012 * Reflect first query at pim6sd 1013 */ 1014 if ((err = ip6mr_cache_report(skb, vifi, MRT6MSG_NOCACHE))<0) { 1015 /* If the report failed throw the cache entry 1016 out - Brad Parker 1017 */ 1018 spin_unlock_bh(&mfc_unres_lock); 1019 1020 kmem_cache_free(mrt_cachep, c); 1021 kfree_skb(skb); 1022 return err; 1023 } 1024 1025 atomic_inc(&cache_resolve_queue_len); 1026 c->next = mfc_unres_queue; 1027 mfc_unres_queue = c; 1028 1029 mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires); 1030 } 1031 1032 /* 1033 * See if we can append the packet 1034 */ 1035 if (c->mfc_un.unres.unresolved.qlen>3) { 1036 kfree_skb(skb); 1037 err = -ENOBUFS; 1038 } else { 1039 skb_queue_tail(&c->mfc_un.unres.unresolved,skb); 1040 err = 0; 1041 } 1042 1043 spin_unlock_bh(&mfc_unres_lock); 1044 return err; 1045} 1046 1047/* 1048 * MFC6 cache manipulation by user space 1049 */ 1050 1051static int ip6mr_mfc_delete(struct mf6cctl *mfc) 1052{ 1053 int line; 1054 struct mfc6_cache *c, **cp; 1055 1056 line=MFC6_HASH(mfc->mf6cc_mcastgrp.sin6_addr, mfc->mf6cc_origin.sin6_addr); 1057 1058 for (cp=&mfc6_cache_array[line]; (c=*cp) != NULL; cp = &c->next) { 1059 if (IN6_ARE_ADDR_EQUAL(&c->mf6c_origin,&mfc->mf6cc_origin.sin6_addr) && 1060 IN6_ARE_ADDR_EQUAL(&c->mf6c_mcastgrp,&mfc->mf6cc_mcastgrp.sin6_addr)) { 1061 write_lock_bh(&mrt_lock); 1062 *cp = c->next; 1063 write_unlock_bh(&mrt_lock); 1064 1065 kmem_cache_free(mrt_cachep, c); 1066 return 0; 1067 } 1068 } 1069 return -ENOENT; 1070} 1071 1072static int ip6mr_device_event(struct notifier_block *this, unsigned long event, void *ptr) 1073{ 1074 struct mif_device *v; 1075 int ct; 1076 if (event != NETDEV_UNREGISTER) 1077 return NOTIFY_DONE; 1078 v=&vif6_table[0]; 1079 for(ct=0;ct<maxvif;ct++,v++) { 1080 if (v->dev==ptr) 1081 mif6_delete(ct); 1082 } 1083 return NOTIFY_DONE; 1084} 1085 1086static struct notifier_block ip6_mr_notifier = { 1087 .notifier_call = ip6mr_device_event 1088}; 1089 1090/* 1091 * Setup for IP multicast routing 1092 */ 1093 1094void __init ip6_mr_init(void) 1095{ 1096 printk(KERN_INFO "6WIND/LSIIT IPv6 multicast forwarding 0.1 plus PIM-SM/SSM with *BSD API\n"); 1097 1098 mrt_cachep = kmem_cache_create("ip6_mrt_cache", 1099 sizeof(struct mfc6_cache), 1100 0, SLAB_HWCACHE_ALIGN, 1101 NULL, NULL); 1102 if (!mrt_cachep) 1103 panic("cannot allocate ip_mrt_cache"); 1104 1105 init_timer(&ipmr_expire_timer); 1106 ipmr_expire_timer.function=ipmr_expire_process; 1107 register_netdevice_notifier(&ip6_mr_notifier); 1108#ifdef CONFIG_PROC_FS 1109 proc_net_fops_create("ip6_mr_vif", 0, &ip6mr_vif_fops); 1110 proc_net_fops_create("ip6_mr_cache", 0, &ip6mr_mfc_fops); 1111#endif 1112} 1113 1114 1115static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock) 1116{ 1117 int line; 1118 struct mfc6_cache *uc, *c, **cp; 1119 unsigned char ttls[MAXVIFS]; 1120 int i; 1121 1122 memset(ttls, 255, MAXVIFS); 1123 for(i=0;i<MAXVIFS;i++) { 1124 if(IF_ISSET(i,&mfc->mf6cc_ifset)) { 1125 ttls[i]=1; 1126 } 1127 1128 } 1129 1130 line=MFC6_HASH(mfc->mf6cc_mcastgrp.sin6_addr, mfc->mf6cc_origin.sin6_addr); 1131 1132 for (cp=&mfc6_cache_array[line]; (c=*cp) != NULL; cp = &c->next) { 1133 if (IN6_ARE_ADDR_EQUAL(&c->mf6c_origin,&mfc->mf6cc_origin.sin6_addr) && 1134 IN6_ARE_ADDR_EQUAL(&c->mf6c_mcastgrp,&mfc->mf6cc_mcastgrp.sin6_addr)) 1135 break; 1136 } 1137 1138 if (c != NULL) { 1139 write_lock_bh(&mrt_lock); 1140 c->mf6c_parent = mfc->mf6cc_parent; 1141 ip6mr_update_threshoulds(c, ttls); 1142 if (!mrtsock) 1143 c->mfc_flags |= MFC_STATIC; 1144 write_unlock_bh(&mrt_lock); 1145 return 0; 1146 } 1147 1148 if(!(ipv6_addr_type(&mfc->mf6cc_mcastgrp.sin6_addr)&IPV6_ADDR_MULTICAST)) 1149 return -EINVAL; 1150 1151 c=ip6mr_cache_alloc(); 1152 if (c==NULL) 1153 return -ENOMEM; 1154 1155 c->mf6c_origin=mfc->mf6cc_origin.sin6_addr; 1156 c->mf6c_mcastgrp=mfc->mf6cc_mcastgrp.sin6_addr; 1157 c->mf6c_parent=mfc->mf6cc_parent; 1158 ip6mr_update_threshoulds(c, ttls); 1159 if (!mrtsock) 1160 c->mfc_flags |= MFC_STATIC; 1161 1162 write_lock_bh(&mrt_lock); 1163 c->next = mfc6_cache_array[line]; 1164 mfc6_cache_array[line] = c; 1165 write_unlock_bh(&mrt_lock); 1166 1167 /* 1168 * Check to see if we resolved a queued list. If so we 1169 * need to send on the frames and tidy up. 1170 */ 1171 spin_lock_bh(&mfc_unres_lock); 1172 for (cp = &mfc_unres_queue; (uc=*cp) != NULL; 1173 cp = &uc->next) { 1174 if (IN6_ARE_ADDR_EQUAL(&uc->mf6c_origin,&c->mf6c_origin) && 1175 IN6_ARE_ADDR_EQUAL(&uc->mf6c_mcastgrp,&c->mf6c_mcastgrp)) { 1176 *cp = uc->next; 1177 if (atomic_dec_and_test(&cache_resolve_queue_len)) 1178 del_timer(&ipmr_expire_timer); 1179 break; 1180 } 1181 } 1182 spin_unlock_bh(&mfc_unres_lock); 1183 1184 if (uc) { 1185 ip6mr_cache_resolve(uc, c); 1186 kmem_cache_free(mrt_cachep, uc); 1187 } 1188 return 0; 1189} 1190 1191/* 1192 * Close the multicast socket, and clear the vif tables etc 1193 */ 1194 1195static void mroute_clean_tables(struct sock *sk) 1196{ 1197 int i; 1198 1199 /* 1200 * Shut down all active vif entries 1201 */ 1202 for(i=0; i<maxvif; i++) { 1203 if (!(vif6_table[i].flags&VIFF_STATIC)) 1204 mif6_delete(i); 1205 } 1206 1207 /* 1208 * Wipe the cache 1209 */ 1210 for (i=0;i<MFC_LINES;i++) { 1211 struct mfc6_cache *c, **cp; 1212 1213 cp = &mfc6_cache_array[i]; 1214 while ((c = *cp) != NULL) { 1215 if (c->mfc_flags&MFC_STATIC) { 1216 cp = &c->next; 1217 continue; 1218 } 1219 write_lock_bh(&mrt_lock); 1220 *cp = c->next; 1221 write_unlock_bh(&mrt_lock); 1222 1223 kmem_cache_free(mrt_cachep, c); 1224 } 1225 } 1226 1227 if (atomic_read(&cache_resolve_queue_len) != 0) { 1228 struct mfc6_cache *c; 1229 1230 spin_lock_bh(&mfc_unres_lock); 1231 while (mfc_unres_queue != NULL) { 1232 c = mfc_unres_queue; 1233 mfc_unres_queue = c->next; 1234 spin_unlock_bh(&mfc_unres_lock); 1235 1236 ip6mr_destroy_unres(c); 1237 1238 spin_lock_bh(&mfc_unres_lock); 1239 } 1240 spin_unlock_bh(&mfc_unres_lock); 1241 } 1242} 1243 1244static void mrtsock_destruct(struct sock *sk) 1245{ 1246 rtnl_lock(); 1247 if (sk == mroute6_socket) { 1248 ipv6_devconf.mc_forwarding--; 1249 1250 write_lock_bh(&mrt_lock); 1251 mroute6_socket=NULL; 1252 write_unlock_bh(&mrt_lock); 1253 1254 mroute_clean_tables(sk); 1255 } 1256 rtnl_unlock(); 1257} 1258 1259/* 1260 * Socket options and virtual interface manipulation. The whole 1261 * virtual interface system is a complete heap, but unfortunately 1262 * that's how BSD mrouted happens to think. Maybe one day with a proper 1263 * MOSPF/PIM router set up we can clean this up. 1264 */ 1265 1266int ip6_mroute_setsockopt(struct sock *sk,int optname,char __user *optval,int optlen) 1267{ 1268 int ret; 1269 struct mif6ctl vif; 1270 struct mf6cctl mfc; 1271 mifi_t mifi; 1272 1273 if(optname!=MRT6_INIT) 1274 { 1275 if(sk!=mroute6_socket && !capable(CAP_NET_ADMIN)) 1276 return -EACCES; 1277 } 1278 1279 switch(optname) 1280 { 1281 case MRT6_INIT: 1282 if (sk->sk_type != SOCK_RAW || 1283 inet_sk(sk)->num != IPPROTO_ICMPV6) 1284 return -EOPNOTSUPP; 1285 if(optlen!=sizeof(int)) 1286 return -ENOPROTOOPT; 1287 1288 rtnl_lock(); 1289 if (mroute6_socket) { 1290 rtnl_unlock(); 1291 return -EADDRINUSE; 1292 } 1293 1294 ret = ip6_ra_control(sk, 1, mrtsock_destruct); 1295 if (ret == 0) { 1296 write_lock_bh(&mrt_lock); 1297 mroute6_socket=sk; 1298 write_unlock_bh(&mrt_lock); 1299 1300 ipv6_devconf.mc_forwarding++; 1301 } 1302 rtnl_unlock(); 1303 return ret; 1304 case MRT6_DONE: 1305 if (sk!=mroute6_socket) 1306 return -EACCES; 1307 return ip6_ra_control(sk, -1, NULL); 1308 case MRT6_ADD_MIF: 1309 if(optlen!=sizeof(vif)) 1310 return -EINVAL; 1311 if (copy_from_user(&vif,optval,sizeof(vif))) 1312 return -EFAULT; 1313 if(vif.mif6c_mifi >= MAXVIFS) 1314 return -ENFILE; 1315 rtnl_lock(); 1316 ret = mif6_add(&vif, sk==mroute6_socket); 1317 rtnl_unlock(); 1318 return ret; 1319 case MRT6_DEL_MIF: 1320 if(optlen!=sizeof(mifi_t)) 1321 return -EINVAL; 1322 if (copy_from_user(&mifi,optval,sizeof(mifi_t))) 1323 return -EFAULT; 1324 rtnl_lock(); 1325 ret = mif6_delete(mifi); 1326 rtnl_unlock(); 1327 return ret; 1328 1329 /* 1330 * Manipulate the forwarding caches. These live 1331 * in a sort of kernel/user symbiosis. 1332 */ 1333 case MRT6_ADD_MFC: 1334 case MRT6_DEL_MFC: 1335 if(optlen!=sizeof(mfc)) 1336 return -EINVAL; 1337 if (copy_from_user(&mfc,optval, sizeof(mfc))) 1338 return -EFAULT; 1339 rtnl_lock(); 1340 if (optname==MRT6_DEL_MFC) 1341 ret = ip6mr_mfc_delete(&mfc); 1342 else 1343 ret = ip6mr_mfc_add(&mfc, sk==mroute6_socket); 1344 rtnl_unlock(); 1345 return ret; 1346 /* 1347 * Control PIM assert (to activate pim will activate assert) 1348 */ 1349 case MRT6_ASSERT: 1350 { 1351 int v; 1352 if(get_user(v,(int __user *)optval)) 1353 return -EFAULT; 1354 mroute_do_assert=(v)?1:0; 1355 return 0; 1356 } 1357#ifdef CONFIG_IPV6_PIMSM_V2 1358 case MRT6_PIM: 1359 { 1360 int v, ret; 1361 if(get_user(v,(int __user *)optval)) 1362 return -EFAULT; 1363 v = (v)?1:0; 1364 rtnl_lock(); 1365 ret = 0; 1366 if (v != mroute_do_pim) { 1367 mroute_do_pim = v; 1368 mroute_do_assert = v; 1369 if (mroute_do_pim) 1370 ret = inet6_add_protocol(&pim6_protocol, 1371 IPPROTO_PIM); 1372 else 1373 ret = inet6_del_protocol(&pim6_protocol, 1374 IPPROTO_PIM); 1375 if (ret < 0) 1376 ret = -EAGAIN; 1377 } 1378 rtnl_unlock(); 1379 return ret; 1380 } 1381#endif 1382 /* 1383 * Spurious command, or MRT_VERSION which you cannot 1384 * set. 1385 */ 1386 default: 1387 return -ENOPROTOOPT; 1388 } 1389} 1390 1391/* 1392 * Getsock opt support for the multicast routing system. 1393 */ 1394 1395int ip6_mroute_getsockopt(struct sock *sk,int optname,char __user *optval,int __user *optlen) 1396{ 1397 int olr; 1398 int val; 1399 1400 if(optname!=MRT6_VERSION && 1401#ifdef CONFIG_IPV6_PIMSM_V2 1402 optname!=MRT6_PIM && 1403#endif 1404 optname!=MRT6_ASSERT) 1405 return -ENOPROTOOPT; 1406 1407 if (get_user(olr, optlen)) 1408 return -EFAULT; 1409 1410 olr = min_t(unsigned int, olr, sizeof(int)); 1411 if (olr < 0) 1412 return -EINVAL; 1413 1414 if(put_user(olr,optlen)) 1415 return -EFAULT; 1416 if(optname==MRT6_VERSION) 1417 val=0x0305; 1418#ifdef CONFIG_IPV6_PIMSM_V2 1419 else if(optname==MRT6_PIM) 1420 val=mroute_do_pim; 1421#endif 1422 else 1423 val=mroute_do_assert; 1424 if(copy_to_user(optval,&val,olr)) 1425 return -EFAULT; 1426 return 0; 1427} 1428 1429/* 1430 * The IP multicast ioctl support routines. 1431 */ 1432 1433int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) 1434{ 1435 struct sioc_sg_req6 sr; 1436 struct sioc_mif_req6 vr; 1437 struct mif_device *vif; 1438 struct mfc6_cache *c; 1439 1440 switch(cmd) 1441 { 1442 case SIOCGETMIFCNT_IN6: 1443 if (copy_from_user(&vr,arg,sizeof(vr))) 1444 return -EFAULT; 1445 if(vr.mifi>=maxvif) 1446 return -EINVAL; 1447 read_lock(&mrt_lock); 1448 vif=&vif6_table[vr.mifi]; 1449 if(MIF_EXISTS(vr.mifi)) { 1450 vr.icount=vif->pkt_in; 1451 vr.ocount=vif->pkt_out; 1452 vr.ibytes=vif->bytes_in; 1453 vr.obytes=vif->bytes_out; 1454 read_unlock(&mrt_lock); 1455 1456 if (copy_to_user(arg,&vr,sizeof(vr))) 1457 return -EFAULT; 1458 return 0; 1459 } 1460 read_unlock(&mrt_lock); 1461 return -EADDRNOTAVAIL; 1462 case SIOCGETSGCNT_IN6: 1463 if (copy_from_user(&sr,arg,sizeof(sr))) 1464 return -EFAULT; 1465 1466 read_lock(&mrt_lock); 1467 c = ip6mr_cache_find(sr.src.sin6_addr, sr.grp.sin6_addr); 1468 if (c) { 1469 sr.pktcnt = c->mfc_un.res.pkt; 1470 sr.bytecnt = c->mfc_un.res.bytes; 1471 sr.wrong_if = c->mfc_un.res.wrong_if; 1472 read_unlock(&mrt_lock); 1473 1474 if (copy_to_user(arg,&sr,sizeof(sr))) 1475 return -EFAULT; 1476 return 0; 1477 } 1478 read_unlock(&mrt_lock); 1479 return -EADDRNOTAVAIL; 1480 default: 1481 return -ENOIOCTLCMD; 1482 } 1483} 1484 1485 1486static inline int ip6mr_forward_finish(struct sk_buff *skb) 1487{ 1488#ifdef notyet 1489 struct ip_options * opt = &(IP6CB(skb)->opt); 1490 1491 IP_INC_STATS_BH(OutForwDatagrams); 1492 1493 if (unlikely(opt->optlen)) 1494 ip_forward_options(skb); 1495#endif 1496 1497 return dst_output(skb); 1498} 1499 1500/* 1501 * Processing handlers for ip6mr_forward 1502 */ 1503 1504static void ip6mr_queue_xmit(struct sk_buff *skb, struct mfc6_cache *c, int vifi) 1505{ 1506 //struct ipv6hdr *ipv6h = skb->nh.ipv6h; //bob modified 1507 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 1508 struct mif_device *vif = &vif6_table[vifi]; 1509 struct net_device *dev; 1510 struct in6_addr *snd_addr=&ipv6h->daddr; 1511 int full_len = skb->len; 1512 1513 if (vif->dev == NULL) 1514 goto out_free; 1515 1516#ifdef CONFIG_IPV6_PIMSM_V2 1517 if (vif->flags & MIFF_REGISTER) { 1518 vif->pkt_out++; 1519 vif->bytes_out+=skb->len; 1520 ((struct net_device_stats*)vif->dev->priv)->tx_bytes += skb->len; 1521 ((struct net_device_stats*)vif->dev->priv)->tx_packets++; 1522 ip6mr_cache_report(skb, vifi, MRT6MSG_WHOLEPKT); 1523 kfree_skb(skb); 1524 return; 1525 } 1526#endif 1527 /* 1528 * RFC1584 teaches, that DVMRP/PIM router must deliver packets locally 1529 * not only before forwarding, but after forwarding on all output 1530 * interfaces. It is clear, if mrouter runs a multicasting 1531 * program, it should receive packets not depending to what interface 1532 * program is joined. 1533 * If we will not make it, the program will have to join on all 1534 * interfaces. On the other hand, multihoming host (or router, but 1535 * not mrouter) cannot join to more than one interface - it will 1536 * result in receiving multiple packets. 1537 */ 1538 dev = vif->dev; 1539 skb->dev=dev; 1540 vif->pkt_out++; 1541 vif->bytes_out+=skb->len; 1542 1543 //ipv6h = skb->nh.ipv6h; //bob modified 1544 ipv6h = ipv6_hdr(skb); 1545 1546 ipv6h->hop_limit--; 1547 1548 if(dev->hard_header) { 1549 unsigned char ha[MAX_ADDR_LEN]; 1550 ndisc_mc_map(snd_addr,ha,dev,1); 1551 if(dev->hard_header(skb,dev, ETH_P_IPV6,ha,NULL,full_len) < 0) 1552 goto out_free; 1553 } 1554 1555 NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, skb->dev, dev, 1556 dev_queue_xmit); 1557/* NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, skb->dev, dev, 1558 ip6mr_forward_finish); 1559*/ 1560 1561 1562 /* NF_HOOK(PF_INET6, NF_IP6_FORWARD, skb, skb->dev, dev, 1563 ip6mr_forward_finish); 1564 */ 1565 return; 1566 /* XXX */ 1567 1568out_free: 1569 kfree_skb(skb); 1570 return; 1571} 1572 1573static int ip6mr_find_vif(struct net_device *dev) 1574{ 1575 int ct; 1576 for (ct=maxvif-1; ct>=0; ct--) { 1577 if (vif6_table[ct].dev == dev) 1578 break; 1579 } 1580 return ct; 1581} 1582 1583static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache, int local) 1584{ 1585 int psend = -1; 1586 int vif, ct; 1587 struct dst_entry *dst = skb->dst; 1588 static struct net_device *lan_device = NULL; 1589 1590 vif = cache->mf6c_parent; 1591 cache->mfc_un.res.pkt++; 1592 cache->mfc_un.res.bytes += skb->len; 1593 1594 /* Bob added start, 08/19/2009, ipv6ready v6LC.1.1.10 part J */ 1595 if(! (ipv6_hdr(skb)->daddr.s6_addr[1] & 0x0f)) 1596 { 1597 goto dont_forward; 1598 } 1599 /* Bob added end, 08/19/2009, ipv6ready v6LC.1.1.10 part J */ 1600 1601 /* Bob added start, 08/19/2009, ipv6ready v6LC.5.1.4 part B */ 1602 if(!lan_device) 1603 lan_device = dev_get_by_name("eth0"); //todo: not to hardcode br0 1604 //lan_device = dev_get_by_name("br0"); //todo: not to hardcode br0 1605 if (skb->len > lan_device->mtu) 1606 { 1607 skb->dev = lan_device; 1608 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, lan_device->mtu, skb->dev); 1609 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); 1610 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS); 1611 kfree_skb(skb); 1612 return -EMSGSIZE; 1613 } 1614 /* Bob added end, 08/19/2009, ipv6ready v6LC.5.1.4 part B */ 1615 1616 /* 1617 * Wrong interface: drop packet and (maybe) send PIM assert. 1618 */ 1619 if (vif6_table[vif].dev != skb->dev) { 1620 int true_vifi; 1621 1622 if (((struct rtable*)skb->dst)->fl.iif == 0) { 1623 /* It is our own packet, looped back. 1624 Very complicated situation... 1625 1626 The best workaround until routing daemons will be 1627 fixed is not to redistribute packet, if it was 1628 send through wrong interface. It means, that 1629 multicast applications WILL NOT work for 1630 (S,G), which have default multicast route pointing 1631 to wrong oif. In any case, it is not a good 1632 idea to use multicasting applications on router. 1633 */ 1634 goto dont_forward; 1635 } 1636 1637 cache->mfc_un.res.wrong_if++; 1638 true_vifi = ip6mr_find_vif(skb->dev); 1639 1640 if (true_vifi >= 0 && mroute_do_assert && 1641 /* pimsm uses asserts, when switching from RPT to SPT, 1642 so that we cannot check that packet arrived on an oif. 1643 It is bad, but otherwise we would need to move pretty 1644 large chunk of pimd to kernel. Ough... --ANK 1645 */ 1646 (mroute_do_pim || cache->mfc_un.res.ttls[true_vifi] < 255) && 1647 time_after(jiffies, 1648 cache->mfc_un.res.last_assert + MFC_ASSERT_THRESH)) { 1649 cache->mfc_un.res.last_assert = jiffies; 1650 ip6mr_cache_report(skb, true_vifi, MRT6MSG_WRONGMIF); 1651 } 1652 goto dont_forward; 1653 } 1654 1655 vif6_table[vif].pkt_in++; 1656 vif6_table[vif].bytes_in+=skb->len; 1657 1658 /* 1659 * Forward the frame 1660 */ 1661 for (ct = cache->mfc_un.res.maxvif-1; ct >= cache->mfc_un.res.minvif; ct--) { 1662 //if (skb->nh.ipv6h->hop_limit > cache->mfc_un.res.ttls[ct]) { //bob modified 1663 if (ipv6_hdr(skb)->hop_limit > cache->mfc_un.res.ttls[ct]) { //bob modified 1664 //struct ipv6hdr *ipv6h = skb->nh.ipv6h; //bob modified 1665 struct ipv6hdr *ipv6h = ipv6_hdr(skb); //bob modified 1666 if (psend != -1) { 1667 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); 1668 if (skb2) { 1669 ip6mr_queue_xmit(skb2, cache, psend); 1670 ipv6h->hop_limit++; 1671 } 1672 } 1673 psend=ct; 1674 } 1675 } 1676 if (psend != -1) { 1677 //struct ipv6hdr *ipv6h = skb->nh.ipv6h; //bob modified 1678 struct ipv6hdr *ipv6h = ipv6_hdr(skb); //bob modified 1679 if (local) { 1680 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); 1681 if (skb2) { 1682 ip6mr_queue_xmit(skb2, cache, psend); 1683 ipv6h->hop_limit++; 1684 } 1685 } else { 1686 ip6mr_queue_xmit(skb, cache, psend); 1687 ipv6h->hop_limit++; 1688 return 0; 1689 } 1690 } 1691 1692dont_forward: 1693 if (!local) 1694 kfree_skb(skb); 1695 return 0; 1696} 1697 1698 1699/* 1700 * Multicast packets for forwarding arrive here 1701 */ 1702 1703int ip6_mr_input(struct sk_buff *skb) 1704{ 1705 struct mfc6_cache *cache; 1706 int local = ((struct rt6_info*)skb->dst)->rt6i_flags&RTCF_LOCAL; 1707 IP6CB(skb)->flags = 0; 1708 1709 read_lock(&mrt_lock); 1710 //cache = ip6mr_cache_find(skb->nh.ipv6h->saddr, skb->nh.ipv6h->daddr); 1711 cache = ip6mr_cache_find(ipv6_hdr(skb)->saddr, ipv6_hdr(skb)->daddr); 1712 1713 /* 1714 * No usable cache entry 1715 */ 1716 if (cache==NULL) { 1717 int vif; 1718 1719 vif = ip6mr_find_vif(skb->dev); 1720 if (vif >= 0) { 1721 int err = ip6mr_cache_unresolved(vif, skb); 1722 read_unlock(&mrt_lock); 1723 1724 return err; 1725 } 1726 read_unlock(&mrt_lock); 1727 kfree_skb(skb); 1728 return -ENODEV; 1729 } 1730 1731 ip6_mr_forward(skb, cache, local); 1732 1733 read_unlock(&mrt_lock); 1734 1735 return 0; 1736 1737dont_forward: 1738 kfree_skb(skb); 1739 return 0; 1740} 1741 1742 1743static int 1744ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm) 1745{ 1746 int ct; 1747 struct rtnexthop *nhp; 1748 struct net_device *dev = vif6_table[c->mf6c_parent].dev; 1749 u8 *b = skb->tail; 1750 struct rtattr *mp_head; 1751 1752 if (dev) 1753 RTA_PUT(skb, RTA_IIF, 4, &dev->ifindex); 1754 1755 mp_head = (struct rtattr*)skb_put(skb, RTA_LENGTH(0)); 1756 1757 for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { 1758 if (c->mfc_un.res.ttls[ct] < 255) { 1759 if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) 1760 goto rtattr_failure; 1761 nhp = (struct rtnexthop*)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); 1762 nhp->rtnh_flags = 0; 1763 nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; 1764 nhp->rtnh_ifindex = vif6_table[ct].dev->ifindex; 1765 nhp->rtnh_len = sizeof(*nhp); 1766 } 1767 } 1768 mp_head->rta_type = RTA_MULTIPATH; 1769 mp_head->rta_len = skb->tail - (u8*)mp_head; 1770 rtm->rtm_type = RTN_MULTICAST; 1771 return 1; 1772 1773rtattr_failure: 1774 skb_trim(skb, b - skb->data); 1775 return -EMSGSIZE; 1776} 1777