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