1 /* $FreeBSD$ */ 2 /* $KAME: ip6_mroute.c,v 1.58 2001/12/18 02:36:31 itojun Exp $ */ 3 4 /*- 5 * Copyright (C) 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 /* BSDI ip_mroute.c,v 2.10 1996/11/14 00:29:52 jch Exp */ 34 35 /*- 36 * Copyright (c) 1989 Stephen Deering 37 * Copyright (c) 1992, 1993 38 * The Regents of the University of California. All rights reserved. 39 * 40 * This code is derived from software contributed to Berkeley by 41 * Stephen Deering of Stanford University. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 4. Neither the name of the University nor the names of its contributors 52 * may be used to endorse or promote products derived from this software 53 * without specific prior written permission. 54 * 55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 58 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 65 * SUCH DAMAGE. 66 * 67 * @(#)ip_mroute.c 8.2 (Berkeley) 11/15/93 68 */ 69 70 /* 71 * IP multicast forwarding procedures 72 * 73 * Written by David Waitzman, BBN Labs, August 1988. 74 * Modified by Steve Deering, Stanford, February 1989. 75 * Modified by Mark J. Steiglitz, Stanford, May, 1991 76 * Modified by Van Jacobson, LBL, January 1993 77 * Modified by Ajit Thyagarajan, PARC, August 1993 78 * Modified by Bill Fenner, PARC, April 1994 79 * 80 * MROUTING Revision: 3.5.1.2 + PIM-SMv2 (pimd) Support 81 */ 82 83 #include "opt_inet.h" 84 #include "opt_inet6.h" 85 86 #include <sys/param.h> 87 #include <sys/callout.h> 88 #include <sys/errno.h> 89 #include <sys/kernel.h> 90 #include <sys/lock.h> 91 #include <sys/malloc.h> 92 #include <sys/mbuf.h> 93 #include <sys/protosw.h> 94 #include <sys/signalvar.h> 95 #include <sys/socket.h> 96 #include <sys/socketvar.h> 97 #include <sys/sockio.h> 98 #include <sys/sx.h> 99 #include <sys/syslog.h> 100 #include <sys/systm.h> 101 #include <sys/time.h> 102 103 #include <net/if.h> 104 #include <net/raw_cb.h> 105 #include <net/route.h> 106 107 #include <netinet/in.h> 108 #include <netinet/in_var.h> 109 110 #include <netinet/ip6.h> 111 #include <netinet6/ip6_var.h> 112 #include <netinet6/nd6.h> 113 #include <netinet6/ip6_mroute.h> 114 #include <netinet6/pim6.h> 115 #include <netinet6/pim6_var.h> 116 117 #include <net/net_osdep.h> 118 119 static MALLOC_DEFINE(M_MRTABLE, "mf6c", "multicast forwarding cache entry"); 120 121 #define M_HASCL(m) ((m)->m_flags & M_EXT) 122 123 static int ip6_mdq __P((struct mbuf *, struct ifnet *, struct mf6c *)); 124 static void phyint_send __P((struct ip6_hdr *, struct mif6 *, struct mbuf *)); 125 126 static int set_pim6 __P((int *)); 127 static int socket_send __P((struct socket *, struct mbuf *, 128 struct sockaddr_in6 *)); 129 static int register_send __P((struct ip6_hdr *, struct mif6 *, 130 struct mbuf *)); 131 132 /* 133 * Globals. All but ip6_mrouter, ip6_mrtproto and mrt6stat could be static, 134 * except for netstat or debugging purposes. 135 */ 136 struct socket *ip6_mrouter = NULL; 137 int ip6_mrouter_ver = 0; 138 int ip6_mrtproto = IPPROTO_PIM; /* for netstat only */ 139 struct mrt6stat mrt6stat; 140 141 #define NO_RTE_FOUND 0x1 142 #define RTE_FOUND 0x2 143 144 struct mf6c *mf6ctable[MF6CTBLSIZ]; 145 u_char n6expire[MF6CTBLSIZ]; 146 static struct mif6 mif6table[MAXMIFS]; 147 #ifdef MRT6DEBUG 148 u_int mrt6debug = 0; /* debug level */ 149 #define DEBUG_MFC 0x02 150 #define DEBUG_FORWARD 0x04 151 #define DEBUG_EXPIRE 0x08 152 #define DEBUG_XMIT 0x10 153 #define DEBUG_REG 0x20 154 #define DEBUG_PIM 0x40 155 #endif 156 157 static void expire_upcalls __P((void *)); 158 #define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */ 159 #define UPCALL_EXPIRE 6 /* number of timeouts */ 160 161 #ifdef INET 162 #ifdef MROUTING 163 extern struct socket *ip_mrouter; 164 #endif 165 #endif 166 167 /* 168 * 'Interfaces' associated with decapsulator (so we can tell 169 * packets that went through it from ones that get reflected 170 * by a broken gateway). These interfaces are never linked into 171 * the system ifnet list & no routes point to them. I.e., packets 172 * can't be sent this way. They only exist as a placeholder for 173 * multicast source verification. 174 */ 175 struct ifnet multicast_register_if; 176 177 #define ENCAP_HOPS 64 178 179 /* 180 * Private variables. 181 */ 182 static mifi_t nummifs = 0; 183 static mifi_t reg_mif_num = (mifi_t)-1; 184 185 static struct pim6stat pim6stat; 186 static int pim6; 187 188 /* 189 * Hash function for a source, group entry 190 */ 191 #define MF6CHASH(a, g) MF6CHASHMOD((a).s6_addr32[0] ^ (a).s6_addr32[1] ^ \ 192 (a).s6_addr32[2] ^ (a).s6_addr32[3] ^ \ 193 (g).s6_addr32[0] ^ (g).s6_addr32[1] ^ \ 194 (g).s6_addr32[2] ^ (g).s6_addr32[3]) 195 196 /* 197 * Find a route for a given origin IPv6 address and Multicast group address. 198 * Quality of service parameter to be added in the future!!! 199 */ 200 201 #define MF6CFIND(o, g, rt) do { \ 202 struct mf6c *_rt = mf6ctable[MF6CHASH(o,g)]; \ 203 rt = NULL; \ 204 mrt6stat.mrt6s_mfc_lookups++; \ 205 while (_rt) { \ 206 if (IN6_ARE_ADDR_EQUAL(&_rt->mf6c_origin.sin6_addr, &(o)) && \ 207 IN6_ARE_ADDR_EQUAL(&_rt->mf6c_mcastgrp.sin6_addr, &(g)) && \ 208 (_rt->mf6c_stall == NULL)) { \ 209 rt = _rt; \ 210 break; \ 211 } \ 212 _rt = _rt->mf6c_next; \ 213 } \ 214 if (rt == NULL) { \ 215 mrt6stat.mrt6s_mfc_misses++; \ 216 } \ 217 } while (/*CONSTCOND*/ 0) 218 219 /* 220 * Macros to compute elapsed time efficiently 221 * Borrowed from Van Jacobson's scheduling code 222 */ 223 #define TV_DELTA(a, b, delta) do { \ 224 int xxs; \ 225 \ 226 delta = (a).tv_usec - (b).tv_usec; \ 227 if ((xxs = (a).tv_sec - (b).tv_sec)) { \ 228 switch (xxs) { \ 229 case 2: \ 230 delta += 1000000; \ 231 /* FALLTHROUGH */ \ 232 case 1: \ 233 delta += 1000000; \ 234 break; \ 235 default: \ 236 delta += (1000000 * xxs); \ 237 } \ 238 } \ 239 } while (/*CONSTCOND*/ 0) 240 241 #define TV_LT(a, b) (((a).tv_usec < (b).tv_usec && \ 242 (a).tv_sec <= (b).tv_sec) || (a).tv_sec < (b).tv_sec) 243 244 #ifdef UPCALL_TIMING 245 #define UPCALL_MAX 50 246 u_long upcall_data[UPCALL_MAX + 1]; 247 static void collate(); 248 #endif /* UPCALL_TIMING */ 249 250 static int get_sg_cnt __P((struct sioc_sg_req6 *)); 251 static int get_mif6_cnt __P((struct sioc_mif_req6 *)); 252 static int ip6_mrouter_init __P((struct socket *, int, int)); 253 static int add_m6if __P((struct mif6ctl *)); 254 static int del_m6if __P((mifi_t *)); 255 static int add_m6fc __P((struct mf6cctl *)); 256 static int del_m6fc __P((struct mf6cctl *)); 257 258 static struct callout expire_upcalls_ch; 259 260 /* 261 * Handle MRT setsockopt commands to modify the multicast routing tables. 262 */ 263 int 264 ip6_mrouter_set(so, sopt) 265 struct socket *so; 266 struct sockopt *sopt; 267 { 268 int error = 0; 269 int optval; 270 struct mif6ctl mifc; 271 struct mf6cctl mfcc; 272 mifi_t mifi; 273 274 if (so != ip6_mrouter && sopt->sopt_name != MRT6_INIT) 275 return (EACCES); 276 277 switch (sopt->sopt_name) { 278 case MRT6_INIT: 279 #ifdef MRT6_OINIT 280 case MRT6_OINIT: 281 #endif 282 error = sooptcopyin(sopt, &optval, sizeof(optval), 283 sizeof(optval)); 284 if (error) 285 break; 286 error = ip6_mrouter_init(so, optval, sopt->sopt_name); 287 break; 288 case MRT6_DONE: 289 error = ip6_mrouter_done(); 290 break; 291 case MRT6_ADD_MIF: 292 error = sooptcopyin(sopt, &mifc, sizeof(mifc), sizeof(mifc)); 293 if (error) 294 break; 295 error = add_m6if(&mifc); 296 break; 297 case MRT6_ADD_MFC: 298 error = sooptcopyin(sopt, &mfcc, sizeof(mfcc), sizeof(mfcc)); 299 if (error) 300 break; 301 error = add_m6fc(&mfcc); 302 break; 303 case MRT6_DEL_MFC: 304 error = sooptcopyin(sopt, &mfcc, sizeof(mfcc), sizeof(mfcc)); 305 if (error) 306 break; 307 error = del_m6fc(&mfcc); 308 break; 309 case MRT6_DEL_MIF: 310 error = sooptcopyin(sopt, &mifi, sizeof(mifi), sizeof(mifi)); 311 if (error) 312 break; 313 error = del_m6if(&mifi); 314 break; 315 case MRT6_PIM: 316 error = sooptcopyin(sopt, &optval, sizeof(optval), 317 sizeof(optval)); 318 if (error) 319 break; 320 error = set_pim6(&optval); 321 break; 322 default: 323 error = EOPNOTSUPP; 324 break; 325 } 326 327 return (error); 328 } 329 330 /* 331 * Handle MRT getsockopt commands 332 */ 333 int 334 ip6_mrouter_get(so, sopt) 335 struct socket *so; 336 struct sockopt *sopt; 337 { 338 int error = 0; 339 340 if (so != ip6_mrouter) 341 return (EACCES); 342 343 switch (sopt->sopt_name) { 344 case MRT6_PIM: 345 error = sooptcopyout(sopt, &pim6, sizeof(pim6)); 346 break; 347 } 348 return (error); 349 } 350 351 /* 352 * Handle ioctl commands to obtain information from the cache 353 */ 354 int 355 mrt6_ioctl(cmd, data) 356 int cmd; 357 caddr_t data; 358 { 359 switch (cmd) { 360 case SIOCGETSGCNT_IN6: 361 return (get_sg_cnt((struct sioc_sg_req6 *)data)); 362 case SIOCGETMIFCNT_IN6: 363 return (get_mif6_cnt((struct sioc_mif_req6 *)data)); 364 default: 365 return (EINVAL); 366 } 367 } 368 369 /* 370 * returns the packet, byte, rpf-failure count for the source group provided 371 */ 372 static int 373 get_sg_cnt(req) 374 struct sioc_sg_req6 *req; 375 { 376 struct mf6c *rt; 377 int s; 378 379 s = splnet(); 380 MF6CFIND(req->src.sin6_addr, req->grp.sin6_addr, rt); 381 splx(s); 382 if (rt != NULL) { 383 req->pktcnt = rt->mf6c_pkt_cnt; 384 req->bytecnt = rt->mf6c_byte_cnt; 385 req->wrong_if = rt->mf6c_wrong_if; 386 } else 387 return (ESRCH); 388 #if 0 389 req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff; 390 #endif 391 392 return (0); 393 } 394 395 /* 396 * returns the input and output packet and byte counts on the mif provided 397 */ 398 static int 399 get_mif6_cnt(req) 400 struct sioc_mif_req6 *req; 401 { 402 mifi_t mifi = req->mifi; 403 404 if (mifi >= nummifs) 405 return (EINVAL); 406 407 req->icount = mif6table[mifi].m6_pkt_in; 408 req->ocount = mif6table[mifi].m6_pkt_out; 409 req->ibytes = mif6table[mifi].m6_bytes_in; 410 req->obytes = mif6table[mifi].m6_bytes_out; 411 412 return (0); 413 } 414 415 static int 416 set_pim6(i) 417 int *i; 418 { 419 if ((*i != 1) && (*i != 0)) 420 return (EINVAL); 421 422 pim6 = *i; 423 424 return (0); 425 } 426 427 /* 428 * Enable multicast routing 429 */ 430 static int 431 ip6_mrouter_init(so, v, cmd) 432 struct socket *so; 433 int v; 434 int cmd; 435 { 436 #ifdef MRT6DEBUG 437 if (mrt6debug) 438 log(LOG_DEBUG, 439 "ip6_mrouter_init: so_type = %d, pr_protocol = %d\n", 440 so->so_type, so->so_proto->pr_protocol); 441 #endif 442 443 if (so->so_type != SOCK_RAW || 444 so->so_proto->pr_protocol != IPPROTO_ICMPV6) 445 return (EOPNOTSUPP); 446 447 if (v != 1) 448 return (ENOPROTOOPT); 449 450 if (ip6_mrouter != NULL) 451 return (EADDRINUSE); 452 453 ip6_mrouter = so; 454 ip6_mrouter_ver = cmd; 455 456 bzero((caddr_t)mf6ctable, sizeof(mf6ctable)); 457 bzero((caddr_t)n6expire, sizeof(n6expire)); 458 459 pim6 = 0;/* used for stubbing out/in pim stuff */ 460 461 callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT, 462 expire_upcalls, NULL); 463 464 #ifdef MRT6DEBUG 465 if (mrt6debug) 466 log(LOG_DEBUG, "ip6_mrouter_init\n"); 467 #endif 468 469 return (0); 470 } 471 472 /* 473 * Disable multicast routing 474 */ 475 int 476 ip6_mrouter_done() 477 { 478 mifi_t mifi; 479 int i; 480 struct ifnet *ifp; 481 struct in6_ifreq ifr; 482 struct mf6c *rt; 483 struct rtdetq *rte; 484 int s; 485 486 s = splnet(); 487 488 /* 489 * For each phyint in use, disable promiscuous reception of all IPv6 490 * multicasts. 491 */ 492 #ifdef INET 493 #ifdef MROUTING 494 /* 495 * If there is still IPv4 multicast routing daemon, 496 * we remain interfaces to receive all muliticasted packets. 497 * XXX: there may be an interface in which the IPv4 multicast 498 * daemon is not interested... 499 */ 500 if (!ip_mrouter) 501 #endif 502 #endif 503 { 504 for (mifi = 0; mifi < nummifs; mifi++) { 505 if (mif6table[mifi].m6_ifp && 506 !(mif6table[mifi].m6_flags & MIFF_REGISTER)) { 507 ifr.ifr_addr.sin6_family = AF_INET6; 508 ifr.ifr_addr.sin6_addr = in6addr_any; 509 ifp = mif6table[mifi].m6_ifp; 510 (*ifp->if_ioctl)(ifp, SIOCDELMULTI, 511 (caddr_t)&ifr); 512 } 513 } 514 } 515 #ifdef notyet 516 bzero((caddr_t)qtable, sizeof(qtable)); 517 bzero((caddr_t)tbftable, sizeof(tbftable)); 518 #endif 519 bzero((caddr_t)mif6table, sizeof(mif6table)); 520 nummifs = 0; 521 522 pim6 = 0; /* used to stub out/in pim specific code */ 523 524 callout_stop(&expire_upcalls_ch); 525 526 /* 527 * Free all multicast forwarding cache entries. 528 */ 529 for (i = 0; i < MF6CTBLSIZ; i++) { 530 rt = mf6ctable[i]; 531 while (rt) { 532 struct mf6c *frt; 533 534 for (rte = rt->mf6c_stall; rte != NULL; ) { 535 struct rtdetq *n = rte->next; 536 537 m_free(rte->m); 538 free(rte, M_MRTABLE); 539 rte = n; 540 } 541 frt = rt; 542 rt = rt->mf6c_next; 543 free(frt, M_MRTABLE); 544 } 545 } 546 547 bzero((caddr_t)mf6ctable, sizeof(mf6ctable)); 548 549 /* 550 * Reset de-encapsulation cache 551 */ 552 reg_mif_num = -1; 553 554 ip6_mrouter = NULL; 555 ip6_mrouter_ver = 0; 556 557 splx(s); 558 559 #ifdef MRT6DEBUG 560 if (mrt6debug) 561 log(LOG_DEBUG, "ip6_mrouter_done\n"); 562 #endif 563 564 return (0); 565 } 566 567 static struct sockaddr_in6 sin6 = { sizeof(sin6), AF_INET6 }; 568 569 /* 570 * Add a mif to the mif table 571 */ 572 static int 573 add_m6if(mifcp) 574 struct mif6ctl *mifcp; 575 { 576 struct mif6 *mifp; 577 struct ifnet *ifp; 578 int error, s; 579 #ifdef notyet 580 struct tbf *m_tbf = tbftable + mifcp->mif6c_mifi; 581 #endif 582 583 if (mifcp->mif6c_mifi >= MAXMIFS) 584 return (EINVAL); 585 mifp = mif6table + mifcp->mif6c_mifi; 586 if (mifp->m6_ifp) 587 return (EADDRINUSE); /* XXX: is it appropriate? */ 588 if (mifcp->mif6c_pifi == 0 || mifcp->mif6c_pifi > if_index) 589 return (ENXIO); 590 ifp = ifnet_byindex(mifcp->mif6c_pifi); 591 592 if (mifcp->mif6c_flags & MIFF_REGISTER) { 593 if (reg_mif_num == (mifi_t)-1) { 594 strlcpy(multicast_register_if.if_xname, "register_mif", 595 IFNAMSIZ); 596 multicast_register_if.if_flags |= IFF_LOOPBACK; 597 multicast_register_if.if_index = mifcp->mif6c_mifi; 598 reg_mif_num = mifcp->mif6c_mifi; 599 } 600 601 ifp = &multicast_register_if; 602 603 } /* if REGISTER */ 604 else { 605 /* Make sure the interface supports multicast */ 606 if ((ifp->if_flags & IFF_MULTICAST) == 0) 607 return (EOPNOTSUPP); 608 609 s = splnet(); 610 error = if_allmulti(ifp, 1); 611 splx(s); 612 if (error) 613 return (error); 614 } 615 616 s = splnet(); 617 mifp->m6_flags = mifcp->mif6c_flags; 618 mifp->m6_ifp = ifp; 619 #ifdef notyet 620 /* scaling up here allows division by 1024 in critical code */ 621 mifp->m6_rate_limit = mifcp->mif6c_rate_limit * 1024 / 1000; 622 #endif 623 /* initialize per mif pkt counters */ 624 mifp->m6_pkt_in = 0; 625 mifp->m6_pkt_out = 0; 626 mifp->m6_bytes_in = 0; 627 mifp->m6_bytes_out = 0; 628 splx(s); 629 630 /* Adjust nummifs up if the mifi is higher than nummifs */ 631 if (nummifs <= mifcp->mif6c_mifi) 632 nummifs = mifcp->mif6c_mifi + 1; 633 634 #ifdef MRT6DEBUG 635 if (mrt6debug) 636 log(LOG_DEBUG, 637 "add_mif #%d, phyint %s\n", 638 mifcp->mif6c_mifi, 639 ifp->if_xname); 640 #endif 641 642 return (0); 643 } 644 645 /* 646 * Delete a mif from the mif table 647 */ 648 static int 649 del_m6if(mifip) 650 mifi_t *mifip; 651 { 652 struct mif6 *mifp = mif6table + *mifip; 653 mifi_t mifi; 654 struct ifnet *ifp; 655 int s; 656 657 if (*mifip >= nummifs) 658 return (EINVAL); 659 if (mifp->m6_ifp == NULL) 660 return (EINVAL); 661 662 s = splnet(); 663 664 if (!(mifp->m6_flags & MIFF_REGISTER)) { 665 /* 666 * XXX: what if there is yet IPv4 multicast daemon 667 * using the interface? 668 */ 669 ifp = mifp->m6_ifp; 670 671 if_allmulti(ifp, 0); 672 } 673 674 #ifdef notyet 675 bzero((caddr_t)qtable[*mifip], sizeof(qtable[*mifip])); 676 bzero((caddr_t)mifp->m6_tbf, sizeof(*(mifp->m6_tbf))); 677 #endif 678 bzero((caddr_t)mifp, sizeof(*mifp)); 679 680 /* Adjust nummifs down */ 681 for (mifi = nummifs; mifi > 0; mifi--) 682 if (mif6table[mifi - 1].m6_ifp) 683 break; 684 nummifs = mifi; 685 686 splx(s); 687 688 #ifdef MRT6DEBUG 689 if (mrt6debug) 690 log(LOG_DEBUG, "del_m6if %d, nummifs %d\n", *mifip, nummifs); 691 #endif 692 693 return (0); 694 } 695 696 /* 697 * Add an mfc entry 698 */ 699 static int 700 add_m6fc(mfccp) 701 struct mf6cctl *mfccp; 702 { 703 struct mf6c *rt; 704 u_long hash; 705 struct rtdetq *rte; 706 u_short nstl; 707 int s; 708 709 MF6CFIND(mfccp->mf6cc_origin.sin6_addr, 710 mfccp->mf6cc_mcastgrp.sin6_addr, rt); 711 712 /* If an entry already exists, just update the fields */ 713 if (rt) { 714 #ifdef MRT6DEBUG 715 if (mrt6debug & DEBUG_MFC) 716 log(LOG_DEBUG, 717 "add_m6fc no upcall h %d o %s g %s p %x\n", 718 ip6_sprintf(&mfccp->mf6cc_origin.sin6_addr), 719 ip6_sprintf(&mfccp->mf6cc_mcastgrp.sin6_addr), 720 mfccp->mf6cc_parent); 721 #endif 722 723 s = splnet(); 724 rt->mf6c_parent = mfccp->mf6cc_parent; 725 rt->mf6c_ifset = mfccp->mf6cc_ifset; 726 splx(s); 727 return (0); 728 } 729 730 /* 731 * Find the entry for which the upcall was made and update 732 */ 733 s = splnet(); 734 hash = MF6CHASH(mfccp->mf6cc_origin.sin6_addr, 735 mfccp->mf6cc_mcastgrp.sin6_addr); 736 for (rt = mf6ctable[hash], nstl = 0; rt; rt = rt->mf6c_next) { 737 if (IN6_ARE_ADDR_EQUAL(&rt->mf6c_origin.sin6_addr, 738 &mfccp->mf6cc_origin.sin6_addr) && 739 IN6_ARE_ADDR_EQUAL(&rt->mf6c_mcastgrp.sin6_addr, 740 &mfccp->mf6cc_mcastgrp.sin6_addr) && 741 (rt->mf6c_stall != NULL)) { 742 743 if (nstl++) 744 log(LOG_ERR, 745 "add_m6fc: %s o %s g %s p %x dbx %p\n", 746 "multiple kernel entries", 747 ip6_sprintf(&mfccp->mf6cc_origin.sin6_addr), 748 ip6_sprintf(&mfccp->mf6cc_mcastgrp.sin6_addr), 749 mfccp->mf6cc_parent, rt->mf6c_stall); 750 751 #ifdef MRT6DEBUG 752 if (mrt6debug & DEBUG_MFC) 753 log(LOG_DEBUG, 754 "add_m6fc o %s g %s p %x dbg %x\n", 755 ip6_sprintf(&mfccp->mf6cc_origin.sin6_addr), 756 ip6_sprintf(&mfccp->mf6cc_mcastgrp.sin6_addr), 757 mfccp->mf6cc_parent, rt->mf6c_stall); 758 #endif 759 760 rt->mf6c_origin = mfccp->mf6cc_origin; 761 rt->mf6c_mcastgrp = mfccp->mf6cc_mcastgrp; 762 rt->mf6c_parent = mfccp->mf6cc_parent; 763 rt->mf6c_ifset = mfccp->mf6cc_ifset; 764 /* initialize pkt counters per src-grp */ 765 rt->mf6c_pkt_cnt = 0; 766 rt->mf6c_byte_cnt = 0; 767 rt->mf6c_wrong_if = 0; 768 769 rt->mf6c_expire = 0; /* Don't clean this guy up */ 770 n6expire[hash]--; 771 772 /* free packets Qed at the end of this entry */ 773 for (rte = rt->mf6c_stall; rte != NULL; ) { 774 struct rtdetq *n = rte->next; 775 ip6_mdq(rte->m, rte->ifp, rt); 776 m_freem(rte->m); 777 #ifdef UPCALL_TIMING 778 collate(&(rte->t)); 779 #endif /* UPCALL_TIMING */ 780 free(rte, M_MRTABLE); 781 rte = n; 782 } 783 rt->mf6c_stall = NULL; 784 } 785 } 786 787 /* 788 * It is possible that an entry is being inserted without an upcall 789 */ 790 if (nstl == 0) { 791 #ifdef MRT6DEBUG 792 if (mrt6debug & DEBUG_MFC) 793 log(LOG_DEBUG, 794 "add_mfc no upcall h %d o %s g %s p %x\n", 795 hash, 796 ip6_sprintf(&mfccp->mf6cc_origin.sin6_addr), 797 ip6_sprintf(&mfccp->mf6cc_mcastgrp.sin6_addr), 798 mfccp->mf6cc_parent); 799 #endif 800 801 for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) { 802 803 if (IN6_ARE_ADDR_EQUAL(&rt->mf6c_origin.sin6_addr, 804 &mfccp->mf6cc_origin.sin6_addr)&& 805 IN6_ARE_ADDR_EQUAL(&rt->mf6c_mcastgrp.sin6_addr, 806 &mfccp->mf6cc_mcastgrp.sin6_addr)) { 807 808 rt->mf6c_origin = mfccp->mf6cc_origin; 809 rt->mf6c_mcastgrp = mfccp->mf6cc_mcastgrp; 810 rt->mf6c_parent = mfccp->mf6cc_parent; 811 rt->mf6c_ifset = mfccp->mf6cc_ifset; 812 /* initialize pkt counters per src-grp */ 813 rt->mf6c_pkt_cnt = 0; 814 rt->mf6c_byte_cnt = 0; 815 rt->mf6c_wrong_if = 0; 816 817 if (rt->mf6c_expire) 818 n6expire[hash]--; 819 rt->mf6c_expire = 0; 820 } 821 } 822 if (rt == NULL) { 823 /* no upcall, so make a new entry */ 824 rt = (struct mf6c *)malloc(sizeof(*rt), M_MRTABLE, 825 M_NOWAIT); 826 if (rt == NULL) { 827 splx(s); 828 return (ENOBUFS); 829 } 830 831 /* insert new entry at head of hash chain */ 832 rt->mf6c_origin = mfccp->mf6cc_origin; 833 rt->mf6c_mcastgrp = mfccp->mf6cc_mcastgrp; 834 rt->mf6c_parent = mfccp->mf6cc_parent; 835 rt->mf6c_ifset = mfccp->mf6cc_ifset; 836 /* initialize pkt counters per src-grp */ 837 rt->mf6c_pkt_cnt = 0; 838 rt->mf6c_byte_cnt = 0; 839 rt->mf6c_wrong_if = 0; 840 rt->mf6c_expire = 0; 841 rt->mf6c_stall = NULL; 842 843 /* link into table */ 844 rt->mf6c_next = mf6ctable[hash]; 845 mf6ctable[hash] = rt; 846 } 847 } 848 splx(s); 849 return (0); 850 } 851 852 #ifdef UPCALL_TIMING 853 /* 854 * collect delay statistics on the upcalls 855 */ 856 static void 857 collate(t) 858 struct timeval *t; 859 { 860 u_long d; 861 struct timeval tp; 862 u_long delta; 863 864 GET_TIME(tp); 865 866 if (TV_LT(*t, tp)) 867 { 868 TV_DELTA(tp, *t, delta); 869 870 d = delta >> 10; 871 if (d > UPCALL_MAX) 872 d = UPCALL_MAX; 873 874 ++upcall_data[d]; 875 } 876 } 877 #endif /* UPCALL_TIMING */ 878 879 /* 880 * Delete an mfc entry 881 */ 882 static int 883 del_m6fc(mfccp) 884 struct mf6cctl *mfccp; 885 { 886 struct sockaddr_in6 origin; 887 struct sockaddr_in6 mcastgrp; 888 struct mf6c *rt; 889 struct mf6c **nptr; 890 u_long hash; 891 int s; 892 893 origin = mfccp->mf6cc_origin; 894 mcastgrp = mfccp->mf6cc_mcastgrp; 895 hash = MF6CHASH(origin.sin6_addr, mcastgrp.sin6_addr); 896 897 #ifdef MRT6DEBUG 898 if (mrt6debug & DEBUG_MFC) 899 log(LOG_DEBUG,"del_m6fc orig %s mcastgrp %s\n", 900 ip6_sprintf(&origin.sin6_addr), 901 ip6_sprintf(&mcastgrp.sin6_addr)); 902 #endif 903 904 s = splnet(); 905 906 nptr = &mf6ctable[hash]; 907 while ((rt = *nptr) != NULL) { 908 if (IN6_ARE_ADDR_EQUAL(&origin.sin6_addr, 909 &rt->mf6c_origin.sin6_addr) && 910 IN6_ARE_ADDR_EQUAL(&mcastgrp.sin6_addr, 911 &rt->mf6c_mcastgrp.sin6_addr) && 912 rt->mf6c_stall == NULL) 913 break; 914 915 nptr = &rt->mf6c_next; 916 } 917 if (rt == NULL) { 918 splx(s); 919 return (EADDRNOTAVAIL); 920 } 921 922 *nptr = rt->mf6c_next; 923 free(rt, M_MRTABLE); 924 925 splx(s); 926 927 return (0); 928 } 929 930 static int 931 socket_send(s, mm, src) 932 struct socket *s; 933 struct mbuf *mm; 934 struct sockaddr_in6 *src; 935 { 936 if (s) { 937 if (sbappendaddr(&s->so_rcv, 938 (struct sockaddr *)src, 939 mm, (struct mbuf *)0) != 0) { 940 sorwakeup(s); 941 return (0); 942 } 943 } 944 m_freem(mm); 945 return (-1); 946 } 947 948 /* 949 * IPv6 multicast forwarding function. This function assumes that the packet 950 * pointed to by "ip6" has arrived on (or is about to be sent to) the interface 951 * pointed to by "ifp", and the packet is to be relayed to other networks 952 * that have members of the packet's destination IPv6 multicast group. 953 * 954 * The packet is returned unscathed to the caller, unless it is 955 * erroneous, in which case a non-zero return value tells the caller to 956 * discard it. 957 */ 958 959 int 960 ip6_mforward(ip6, ifp, m) 961 struct ip6_hdr *ip6; 962 struct ifnet *ifp; 963 struct mbuf *m; 964 { 965 struct mf6c *rt; 966 struct mif6 *mifp; 967 struct mbuf *mm; 968 int s; 969 mifi_t mifi; 970 971 #ifdef MRT6DEBUG 972 if (mrt6debug & DEBUG_FORWARD) 973 log(LOG_DEBUG, "ip6_mforward: src %s, dst %s, ifindex %d\n", 974 ip6_sprintf(&ip6->ip6_src), ip6_sprintf(&ip6->ip6_dst), 975 ifp->if_index); 976 #endif 977 978 /* 979 * Don't forward a packet with Hop limit of zero or one, 980 * or a packet destined to a local-only group. 981 */ 982 if (ip6->ip6_hlim <= 1 || IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst) || 983 IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)) 984 return (0); 985 ip6->ip6_hlim--; 986 987 /* 988 * Source address check: do not forward packets with unspecified 989 * source. It was discussed in July 2000, on ipngwg mailing list. 990 * This is rather more serious than unicast cases, because some 991 * MLD packets can be sent with the unspecified source address 992 * (although such packets must normally set 1 to the hop limit field). 993 */ 994 if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { 995 ip6stat.ip6s_cantforward++; 996 if (ip6_log_time + ip6_log_interval < time_second) { 997 ip6_log_time = time_second; 998 log(LOG_DEBUG, 999 "cannot forward " 1000 "from %s to %s nxt %d received on %s\n", 1001 ip6_sprintf(&ip6->ip6_src), 1002 ip6_sprintf(&ip6->ip6_dst), 1003 ip6->ip6_nxt, 1004 if_name(m->m_pkthdr.rcvif)); 1005 } 1006 return (0); 1007 } 1008 1009 /* 1010 * Determine forwarding mifs from the forwarding cache table 1011 */ 1012 s = splnet(); 1013 MF6CFIND(ip6->ip6_src, ip6->ip6_dst, rt); 1014 1015 /* Entry exists, so forward if necessary */ 1016 if (rt) { 1017 splx(s); 1018 return (ip6_mdq(m, ifp, rt)); 1019 } else { 1020 /* 1021 * If we don't have a route for packet's origin, 1022 * Make a copy of the packet & 1023 * send message to routing daemon 1024 */ 1025 1026 struct mbuf *mb0; 1027 struct rtdetq *rte; 1028 u_long hash; 1029 /* int i, npkts;*/ 1030 #ifdef UPCALL_TIMING 1031 struct timeval tp; 1032 1033 GET_TIME(tp); 1034 #endif /* UPCALL_TIMING */ 1035 1036 mrt6stat.mrt6s_no_route++; 1037 #ifdef MRT6DEBUG 1038 if (mrt6debug & (DEBUG_FORWARD | DEBUG_MFC)) 1039 log(LOG_DEBUG, "ip6_mforward: no rte s %s g %s\n", 1040 ip6_sprintf(&ip6->ip6_src), 1041 ip6_sprintf(&ip6->ip6_dst)); 1042 #endif 1043 1044 /* 1045 * Allocate mbufs early so that we don't do extra work if we 1046 * are just going to fail anyway. 1047 */ 1048 rte = (struct rtdetq *)malloc(sizeof(*rte), M_MRTABLE, 1049 M_NOWAIT); 1050 if (rte == NULL) { 1051 splx(s); 1052 return (ENOBUFS); 1053 } 1054 mb0 = m_copy(m, 0, M_COPYALL); 1055 /* 1056 * Pullup packet header if needed before storing it, 1057 * as other references may modify it in the meantime. 1058 */ 1059 if (mb0 && 1060 (M_HASCL(mb0) || mb0->m_len < sizeof(struct ip6_hdr))) 1061 mb0 = m_pullup(mb0, sizeof(struct ip6_hdr)); 1062 if (mb0 == NULL) { 1063 free(rte, M_MRTABLE); 1064 splx(s); 1065 return (ENOBUFS); 1066 } 1067 1068 /* is there an upcall waiting for this packet? */ 1069 hash = MF6CHASH(ip6->ip6_src, ip6->ip6_dst); 1070 for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) { 1071 if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, 1072 &rt->mf6c_origin.sin6_addr) && 1073 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, 1074 &rt->mf6c_mcastgrp.sin6_addr) && 1075 (rt->mf6c_stall != NULL)) 1076 break; 1077 } 1078 1079 if (rt == NULL) { 1080 struct mrt6msg *im; 1081 #ifdef MRT6_OINIT 1082 struct omrt6msg *oim; 1083 #endif 1084 1085 /* no upcall, so make a new entry */ 1086 rt = (struct mf6c *)malloc(sizeof(*rt), M_MRTABLE, 1087 M_NOWAIT); 1088 if (rt == NULL) { 1089 free(rte, M_MRTABLE); 1090 m_freem(mb0); 1091 splx(s); 1092 return (ENOBUFS); 1093 } 1094 /* 1095 * Make a copy of the header to send to the user 1096 * level process 1097 */ 1098 mm = m_copy(mb0, 0, sizeof(struct ip6_hdr)); 1099 1100 if (mm == NULL) { 1101 free(rte, M_MRTABLE); 1102 m_freem(mb0); 1103 free(rt, M_MRTABLE); 1104 splx(s); 1105 return (ENOBUFS); 1106 } 1107 1108 /* 1109 * Send message to routing daemon 1110 */ 1111 sin6.sin6_addr = ip6->ip6_src; 1112 1113 im = NULL; 1114 #ifdef MRT6_OINIT 1115 oim = NULL; 1116 #endif 1117 switch (ip6_mrouter_ver) { 1118 #ifdef MRT6_OINIT 1119 case MRT6_OINIT: 1120 oim = mtod(mm, struct omrt6msg *); 1121 oim->im6_msgtype = MRT6MSG_NOCACHE; 1122 oim->im6_mbz = 0; 1123 break; 1124 #endif 1125 case MRT6_INIT: 1126 im = mtod(mm, struct mrt6msg *); 1127 im->im6_msgtype = MRT6MSG_NOCACHE; 1128 im->im6_mbz = 0; 1129 break; 1130 default: 1131 free(rte, M_MRTABLE); 1132 m_freem(mb0); 1133 free(rt, M_MRTABLE); 1134 splx(s); 1135 return (EINVAL); 1136 } 1137 1138 #ifdef MRT6DEBUG 1139 if (mrt6debug & DEBUG_FORWARD) 1140 log(LOG_DEBUG, 1141 "getting the iif info in the kernel\n"); 1142 #endif 1143 1144 for (mifp = mif6table, mifi = 0; 1145 mifi < nummifs && mifp->m6_ifp != ifp; 1146 mifp++, mifi++) 1147 ; 1148 1149 switch (ip6_mrouter_ver) { 1150 #ifdef MRT6_OINIT 1151 case MRT6_OINIT: 1152 oim->im6_mif = mifi; 1153 break; 1154 #endif 1155 case MRT6_INIT: 1156 im->im6_mif = mifi; 1157 break; 1158 } 1159 1160 if (socket_send(ip6_mrouter, mm, &sin6) < 0) { 1161 log(LOG_WARNING, "ip6_mforward: ip6_mrouter " 1162 "socket queue full\n"); 1163 mrt6stat.mrt6s_upq_sockfull++; 1164 free(rte, M_MRTABLE); 1165 m_freem(mb0); 1166 free(rt, M_MRTABLE); 1167 splx(s); 1168 return (ENOBUFS); 1169 } 1170 1171 mrt6stat.mrt6s_upcalls++; 1172 1173 /* insert new entry at head of hash chain */ 1174 bzero(rt, sizeof(*rt)); 1175 rt->mf6c_origin.sin6_family = AF_INET6; 1176 rt->mf6c_origin.sin6_len = sizeof(struct sockaddr_in6); 1177 rt->mf6c_origin.sin6_addr = ip6->ip6_src; 1178 rt->mf6c_mcastgrp.sin6_family = AF_INET6; 1179 rt->mf6c_mcastgrp.sin6_len = sizeof(struct sockaddr_in6); 1180 rt->mf6c_mcastgrp.sin6_addr = ip6->ip6_dst; 1181 rt->mf6c_expire = UPCALL_EXPIRE; 1182 n6expire[hash]++; 1183 rt->mf6c_parent = MF6C_INCOMPLETE_PARENT; 1184 1185 /* link into table */ 1186 rt->mf6c_next = mf6ctable[hash]; 1187 mf6ctable[hash] = rt; 1188 /* Add this entry to the end of the queue */ 1189 rt->mf6c_stall = rte; 1190 } else { 1191 /* determine if q has overflowed */ 1192 struct rtdetq **p; 1193 int npkts = 0; 1194 1195 for (p = &rt->mf6c_stall; *p != NULL; p = &(*p)->next) 1196 if (++npkts > MAX_UPQ6) { 1197 mrt6stat.mrt6s_upq_ovflw++; 1198 free(rte, M_MRTABLE); 1199 m_freem(mb0); 1200 splx(s); 1201 return (0); 1202 } 1203 1204 /* Add this entry to the end of the queue */ 1205 *p = rte; 1206 } 1207 1208 rte->next = NULL; 1209 rte->m = mb0; 1210 rte->ifp = ifp; 1211 #ifdef UPCALL_TIMING 1212 rte->t = tp; 1213 #endif /* UPCALL_TIMING */ 1214 1215 splx(s); 1216 1217 return (0); 1218 } 1219 } 1220 1221 /* 1222 * Clean up cache entries if upcalls are not serviced 1223 * Call from the Slow Timeout mechanism, every half second. 1224 */ 1225 static void 1226 expire_upcalls(unused) 1227 void *unused; 1228 { 1229 struct rtdetq *rte; 1230 struct mf6c *mfc, **nptr; 1231 int i; 1232 int s; 1233 1234 s = splnet(); 1235 for (i = 0; i < MF6CTBLSIZ; i++) { 1236 if (n6expire[i] == 0) 1237 continue; 1238 nptr = &mf6ctable[i]; 1239 while ((mfc = *nptr) != NULL) { 1240 rte = mfc->mf6c_stall; 1241 /* 1242 * Skip real cache entries 1243 * Make sure it wasn't marked to not expire (shouldn't happen) 1244 * If it expires now 1245 */ 1246 if (rte != NULL && 1247 mfc->mf6c_expire != 0 && 1248 --mfc->mf6c_expire == 0) { 1249 #ifdef MRT6DEBUG 1250 if (mrt6debug & DEBUG_EXPIRE) 1251 log(LOG_DEBUG, "expire_upcalls: expiring (%s %s)\n", 1252 ip6_sprintf(&mfc->mf6c_origin.sin6_addr), 1253 ip6_sprintf(&mfc->mf6c_mcastgrp.sin6_addr)); 1254 #endif 1255 /* 1256 * drop all the packets 1257 * free the mbuf with the pkt, if, timing info 1258 */ 1259 do { 1260 struct rtdetq *n = rte->next; 1261 m_freem(rte->m); 1262 free(rte, M_MRTABLE); 1263 rte = n; 1264 } while (rte != NULL); 1265 mrt6stat.mrt6s_cache_cleanups++; 1266 n6expire[i]--; 1267 1268 *nptr = mfc->mf6c_next; 1269 free(mfc, M_MRTABLE); 1270 } else { 1271 nptr = &mfc->mf6c_next; 1272 } 1273 } 1274 } 1275 splx(s); 1276 callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT, 1277 expire_upcalls, NULL); 1278 } 1279 1280 /* 1281 * Packet forwarding routine once entry in the cache is made 1282 */ 1283 static int 1284 ip6_mdq(m, ifp, rt) 1285 struct mbuf *m; 1286 struct ifnet *ifp; 1287 struct mf6c *rt; 1288 { 1289 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1290 mifi_t mifi, iif; 1291 struct mif6 *mifp; 1292 int plen = m->m_pkthdr.len; 1293 u_int32_t dscopein, sscopein; 1294 1295 /* 1296 * Macro to send packet on mif. Since RSVP packets don't get counted on 1297 * input, they shouldn't get counted on output, so statistics keeping is 1298 * separate. 1299 */ 1300 1301 #define MC6_SEND(ip6, mifp, m) do { \ 1302 if ((mifp)->m6_flags & MIFF_REGISTER) \ 1303 register_send((ip6), (mifp), (m)); \ 1304 else \ 1305 phyint_send((ip6), (mifp), (m)); \ 1306 } while (/*CONSTCOND*/ 0) 1307 1308 /* 1309 * Don't forward if it didn't arrive from the parent mif 1310 * for its origin. 1311 */ 1312 mifi = rt->mf6c_parent; 1313 if ((mifi >= nummifs) || (mif6table[mifi].m6_ifp != ifp)) { 1314 /* came in the wrong interface */ 1315 #ifdef MRT6DEBUG 1316 if (mrt6debug & DEBUG_FORWARD) 1317 log(LOG_DEBUG, 1318 "wrong if: ifid %d mifi %d mififid %x\n", 1319 ifp->if_index, mifi, 1320 mif6table[mifi].m6_ifp->if_index); 1321 #endif 1322 mrt6stat.mrt6s_wrong_if++; 1323 rt->mf6c_wrong_if++; 1324 /* 1325 * If we are doing PIM processing, and we are forwarding 1326 * packets on this interface, send a message to the 1327 * routing daemon. 1328 */ 1329 /* have to make sure this is a valid mif */ 1330 if (mifi < nummifs && mif6table[mifi].m6_ifp) 1331 if (pim6 && (m->m_flags & M_LOOP) == 0) { 1332 /* 1333 * Check the M_LOOP flag to avoid an 1334 * unnecessary PIM assert. 1335 * XXX: M_LOOP is an ad-hoc hack... 1336 */ 1337 static struct sockaddr_in6 sin6 = 1338 { sizeof(sin6), AF_INET6 }; 1339 1340 struct mbuf *mm; 1341 struct mrt6msg *im; 1342 #ifdef MRT6_OINIT 1343 struct omrt6msg *oim; 1344 #endif 1345 1346 mm = m_copy(m, 0, sizeof(struct ip6_hdr)); 1347 if (mm && 1348 (M_HASCL(mm) || 1349 mm->m_len < sizeof(struct ip6_hdr))) 1350 mm = m_pullup(mm, sizeof(struct ip6_hdr)); 1351 if (mm == NULL) 1352 return (ENOBUFS); 1353 1354 #ifdef MRT6_OINIT 1355 oim = NULL; 1356 #endif 1357 im = NULL; 1358 switch (ip6_mrouter_ver) { 1359 #ifdef MRT6_OINIT 1360 case MRT6_OINIT: 1361 oim = mtod(mm, struct omrt6msg *); 1362 oim->im6_msgtype = MRT6MSG_WRONGMIF; 1363 oim->im6_mbz = 0; 1364 break; 1365 #endif 1366 case MRT6_INIT: 1367 im = mtod(mm, struct mrt6msg *); 1368 im->im6_msgtype = MRT6MSG_WRONGMIF; 1369 im->im6_mbz = 0; 1370 break; 1371 default: 1372 m_freem(mm); 1373 return (EINVAL); 1374 } 1375 1376 for (mifp = mif6table, iif = 0; 1377 iif < nummifs && mifp && 1378 mifp->m6_ifp != ifp; 1379 mifp++, iif++) 1380 ; 1381 1382 switch (ip6_mrouter_ver) { 1383 #ifdef MRT6_OINIT 1384 case MRT6_OINIT: 1385 oim->im6_mif = iif; 1386 sin6.sin6_addr = oim->im6_src; 1387 break; 1388 #endif 1389 case MRT6_INIT: 1390 im->im6_mif = iif; 1391 sin6.sin6_addr = im->im6_src; 1392 break; 1393 } 1394 1395 mrt6stat.mrt6s_upcalls++; 1396 1397 if (socket_send(ip6_mrouter, mm, &sin6) < 0) { 1398 #ifdef MRT6DEBUG 1399 if (mrt6debug) 1400 log(LOG_WARNING, "mdq, ip6_mrouter socket queue full\n"); 1401 #endif 1402 ++mrt6stat.mrt6s_upq_sockfull; 1403 return (ENOBUFS); 1404 } /* if socket Q full */ 1405 } /* if PIM */ 1406 return (0); 1407 } /* if wrong iif */ 1408 1409 /* If I sourced this packet, it counts as output, else it was input. */ 1410 if (m->m_pkthdr.rcvif == NULL) { 1411 /* XXX: is rcvif really NULL when output?? */ 1412 mif6table[mifi].m6_pkt_out++; 1413 mif6table[mifi].m6_bytes_out += plen; 1414 } else { 1415 mif6table[mifi].m6_pkt_in++; 1416 mif6table[mifi].m6_bytes_in += plen; 1417 } 1418 rt->mf6c_pkt_cnt++; 1419 rt->mf6c_byte_cnt += plen; 1420 1421 /* 1422 * For each mif, forward a copy of the packet if there are group 1423 * members downstream on the interface. 1424 */ 1425 if (in6_addr2zoneid(ifp, &ip6->ip6_dst, &dscopein) || 1426 in6_addr2zoneid(ifp, &ip6->ip6_src, &sscopein)) 1427 return (EINVAL); 1428 for (mifp = mif6table, mifi = 0; mifi < nummifs; mifp++, mifi++) { 1429 if (IF_ISSET(mifi, &rt->mf6c_ifset)) { 1430 u_int32_t dscopeout, sscopeout; 1431 1432 /* 1433 * check if the outgoing packet is going to break 1434 * a scope boundary. 1435 * XXX For packets through PIM register tunnel 1436 * interface, we believe a routing daemon. 1437 */ 1438 if (!(mif6table[rt->mf6c_parent].m6_flags & 1439 MIFF_REGISTER) && 1440 !(mif6table[mifi].m6_flags & MIFF_REGISTER)) { 1441 if (in6_addr2zoneid(mif6table[mifi].m6_ifp, 1442 &ip6->ip6_dst, 1443 &dscopeout) || 1444 in6_addr2zoneid(mif6table[mifi].m6_ifp, 1445 &ip6->ip6_src, 1446 &sscopeout) || 1447 dscopein != dscopeout || 1448 sscopein != sscopeout) { 1449 ip6stat.ip6s_badscope++; 1450 continue; 1451 } 1452 } 1453 1454 mifp->m6_pkt_out++; 1455 mifp->m6_bytes_out += plen; 1456 MC6_SEND(ip6, mifp, m); 1457 } 1458 } 1459 return (0); 1460 } 1461 1462 static void 1463 phyint_send(ip6, mifp, m) 1464 struct ip6_hdr *ip6; 1465 struct mif6 *mifp; 1466 struct mbuf *m; 1467 { 1468 struct mbuf *mb_copy; 1469 struct ifnet *ifp = mifp->m6_ifp; 1470 int error = 0; 1471 int s = splnet(); /* needs to protect static "ro" below. */ 1472 static struct route_in6 ro; 1473 struct in6_multi *in6m; 1474 struct sockaddr_in6 *dst6; 1475 u_long linkmtu; 1476 1477 /* 1478 * Make a new reference to the packet; make sure that 1479 * the IPv6 header is actually copied, not just referenced, 1480 * so that ip6_output() only scribbles on the copy. 1481 */ 1482 mb_copy = m_copy(m, 0, M_COPYALL); 1483 if (mb_copy && 1484 (M_HASCL(mb_copy) || mb_copy->m_len < sizeof(struct ip6_hdr))) 1485 mb_copy = m_pullup(mb_copy, sizeof(struct ip6_hdr)); 1486 if (mb_copy == NULL) { 1487 splx(s); 1488 return; 1489 } 1490 /* set MCAST flag to the outgoing packet */ 1491 mb_copy->m_flags |= M_MCAST; 1492 1493 /* 1494 * If we sourced the packet, call ip6_output since we may devide 1495 * the packet into fragments when the packet is too big for the 1496 * outgoing interface. 1497 * Otherwise, we can simply send the packet to the interface 1498 * sending queue. 1499 */ 1500 if (m->m_pkthdr.rcvif == NULL) { 1501 struct ip6_moptions im6o; 1502 1503 im6o.im6o_multicast_ifp = ifp; 1504 /* XXX: ip6_output will override ip6->ip6_hlim */ 1505 im6o.im6o_multicast_hlim = ip6->ip6_hlim; 1506 im6o.im6o_multicast_loop = 1; 1507 error = ip6_output(mb_copy, NULL, &ro, 1508 IPV6_FORWARDING, &im6o, NULL, NULL); 1509 1510 #ifdef MRT6DEBUG 1511 if (mrt6debug & DEBUG_XMIT) 1512 log(LOG_DEBUG, "phyint_send on mif %d err %d\n", 1513 mifp - mif6table, error); 1514 #endif 1515 splx(s); 1516 return; 1517 } 1518 1519 /* 1520 * If we belong to the destination multicast group 1521 * on the outgoing interface, loop back a copy. 1522 */ 1523 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 1524 IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m); 1525 if (in6m != NULL) { 1526 dst6->sin6_len = sizeof(struct sockaddr_in6); 1527 dst6->sin6_family = AF_INET6; 1528 dst6->sin6_addr = ip6->ip6_dst; 1529 ip6_mloopback(ifp, m, (struct sockaddr_in6 *)&ro.ro_dst); 1530 } 1531 /* 1532 * Put the packet into the sending queue of the outgoing interface 1533 * if it would fit in the MTU of the interface. 1534 */ 1535 linkmtu = IN6_LINKMTU(ifp); 1536 if (mb_copy->m_pkthdr.len <= linkmtu || linkmtu < IPV6_MMTU) { 1537 dst6->sin6_len = sizeof(struct sockaddr_in6); 1538 dst6->sin6_family = AF_INET6; 1539 dst6->sin6_addr = ip6->ip6_dst; 1540 /* 1541 * We just call if_output instead of nd6_output here, since 1542 * we need no ND for a multicast forwarded packet...right? 1543 */ 1544 error = (*ifp->if_output)(ifp, mb_copy, 1545 (struct sockaddr *)&ro.ro_dst, NULL); 1546 #ifdef MRT6DEBUG 1547 if (mrt6debug & DEBUG_XMIT) 1548 log(LOG_DEBUG, "phyint_send on mif %d err %d\n", 1549 mifp - mif6table, error); 1550 #endif 1551 } else { 1552 #ifdef MULTICAST_PMTUD 1553 icmp6_error(mb_copy, ICMP6_PACKET_TOO_BIG, 0, linkmtu); 1554 #else 1555 #ifdef MRT6DEBUG 1556 if (mrt6debug & DEBUG_XMIT) 1557 log(LOG_DEBUG, 1558 "phyint_send: packet too big on %s o %s g %s" 1559 " size %d(discarded)\n", 1560 if_name(ifp), 1561 ip6_sprintf(&ip6->ip6_src), 1562 ip6_sprintf(&ip6->ip6_dst), 1563 mb_copy->m_pkthdr.len); 1564 #endif /* MRT6DEBUG */ 1565 m_freem(mb_copy); /* simply discard the packet */ 1566 #endif 1567 } 1568 1569 splx(s); 1570 } 1571 1572 static int 1573 register_send(ip6, mif, m) 1574 struct ip6_hdr *ip6; 1575 struct mif6 *mif; 1576 struct mbuf *m; 1577 { 1578 struct mbuf *mm; 1579 int i, len = m->m_pkthdr.len; 1580 static struct sockaddr_in6 sin6 = { sizeof(sin6), AF_INET6 }; 1581 struct mrt6msg *im6; 1582 1583 #ifdef MRT6DEBUG 1584 if (mrt6debug) 1585 log(LOG_DEBUG, "** IPv6 register_send **\n src %s dst %s\n", 1586 ip6_sprintf(&ip6->ip6_src), ip6_sprintf(&ip6->ip6_dst)); 1587 #endif 1588 ++pim6stat.pim6s_snd_registers; 1589 1590 /* Make a copy of the packet to send to the user level process */ 1591 MGETHDR(mm, M_DONTWAIT, MT_HEADER); 1592 if (mm == NULL) 1593 return (ENOBUFS); 1594 mm->m_pkthdr.rcvif = NULL; 1595 mm->m_data += max_linkhdr; 1596 mm->m_len = sizeof(struct ip6_hdr); 1597 1598 if ((mm->m_next = m_copy(m, 0, M_COPYALL)) == NULL) { 1599 m_freem(mm); 1600 return (ENOBUFS); 1601 } 1602 i = MHLEN - M_LEADINGSPACE(mm); 1603 if (i > len) 1604 i = len; 1605 mm = m_pullup(mm, i); 1606 if (mm == NULL) 1607 return (ENOBUFS); 1608 /* TODO: check it! */ 1609 mm->m_pkthdr.len = len + sizeof(struct ip6_hdr); 1610 1611 /* 1612 * Send message to routing daemon 1613 */ 1614 sin6.sin6_addr = ip6->ip6_src; 1615 1616 im6 = mtod(mm, struct mrt6msg *); 1617 im6->im6_msgtype = MRT6MSG_WHOLEPKT; 1618 im6->im6_mbz = 0; 1619 1620 im6->im6_mif = mif - mif6table; 1621 1622 /* iif info is not given for reg. encap.n */ 1623 mrt6stat.mrt6s_upcalls++; 1624 1625 if (socket_send(ip6_mrouter, mm, &sin6) < 0) { 1626 #ifdef MRT6DEBUG 1627 if (mrt6debug) 1628 log(LOG_WARNING, 1629 "register_send: ip6_mrouter socket queue full\n"); 1630 #endif 1631 ++mrt6stat.mrt6s_upq_sockfull; 1632 return (ENOBUFS); 1633 } 1634 return (0); 1635 } 1636 1637 /* 1638 * PIM sparse mode hook 1639 * Receives the pim control messages, and passes them up to the listening 1640 * socket, using rip6_input. 1641 * The only message processed is the REGISTER pim message; the pim header 1642 * is stripped off, and the inner packet is passed to register_mforward. 1643 */ 1644 int 1645 pim6_input(mp, offp, proto) 1646 struct mbuf **mp; 1647 int *offp, proto; 1648 { 1649 struct pim *pim; /* pointer to a pim struct */ 1650 struct ip6_hdr *ip6; 1651 int pimlen; 1652 struct mbuf *m = *mp; 1653 int minlen; 1654 int off = *offp; 1655 1656 ++pim6stat.pim6s_rcv_total; 1657 1658 ip6 = mtod(m, struct ip6_hdr *); 1659 pimlen = m->m_pkthdr.len - *offp; 1660 1661 /* 1662 * Validate lengths 1663 */ 1664 if (pimlen < PIM_MINLEN) { 1665 ++pim6stat.pim6s_rcv_tooshort; 1666 #ifdef MRT6DEBUG 1667 if (mrt6debug & DEBUG_PIM) 1668 log(LOG_DEBUG,"pim6_input: PIM packet too short\n"); 1669 #endif 1670 m_freem(m); 1671 return (IPPROTO_DONE); 1672 } 1673 1674 /* 1675 * if the packet is at least as big as a REGISTER, go ahead 1676 * and grab the PIM REGISTER header size, to avoid another 1677 * possible m_pullup() later. 1678 * 1679 * PIM_MINLEN == pimhdr + u_int32 == 8 1680 * PIM6_REG_MINLEN == pimhdr + reghdr + eip6hdr == 4 + 4 + 40 1681 */ 1682 minlen = (pimlen >= PIM6_REG_MINLEN) ? PIM6_REG_MINLEN : PIM_MINLEN; 1683 1684 /* 1685 * Make sure that the IP6 and PIM headers in contiguous memory, and 1686 * possibly the PIM REGISTER header 1687 */ 1688 #ifndef PULLDOWN_TEST 1689 IP6_EXTHDR_CHECK(m, off, minlen, IPPROTO_DONE); 1690 /* adjust pointer */ 1691 ip6 = mtod(m, struct ip6_hdr *); 1692 1693 /* adjust mbuf to point to the PIM header */ 1694 pim = (struct pim *)((caddr_t)ip6 + off); 1695 #else 1696 IP6_EXTHDR_GET(pim, struct pim *, m, off, minlen); 1697 if (pim == NULL) { 1698 pim6stat.pim6s_rcv_tooshort++; 1699 return (IPPROTO_DONE); 1700 } 1701 #endif 1702 1703 #define PIM6_CHECKSUM 1704 #ifdef PIM6_CHECKSUM 1705 { 1706 int cksumlen; 1707 1708 /* 1709 * Validate checksum. 1710 * If PIM REGISTER, exclude the data packet 1711 */ 1712 if (pim->pim_type == PIM_REGISTER) 1713 cksumlen = PIM_MINLEN; 1714 else 1715 cksumlen = pimlen; 1716 1717 if (in6_cksum(m, IPPROTO_PIM, off, cksumlen)) { 1718 ++pim6stat.pim6s_rcv_badsum; 1719 #ifdef MRT6DEBUG 1720 if (mrt6debug & DEBUG_PIM) 1721 log(LOG_DEBUG, 1722 "pim6_input: invalid checksum\n"); 1723 #endif 1724 m_freem(m); 1725 return (IPPROTO_DONE); 1726 } 1727 } 1728 #endif /* PIM_CHECKSUM */ 1729 1730 /* PIM version check */ 1731 if (pim->pim_ver != PIM_VERSION) { 1732 ++pim6stat.pim6s_rcv_badversion; 1733 #ifdef MRT6DEBUG 1734 log(LOG_ERR, 1735 "pim6_input: incorrect version %d, expecting %d\n", 1736 pim->pim_ver, PIM_VERSION); 1737 #endif 1738 m_freem(m); 1739 return (IPPROTO_DONE); 1740 } 1741 1742 if (pim->pim_type == PIM_REGISTER) { 1743 /* 1744 * since this is a REGISTER, we'll make a copy of the register 1745 * headers ip6+pim+u_int32_t+encap_ip6, to be passed up to the 1746 * routing daemon. 1747 */ 1748 static struct sockaddr_in6 dst = { sizeof(dst), AF_INET6 }; 1749 1750 struct mbuf *mcp; 1751 struct ip6_hdr *eip6; 1752 u_int32_t *reghdr; 1753 int rc; 1754 1755 ++pim6stat.pim6s_rcv_registers; 1756 1757 if ((reg_mif_num >= nummifs) || (reg_mif_num == (mifi_t) -1)) { 1758 #ifdef MRT6DEBUG 1759 if (mrt6debug & DEBUG_PIM) 1760 log(LOG_DEBUG, 1761 "pim6_input: register mif not set: %d\n", 1762 reg_mif_num); 1763 #endif 1764 m_freem(m); 1765 return (IPPROTO_DONE); 1766 } 1767 1768 reghdr = (u_int32_t *)(pim + 1); 1769 1770 if ((ntohl(*reghdr) & PIM_NULL_REGISTER)) 1771 goto pim6_input_to_daemon; 1772 1773 /* 1774 * Validate length 1775 */ 1776 if (pimlen < PIM6_REG_MINLEN) { 1777 ++pim6stat.pim6s_rcv_tooshort; 1778 ++pim6stat.pim6s_rcv_badregisters; 1779 #ifdef MRT6DEBUG 1780 log(LOG_ERR, 1781 "pim6_input: register packet size too " 1782 "small %d from %s\n", 1783 pimlen, ip6_sprintf(&ip6->ip6_src)); 1784 #endif 1785 m_freem(m); 1786 return (IPPROTO_DONE); 1787 } 1788 1789 eip6 = (struct ip6_hdr *) (reghdr + 1); 1790 #ifdef MRT6DEBUG 1791 if (mrt6debug & DEBUG_PIM) 1792 log(LOG_DEBUG, 1793 "pim6_input[register], eip6: %s -> %s, " 1794 "eip6 plen %d\n", 1795 ip6_sprintf(&eip6->ip6_src), 1796 ip6_sprintf(&eip6->ip6_dst), 1797 ntohs(eip6->ip6_plen)); 1798 #endif 1799 1800 /* verify the version number of the inner packet */ 1801 if ((eip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 1802 ++pim6stat.pim6s_rcv_badregisters; 1803 #ifdef MRT6DEBUG 1804 log(LOG_DEBUG, "pim6_input: invalid IP version (%d) " 1805 "of the inner packet\n", 1806 (eip6->ip6_vfc & IPV6_VERSION)); 1807 #endif 1808 m_freem(m); 1809 return (IPPROTO_NONE); 1810 } 1811 1812 /* verify the inner packet is destined to a mcast group */ 1813 if (!IN6_IS_ADDR_MULTICAST(&eip6->ip6_dst)) { 1814 ++pim6stat.pim6s_rcv_badregisters; 1815 #ifdef MRT6DEBUG 1816 if (mrt6debug & DEBUG_PIM) 1817 log(LOG_DEBUG, 1818 "pim6_input: inner packet of register " 1819 "is not multicast %s\n", 1820 ip6_sprintf(&eip6->ip6_dst)); 1821 #endif 1822 m_freem(m); 1823 return (IPPROTO_DONE); 1824 } 1825 1826 /* 1827 * make a copy of the whole header to pass to the daemon later. 1828 */ 1829 mcp = m_copy(m, 0, off + PIM6_REG_MINLEN); 1830 if (mcp == NULL) { 1831 #ifdef MRT6DEBUG 1832 log(LOG_ERR, 1833 "pim6_input: pim register: " 1834 "could not copy register head\n"); 1835 #endif 1836 m_freem(m); 1837 return (IPPROTO_DONE); 1838 } 1839 1840 /* 1841 * forward the inner ip6 packet; point m_data at the inner ip6. 1842 */ 1843 m_adj(m, off + PIM_MINLEN); 1844 #ifdef MRT6DEBUG 1845 if (mrt6debug & DEBUG_PIM) { 1846 log(LOG_DEBUG, 1847 "pim6_input: forwarding decapsulated register: " 1848 "src %s, dst %s, mif %d\n", 1849 ip6_sprintf(&eip6->ip6_src), 1850 ip6_sprintf(&eip6->ip6_dst), 1851 reg_mif_num); 1852 } 1853 #endif 1854 1855 rc = if_simloop(mif6table[reg_mif_num].m6_ifp, m, 1856 dst.sin6_family, 0); 1857 1858 /* prepare the register head to send to the mrouting daemon */ 1859 m = mcp; 1860 } 1861 1862 /* 1863 * Pass the PIM message up to the daemon; if it is a register message 1864 * pass the 'head' only up to the daemon. This includes the 1865 * encapsulator ip6 header, pim header, register header and the 1866 * encapsulated ip6 header. 1867 */ 1868 pim6_input_to_daemon: 1869 rip6_input(&m, offp, proto); 1870 return (IPPROTO_DONE); 1871 } 1872