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