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