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