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