]> git.saurik.com Git - apple/xnu.git/blob - bsd/netinet/ip_mroute.c
xnu-792.22.5.tar.gz
[apple/xnu.git] / bsd / netinet / ip_mroute.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28 /*
29 * IP multicast forwarding procedures
30 *
31 * Written by David Waitzman, BBN Labs, August 1988.
32 * Modified by Steve Deering, Stanford, February 1989.
33 * Modified by Mark J. Steiglitz, Stanford, May, 1991
34 * Modified by Van Jacobson, LBL, January 1993
35 * Modified by Ajit Thyagarajan, PARC, August 1993
36 * Modified by Bill Fenner, PARC, April 1995
37 *
38 * MROUTING Revision: 3.5
39 * $FreeBSD: src/sys/netinet/ip_mroute.c,v 1.56.2.2 2001/07/19 06:37:26 kris Exp $
40 */
41
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/malloc.h>
46 #include <sys/mbuf.h>
47 #include <sys/socket.h>
48 #include <sys/socketvar.h>
49 #include <sys/protosw.h>
50 #include <sys/time.h>
51 #include <sys/kernel.h>
52 #include <sys/sockio.h>
53 #include <sys/syslog.h>
54 #include <net/if.h>
55 #include <net/route.h>
56 #include <netinet/in.h>
57 #include <netinet/in_systm.h>
58 #include <netinet/ip.h>
59 #include <netinet/ip_var.h>
60 #include <netinet/in_var.h>
61 #include <netinet/igmp.h>
62 #include <netinet/ip_mroute.h>
63 #include <netinet/udp.h>
64
65 #ifndef NTOHL
66 #if BYTE_ORDER != BIG_ENDIAN
67 #define NTOHL(d) ((d) = ntohl((d)))
68 #define NTOHS(d) ((d) = ntohs((u_short)(d)))
69 #define HTONL(d) ((d) = htonl((d)))
70 #define HTONS(d) ((d) = htons((u_short)(d)))
71 #else
72 #define NTOHL(d)
73 #define NTOHS(d)
74 #define HTONL(d)
75 #define HTONS(d)
76 #endif
77 #endif
78
79 #ifndef MROUTING
80 extern u_long _ip_mcast_src(int vifi);
81 extern int _ip_mforward(struct ip *ip, struct ifnet *ifp,
82 struct mbuf *m, struct ip_moptions *imo);
83 extern int _ip_mrouter_done(void);
84 extern int _ip_mrouter_get(struct socket *so, struct sockopt *sopt);
85 extern int _ip_mrouter_set(struct socket *so, struct sockopt *sopt);
86 extern int _mrt_ioctl(int req, caddr_t data, struct proc *p);
87
88 /*
89 * Dummy routines and globals used when multicast routing is not compiled in.
90 */
91
92 struct socket *ip_mrouter = NULL;
93 u_int rsvpdebug = 0;
94
95 int
96 _ip_mrouter_set(so, sopt)
97 struct socket *so;
98 struct sockopt *sopt;
99 {
100 return(EOPNOTSUPP);
101 }
102
103 int (*ip_mrouter_set)(struct socket *, struct sockopt *) = _ip_mrouter_set;
104
105
106 int
107 _ip_mrouter_get(so, sopt)
108 struct socket *so;
109 struct sockopt *sopt;
110 {
111 return(EOPNOTSUPP);
112 }
113
114 int (*ip_mrouter_get)(struct socket *, struct sockopt *) = _ip_mrouter_get;
115
116 int
117 _ip_mrouter_done()
118 {
119 return(0);
120 }
121
122 int (*ip_mrouter_done)(void) = _ip_mrouter_done;
123
124 int
125 _ip_mforward(ip, ifp, m, imo)
126 struct ip *ip;
127 struct ifnet *ifp;
128 struct mbuf *m;
129 struct ip_moptions *imo;
130 {
131 return(0);
132 }
133
134 int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
135 struct ip_moptions *) = _ip_mforward;
136
137 int
138 _mrt_ioctl(int req, caddr_t data, struct proc *p)
139 {
140 return EOPNOTSUPP;
141 }
142
143 int (*mrt_ioctl)(int, caddr_t, struct proc *) = _mrt_ioctl;
144
145 void
146 rsvp_input(m, iphlen) /* XXX must fixup manually */
147 struct mbuf *m;
148 int iphlen;
149 {
150 /* Can still get packets with rsvp_on = 0 if there is a local member
151 * of the group to which the RSVP packet is addressed. But in this
152 * case we want to throw the packet away.
153 */
154 if (!rsvp_on) {
155 m_freem(m);
156 return;
157 }
158
159 if (ip_rsvpd != NULL) {
160 if (rsvpdebug)
161 printf("rsvp_input: Sending packet up old-style socket\n");
162 rip_input(m, iphlen);
163 return;
164 }
165 /* Drop the packet */
166 m_freem(m);
167 }
168
169 void ipip_input(struct mbuf *m, int iphlen) { /* XXX must fixup manually */
170 rip_input(m, iphlen);
171 }
172
173 int (*legal_vif_num)(int) = 0;
174
175 /*
176 * This should never be called, since IP_MULTICAST_VIF should fail, but
177 * just in case it does get called, the code a little lower in ip_output
178 * will assign the packet a local address.
179 */
180 u_long
181 _ip_mcast_src(int vifi) { return INADDR_ANY; }
182 u_long (*ip_mcast_src)(int) = _ip_mcast_src;
183
184 int
185 ip_rsvp_vif_init(so, sopt)
186 struct socket *so;
187 struct sockopt *sopt;
188 {
189 return(EINVAL);
190 }
191
192 int
193 ip_rsvp_vif_done(so, sopt)
194 struct socket *so;
195 struct sockopt *sopt;
196 {
197 return(EINVAL);
198 }
199
200 void
201 ip_rsvp_force_done(so)
202 struct socket *so;
203 {
204 return;
205 }
206
207 #else /* MROUTING */
208
209 #define M_HASCL(m) ((m)->m_flags & M_EXT)
210
211 #define INSIZ sizeof(struct in_addr)
212 #define same(a1, a2) \
213 (bcmp((caddr_t)(a1), (caddr_t)(a2), INSIZ) == 0)
214
215
216 /*
217 * Globals. All but ip_mrouter and ip_mrtproto could be static,
218 * except for netstat or debugging purposes.
219 */
220 #ifndef MROUTE_LKM
221 struct socket *ip_mrouter = NULL;
222 static struct mrtstat mrtstat;
223 #else /* MROUTE_LKM */
224 extern void X_ipip_input(struct mbuf *m, int iphlen);
225 extern struct mrtstat mrtstat;
226 static int ip_mrtproto;
227 #endif
228
229 #define NO_RTE_FOUND 0x1
230 #define RTE_FOUND 0x2
231
232 static struct mfc *mfctable[MFCTBLSIZ];
233 static u_char nexpire[MFCTBLSIZ];
234 static struct vif viftable[MAXVIFS];
235 static u_int mrtdebug = 0; /* debug level */
236 #define DEBUG_MFC 0x02
237 #define DEBUG_FORWARD 0x04
238 #define DEBUG_EXPIRE 0x08
239 #define DEBUG_XMIT 0x10
240 static u_int tbfdebug = 0; /* tbf debug level */
241 static u_int rsvpdebug = 0; /* rsvp debug level */
242
243 #define EXPIRE_TIMEOUT (hz / 4) /* 4x / second */
244 #define UPCALL_EXPIRE 6 /* number of timeouts */
245
246 /*
247 * Define the token bucket filter structures
248 * tbftable -> each vif has one of these for storing info
249 */
250
251 static struct tbf tbftable[MAXVIFS];
252 #define TBF_REPROCESS (hz / 100) /* 100x / second */
253
254 /*
255 * 'Interfaces' associated with decapsulator (so we can tell
256 * packets that went through it from ones that get reflected
257 * by a broken gateway). These interfaces are never linked into
258 * the system ifnet list & no routes point to them. I.e., packets
259 * can't be sent this way. They only exist as a placeholder for
260 * multicast source verification.
261 */
262 static struct ifnet multicast_decap_if[MAXVIFS];
263
264 #define ENCAP_TTL 64
265 #define ENCAP_PROTO IPPROTO_IPIP /* 4 */
266
267 /* prototype IP hdr for encapsulated packets */
268 static struct ip multicast_encap_iphdr = {
269 #if BYTE_ORDER == LITTLE_ENDIAN
270 sizeof(struct ip) >> 2, IPVERSION,
271 #else
272 IPVERSION, sizeof(struct ip) >> 2,
273 #endif
274 0, /* tos */
275 sizeof(struct ip), /* total length */
276 0, /* id */
277 0, /* frag offset */
278 ENCAP_TTL, ENCAP_PROTO,
279 0, /* checksum */
280 };
281
282 /*
283 * Private variables.
284 */
285 static vifi_t numvifs = 0;
286 static int have_encap_tunnel = 0;
287
288 /*
289 * one-back cache used by ipip_input to locate a tunnel's vif
290 * given a datagram's src ip address.
291 */
292 static u_long last_encap_src;
293 static struct vif *last_encap_vif;
294
295 static u_long X_ip_mcast_src(int vifi);
296 static int X_ip_mforward(struct ip *ip, struct ifnet *ifp, struct mbuf *m, struct ip_moptions *imo);
297 static int X_ip_mrouter_done(void);
298 static int X_ip_mrouter_get(struct socket *so, struct sockopt *m);
299 static int X_ip_mrouter_set(struct socket *so, struct sockopt *m);
300 static int X_legal_vif_num(int vif);
301 static int X_mrt_ioctl(int cmd, caddr_t data);
302
303 static int get_sg_cnt(struct sioc_sg_req *);
304 static int get_vif_cnt(struct sioc_vif_req *);
305 static int ip_mrouter_init(struct socket *, int);
306 static int add_vif(struct vifctl *);
307 static int del_vif(vifi_t);
308 static int add_mfc(struct mfcctl *);
309 static int del_mfc(struct mfcctl *);
310 static int socket_send(struct socket *, struct mbuf *, struct sockaddr_in *);
311 static int set_assert(int);
312 static void expire_upcalls(void *);
313 static int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *,
314 vifi_t);
315 static void phyint_send(struct ip *, struct vif *, struct mbuf *);
316 static void encap_send(struct ip *, struct vif *, struct mbuf *);
317 static void tbf_control(struct vif *, struct mbuf *, struct ip *, u_long);
318 static void tbf_queue(struct vif *, struct mbuf *);
319 static void tbf_process_q(struct vif *);
320 static void tbf_reprocess_q(void *);
321 static int tbf_dq_sel(struct vif *, struct ip *);
322 static void tbf_send_packet(struct vif *, struct mbuf *);
323 static void tbf_update_tokens(struct vif *);
324 static int priority(struct vif *, struct ip *);
325 void multiencap_decap(struct mbuf *);
326
327 /*
328 * whether or not special PIM assert processing is enabled.
329 */
330 static int pim_assert;
331 /*
332 * Rate limit for assert notification messages, in usec
333 */
334 #define ASSERT_MSG_TIME 3000000
335
336 /*
337 * Hash function for a source, group entry
338 */
339 #define MFCHASH(a, g) MFCHASHMOD(((a) >> 20) ^ ((a) >> 10) ^ (a) ^ \
340 ((g) >> 20) ^ ((g) >> 10) ^ (g))
341
342 /*
343 * Find a route for a given origin IP address and Multicast group address
344 * Type of service parameter to be added in the future!!!
345 */
346
347 #define MFCFIND(o, g, rt) { \
348 register struct mfc *_rt = mfctable[MFCHASH(o,g)]; \
349 rt = NULL; \
350 ++mrtstat.mrts_mfc_lookups; \
351 while (_rt) { \
352 if ((_rt->mfc_origin.s_addr == o) && \
353 (_rt->mfc_mcastgrp.s_addr == g) && \
354 (_rt->mfc_stall == NULL)) { \
355 rt = _rt; \
356 break; \
357 } \
358 _rt = _rt->mfc_next; \
359 } \
360 if (rt == NULL) { \
361 ++mrtstat.mrts_mfc_misses; \
362 } \
363 }
364
365
366 /*
367 * Macros to compute elapsed time efficiently
368 * Borrowed from Van Jacobson's scheduling code
369 */
370 #define TV_DELTA(a, b, delta) { \
371 register int xxs; \
372 \
373 delta = (a).tv_usec - (b).tv_usec; \
374 if ((xxs = (a).tv_sec - (b).tv_sec)) { \
375 switch (xxs) { \
376 case 2: \
377 delta += 1000000; \
378 /* fall through */ \
379 case 1: \
380 delta += 1000000; \
381 break; \
382 default: \
383 delta += (1000000 * xxs); \
384 } \
385 } \
386 }
387
388 #define TV_LT(a, b) (((a).tv_usec < (b).tv_usec && \
389 (a).tv_sec <= (b).tv_sec) || (a).tv_sec < (b).tv_sec)
390
391 #if UPCALL_TIMING
392 u_long upcall_data[51];
393 static void collate(struct timeval *);
394 #endif /* UPCALL_TIMING */
395
396
397 /*
398 * Handle MRT setsockopt commands to modify the multicast routing tables.
399 */
400 static int
401 X_ip_mrouter_set(so, sopt)
402 struct socket *so;
403 struct sockopt *sopt;
404 {
405 int error, optval;
406 vifi_t vifi;
407 struct vifctl vifc;
408 struct mfcctl mfc;
409
410 if (so != ip_mrouter && sopt->sopt_name != MRT_INIT)
411 return (EPERM);
412
413 error = 0;
414 switch (sopt->sopt_name) {
415 case MRT_INIT:
416 error = sooptcopyin(sopt, &optval, sizeof optval,
417 sizeof optval);
418 if (error)
419 break;
420 error = ip_mrouter_init(so, optval);
421 break;
422
423 case MRT_DONE:
424 error = ip_mrouter_done();
425 break;
426
427 case MRT_ADD_VIF:
428 error = sooptcopyin(sopt, &vifc, sizeof vifc, sizeof vifc);
429 if (error)
430 break;
431 error = add_vif(&vifc);
432 break;
433
434 case MRT_DEL_VIF:
435 error = sooptcopyin(sopt, &vifi, sizeof vifi, sizeof vifi);
436 if (error)
437 break;
438 error = del_vif(vifi);
439 break;
440
441 case MRT_ADD_MFC:
442 case MRT_DEL_MFC:
443 error = sooptcopyin(sopt, &mfc, sizeof mfc, sizeof mfc);
444 if (error)
445 break;
446 if (sopt->sopt_name == MRT_ADD_MFC)
447 error = add_mfc(&mfc);
448 else
449 error = del_mfc(&mfc);
450 break;
451
452 case MRT_ASSERT:
453 error = sooptcopyin(sopt, &optval, sizeof optval,
454 sizeof optval);
455 if (error)
456 break;
457 set_assert(optval);
458 break;
459
460 default:
461 error = EOPNOTSUPP;
462 break;
463 }
464 return (error);
465 }
466
467 #if !defined(MROUTE_LKM) || !MROUTE_LKM
468 int (*ip_mrouter_set)(struct socket *, struct sockopt *) = X_ip_mrouter_set;
469 #endif
470
471 /*
472 * Handle MRT getsockopt commands
473 */
474 static int
475 X_ip_mrouter_get(so, sopt)
476 struct socket *so;
477 struct sockopt *sopt;
478 {
479 int error;
480 static int version = 0x0305; /* !!! why is this here? XXX */
481
482 switch (sopt->sopt_name) {
483 case MRT_VERSION:
484 error = sooptcopyout(sopt, &version, sizeof version);
485 break;
486
487 case MRT_ASSERT:
488 error = sooptcopyout(sopt, &pim_assert, sizeof pim_assert);
489 break;
490 default:
491 error = EOPNOTSUPP;
492 break;
493 }
494 return (error);
495 }
496
497 #if !defined(MROUTE_LKM) || !MROUTE_LKM
498 int (*ip_mrouter_get)(struct socket *, struct sockopt *) = X_ip_mrouter_get;
499 #endif
500
501 /*
502 * Handle ioctl commands to obtain information from the cache
503 */
504 static int
505 X_mrt_ioctl(cmd, data)
506 int cmd;
507 caddr_t data;
508 {
509 int error = 0;
510
511 switch (cmd) {
512 case (SIOCGETVIFCNT):
513 return (get_vif_cnt((struct sioc_vif_req *)data));
514 break;
515 case (SIOCGETSGCNT):
516 return (get_sg_cnt((struct sioc_sg_req *)data));
517 break;
518 default:
519 return (EINVAL);
520 break;
521 }
522 return error;
523 }
524
525 #if !defined(MROUTE_LKM) || !MROUTE_LKM
526 int (*mrt_ioctl)(int, caddr_t) = X_mrt_ioctl;
527 #endif
528
529 /*
530 * returns the packet, byte, rpf-failure count for the source group provided
531 */
532 static int
533 get_sg_cnt(req)
534 register struct sioc_sg_req *req;
535 {
536 register struct mfc *rt;
537 int s;
538
539 s = splnet();
540 MFCFIND(req->src.s_addr, req->grp.s_addr, rt);
541 splx(s);
542 if (rt != NULL) {
543 req->pktcnt = rt->mfc_pkt_cnt;
544 req->bytecnt = rt->mfc_byte_cnt;
545 req->wrong_if = rt->mfc_wrong_if;
546 } else
547 req->pktcnt = req->bytecnt = req->wrong_if = 0xffffffff;
548
549 return 0;
550 }
551
552 /*
553 * returns the input and output packet and byte counts on the vif provided
554 */
555 static int
556 get_vif_cnt(req)
557 register struct sioc_vif_req *req;
558 {
559 register vifi_t vifi = req->vifi;
560
561 if (vifi >= numvifs) return EINVAL;
562
563 req->icount = viftable[vifi].v_pkt_in;
564 req->ocount = viftable[vifi].v_pkt_out;
565 req->ibytes = viftable[vifi].v_bytes_in;
566 req->obytes = viftable[vifi].v_bytes_out;
567
568 return 0;
569 }
570
571 /*
572 * Enable multicast routing
573 */
574 static int
575 ip_mrouter_init(so, version)
576 struct socket *so;
577 int version;
578 {
579 if (mrtdebug)
580 log(LOG_DEBUG,"ip_mrouter_init: so_type = %d, pr_protocol = %d\n",
581 so->so_type, so->so_proto->pr_protocol);
582
583 if (so->so_type != SOCK_RAW ||
584 so->so_proto->pr_protocol != IPPROTO_IGMP) return EOPNOTSUPP;
585
586 if (version != 1)
587 return ENOPROTOOPT;
588
589 if (ip_mrouter != NULL) return EADDRINUSE;
590
591 ip_mrouter = so;
592
593 bzero((caddr_t)mfctable, sizeof(mfctable));
594 bzero((caddr_t)nexpire, sizeof(nexpire));
595
596 pim_assert = 0;
597
598 timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT);
599
600 if (mrtdebug)
601 log(LOG_DEBUG, "ip_mrouter_init\n");
602
603 return 0;
604 }
605
606 /*
607 * Disable multicast routing
608 */
609 static int
610 X_ip_mrouter_done()
611 {
612 vifi_t vifi;
613 int i;
614 struct ifnet *ifp;
615 struct ifreq ifr;
616 struct mfc *rt;
617 struct rtdetq *rte;
618 int s;
619
620 s = splnet();
621
622 /*
623 * For each phyint in use, disable promiscuous reception of all IP
624 * multicasts.
625 */
626 for (vifi = 0; vifi < numvifs; vifi++) {
627 if (viftable[vifi].v_lcl_addr.s_addr != 0 &&
628 !(viftable[vifi].v_flags & VIFF_TUNNEL)) {
629 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
630 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr
631 = INADDR_ANY;
632 ifp = viftable[vifi].v_ifp;
633 if_allmulti(ifp, 0);
634 }
635 }
636 bzero((caddr_t)tbftable, sizeof(tbftable));
637 bzero((caddr_t)viftable, sizeof(viftable));
638 numvifs = 0;
639 pim_assert = 0;
640
641 untimeout(expire_upcalls, (caddr_t)NULL);
642
643 /*
644 * Free all multicast forwarding cache entries.
645 */
646 for (i = 0; i < MFCTBLSIZ; i++) {
647 for (rt = mfctable[i]; rt != NULL; ) {
648 struct mfc *nr = rt->mfc_next;
649
650 for (rte = rt->mfc_stall; rte != NULL; ) {
651 struct rtdetq *n = rte->next;
652
653 m_freem(rte->m);
654 FREE(rte, M_MRTABLE);
655 rte = n;
656 }
657 FREE(rt, M_MRTABLE);
658 rt = nr;
659 }
660 }
661
662 bzero((caddr_t)mfctable, sizeof(mfctable));
663
664 /*
665 * Reset de-encapsulation cache
666 */
667 last_encap_src = 0;
668 last_encap_vif = NULL;
669 have_encap_tunnel = 0;
670
671 ip_mrouter = NULL;
672
673 splx(s);
674
675 if (mrtdebug)
676 log(LOG_DEBUG, "ip_mrouter_done\n");
677
678 return 0;
679 }
680
681 #if !defined(MROUTE_LKM) || !MROUTE_LKM
682 int (*ip_mrouter_done)(void) = X_ip_mrouter_done;
683 #endif
684
685 /*
686 * Set PIM assert processing global
687 */
688 static int
689 set_assert(i)
690 int i;
691 {
692 if ((i != 1) && (i != 0))
693 return EINVAL;
694
695 pim_assert = i;
696
697 return 0;
698 }
699
700 /*
701 * Add a vif to the vif table
702 */
703 static int
704 add_vif(vifcp)
705 register struct vifctl *vifcp;
706 {
707 register struct vif *vifp = viftable + vifcp->vifc_vifi;
708 static struct sockaddr_in sin = {sizeof sin, AF_INET};
709 struct ifaddr *ifa;
710 struct ifnet *ifp;
711 int error, s;
712 struct tbf *v_tbf = tbftable + vifcp->vifc_vifi;
713
714 if (vifcp->vifc_vifi >= MAXVIFS) return EINVAL;
715 if (vifp->v_lcl_addr.s_addr != 0) return EADDRINUSE;
716
717 /* Find the interface with an address in AF_INET family */
718 sin.sin_addr = vifcp->vifc_lcl_addr;
719 ifa = ifa_ifwithaddr((struct sockaddr *)&sin);
720 if (ifa == 0) return EADDRNOTAVAIL;
721 ifp = ifa->ifa_ifp;
722 ifafree(ifa);
723 ifa = NULL;
724
725 if (vifcp->vifc_flags & VIFF_TUNNEL) {
726 if ((vifcp->vifc_flags & VIFF_SRCRT) == 0) {
727 /*
728 * An encapsulating tunnel is wanted. Tell ipip_input() to
729 * start paying attention to encapsulated packets.
730 */
731 if (have_encap_tunnel == 0) {
732 have_encap_tunnel = 1;
733 for (s = 0; s < MAXVIFS; ++s) {
734 multicast_decap_if[s].if_name = "mdecap";
735 multicast_decap_if[s].if_unit = s;
736 multicast_decap_if[s].if_family = APPLE_IF_FAM_MDECAP;
737 }
738 }
739 /*
740 * Set interface to fake encapsulator interface
741 */
742 ifp = &multicast_decap_if[vifcp->vifc_vifi];
743 /*
744 * Prepare cached route entry
745 */
746 bzero(&vifp->v_route, sizeof(vifp->v_route));
747 } else {
748 log(LOG_ERR, "source routed tunnels not supported\n");
749 return EOPNOTSUPP;
750 }
751 } else {
752 /* Make sure the interface supports multicast */
753 if ((ifp->if_flags & IFF_MULTICAST) == 0)
754 return EOPNOTSUPP;
755
756 /* Enable promiscuous reception of all IP multicasts from the if */
757 s = splnet();
758 error = if_allmulti(ifp, 1);
759 splx(s);
760 if (error)
761 return error;
762 }
763
764 s = splnet();
765 /* define parameters for the tbf structure */
766 vifp->v_tbf = v_tbf;
767 GET_TIME(vifp->v_tbf->tbf_last_pkt_t);
768 vifp->v_tbf->tbf_n_tok = 0;
769 vifp->v_tbf->tbf_q_len = 0;
770 vifp->v_tbf->tbf_max_q_len = MAXQSIZE;
771 vifp->v_tbf->tbf_q = vifp->v_tbf->tbf_t = NULL;
772
773 vifp->v_flags = vifcp->vifc_flags;
774 vifp->v_threshold = vifcp->vifc_threshold;
775 vifp->v_lcl_addr = vifcp->vifc_lcl_addr;
776 vifp->v_rmt_addr = vifcp->vifc_rmt_addr;
777 vifp->v_ifp = ifp;
778 /* scaling up here allows division by 1024 in critical code */
779 vifp->v_rate_limit= vifcp->vifc_rate_limit * 1024 / 1000;
780 vifp->v_rsvp_on = 0;
781 vifp->v_rsvpd = NULL;
782 /* initialize per vif pkt counters */
783 vifp->v_pkt_in = 0;
784 vifp->v_pkt_out = 0;
785 vifp->v_bytes_in = 0;
786 vifp->v_bytes_out = 0;
787 splx(s);
788
789 /* Adjust numvifs up if the vifi is higher than numvifs */
790 if (numvifs <= vifcp->vifc_vifi) numvifs = vifcp->vifc_vifi + 1;
791
792 if (mrtdebug)
793 log(LOG_DEBUG, "add_vif #%d, lcladdr %lx, %s %lx, thresh %x, rate %d\n",
794 vifcp->vifc_vifi,
795 (u_long)ntohl(vifcp->vifc_lcl_addr.s_addr),
796 (vifcp->vifc_flags & VIFF_TUNNEL) ? "rmtaddr" : "mask",
797 (u_long)ntohl(vifcp->vifc_rmt_addr.s_addr),
798 vifcp->vifc_threshold,
799 vifcp->vifc_rate_limit);
800
801 return 0;
802 }
803
804 /*
805 * Delete a vif from the vif table
806 */
807 static int
808 del_vif(vifi)
809 vifi_t vifi;
810 {
811 register struct vif *vifp = &viftable[vifi];
812 register struct mbuf *m;
813 struct ifnet *ifp;
814 struct ifreq ifr;
815 int s;
816
817 if (vifi >= numvifs) return EINVAL;
818 if (vifp->v_lcl_addr.s_addr == 0) return EADDRNOTAVAIL;
819
820 s = splnet();
821
822 if (!(vifp->v_flags & VIFF_TUNNEL)) {
823 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_family = AF_INET;
824 ((struct sockaddr_in *)&(ifr.ifr_addr))->sin_addr.s_addr = INADDR_ANY;
825 ifp = vifp->v_ifp;
826 if_allmulti(ifp, 0);
827 }
828
829 if (vifp == last_encap_vif) {
830 last_encap_vif = 0;
831 last_encap_src = 0;
832 }
833
834 /*
835 * Free packets queued at the interface
836 */
837 while (vifp->v_tbf->tbf_q) {
838 m = vifp->v_tbf->tbf_q;
839 vifp->v_tbf->tbf_q = m->m_act;
840 m_freem(m);
841 }
842
843 bzero((caddr_t)vifp->v_tbf, sizeof(*(vifp->v_tbf)));
844 bzero((caddr_t)vifp, sizeof (*vifp));
845
846 if (mrtdebug)
847 log(LOG_DEBUG, "del_vif %d, numvifs %d\n", vifi, numvifs);
848
849 /* Adjust numvifs down */
850 for (vifi = numvifs; vifi > 0; vifi--)
851 if (viftable[vifi-1].v_lcl_addr.s_addr != 0) break;
852 numvifs = vifi;
853
854 splx(s);
855
856 return 0;
857 }
858
859 /*
860 * Add an mfc entry
861 */
862 static int
863 add_mfc(mfccp)
864 struct mfcctl *mfccp;
865 {
866 struct mfc *rt;
867 u_long hash;
868 struct rtdetq *rte;
869 register u_short nstl;
870 int s;
871 int i;
872
873 MFCFIND(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr, rt);
874
875 /* If an entry already exists, just update the fields */
876 if (rt) {
877 if (mrtdebug & DEBUG_MFC)
878 log(LOG_DEBUG,"add_mfc update o %lx g %lx p %x\n",
879 (u_long)ntohl(mfccp->mfcc_origin.s_addr),
880 (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),
881 mfccp->mfcc_parent);
882
883 s = splnet();
884 rt->mfc_parent = mfccp->mfcc_parent;
885 for (i = 0; i < numvifs; i++)
886 rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
887 splx(s);
888 return 0;
889 }
890
891 /*
892 * Find the entry for which the upcall was made and update
893 */
894 s = splnet();
895 hash = MFCHASH(mfccp->mfcc_origin.s_addr, mfccp->mfcc_mcastgrp.s_addr);
896 for (rt = mfctable[hash], nstl = 0; rt; rt = rt->mfc_next) {
897
898 if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) &&
899 (rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr) &&
900 (rt->mfc_stall != NULL)) {
901
902 if (nstl++)
903 log(LOG_ERR, "add_mfc %s o %lx g %lx p %x dbx %p\n",
904 "multiple kernel entries",
905 (u_long)ntohl(mfccp->mfcc_origin.s_addr),
906 (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),
907 mfccp->mfcc_parent, (void *)rt->mfc_stall);
908
909 if (mrtdebug & DEBUG_MFC)
910 log(LOG_DEBUG,"add_mfc o %lx g %lx p %x dbg %p\n",
911 (u_long)ntohl(mfccp->mfcc_origin.s_addr),
912 (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),
913 mfccp->mfcc_parent, (void *)rt->mfc_stall);
914
915 rt->mfc_origin = mfccp->mfcc_origin;
916 rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
917 rt->mfc_parent = mfccp->mfcc_parent;
918 for (i = 0; i < numvifs; i++)
919 rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
920 /* initialize pkt counters per src-grp */
921 rt->mfc_pkt_cnt = 0;
922 rt->mfc_byte_cnt = 0;
923 rt->mfc_wrong_if = 0;
924 rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
925
926 rt->mfc_expire = 0; /* Don't clean this guy up */
927 nexpire[hash]--;
928
929 /* free packets Qed at the end of this entry */
930 for (rte = rt->mfc_stall; rte != NULL; ) {
931 struct rtdetq *n = rte->next;
932
933 ip_mdq(rte->m, rte->ifp, rt, -1);
934 m_freem(rte->m);
935 #if UPCALL_TIMING
936 collate(&(rte->t));
937 #endif /* UPCALL_TIMING */
938 FREE(rte, M_MRTABLE);
939 rte = n;
940 }
941 rt->mfc_stall = NULL;
942 }
943 }
944
945 /*
946 * It is possible that an entry is being inserted without an upcall
947 */
948 if (nstl == 0) {
949 if (mrtdebug & DEBUG_MFC)
950 log(LOG_DEBUG,"add_mfc no upcall h %lu o %lx g %lx p %x\n",
951 hash, (u_long)ntohl(mfccp->mfcc_origin.s_addr),
952 (u_long)ntohl(mfccp->mfcc_mcastgrp.s_addr),
953 mfccp->mfcc_parent);
954
955 for (rt = mfctable[hash]; rt != NULL; rt = rt->mfc_next) {
956
957 if ((rt->mfc_origin.s_addr == mfccp->mfcc_origin.s_addr) &&
958 (rt->mfc_mcastgrp.s_addr == mfccp->mfcc_mcastgrp.s_addr)) {
959
960 rt->mfc_origin = mfccp->mfcc_origin;
961 rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
962 rt->mfc_parent = mfccp->mfcc_parent;
963 for (i = 0; i < numvifs; i++)
964 rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
965 /* initialize pkt counters per src-grp */
966 rt->mfc_pkt_cnt = 0;
967 rt->mfc_byte_cnt = 0;
968 rt->mfc_wrong_if = 0;
969 rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
970 if (rt->mfc_expire)
971 nexpire[hash]--;
972 rt->mfc_expire = 0;
973 }
974 }
975 if (rt == NULL) {
976 /* no upcall, so make a new entry */
977 rt = (struct mfc *) _MALLOC(sizeof(*rt), M_MRTABLE, M_NOWAIT);
978 if (rt == NULL) {
979 splx(s);
980 return ENOBUFS;
981 }
982
983 /* insert new entry at head of hash chain */
984 rt->mfc_origin = mfccp->mfcc_origin;
985 rt->mfc_mcastgrp = mfccp->mfcc_mcastgrp;
986 rt->mfc_parent = mfccp->mfcc_parent;
987 for (i = 0; i < numvifs; i++)
988 rt->mfc_ttls[i] = mfccp->mfcc_ttls[i];
989 /* initialize pkt counters per src-grp */
990 rt->mfc_pkt_cnt = 0;
991 rt->mfc_byte_cnt = 0;
992 rt->mfc_wrong_if = 0;
993 rt->mfc_last_assert.tv_sec = rt->mfc_last_assert.tv_usec = 0;
994 rt->mfc_expire = 0;
995 rt->mfc_stall = NULL;
996
997 /* link into table */
998 rt->mfc_next = mfctable[hash];
999 mfctable[hash] = rt;
1000 }
1001 }
1002 splx(s);
1003 return 0;
1004 }
1005
1006 #if UPCALL_TIMING
1007 /*
1008 * collect delay statistics on the upcalls
1009 */
1010 static void collate(t)
1011 register struct timeval *t;
1012 {
1013 register u_long d;
1014 register struct timeval tp;
1015 register u_long delta;
1016
1017 GET_TIME(tp);
1018
1019 if (TV_LT(*t, tp))
1020 {
1021 TV_DELTA(tp, *t, delta);
1022
1023 d = delta >> 10;
1024 if (d > 50)
1025 d = 50;
1026
1027 ++upcall_data[d];
1028 }
1029 }
1030 #endif /* UPCALL_TIMING */
1031
1032 /*
1033 * Delete an mfc entry
1034 */
1035 static int
1036 del_mfc(mfccp)
1037 struct mfcctl *mfccp;
1038 {
1039 struct in_addr origin;
1040 struct in_addr mcastgrp;
1041 struct mfc *rt;
1042 struct mfc **nptr;
1043 u_long hash;
1044 int s;
1045
1046 origin = mfccp->mfcc_origin;
1047 mcastgrp = mfccp->mfcc_mcastgrp;
1048 hash = MFCHASH(origin.s_addr, mcastgrp.s_addr);
1049
1050 if (mrtdebug & DEBUG_MFC)
1051 log(LOG_DEBUG,"del_mfc orig %lx mcastgrp %lx\n",
1052 (u_long)ntohl(origin.s_addr), (u_long)ntohl(mcastgrp.s_addr));
1053
1054 s = splnet();
1055
1056 nptr = &mfctable[hash];
1057 while ((rt = *nptr) != NULL) {
1058 if (origin.s_addr == rt->mfc_origin.s_addr &&
1059 mcastgrp.s_addr == rt->mfc_mcastgrp.s_addr &&
1060 rt->mfc_stall == NULL)
1061 break;
1062
1063 nptr = &rt->mfc_next;
1064 }
1065 if (rt == NULL) {
1066 splx(s);
1067 return EADDRNOTAVAIL;
1068 }
1069
1070 *nptr = rt->mfc_next;
1071 FREE(rt, M_MRTABLE);
1072
1073 splx(s);
1074
1075 return 0;
1076 }
1077
1078 /*
1079 * Send a message to mrouted on the multicast routing socket
1080 */
1081 static int
1082 socket_send(s, mm, src)
1083 struct socket *s;
1084 struct mbuf *mm;
1085 struct sockaddr_in *src;
1086 {
1087 socket_lock(s, 1);
1088 if (s) {
1089 if (sbappendaddr(&s->so_rcv,
1090 (struct sockaddr *)src,
1091 mm, (struct mbuf *)0, NULL) != 0) {
1092 sorwakeup(s);
1093 socket_unlock(s, 1);
1094 return 0;
1095 }
1096 }
1097 socket_unlock(s, 1);
1098 m_freem(mm);
1099 return -1;
1100 }
1101
1102 /*
1103 * IP multicast forwarding function. This function assumes that the packet
1104 * pointed to by "ip" has arrived on (or is about to be sent to) the interface
1105 * pointed to by "ifp", and the packet is to be relayed to other networks
1106 * that have members of the packet's destination IP multicast group.
1107 *
1108 * The packet is returned unscathed to the caller, unless it is
1109 * erroneous, in which case a non-zero return value tells the caller to
1110 * discard it.
1111 */
1112
1113 #define IP_HDR_LEN 20 /* # bytes of fixed IP header (excluding options) */
1114 #define TUNNEL_LEN 12 /* # bytes of IP option for tunnel encapsulation */
1115
1116 static int
1117 X_ip_mforward(ip, ifp, m, imo)
1118 register struct ip *ip;
1119 struct ifnet *ifp;
1120 struct mbuf *m;
1121 struct ip_moptions *imo;
1122 {
1123 register struct mfc *rt;
1124 register u_char *ipoptions;
1125 static struct sockaddr_in k_igmpsrc = { sizeof k_igmpsrc, AF_INET };
1126 static int srctun = 0;
1127 register struct mbuf *mm;
1128 int s;
1129 vifi_t vifi;
1130 struct vif *vifp;
1131
1132 if (mrtdebug & DEBUG_FORWARD)
1133 log(LOG_DEBUG, "ip_mforward: src %lx, dst %lx, ifp %p\n",
1134 (u_long)ntohl(ip->ip_src.s_addr), (u_long)ntohl(ip->ip_dst.s_addr),
1135 (void *)ifp);
1136
1137 if (ip->ip_hl < (IP_HDR_LEN + TUNNEL_LEN) >> 2 ||
1138 (ipoptions = (u_char *)(ip + 1))[1] != IPOPT_LSRR ) {
1139 /*
1140 * Packet arrived via a physical interface or
1141 * an encapsulated tunnel.
1142 */
1143 } else {
1144 /*
1145 * Packet arrived through a source-route tunnel.
1146 * Source-route tunnels are no longer supported.
1147 */
1148 if ((srctun++ % 1000) == 0)
1149 log(LOG_ERR,
1150 "ip_mforward: received source-routed packet from %lx\n",
1151 (u_long)ntohl(ip->ip_src.s_addr));
1152
1153 return 1;
1154 }
1155
1156 if ((imo) && ((vifi = imo->imo_multicast_vif) < numvifs)) {
1157 if (ip->ip_ttl < 255)
1158 ip->ip_ttl++; /* compensate for -1 in *_send routines */
1159 if (rsvpdebug && ip->ip_p == IPPROTO_RSVP) {
1160 vifp = viftable + vifi;
1161 printf("Sending IPPROTO_RSVP from %lx to %lx on vif %d (%s%s%d)\n",
1162 ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr), vifi,
1163 (vifp->v_flags & VIFF_TUNNEL) ? "tunnel on " : "",
1164 vifp->v_ifp->if_name, vifp->v_ifp->if_unit);
1165 }
1166 return (ip_mdq(m, ifp, NULL, vifi));
1167 }
1168 if (rsvpdebug && ip->ip_p == IPPROTO_RSVP) {
1169 printf("Warning: IPPROTO_RSVP from %lx to %lx without vif option\n",
1170 ntohl(ip->ip_src.s_addr), ntohl(ip->ip_dst.s_addr));
1171 if(!imo)
1172 printf("In fact, no options were specified at all\n");
1173 }
1174
1175 /*
1176 * Don't forward a packet with time-to-live of zero or one,
1177 * or a packet destined to a local-only group.
1178 */
1179 if (ip->ip_ttl <= 1 ||
1180 ntohl(ip->ip_dst.s_addr) <= INADDR_MAX_LOCAL_GROUP)
1181 return 0;
1182
1183 /*
1184 * Determine forwarding vifs from the forwarding cache table
1185 */
1186 s = splnet();
1187 MFCFIND(ip->ip_src.s_addr, ip->ip_dst.s_addr, rt);
1188
1189 /* Entry exists, so forward if necessary */
1190 if (rt != NULL) {
1191 splx(s);
1192 return (ip_mdq(m, ifp, rt, -1));
1193 } else {
1194 /*
1195 * If we don't have a route for packet's origin,
1196 * Make a copy of the packet &
1197 * send message to routing daemon
1198 */
1199
1200 register struct mbuf *mb0;
1201 register struct rtdetq *rte;
1202 register u_long hash;
1203 int hlen = ip->ip_hl << 2;
1204 #if UPCALL_TIMING
1205 struct timeval tp;
1206
1207 GET_TIME(tp);
1208 #endif
1209
1210 mrtstat.mrts_no_route++;
1211 if (mrtdebug & (DEBUG_FORWARD | DEBUG_MFC))
1212 log(LOG_DEBUG, "ip_mforward: no rte s %lx g %lx\n",
1213 (u_long)ntohl(ip->ip_src.s_addr),
1214 (u_long)ntohl(ip->ip_dst.s_addr));
1215
1216 /*
1217 * Allocate mbufs early so that we don't do extra work if we are
1218 * just going to fail anyway. Make sure to pullup the header so
1219 * that other people can't step on it.
1220 */
1221 rte = (struct rtdetq *) _MALLOC((sizeof *rte), M_MRTABLE, M_NOWAIT);
1222 if (rte == NULL) {
1223 splx(s);
1224 return ENOBUFS;
1225 }
1226 mb0 = m_copy(m, 0, M_COPYALL);
1227 if (mb0 && (M_HASCL(mb0) || mb0->m_len < hlen))
1228 mb0 = m_pullup(mb0, hlen);
1229 if (mb0 == NULL) {
1230 FREE(rte, M_MRTABLE);
1231 splx(s);
1232 return ENOBUFS;
1233 }
1234
1235 /* is there an upcall waiting for this packet? */
1236 hash = MFCHASH(ip->ip_src.s_addr, ip->ip_dst.s_addr);
1237 for (rt = mfctable[hash]; rt; rt = rt->mfc_next) {
1238 if ((ip->ip_src.s_addr == rt->mfc_origin.s_addr) &&
1239 (ip->ip_dst.s_addr == rt->mfc_mcastgrp.s_addr) &&
1240 (rt->mfc_stall != NULL))
1241 break;
1242 }
1243
1244 if (rt == NULL) {
1245 int i;
1246 struct igmpmsg *im;
1247
1248 /* no upcall, so make a new entry */
1249 rt = (struct mfc *) _MALLOC(sizeof(*rt), M_MRTABLE, M_NOWAIT);
1250 if (rt == NULL) {
1251 FREE(rte, M_MRTABLE);
1252 m_freem(mb0);
1253 splx(s);
1254 return ENOBUFS;
1255 }
1256 /* Make a copy of the header to send to the user level process */
1257 mm = m_copy(mb0, 0, hlen);
1258 if (mm == NULL) {
1259 FREE(rte, M_MRTABLE);
1260 m_freem(mb0);
1261 FREE(rt, M_MRTABLE);
1262 splx(s);
1263 return ENOBUFS;
1264 }
1265
1266 /*
1267 * Send message to routing daemon to install
1268 * a route into the kernel table
1269 */
1270 k_igmpsrc.sin_addr = ip->ip_src;
1271
1272 im = mtod(mm, struct igmpmsg *);
1273 im->im_msgtype = IGMPMSG_NOCACHE;
1274 im->im_mbz = 0;
1275
1276 mrtstat.mrts_upcalls++;
1277
1278 if (socket_send(ip_mrouter, mm, &k_igmpsrc) < 0) {
1279 log(LOG_WARNING, "ip_mforward: ip_mrouter socket queue full\n");
1280 ++mrtstat.mrts_upq_sockfull;
1281 FREE(rte, M_MRTABLE);
1282 m_freem(mb0);
1283 FREE(rt, M_MRTABLE);
1284 splx(s);
1285 return ENOBUFS;
1286 }
1287
1288 /* insert new entry at head of hash chain */
1289 rt->mfc_origin.s_addr = ip->ip_src.s_addr;
1290 rt->mfc_mcastgrp.s_addr = ip->ip_dst.s_addr;
1291 rt->mfc_expire = UPCALL_EXPIRE;
1292 nexpire[hash]++;
1293 for (i = 0; i < numvifs; i++)
1294 rt->mfc_ttls[i] = 0;
1295 rt->mfc_parent = -1;
1296
1297 /* link into table */
1298 rt->mfc_next = mfctable[hash];
1299 mfctable[hash] = rt;
1300 rt->mfc_stall = rte;
1301
1302 } else {
1303 /* determine if q has overflowed */
1304 int npkts = 0;
1305 struct rtdetq **p;
1306
1307 for (p = &rt->mfc_stall; *p != NULL; p = &(*p)->next)
1308 npkts++;
1309
1310 if (npkts > MAX_UPQ) {
1311 mrtstat.mrts_upq_ovflw++;
1312 FREE(rte, M_MRTABLE);
1313 m_freem(mb0);
1314 splx(s);
1315 return 0;
1316 }
1317
1318 /* Add this entry to the end of the queue */
1319 *p = rte;
1320 }
1321
1322 rte->m = mb0;
1323 rte->ifp = ifp;
1324 #if UPCALL_TIMING
1325 rte->t = tp;
1326 #endif
1327 rte->next = NULL;
1328
1329 splx(s);
1330
1331 return 0;
1332 }
1333 }
1334
1335 #if !defined(MROUTE_LKM) || !MROUTE_LKM
1336 int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
1337 struct ip_moptions *) = X_ip_mforward;
1338 #endif
1339
1340 /*
1341 * Clean up the cache entry if upcall is not serviced
1342 */
1343 static void
1344 expire_upcalls(void *unused)
1345 {
1346 struct rtdetq *rte;
1347 struct mfc *mfc, **nptr;
1348 int i;
1349 int s;
1350
1351
1352 s = splnet();
1353 for (i = 0; i < MFCTBLSIZ; i++) {
1354 if (nexpire[i] == 0)
1355 continue;
1356 nptr = &mfctable[i];
1357 for (mfc = *nptr; mfc != NULL; mfc = *nptr) {
1358 /*
1359 * Skip real cache entries
1360 * Make sure it wasn't marked to not expire (shouldn't happen)
1361 * If it expires now
1362 */
1363 if (mfc->mfc_stall != NULL &&
1364 mfc->mfc_expire != 0 &&
1365 --mfc->mfc_expire == 0) {
1366 if (mrtdebug & DEBUG_EXPIRE)
1367 log(LOG_DEBUG, "expire_upcalls: expiring (%lx %lx)\n",
1368 (u_long)ntohl(mfc->mfc_origin.s_addr),
1369 (u_long)ntohl(mfc->mfc_mcastgrp.s_addr));
1370 /*
1371 * drop all the packets
1372 * free the mbuf with the pkt, if, timing info
1373 */
1374 for (rte = mfc->mfc_stall; rte; ) {
1375 struct rtdetq *n = rte->next;
1376
1377 m_freem(rte->m);
1378 FREE(rte, M_MRTABLE);
1379 rte = n;
1380 }
1381 ++mrtstat.mrts_cache_cleanups;
1382 nexpire[i]--;
1383
1384 *nptr = mfc->mfc_next;
1385 FREE(mfc, M_MRTABLE);
1386 } else {
1387 nptr = &mfc->mfc_next;
1388 }
1389 }
1390 }
1391 splx(s);
1392 timeout(expire_upcalls, (caddr_t)NULL, EXPIRE_TIMEOUT);
1393 }
1394
1395 /*
1396 * Packet forwarding routine once entry in the cache is made
1397 */
1398 static int
1399 ip_mdq(m, ifp, rt, xmt_vif)
1400 register struct mbuf *m;
1401 register struct ifnet *ifp;
1402 register struct mfc *rt;
1403 register vifi_t xmt_vif;
1404 {
1405 register struct ip *ip = mtod(m, struct ip *);
1406 register vifi_t vifi;
1407 register struct vif *vifp;
1408 register int plen = ip->ip_len;
1409
1410 /*
1411 * Macro to send packet on vif. Since RSVP packets don't get counted on
1412 * input, they shouldn't get counted on output, so statistics keeping is
1413 * seperate.
1414 */
1415 #define MC_SEND(ip,vifp,m) { \
1416 if ((vifp)->v_flags & VIFF_TUNNEL) \
1417 encap_send((ip), (vifp), (m)); \
1418 else \
1419 phyint_send((ip), (vifp), (m)); \
1420 }
1421
1422 /*
1423 * If xmt_vif is not -1, send on only the requested vif.
1424 *
1425 * (since vifi_t is u_short, -1 becomes MAXUSHORT, which > numvifs.)
1426 */
1427 if (xmt_vif < numvifs) {
1428 MC_SEND(ip, viftable + xmt_vif, m);
1429 return 1;
1430 }
1431
1432 /*
1433 * Don't forward if it didn't arrive from the parent vif for its origin.
1434 */
1435 vifi = rt->mfc_parent;
1436 if ((vifi >= numvifs) || (viftable[vifi].v_ifp != ifp)) {
1437 /* came in the wrong interface */
1438 if (mrtdebug & DEBUG_FORWARD)
1439 log(LOG_DEBUG, "wrong if: ifp %p vifi %d vififp %p\n",
1440 (void *)ifp, vifi, (void *)viftable[vifi].v_ifp);
1441 ++mrtstat.mrts_wrong_if;
1442 ++rt->mfc_wrong_if;
1443 /*
1444 * If we are doing PIM assert processing, and we are forwarding
1445 * packets on this interface, and it is a broadcast medium
1446 * interface (and not a tunnel), send a message to the routing daemon.
1447 */
1448 if (pim_assert && rt->mfc_ttls[vifi] &&
1449 (ifp->if_flags & IFF_BROADCAST) &&
1450 !(viftable[vifi].v_flags & VIFF_TUNNEL)) {
1451 struct sockaddr_in k_igmpsrc;
1452 struct mbuf *mm;
1453 struct igmpmsg *im;
1454 int hlen = ip->ip_hl << 2;
1455 struct timeval now;
1456 register u_long delta;
1457
1458 GET_TIME(now);
1459
1460 TV_DELTA(rt->mfc_last_assert, now, delta);
1461
1462 if (delta > ASSERT_MSG_TIME) {
1463 mm = m_copy(m, 0, hlen);
1464 if (mm && (M_HASCL(mm) || mm->m_len < hlen))
1465 mm = m_pullup(mm, hlen);
1466 if (mm == NULL) {
1467 return ENOBUFS;
1468 }
1469
1470 rt->mfc_last_assert = now;
1471
1472 im = mtod(mm, struct igmpmsg *);
1473 im->im_msgtype = IGMPMSG_WRONGVIF;
1474 im->im_mbz = 0;
1475 im->im_vif = vifi;
1476
1477 k_igmpsrc.sin_addr = im->im_src;
1478
1479 socket_send(ip_mrouter, mm, &k_igmpsrc);
1480 }
1481 }
1482 return 0;
1483 }
1484
1485 /* If I sourced this packet, it counts as output, else it was input. */
1486 if (ip->ip_src.s_addr == viftable[vifi].v_lcl_addr.s_addr) {
1487 viftable[vifi].v_pkt_out++;
1488 viftable[vifi].v_bytes_out += plen;
1489 } else {
1490 viftable[vifi].v_pkt_in++;
1491 viftable[vifi].v_bytes_in += plen;
1492 }
1493 rt->mfc_pkt_cnt++;
1494 rt->mfc_byte_cnt += plen;
1495
1496 /*
1497 * For each vif, decide if a copy of the packet should be forwarded.
1498 * Forward if:
1499 * - the ttl exceeds the vif's threshold
1500 * - there are group members downstream on interface
1501 */
1502 for (vifp = viftable, vifi = 0; vifi < numvifs; vifp++, vifi++)
1503 if ((rt->mfc_ttls[vifi] > 0) &&
1504 (ip->ip_ttl > rt->mfc_ttls[vifi])) {
1505 vifp->v_pkt_out++;
1506 vifp->v_bytes_out += plen;
1507 MC_SEND(ip, vifp, m);
1508 }
1509
1510 return 0;
1511 }
1512
1513 /*
1514 * check if a vif number is legal/ok. This is used by ip_output, to export
1515 * numvifs there,
1516 */
1517 static int
1518 X_legal_vif_num(vif)
1519 int vif;
1520 {
1521 if (vif >= 0 && vif < numvifs)
1522 return(1);
1523 else
1524 return(0);
1525 }
1526
1527 #if !defined(MROUTE_LKM) || !MROUTE_LKM
1528 int (*legal_vif_num)(int) = X_legal_vif_num;
1529 #endif
1530
1531 /*
1532 * Return the local address used by this vif
1533 */
1534 static u_long
1535 X_ip_mcast_src(vifi)
1536 int vifi;
1537 {
1538 if (vifi >= 0 && vifi < numvifs)
1539 return viftable[vifi].v_lcl_addr.s_addr;
1540 else
1541 return INADDR_ANY;
1542 }
1543
1544 #if !defined(MROUTE_LKM) || !MROUTE_LKM
1545 u_long (*ip_mcast_src)(int) = X_ip_mcast_src;
1546 #endif
1547
1548 static void
1549 phyint_send(ip, vifp, m)
1550 struct ip *ip;
1551 struct vif *vifp;
1552 struct mbuf *m;
1553 {
1554 register struct mbuf *mb_copy;
1555 register int hlen = ip->ip_hl << 2;
1556
1557 /*
1558 * Make a new reference to the packet; make sure that
1559 * the IP header is actually copied, not just referenced,
1560 * so that ip_output() only scribbles on the copy.
1561 */
1562 mb_copy = m_copy(m, 0, M_COPYALL);
1563 if (mb_copy && (M_HASCL(mb_copy) || mb_copy->m_len < hlen))
1564 mb_copy = m_pullup(mb_copy, hlen);
1565 if (mb_copy == NULL)
1566 return;
1567
1568 if (vifp->v_rate_limit == 0)
1569 tbf_send_packet(vifp, mb_copy);
1570 else
1571 tbf_control(vifp, mb_copy, mtod(mb_copy, struct ip *), ip->ip_len);
1572 }
1573
1574 static void
1575 encap_send(ip, vifp, m)
1576 register struct ip *ip;
1577 register struct vif *vifp;
1578 register struct mbuf *m;
1579 {
1580 register struct mbuf *mb_copy;
1581 register struct ip *ip_copy;
1582 register int i, len = ip->ip_len;
1583
1584 /*
1585 * copy the old packet & pullup its IP header into the
1586 * new mbuf so we can modify it. Try to fill the new
1587 * mbuf since if we don't the ethernet driver will.
1588 */
1589 MGETHDR(mb_copy, M_DONTWAIT, MT_HEADER);
1590 if (mb_copy == NULL)
1591 return;
1592 mb_copy->m_data += max_linkhdr;
1593 mb_copy->m_len = sizeof(multicast_encap_iphdr);
1594
1595 if ((mb_copy->m_next = m_copy(m, 0, M_COPYALL)) == NULL) {
1596 m_freem(mb_copy);
1597 return;
1598 }
1599 i = MHLEN - M_LEADINGSPACE(mb_copy);
1600 if (i > len)
1601 i = len;
1602 mb_copy = m_pullup(mb_copy, i);
1603 if (mb_copy == NULL)
1604 return;
1605 mb_copy->m_pkthdr.len = len + sizeof(multicast_encap_iphdr);
1606
1607 /*
1608 * fill in the encapsulating IP header.
1609 */
1610 ip_copy = mtod(mb_copy, struct ip *);
1611 *ip_copy = multicast_encap_iphdr;
1612 #if RANDOM_IP_ID
1613 ip_copy->ip_id = ip_randomid();
1614 #else
1615 ip_copy->ip_id = htons(ip_id++);
1616 #endif
1617 ip_copy->ip_len += len;
1618 ip_copy->ip_src = vifp->v_lcl_addr;
1619 ip_copy->ip_dst = vifp->v_rmt_addr;
1620
1621 /*
1622 * turn the encapsulated IP header back into a valid one.
1623 */
1624 ip = (struct ip *)((caddr_t)ip_copy + sizeof(multicast_encap_iphdr));
1625 --ip->ip_ttl;
1626 HTONS(ip->ip_len);
1627 HTONS(ip->ip_off);
1628 ip->ip_sum = 0;
1629 mb_copy->m_data += sizeof(multicast_encap_iphdr);
1630 ip->ip_sum = in_cksum(mb_copy, ip->ip_hl << 2);
1631 mb_copy->m_data -= sizeof(multicast_encap_iphdr);
1632
1633 if (vifp->v_rate_limit == 0)
1634 tbf_send_packet(vifp, mb_copy);
1635 else
1636 tbf_control(vifp, mb_copy, ip, ip_copy->ip_len);
1637 }
1638
1639 /*
1640 * De-encapsulate a packet and feed it back through ip input (this
1641 * routine is called whenever IP gets a packet with proto type
1642 * ENCAP_PROTO and a local destination address).
1643 */
1644 void
1645 #if MROUTE_LKM
1646 X_ipip_input(m, iphlen)
1647 #else
1648 ipip_input(m, iphlen)
1649 #endif
1650 register struct mbuf *m;
1651 int iphlen;
1652 {
1653 struct ifnet *ifp = m->m_pkthdr.rcvif;
1654 register struct ip *ip = mtod(m, struct ip *);
1655 register int hlen = ip->ip_hl << 2;
1656 register struct vif *vifp;
1657
1658 if (!have_encap_tunnel) {
1659 rip_input(m, iphlen);
1660 return;
1661 }
1662 /*
1663 * dump the packet if it's not to a multicast destination or if
1664 * we don't have an encapsulating tunnel with the source.
1665 * Note: This code assumes that the remote site IP address
1666 * uniquely identifies the tunnel (i.e., that this site has
1667 * at most one tunnel with the remote site).
1668 */
1669 if (! IN_MULTICAST(ntohl(((struct ip *)((char *)ip + hlen))->ip_dst.s_addr))) {
1670 ++mrtstat.mrts_bad_tunnel;
1671 m_freem(m);
1672 return;
1673 }
1674 if (ip->ip_src.s_addr != last_encap_src) {
1675 register struct vif *vife;
1676
1677 vifp = viftable;
1678 vife = vifp + numvifs;
1679 last_encap_src = ip->ip_src.s_addr;
1680 last_encap_vif = 0;
1681 for ( ; vifp < vife; ++vifp)
1682 if (vifp->v_rmt_addr.s_addr == ip->ip_src.s_addr) {
1683 if ((vifp->v_flags & (VIFF_TUNNEL|VIFF_SRCRT))
1684 == VIFF_TUNNEL)
1685 last_encap_vif = vifp;
1686 break;
1687 }
1688 }
1689 if ((vifp = last_encap_vif) == 0) {
1690 last_encap_src = 0;
1691 mrtstat.mrts_cant_tunnel++; /*XXX*/
1692 m_freem(m);
1693 if (mrtdebug)
1694 log(LOG_DEBUG, "ip_mforward: no tunnel with %lx\n",
1695 (u_long)ntohl(ip->ip_src.s_addr));
1696 return;
1697 }
1698 ifp = vifp->v_ifp;
1699
1700 if (hlen > IP_HDR_LEN)
1701 ip_stripoptions(m, (struct mbuf *) 0);
1702 m->m_data += IP_HDR_LEN;
1703 m->m_len -= IP_HDR_LEN;
1704 m->m_pkthdr.len -= IP_HDR_LEN;
1705 m->m_pkthdr.rcvif = ifp;
1706
1707 proto_inject(PF_INET, m);
1708 }
1709
1710 /*
1711 * Token bucket filter module
1712 */
1713
1714 static void
1715 tbf_control(vifp, m, ip, p_len)
1716 register struct vif *vifp;
1717 register struct mbuf *m;
1718 register struct ip *ip;
1719 register u_long p_len;
1720 {
1721 register struct tbf *t = vifp->v_tbf;
1722
1723 if (p_len > MAX_BKT_SIZE) {
1724 /* drop if packet is too large */
1725 mrtstat.mrts_pkt2large++;
1726 m_freem(m);
1727 return;
1728 }
1729
1730 tbf_update_tokens(vifp);
1731
1732 /* if there are enough tokens,
1733 * and the queue is empty,
1734 * send this packet out
1735 */
1736
1737 if (t->tbf_q_len == 0) {
1738 /* queue empty, send packet if enough tokens */
1739 if (p_len <= t->tbf_n_tok) {
1740 t->tbf_n_tok -= p_len;
1741 tbf_send_packet(vifp, m);
1742 } else {
1743 /* queue packet and timeout till later */
1744 tbf_queue(vifp, m);
1745 timeout(tbf_reprocess_q, (caddr_t)vifp, TBF_REPROCESS);
1746 }
1747 } else if (t->tbf_q_len < t->tbf_max_q_len) {
1748 /* finite queue length, so queue pkts and process queue */
1749 tbf_queue(vifp, m);
1750 tbf_process_q(vifp);
1751 } else {
1752 /* queue length too much, try to dq and queue and process */
1753 if (!tbf_dq_sel(vifp, ip)) {
1754 mrtstat.mrts_q_overflow++;
1755 m_freem(m);
1756 return;
1757 } else {
1758 tbf_queue(vifp, m);
1759 tbf_process_q(vifp);
1760 }
1761 }
1762 return;
1763 }
1764
1765 /*
1766 * adds a packet to the queue at the interface
1767 */
1768 static void
1769 tbf_queue(vifp, m)
1770 register struct vif *vifp;
1771 register struct mbuf *m;
1772 {
1773 register int s = splnet();
1774 register struct tbf *t = vifp->v_tbf;
1775
1776 if (t->tbf_t == NULL) {
1777 /* Queue was empty */
1778 t->tbf_q = m;
1779 } else {
1780 /* Insert at tail */
1781 t->tbf_t->m_act = m;
1782 }
1783
1784 /* Set new tail pointer */
1785 t->tbf_t = m;
1786
1787 #if DIAGNOSTIC
1788 /* Make sure we didn't get fed a bogus mbuf */
1789 if (m->m_act)
1790 panic("tbf_queue: m_act");
1791 #endif
1792 m->m_act = NULL;
1793
1794 t->tbf_q_len++;
1795
1796 splx(s);
1797 }
1798
1799
1800 /*
1801 * processes the queue at the interface
1802 */
1803 static void
1804 tbf_process_q(vifp)
1805 register struct vif *vifp;
1806 {
1807 register struct mbuf *m;
1808 register int len;
1809 register int s = splnet();
1810 register struct tbf *t = vifp->v_tbf;
1811
1812 /* loop through the queue at the interface and send as many packets
1813 * as possible
1814 */
1815 while (t->tbf_q_len > 0) {
1816 m = t->tbf_q;
1817
1818 len = mtod(m, struct ip *)->ip_len;
1819
1820 /* determine if the packet can be sent */
1821 if (len <= t->tbf_n_tok) {
1822 /* if so,
1823 * reduce no of tokens, dequeue the packet,
1824 * send the packet.
1825 */
1826 t->tbf_n_tok -= len;
1827
1828 t->tbf_q = m->m_act;
1829 if (--t->tbf_q_len == 0)
1830 t->tbf_t = NULL;
1831
1832 m->m_act = NULL;
1833 tbf_send_packet(vifp, m);
1834
1835 } else break;
1836 }
1837 splx(s);
1838 }
1839
1840 static void
1841 tbf_reprocess_q(xvifp)
1842 void *xvifp;
1843 {
1844 register struct vif *vifp = xvifp;
1845
1846 if (ip_mrouter == NULL) {
1847 return;
1848 }
1849
1850 tbf_update_tokens(vifp);
1851
1852 tbf_process_q(vifp);
1853
1854 if (vifp->v_tbf->tbf_q_len)
1855 timeout(tbf_reprocess_q, (caddr_t)vifp, TBF_REPROCESS);
1856 }
1857
1858 /* function that will selectively discard a member of the queue
1859 * based on the precedence value and the priority
1860 */
1861 static int
1862 tbf_dq_sel(vifp, ip)
1863 register struct vif *vifp;
1864 register struct ip *ip;
1865 {
1866 register int s = splnet();
1867 register u_int p;
1868 register struct mbuf *m, *last;
1869 register struct mbuf **np;
1870 register struct tbf *t = vifp->v_tbf;
1871
1872 p = priority(vifp, ip);
1873
1874 np = &t->tbf_q;
1875 last = NULL;
1876 while ((m = *np) != NULL) {
1877 if (p > priority(vifp, mtod(m, struct ip *))) {
1878 *np = m->m_act;
1879 /* If we're removing the last packet, fix the tail pointer */
1880 if (m == t->tbf_t)
1881 t->tbf_t = last;
1882 m_freem(m);
1883 /* it's impossible for the queue to be empty, but
1884 * we check anyway. */
1885 if (--t->tbf_q_len == 0)
1886 t->tbf_t = NULL;
1887 splx(s);
1888 mrtstat.mrts_drop_sel++;
1889 return(1);
1890 }
1891 np = &m->m_act;
1892 last = m;
1893 }
1894 splx(s);
1895 return(0);
1896 }
1897
1898 static void
1899 tbf_send_packet(vifp, m)
1900 register struct vif *vifp;
1901 register struct mbuf *m;
1902 {
1903 struct ip_moptions imo;
1904 int error;
1905 static struct route ro;
1906 int s = splnet();
1907
1908 if (vifp->v_flags & VIFF_TUNNEL) {
1909 /* If tunnel options */
1910 ip_output(m, (struct mbuf *)0, &vifp->v_route,
1911 IP_FORWARDING, (struct ip_moptions *)0);
1912 } else {
1913 imo.imo_multicast_ifp = vifp->v_ifp;
1914 imo.imo_multicast_ttl = mtod(m, struct ip *)->ip_ttl - 1;
1915 imo.imo_multicast_loop = 1;
1916 imo.imo_multicast_vif = -1;
1917
1918 /*
1919 * Re-entrancy should not be a problem here, because
1920 * the packets that we send out and are looped back at us
1921 * should get rejected because they appear to come from
1922 * the loopback interface, thus preventing looping.
1923 */
1924 error = ip_output(m, (struct mbuf *)0, &ro,
1925 IP_FORWARDING, &imo);
1926
1927 if (mrtdebug & DEBUG_XMIT)
1928 log(LOG_DEBUG, "phyint_send on vif %d err %d\n",
1929 vifp - viftable, error);
1930 }
1931 splx(s);
1932 }
1933
1934 /* determine the current time and then
1935 * the elapsed time (between the last time and time now)
1936 * in milliseconds & update the no. of tokens in the bucket
1937 */
1938 static void
1939 tbf_update_tokens(vifp)
1940 register struct vif *vifp;
1941 {
1942 struct timeval tp;
1943 register u_long tm;
1944 register int s = splnet();
1945 register struct tbf *t = vifp->v_tbf;
1946
1947 GET_TIME(tp);
1948
1949 TV_DELTA(tp, t->tbf_last_pkt_t, tm);
1950
1951 /*
1952 * This formula is actually
1953 * "time in seconds" * "bytes/second".
1954 *
1955 * (tm / 1000000) * (v_rate_limit * 1000 * (1000/1024) / 8)
1956 *
1957 * The (1000/1024) was introduced in add_vif to optimize
1958 * this divide into a shift.
1959 */
1960 t->tbf_n_tok += tm * vifp->v_rate_limit / 1024 / 8;
1961 t->tbf_last_pkt_t = tp;
1962
1963 if (t->tbf_n_tok > MAX_BKT_SIZE)
1964 t->tbf_n_tok = MAX_BKT_SIZE;
1965
1966 splx(s);
1967 }
1968
1969 static int
1970 priority(vifp, ip)
1971 register struct vif *vifp;
1972 register struct ip *ip;
1973 {
1974 register int prio;
1975
1976 /* temporary hack; may add general packet classifier some day */
1977
1978 /*
1979 * The UDP port space is divided up into four priority ranges:
1980 * [0, 16384) : unclassified - lowest priority
1981 * [16384, 32768) : audio - highest priority
1982 * [32768, 49152) : whiteboard - medium priority
1983 * [49152, 65536) : video - low priority
1984 */
1985 if (ip->ip_p == IPPROTO_UDP) {
1986 struct udphdr *udp = (struct udphdr *)(((char *)ip) + (ip->ip_hl << 2));
1987 switch (ntohs(udp->uh_dport) & 0xc000) {
1988 case 0x4000:
1989 prio = 70;
1990 break;
1991 case 0x8000:
1992 prio = 60;
1993 break;
1994 case 0xc000:
1995 prio = 55;
1996 break;
1997 default:
1998 prio = 50;
1999 break;
2000 }
2001 if (tbfdebug > 1)
2002 log(LOG_DEBUG, "port %x prio%d\n", ntohs(udp->uh_dport), prio);
2003 } else {
2004 prio = 50;
2005 }
2006 return prio;
2007 }
2008
2009 /*
2010 * End of token bucket filter modifications
2011 */
2012
2013 int
2014 ip_rsvp_vif_init(so, sopt)
2015 struct socket *so;
2016 struct sockopt *sopt;
2017 {
2018 int error, i, s;
2019
2020 if (rsvpdebug)
2021 printf("ip_rsvp_vif_init: so_type = %d, pr_protocol = %d\n",
2022 so->so_type, so->so_proto->pr_protocol);
2023
2024 if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP)
2025 return EOPNOTSUPP;
2026
2027 /* Check mbuf. */
2028 error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
2029 if (error)
2030 return (error);
2031
2032 if (rsvpdebug)
2033 printf("ip_rsvp_vif_init: vif = %d rsvp_on = %d\n", i, rsvp_on);
2034
2035 s = splnet();
2036
2037 /* Check vif. */
2038 if (!legal_vif_num(i)) {
2039 splx(s);
2040 return EADDRNOTAVAIL;
2041 }
2042
2043 /* Check if socket is available. */
2044 if (viftable[i].v_rsvpd != NULL) {
2045 splx(s);
2046 return EADDRINUSE;
2047 }
2048
2049 viftable[i].v_rsvpd = so;
2050 /* This may seem silly, but we need to be sure we don't over-increment
2051 * the RSVP counter, in case something slips up.
2052 */
2053 if (!viftable[i].v_rsvp_on) {
2054 viftable[i].v_rsvp_on = 1;
2055 rsvp_on++;
2056 }
2057
2058 splx(s);
2059 return 0;
2060 }
2061
2062 int
2063 ip_rsvp_vif_done(so, sopt)
2064 struct socket *so;
2065 struct sockopt *sopt;
2066 {
2067 int error, i, s;
2068
2069 if (rsvpdebug)
2070 printf("ip_rsvp_vif_done: so_type = %d, pr_protocol = %d\n",
2071 so->so_type, so->so_proto->pr_protocol);
2072
2073 if (so->so_type != SOCK_RAW ||
2074 so->so_proto->pr_protocol != IPPROTO_RSVP)
2075 return EOPNOTSUPP;
2076
2077 error = sooptcopyin(sopt, &i, sizeof i, sizeof i);
2078 if (error)
2079 return (error);
2080
2081 s = splnet();
2082
2083 /* Check vif. */
2084 if (!legal_vif_num(i)) {
2085 splx(s);
2086 return EADDRNOTAVAIL;
2087 }
2088
2089 if (rsvpdebug)
2090 printf("ip_rsvp_vif_done: v_rsvpd = %p so = %p\n",
2091 viftable[i].v_rsvpd, so);
2092
2093 viftable[i].v_rsvpd = NULL;
2094 /*
2095 * This may seem silly, but we need to be sure we don't over-decrement
2096 * the RSVP counter, in case something slips up.
2097 */
2098 if (viftable[i].v_rsvp_on) {
2099 viftable[i].v_rsvp_on = 0;
2100 rsvp_on--;
2101 }
2102
2103 splx(s);
2104 return 0;
2105 }
2106
2107 void
2108 ip_rsvp_force_done(so)
2109 struct socket *so;
2110 {
2111 int vifi;
2112 register int s;
2113
2114 /* Don't bother if it is not the right type of socket. */
2115 if (so->so_type != SOCK_RAW || so->so_proto->pr_protocol != IPPROTO_RSVP)
2116 return;
2117
2118 s = splnet();
2119
2120 /* The socket may be attached to more than one vif...this
2121 * is perfectly legal.
2122 */
2123 for (vifi = 0; vifi < numvifs; vifi++) {
2124 if (viftable[vifi].v_rsvpd == so) {
2125 viftable[vifi].v_rsvpd = NULL;
2126 /* This may seem silly, but we need to be sure we don't
2127 * over-decrement the RSVP counter, in case something slips up.
2128 */
2129 if (viftable[vifi].v_rsvp_on) {
2130 viftable[vifi].v_rsvp_on = 0;
2131 rsvp_on--;
2132 }
2133 }
2134 }
2135
2136 splx(s);
2137 return;
2138 }
2139
2140 void
2141 rsvp_input(m, iphlen)
2142 struct mbuf *m;
2143 int iphlen;
2144 {
2145 int vifi;
2146 register struct ip *ip = mtod(m, struct ip *);
2147 static struct sockaddr_in rsvp_src = { sizeof rsvp_src, AF_INET };
2148 register int s;
2149 struct ifnet *ifp;
2150
2151 if (rsvpdebug)
2152 printf("rsvp_input: rsvp_on %d\n",rsvp_on);
2153
2154 /* Can still get packets with rsvp_on = 0 if there is a local member
2155 * of the group to which the RSVP packet is addressed. But in this
2156 * case we want to throw the packet away.
2157 */
2158 if (!rsvp_on) {
2159 m_freem(m);
2160 return;
2161 }
2162
2163 s = splnet();
2164
2165 if (rsvpdebug)
2166 printf("rsvp_input: check vifs\n");
2167
2168 #if DIAGNOSTIC
2169 if (!(m->m_flags & M_PKTHDR))
2170 panic("rsvp_input no hdr");
2171 #endif
2172
2173 ifp = m->m_pkthdr.rcvif;
2174 /* Find which vif the packet arrived on. */
2175 for (vifi = 0; vifi < numvifs; vifi++)
2176 if (viftable[vifi].v_ifp == ifp)
2177 break;
2178
2179 if (vifi == numvifs || viftable[vifi].v_rsvpd == NULL) {
2180 /*
2181 * If the old-style non-vif-associated socket is set,
2182 * then use it. Otherwise, drop packet since there
2183 * is no specific socket for this vif.
2184 */
2185 if (ip_rsvpd != NULL) {
2186 if (rsvpdebug)
2187 printf("rsvp_input: Sending packet up old-style socket\n");
2188 rip_input(m, iphlen); /* xxx */
2189 } else {
2190 if (rsvpdebug && vifi == numvifs)
2191 printf("rsvp_input: Can't find vif for packet.\n");
2192 else if (rsvpdebug && viftable[vifi].v_rsvpd == NULL)
2193 printf("rsvp_input: No socket defined for vif %d\n",vifi);
2194 m_freem(m);
2195 }
2196 splx(s);
2197 return;
2198 }
2199 rsvp_src.sin_addr = ip->ip_src;
2200
2201 if (rsvpdebug && m)
2202 printf("rsvp_input: m->m_len = %d, sbspace() = %ld\n",
2203 m->m_len,sbspace(&(viftable[vifi].v_rsvpd->so_rcv)));
2204
2205 if (socket_send(viftable[vifi].v_rsvpd, m, &rsvp_src) < 0) {
2206 if (rsvpdebug)
2207 printf("rsvp_input: Failed to append to socket\n");
2208 } else {
2209 if (rsvpdebug)
2210 printf("rsvp_input: send packet up\n");
2211 }
2212
2213 splx(s);
2214 }
2215
2216 #if MROUTE_LKM
2217 #include <sys/conf.h>
2218 #include <sys/exec.h>
2219 #include <sys/sysent.h>
2220 #include <sys/lkm.h>
2221
2222 MOD_MISC("ip_mroute_mod")
2223
2224 static int
2225 ip_mroute_mod_handle(struct lkm_table *lkmtp, int cmd)
2226 {
2227 int i;
2228 struct lkm_misc *args = lkmtp->private.lkm_misc;
2229 int err = 0;
2230
2231 switch(cmd) {
2232 static int (*old_ip_mrouter_cmd)();
2233 static int (*old_ip_mrouter_done)();
2234 static int (*old_ip_mforward)();
2235 static int (*old_mrt_ioctl)();
2236 static void (*old_proto4_input)();
2237 static int (*old_legal_vif_num)();
2238 extern struct protosw inetsw[];
2239
2240 case LKM_E_LOAD:
2241 if(lkmexists(lkmtp) || ip_mrtproto)
2242 return(EEXIST);
2243 old_ip_mrouter_cmd = ip_mrouter_cmd;
2244 ip_mrouter_cmd = X_ip_mrouter_cmd;
2245 old_ip_mrouter_done = ip_mrouter_done;
2246 ip_mrouter_done = X_ip_mrouter_done;
2247 old_ip_mforward = ip_mforward;
2248 ip_mforward = X_ip_mforward;
2249 old_mrt_ioctl = mrt_ioctl;
2250 mrt_ioctl = X_mrt_ioctl;
2251 old_proto4_input = ip_protox[ENCAP_PROTO]->pr_input;
2252 ip_protox[ENCAP_PROTO]->pr_input = X_ipip_input;
2253 old_legal_vif_num = legal_vif_num;
2254 legal_vif_num = X_legal_vif_num;
2255 ip_mrtproto = IGMP_DVMRP;
2256
2257 printf("\nIP multicast routing loaded\n");
2258 break;
2259
2260 case LKM_E_UNLOAD:
2261 if (ip_mrouter)
2262 return EINVAL;
2263
2264 ip_mrouter_cmd = old_ip_mrouter_cmd;
2265 ip_mrouter_done = old_ip_mrouter_done;
2266 ip_mforward = old_ip_mforward;
2267 mrt_ioctl = old_mrt_ioctl;
2268 ip_protox[ENCAP_PROTO]->pr_input = old_proto4_input;
2269 legal_vif_num = old_legal_vif_num;
2270 ip_mrtproto = 0;
2271 break;
2272
2273 default:
2274 err = EINVAL;
2275 break;
2276 }
2277
2278 return(err);
2279 }
2280
2281 int
2282 ip_mroute_mod(struct lkm_table *lkmtp, int cmd, int ver) {
2283 DISPATCH(lkmtp, cmd, ver, ip_mroute_mod_handle, ip_mroute_mod_handle,
2284 nosys);
2285 }
2286
2287 #endif /* MROUTE_LKM */
2288 #endif /* MROUTING */