1 /* $NetBSD: ip6_mroute.c,v 1.25 2001/12/18 03:04:03 itojun 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.25 2001/12/18 03:04:03 itojun 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 m->m_pkthdr.rcvif ? 977 if_name(m->m_pkthdr.rcvif) : "?"); 978 } 979 return 0; 980 } 981 982 /* 983 * Determine forwarding mifs from the forwarding cache table 984 */ 985 s = splsoftnet(); 986 MF6CFIND(ip6->ip6_src, ip6->ip6_dst, rt); 987 988 /* Entry exists, so forward if necessary */ 989 if (rt) { 990 splx(s); 991 return (ip6_mdq(m, ifp, rt)); 992 } else { 993 /* 994 * If we don't have a route for packet's origin, 995 * Make a copy of the packet & 996 * send message to routing daemon 997 */ 998 999 struct mbuf *mb0; 1000 struct rtdetq *rte; 1001 u_long hash; 1002 /* int i, npkts;*/ 1003 #ifdef UPCALL_TIMING 1004 struct timeval tp; 1005 1006 GET_TIME(tp); 1007 #endif /* UPCALL_TIMING */ 1008 1009 mrt6stat.mrt6s_no_route++; 1010 #ifdef MRT6DEBUG 1011 if (mrt6debug & (DEBUG_FORWARD | DEBUG_MFC)) 1012 log(LOG_DEBUG, "ip6_mforward: no rte s %s g %s\n", 1013 ip6_sprintf(&ip6->ip6_src), 1014 ip6_sprintf(&ip6->ip6_dst)); 1015 #endif 1016 1017 /* 1018 * Allocate mbufs early so that we don't do extra work if we 1019 * are just going to fail anyway. 1020 */ 1021 rte = (struct rtdetq *)malloc(sizeof(*rte), M_MRTABLE, 1022 M_NOWAIT); 1023 if (rte == NULL) { 1024 splx(s); 1025 return ENOBUFS; 1026 } 1027 mb0 = m_copy(m, 0, M_COPYALL); 1028 /* 1029 * Pullup packet header if needed before storing it, 1030 * as other references may modify it in the meantime. 1031 */ 1032 if (mb0 && 1033 (M_HASCL(mb0) || mb0->m_len < sizeof(struct ip6_hdr))) 1034 mb0 = m_pullup(mb0, sizeof(struct ip6_hdr)); 1035 if (mb0 == NULL) { 1036 free(rte, M_MRTABLE); 1037 splx(s); 1038 return ENOBUFS; 1039 } 1040 1041 /* is there an upcall waiting for this packet? */ 1042 hash = MF6CHASH(ip6->ip6_src, ip6->ip6_dst); 1043 for (rt = mf6ctable[hash]; rt; rt = rt->mf6c_next) { 1044 if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, 1045 &rt->mf6c_origin.sin6_addr) && 1046 IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, 1047 &rt->mf6c_mcastgrp.sin6_addr) && 1048 (rt->mf6c_stall != NULL)) 1049 break; 1050 } 1051 1052 if (rt == NULL) { 1053 struct mrt6msg *im; 1054 struct omrt6msg *oim; 1055 1056 /* no upcall, so make a new entry */ 1057 rt = (struct mf6c *)malloc(sizeof(*rt), M_MRTABLE, 1058 M_NOWAIT); 1059 if (rt == NULL) { 1060 free(rte, M_MRTABLE); 1061 m_freem(mb0); 1062 splx(s); 1063 return ENOBUFS; 1064 } 1065 /* 1066 * Make a copy of the header to send to the user 1067 * level process 1068 */ 1069 mm = m_copy(mb0, 0, sizeof(struct ip6_hdr)); 1070 1071 if (mm == NULL) { 1072 free(rte, M_MRTABLE); 1073 m_freem(mb0); 1074 free(rt, M_MRTABLE); 1075 splx(s); 1076 return ENOBUFS; 1077 } 1078 1079 /* 1080 * Send message to routing daemon 1081 */ 1082 sin6.sin6_addr = ip6->ip6_src; 1083 1084 im = NULL; 1085 oim = NULL; 1086 switch (ip6_mrouter_ver) { 1087 case MRT6_OINIT: 1088 oim = mtod(mm, struct omrt6msg *); 1089 oim->im6_msgtype = MRT6MSG_NOCACHE; 1090 oim->im6_mbz = 0; 1091 break; 1092 case MRT6_INIT: 1093 im = mtod(mm, struct mrt6msg *); 1094 im->im6_msgtype = MRT6MSG_NOCACHE; 1095 im->im6_mbz = 0; 1096 break; 1097 default: 1098 free(rte, M_MRTABLE); 1099 m_freem(mb0); 1100 free(rt, M_MRTABLE); 1101 splx(s); 1102 return EINVAL; 1103 } 1104 1105 #ifdef MRT6DEBUG 1106 if (mrt6debug & DEBUG_FORWARD) 1107 log(LOG_DEBUG, 1108 "getting the iif info in the kernel\n"); 1109 #endif 1110 1111 for (mifp = mif6table, mifi = 0; 1112 mifi < nummifs && mifp->m6_ifp != ifp; 1113 mifp++, mifi++) 1114 ; 1115 1116 switch (ip6_mrouter_ver) { 1117 case MRT6_OINIT: 1118 oim->im6_mif = mifi; 1119 break; 1120 case MRT6_INIT: 1121 im->im6_mif = mifi; 1122 break; 1123 } 1124 1125 if (socket_send(ip6_mrouter, mm, &sin6) < 0) { 1126 log(LOG_WARNING, "ip6_mforward: ip6_mrouter " 1127 "socket queue full\n"); 1128 mrt6stat.mrt6s_upq_sockfull++; 1129 free(rte, M_MRTABLE); 1130 m_freem(mb0); 1131 free(rt, M_MRTABLE); 1132 splx(s); 1133 return ENOBUFS; 1134 } 1135 1136 mrt6stat.mrt6s_upcalls++; 1137 1138 /* insert new entry at head of hash chain */ 1139 bzero(rt, sizeof(*rt)); 1140 rt->mf6c_origin.sin6_family = AF_INET6; 1141 rt->mf6c_origin.sin6_len = sizeof(struct sockaddr_in6); 1142 rt->mf6c_origin.sin6_addr = ip6->ip6_src; 1143 rt->mf6c_mcastgrp.sin6_family = AF_INET6; 1144 rt->mf6c_mcastgrp.sin6_len = sizeof(struct sockaddr_in6); 1145 rt->mf6c_mcastgrp.sin6_addr = ip6->ip6_dst; 1146 rt->mf6c_expire = UPCALL_EXPIRE; 1147 nexpire[hash]++; 1148 rt->mf6c_parent = MF6C_INCOMPLETE_PARENT; 1149 1150 /* link into table */ 1151 rt->mf6c_next = mf6ctable[hash]; 1152 mf6ctable[hash] = rt; 1153 /* Add this entry to the end of the queue */ 1154 rt->mf6c_stall = rte; 1155 } else { 1156 /* determine if q has overflowed */ 1157 struct rtdetq **p; 1158 int npkts = 0; 1159 1160 for (p = &rt->mf6c_stall; *p != NULL; p = &(*p)->next) 1161 if (++npkts > MAX_UPQ6) { 1162 mrt6stat.mrt6s_upq_ovflw++; 1163 free(rte, M_MRTABLE); 1164 m_freem(mb0); 1165 splx(s); 1166 return 0; 1167 } 1168 1169 /* Add this entry to the end of the queue */ 1170 *p = rte; 1171 } 1172 1173 rte->next = NULL; 1174 rte->m = mb0; 1175 rte->ifp = ifp; 1176 #ifdef UPCALL_TIMING 1177 rte->t = tp; 1178 #endif /* UPCALL_TIMING */ 1179 1180 splx(s); 1181 1182 return 0; 1183 } 1184 } 1185 1186 /* 1187 * Clean up cache entries if upcalls are not serviced 1188 * Call from the Slow Timeout mechanism, every half second. 1189 */ 1190 static void 1191 expire_upcalls(unused) 1192 void *unused; 1193 { 1194 struct rtdetq *rte; 1195 struct mf6c *mfc, **nptr; 1196 int i; 1197 int s; 1198 1199 s = splsoftnet(); 1200 for (i = 0; i < MF6CTBLSIZ; i++) { 1201 if (nexpire[i] == 0) 1202 continue; 1203 nptr = &mf6ctable[i]; 1204 while ((mfc = *nptr) != NULL) { 1205 rte = mfc->mf6c_stall; 1206 /* 1207 * Skip real cache entries 1208 * Make sure it wasn't marked to not expire (shouldn't happen) 1209 * If it expires now 1210 */ 1211 if (rte != NULL && 1212 mfc->mf6c_expire != 0 && 1213 --mfc->mf6c_expire == 0) { 1214 #ifdef MRT6DEBUG 1215 if (mrt6debug & DEBUG_EXPIRE) 1216 log(LOG_DEBUG, "expire_upcalls: expiring (%s %s)\n", 1217 ip6_sprintf(&mfc->mf6c_origin.sin6_addr), 1218 ip6_sprintf(&mfc->mf6c_mcastgrp.sin6_addr)); 1219 #endif 1220 /* 1221 * drop all the packets 1222 * free the mbuf with the pkt, if, timing info 1223 */ 1224 do { 1225 struct rtdetq *n = rte->next; 1226 m_freem(rte->m); 1227 free(rte, M_MRTABLE); 1228 rte = n; 1229 } while (rte != NULL); 1230 mrt6stat.mrt6s_cache_cleanups++; 1231 nexpire[i]--; 1232 1233 *nptr = mfc->mf6c_next; 1234 free(mfc, M_MRTABLE); 1235 } else { 1236 nptr = &mfc->mf6c_next; 1237 } 1238 } 1239 } 1240 splx(s); 1241 callout_reset(&expire_upcalls_ch, EXPIRE_TIMEOUT, 1242 expire_upcalls, NULL); 1243 } 1244 1245 /* 1246 * Packet forwarding routine once entry in the cache is made 1247 */ 1248 static int 1249 ip6_mdq(m, ifp, rt) 1250 struct mbuf *m; 1251 struct ifnet *ifp; 1252 struct mf6c *rt; 1253 { 1254 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 1255 mifi_t mifi, iif; 1256 struct mif6 *mifp; 1257 int plen = m->m_pkthdr.len; 1258 1259 /* 1260 * Macro to send packet on mif. Since RSVP packets don't get counted on 1261 * input, they shouldn't get counted on output, so statistics keeping is 1262 * separate. 1263 */ 1264 1265 #define MC6_SEND(ip6, mifp, m) do { \ 1266 if ((mifp)->m6_flags & MIFF_REGISTER) \ 1267 register_send((ip6), (mifp), (m)); \ 1268 else \ 1269 phyint_send((ip6), (mifp), (m)); \ 1270 } while (0) 1271 1272 /* 1273 * Don't forward if it didn't arrive from the parent mif 1274 * for its origin. 1275 */ 1276 mifi = rt->mf6c_parent; 1277 if ((mifi >= nummifs) || (mif6table[mifi].m6_ifp != ifp)) { 1278 /* came in the wrong interface */ 1279 #ifdef MRT6DEBUG 1280 if (mrt6debug & DEBUG_FORWARD) 1281 log(LOG_DEBUG, 1282 "wrong if: ifid %d mifi %d mififid %x\n", 1283 ifp->if_index, mifi, 1284 mif6table[mifi].m6_ifp->if_index); 1285 #endif 1286 mrt6stat.mrt6s_wrong_if++; 1287 rt->mf6c_wrong_if++; 1288 /* 1289 * If we are doing PIM processing, and we are forwarding 1290 * packets on this interface, send a message to the 1291 * routing daemon. 1292 */ 1293 /* have to make sure this is a valid mif */ 1294 if (mifi < nummifs && mif6table[mifi].m6_ifp) 1295 if (pim6 && (m->m_flags & M_LOOP) == 0) { 1296 /* 1297 * Check the M_LOOP flag to avoid an 1298 * unnecessary PIM assert. 1299 * XXX: M_LOOP is an ad-hoc hack... 1300 */ 1301 static struct sockaddr_in6 sin6 = 1302 { sizeof(sin6), AF_INET6 }; 1303 1304 struct mbuf *mm; 1305 struct mrt6msg *im; 1306 struct omrt6msg *oim; 1307 1308 mm = m_copy(m, 0, sizeof(struct ip6_hdr)); 1309 if (mm && 1310 (M_HASCL(mm) || 1311 mm->m_len < sizeof(struct ip6_hdr))) 1312 mm = m_pullup(mm, sizeof(struct ip6_hdr)); 1313 if (mm == NULL) 1314 return ENOBUFS; 1315 1316 oim = NULL; 1317 im = NULL; 1318 switch (ip6_mrouter_ver) { 1319 case MRT6_OINIT: 1320 oim = mtod(mm, struct omrt6msg *); 1321 oim->im6_msgtype = MRT6MSG_WRONGMIF; 1322 oim->im6_mbz = 0; 1323 break; 1324 case MRT6_INIT: 1325 im = mtod(mm, struct mrt6msg *); 1326 im->im6_msgtype = MRT6MSG_WRONGMIF; 1327 im->im6_mbz = 0; 1328 break; 1329 default: 1330 m_freem(mm); 1331 return EINVAL; 1332 } 1333 1334 for (mifp = mif6table, iif = 0; 1335 iif < nummifs && mifp && 1336 mifp->m6_ifp != ifp; 1337 mifp++, iif++) 1338 ; 1339 1340 switch (ip6_mrouter_ver) { 1341 case MRT6_OINIT: 1342 oim->im6_mif = iif; 1343 sin6.sin6_addr = oim->im6_src; 1344 break; 1345 case MRT6_INIT: 1346 im->im6_mif = iif; 1347 sin6.sin6_addr = im->im6_src; 1348 break; 1349 } 1350 1351 mrt6stat.mrt6s_upcalls++; 1352 1353 if (socket_send(ip6_mrouter, mm, &sin6) < 0) { 1354 #ifdef MRT6DEBUG 1355 if (mrt6debug) 1356 log(LOG_WARNING, "mdq, ip6_mrouter socket queue full\n"); 1357 #endif 1358 ++mrt6stat.mrt6s_upq_sockfull; 1359 return ENOBUFS; 1360 } /* if socket Q full */ 1361 } /* if PIM */ 1362 return 0; 1363 } /* if wrong iif */ 1364 1365 /* If I sourced this packet, it counts as output, else it was input. */ 1366 if (m->m_pkthdr.rcvif == NULL) { 1367 /* XXX: is rcvif really NULL when output?? */ 1368 mif6table[mifi].m6_pkt_out++; 1369 mif6table[mifi].m6_bytes_out += plen; 1370 } else { 1371 mif6table[mifi].m6_pkt_in++; 1372 mif6table[mifi].m6_bytes_in += plen; 1373 } 1374 rt->mf6c_pkt_cnt++; 1375 rt->mf6c_byte_cnt += plen; 1376 1377 /* 1378 * For each mif, forward a copy of the packet if there are group 1379 * members downstream on the interface. 1380 */ 1381 for (mifp = mif6table, mifi = 0; mifi < nummifs; mifp++, mifi++) 1382 if (IF_ISSET(mifi, &rt->mf6c_ifset)) { 1383 #ifdef notyet 1384 /* 1385 * check if the outgoing packet is going to break 1386 * a scope boundary. 1387 * XXX For packets through PIM register tunnel 1388 * interface, we believe a routing daemon. 1389 */ 1390 if ((mif6table[rt->mf6c_parent].m6_flags & 1391 MIFF_REGISTER) == 0 && 1392 (mif6table[mifi].m6_flags & MIFF_REGISTER) == 0 && 1393 (in6_addr2scopeid(ifp, &ip6->ip6_dst) != 1394 in6_addr2scopeid(mif6table[mifi].m6_ifp, 1395 &ip6->ip6_dst) || 1396 in6_addr2scopeid(ifp, &ip6->ip6_src) != 1397 in6_addr2scopeid(mif6table[mifi].m6_ifp, 1398 &ip6->ip6_src))) { 1399 ip6stat.ip6s_badscope++; 1400 continue; 1401 } 1402 #endif 1403 1404 mifp->m6_pkt_out++; 1405 mifp->m6_bytes_out += plen; 1406 MC6_SEND(ip6, mifp, m); 1407 } 1408 return 0; 1409 } 1410 1411 static void 1412 phyint_send(ip6, mifp, m) 1413 struct ip6_hdr *ip6; 1414 struct mif6 *mifp; 1415 struct mbuf *m; 1416 { 1417 struct mbuf *mb_copy; 1418 struct ifnet *ifp = mifp->m6_ifp; 1419 int error = 0; 1420 int s = splsoftnet(); 1421 static struct route_in6 ro; 1422 struct in6_multi *in6m; 1423 struct sockaddr_in6 *dst6; 1424 1425 /* 1426 * Make a new reference to the packet; make sure that 1427 * the IPv6 header is actually copied, not just referenced, 1428 * so that ip6_output() only scribbles on the copy. 1429 */ 1430 mb_copy = m_copy(m, 0, M_COPYALL); 1431 if (mb_copy && 1432 (M_HASCL(mb_copy) || mb_copy->m_len < sizeof(struct ip6_hdr))) 1433 mb_copy = m_pullup(mb_copy, sizeof(struct ip6_hdr)); 1434 if (mb_copy == NULL) { 1435 splx(s); 1436 return; 1437 } 1438 /* set MCAST flag to the outgoing packet */ 1439 mb_copy->m_flags |= M_MCAST; 1440 1441 /* 1442 * If we sourced the packet, call ip6_output since we may devide 1443 * the packet into fragments when the packet is too big for the 1444 * outgoing interface. 1445 * Otherwise, we can simply send the packet to the interface 1446 * sending queue. 1447 */ 1448 if (m->m_pkthdr.rcvif == NULL) { 1449 struct ip6_moptions im6o; 1450 1451 im6o.im6o_multicast_ifp = ifp; 1452 /* XXX: ip6_output will override ip6->ip6_hlim */ 1453 im6o.im6o_multicast_hlim = ip6->ip6_hlim; 1454 im6o.im6o_multicast_loop = 1; 1455 error = ip6_output(mb_copy, NULL, &ro, 1456 IPV6_FORWARDING, &im6o, NULL); 1457 1458 #ifdef MRT6DEBUG 1459 if (mrt6debug & DEBUG_XMIT) 1460 log(LOG_DEBUG, "phyint_send on mif %d err %d\n", 1461 mifp - mif6table, error); 1462 #endif 1463 splx(s); 1464 return; 1465 } 1466 1467 /* 1468 * If we belong to the destination multicast group 1469 * on the outgoing interface, loop back a copy. 1470 */ 1471 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 1472 IN6_LOOKUP_MULTI(ip6->ip6_dst, ifp, in6m); 1473 if (in6m != NULL) { 1474 dst6->sin6_len = sizeof(struct sockaddr_in6); 1475 dst6->sin6_family = AF_INET6; 1476 dst6->sin6_addr = ip6->ip6_dst; 1477 ip6_mloopback(ifp, m, (struct sockaddr_in6 *)&ro.ro_dst); 1478 } 1479 /* 1480 * Put the packet into the sending queue of the outgoing interface 1481 * if it would fit in the MTU of the interface. 1482 */ 1483 if (mb_copy->m_pkthdr.len < ifp->if_mtu || ifp->if_mtu < IPV6_MMTU) { 1484 dst6->sin6_len = sizeof(struct sockaddr_in6); 1485 dst6->sin6_family = AF_INET6; 1486 dst6->sin6_addr = ip6->ip6_dst; 1487 /* 1488 * We just call if_output instead of nd6_output here, since 1489 * we need no ND for a multicast forwarded packet...right? 1490 */ 1491 error = (*ifp->if_output)(ifp, mb_copy, 1492 (struct sockaddr *)&ro.ro_dst, NULL); 1493 #ifdef MRT6DEBUG 1494 if (mrt6debug & DEBUG_XMIT) 1495 log(LOG_DEBUG, "phyint_send on mif %d err %d\n", 1496 mifp - mif6table, error); 1497 #endif 1498 } else { 1499 #ifdef MULTICAST_PMTUD 1500 icmp6_error(mb_copy, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 1501 #else 1502 #ifdef MRT6DEBUG 1503 if (mrt6debug & DEBUG_XMIT) 1504 log(LOG_DEBUG, 1505 "phyint_send: packet too big on %s o %s g %s" 1506 " size %d(discarded)\n", 1507 if_name(ifp), 1508 ip6_sprintf(&ip6->ip6_src), 1509 ip6_sprintf(&ip6->ip6_dst), 1510 mb_copy->m_pkthdr.len); 1511 #endif /* MRT6DEBUG */ 1512 m_freem(mb_copy); /* simply discard the packet */ 1513 #endif 1514 } 1515 1516 splx(s); 1517 } 1518 1519 static int 1520 register_send(ip6, mif, m) 1521 struct ip6_hdr *ip6; 1522 struct mif6 *mif; 1523 struct mbuf *m; 1524 { 1525 struct mbuf *mm; 1526 int i, len = m->m_pkthdr.len; 1527 static struct sockaddr_in6 sin6 = { sizeof(sin6), AF_INET6 }; 1528 struct mrt6msg *im6; 1529 1530 #ifdef MRT6DEBUG 1531 if (mrt6debug) 1532 log(LOG_DEBUG, "** IPv6 register_send **\n src %s dst %s\n", 1533 ip6_sprintf(&ip6->ip6_src), ip6_sprintf(&ip6->ip6_dst)); 1534 #endif 1535 ++pim6stat.pim6s_snd_registers; 1536 1537 /* Make a copy of the packet to send to the user level process */ 1538 MGETHDR(mm, M_DONTWAIT, MT_HEADER); 1539 if (mm == NULL) 1540 return ENOBUFS; 1541 mm->m_data += max_linkhdr; 1542 mm->m_len = sizeof(struct ip6_hdr); 1543 1544 if ((mm->m_next = m_copy(m, 0, M_COPYALL)) == NULL) { 1545 m_freem(mm); 1546 return ENOBUFS; 1547 } 1548 i = MHLEN - M_LEADINGSPACE(mm); 1549 if (i > len) 1550 i = len; 1551 mm = m_pullup(mm, i); 1552 if (mm == NULL){ 1553 m_freem(mm); 1554 return ENOBUFS; 1555 } 1556 /* TODO: check it! */ 1557 mm->m_pkthdr.len = len + sizeof(struct ip6_hdr); 1558 1559 /* 1560 * Send message to routing daemon 1561 */ 1562 sin6.sin6_addr = ip6->ip6_src; 1563 1564 im6 = mtod(mm, struct mrt6msg *); 1565 im6->im6_msgtype = MRT6MSG_WHOLEPKT; 1566 im6->im6_mbz = 0; 1567 1568 im6->im6_mif = mif - mif6table; 1569 1570 /* iif info is not given for reg. encap.n */ 1571 mrt6stat.mrt6s_upcalls++; 1572 1573 if (socket_send(ip6_mrouter, mm, &sin6) < 0) { 1574 #ifdef MRT6DEBUG 1575 if (mrt6debug) 1576 log(LOG_WARNING, 1577 "register_send: ip_mrouter socket queue full\n"); 1578 #endif 1579 ++mrt6stat.mrt6s_upq_sockfull; 1580 return ENOBUFS; 1581 } 1582 return 0; 1583 } 1584 1585 /* 1586 * PIM sparse mode hook 1587 * Receives the pim control messages, and passes them up to the listening 1588 * socket, using rip6_input. 1589 * The only message processed is the REGISTER pim message; the pim header 1590 * is stripped off, and the inner packet is passed to register_mforward. 1591 */ 1592 int 1593 pim6_input(mp, offp, proto) 1594 struct mbuf **mp; 1595 int *offp, proto; 1596 { 1597 struct pim *pim; /* pointer to a pim struct */ 1598 struct ip6_hdr *ip6; 1599 int pimlen; 1600 struct mbuf *m = *mp; 1601 int minlen; 1602 int off = *offp; 1603 1604 ++pim6stat.pim6s_rcv_total; 1605 1606 ip6 = mtod(m, struct ip6_hdr *); 1607 pimlen = m->m_pkthdr.len - *offp; 1608 1609 /* 1610 * Validate lengths 1611 */ 1612 if (pimlen < PIM_MINLEN) { 1613 ++pim6stat.pim6s_rcv_tooshort; 1614 #ifdef MRT6DEBUG 1615 if (mrt6debug & DEBUG_PIM) 1616 log(LOG_DEBUG,"pim6_input: PIM packet too short\n"); 1617 #endif 1618 m_freem(m); 1619 return(IPPROTO_DONE); 1620 } 1621 1622 /* 1623 * if the packet is at least as big as a REGISTER, go ahead 1624 * and grab the PIM REGISTER header size, to avoid another 1625 * possible m_pullup() later. 1626 * 1627 * PIM_MINLEN == pimhdr + u_int32 == 8 1628 * PIM6_REG_MINLEN == pimhdr + reghdr + eip6hdr == 4 + 4 + 40 1629 */ 1630 minlen = (pimlen >= PIM6_REG_MINLEN) ? PIM6_REG_MINLEN : PIM_MINLEN; 1631 1632 /* 1633 * Make sure that the IP6 and PIM headers in contiguous memory, and 1634 * possibly the PIM REGISTER header 1635 */ 1636 #ifndef PULLDOWN_TEST 1637 IP6_EXTHDR_CHECK(m, off, minlen, IPPROTO_DONE); 1638 /* adjust pointer */ 1639 ip6 = mtod(m, struct ip6_hdr *); 1640 1641 /* adjust mbuf to point to the PIM header */ 1642 pim = (struct pim *)((caddr_t)ip6 + off); 1643 #else 1644 IP6_EXTHDR_GET(pim, struct pim *, m, off, minlen); 1645 if (pim == NULL) { 1646 pim6stat.pim6s_rcv_tooshort++; 1647 return IPPROTO_DONE; 1648 } 1649 #endif 1650 1651 #define PIM6_CHECKSUM 1652 #ifdef PIM6_CHECKSUM 1653 { 1654 int cksumlen; 1655 1656 /* 1657 * Validate checksum. 1658 * If PIM REGISTER, exclude the data packet 1659 */ 1660 if (pim->pim_type == PIM_REGISTER) 1661 cksumlen = PIM_MINLEN; 1662 else 1663 cksumlen = pimlen; 1664 1665 if (in6_cksum(m, IPPROTO_PIM, off, cksumlen)) { 1666 ++pim6stat.pim6s_rcv_badsum; 1667 #ifdef MRT6DEBUG 1668 if (mrt6debug & DEBUG_PIM) 1669 log(LOG_DEBUG, 1670 "pim6_input: invalid checksum\n"); 1671 #endif 1672 m_freem(m); 1673 return(IPPROTO_DONE); 1674 } 1675 } 1676 #endif /* PIM_CHECKSUM */ 1677 1678 /* PIM version check */ 1679 if (pim->pim_ver != PIM_VERSION) { 1680 ++pim6stat.pim6s_rcv_badversion; 1681 #ifdef MRT6DEBUG 1682 log(LOG_ERR, 1683 "pim6_input: incorrect version %d, expecting %d\n", 1684 pim->pim_ver, PIM_VERSION); 1685 #endif 1686 m_freem(m); 1687 return(IPPROTO_DONE); 1688 } 1689 1690 if (pim->pim_type == PIM_REGISTER) { 1691 /* 1692 * since this is a REGISTER, we'll make a copy of the register 1693 * headers ip6+pim+u_int32_t+encap_ip6, to be passed up to the 1694 * routing daemon. 1695 */ 1696 static struct sockaddr_in6 dst = { sizeof(dst), AF_INET6 }; 1697 1698 struct mbuf *mcp; 1699 struct ip6_hdr *eip6; 1700 u_int32_t *reghdr; 1701 int rc; 1702 1703 ++pim6stat.pim6s_rcv_registers; 1704 1705 if ((reg_mif_num >= nummifs) || (reg_mif_num == (mifi_t) -1)) { 1706 #ifdef MRT6DEBUG 1707 if (mrt6debug & DEBUG_PIM) 1708 log(LOG_DEBUG, 1709 "pim6_input: register mif not set: %d\n", 1710 reg_mif_num); 1711 #endif 1712 m_freem(m); 1713 return(IPPROTO_DONE); 1714 } 1715 1716 reghdr = (u_int32_t *)(pim + 1); 1717 1718 if ((ntohl(*reghdr) & PIM_NULL_REGISTER)) 1719 goto pim6_input_to_daemon; 1720 1721 /* 1722 * Validate length 1723 */ 1724 if (pimlen < PIM6_REG_MINLEN) { 1725 ++pim6stat.pim6s_rcv_tooshort; 1726 ++pim6stat.pim6s_rcv_badregisters; 1727 #ifdef MRT6DEBUG 1728 log(LOG_ERR, 1729 "pim6_input: register packet size too " 1730 "small %d from %s\n", 1731 pimlen, ip6_sprintf(&ip6->ip6_src)); 1732 #endif 1733 m_freem(m); 1734 return(IPPROTO_DONE); 1735 } 1736 1737 eip6 = (struct ip6_hdr *) (reghdr + 1); 1738 #ifdef MRT6DEBUG 1739 if (mrt6debug & DEBUG_PIM) 1740 log(LOG_DEBUG, 1741 "pim6_input[register], eip6: %s -> %s, " 1742 "eip6 plen %d\n", 1743 ip6_sprintf(&eip6->ip6_src), 1744 ip6_sprintf(&eip6->ip6_dst), 1745 ntohs(eip6->ip6_plen)); 1746 #endif 1747 1748 /* verify the version number of the inner packet */ 1749 if ((eip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { 1750 ++pim6stat.pim6s_rcv_badregisters; 1751 #ifdef MRT6DEBUG 1752 log(LOG_DEBUG, "pim6_input: invalid IP version (%d) " 1753 "of the inner packet\n", 1754 (eip6->ip6_vfc & IPV6_VERSION)); 1755 #endif 1756 m_freem(m); 1757 return(IPPROTO_NONE); 1758 } 1759 1760 /* verify the inner packet is destined to a mcast group */ 1761 if (!IN6_IS_ADDR_MULTICAST(&eip6->ip6_dst)) { 1762 ++pim6stat.pim6s_rcv_badregisters; 1763 #ifdef MRT6DEBUG 1764 if (mrt6debug & DEBUG_PIM) 1765 log(LOG_DEBUG, 1766 "pim6_input: inner packet of register " 1767 "is not multicast %s\n", 1768 ip6_sprintf(&eip6->ip6_dst)); 1769 #endif 1770 m_freem(m); 1771 return(IPPROTO_DONE); 1772 } 1773 1774 /* 1775 * make a copy of the whole header to pass to the daemon later. 1776 */ 1777 mcp = m_copy(m, 0, off + PIM6_REG_MINLEN); 1778 if (mcp == NULL) { 1779 #ifdef MRT6DEBUG 1780 log(LOG_ERR, 1781 "pim6_input: pim register: " 1782 "could not copy register head\n"); 1783 #endif 1784 m_freem(m); 1785 return(IPPROTO_DONE); 1786 } 1787 1788 /* 1789 * forward the inner ip6 packet; point m_data at the inner ip6. 1790 */ 1791 m_adj(m, off + PIM_MINLEN); 1792 #ifdef MRT6DEBUG 1793 if (mrt6debug & DEBUG_PIM) { 1794 log(LOG_DEBUG, 1795 "pim6_input: forwarding decapsulated register: " 1796 "src %s, dst %s, mif %d\n", 1797 ip6_sprintf(&eip6->ip6_src), 1798 ip6_sprintf(&eip6->ip6_dst), 1799 reg_mif_num); 1800 } 1801 #endif 1802 1803 rc = looutput(mif6table[reg_mif_num].m6_ifp, m, 1804 (struct sockaddr *) &dst, 1805 (struct rtentry *) NULL); 1806 1807 /* prepare the register head to send to the mrouting daemon */ 1808 m = mcp; 1809 } 1810 1811 /* 1812 * Pass the PIM message up to the daemon; if it is a register message 1813 * pass the 'head' only up to the daemon. This includes the 1814 * encapsulator ip6 header, pim header, register header and the 1815 * encapsulated ip6 header. 1816 */ 1817 pim6_input_to_daemon: 1818 rip6_input(&m, offp, proto); 1819 return(IPPROTO_DONE); 1820 } 1821