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