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