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