]> git.saurik.com Git - apple/xnu.git/blame - bsd/netinet/ip_mroute.c
xnu-792.18.15.tar.gz
[apple/xnu.git] / bsd / netinet / ip_mroute.c
CommitLineData
1c79356b 1/*
5d5c5d0d
A
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
8f6c56a5 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
1c79356b 5 *
8f6c56a5
A
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
8ad349bb 24 * limitations under the License.
8f6c56a5
A
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
1c79356b
A
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
9bccf70c 39 * $FreeBSD: src/sys/netinet/ip_mroute.c,v 1.56.2.2 2001/07/19 06:37:26 kris Exp $
1c79356b
A
40 */
41
1c79356b
A
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>
1c79356b
A
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
9bccf70c 79#ifndef MROUTING
91447636
A
80extern u_long _ip_mcast_src(int vifi);
81extern int _ip_mforward(struct ip *ip, struct ifnet *ifp,
82 struct mbuf *m, struct ip_moptions *imo);
83extern int _ip_mrouter_done(void);
84extern int _ip_mrouter_get(struct socket *so, struct sockopt *sopt);
85extern int _ip_mrouter_set(struct socket *so, struct sockopt *sopt);
86extern int _mrt_ioctl(int req, caddr_t data, struct proc *p);
1c79356b
A
87
88/*
89 * Dummy routines and globals used when multicast routing is not compiled in.
90 */
91
92struct socket *ip_mrouter = NULL;
93u_int rsvpdebug = 0;
94
95int
96_ip_mrouter_set(so, sopt)
97 struct socket *so;
98 struct sockopt *sopt;
99{
100 return(EOPNOTSUPP);
101}
102
103int (*ip_mrouter_set)(struct socket *, struct sockopt *) = _ip_mrouter_set;
104
105
106int
107_ip_mrouter_get(so, sopt)
108 struct socket *so;
109 struct sockopt *sopt;
110{
111 return(EOPNOTSUPP);
112}
113
114int (*ip_mrouter_get)(struct socket *, struct sockopt *) = _ip_mrouter_get;
115
116int
117_ip_mrouter_done()
118{
119 return(0);
120}
121
122int (*ip_mrouter_done)(void) = _ip_mrouter_done;
123
124int
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
134int (*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
135 struct ip_moptions *) = _ip_mforward;
136
137int
138_mrt_ioctl(int req, caddr_t data, struct proc *p)
139{
140 return EOPNOTSUPP;
141}
142
143int (*mrt_ioctl)(int, caddr_t, struct proc *) = _mrt_ioctl;
144
145void
146rsvp_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
169void ipip_input(struct mbuf *m, int iphlen) { /* XXX must fixup manually */
170 rip_input(m, iphlen);
171}
172
173int (*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 */
180u_long
181_ip_mcast_src(int vifi) { return INADDR_ANY; }
182u_long (*ip_mcast_src)(int) = _ip_mcast_src;
183
184int
185ip_rsvp_vif_init(so, sopt)
186 struct socket *so;
187 struct sockopt *sopt;
188{
189 return(EINVAL);
190}
191
192int
193ip_rsvp_vif_done(so, sopt)
194 struct socket *so;
195 struct sockopt *sopt;
196{
197 return(EINVAL);
198}
199
200void
201ip_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 */
9bccf70c 220#ifndef MROUTE_LKM
1c79356b
A
221struct socket *ip_mrouter = NULL;
222static struct mrtstat mrtstat;
223#else /* MROUTE_LKM */
91447636 224extern void X_ipip_input(struct mbuf *m, int iphlen);
1c79356b
A
225extern struct mrtstat mrtstat;
226static int ip_mrtproto;
227#endif
228
229#define NO_RTE_FOUND 0x1
230#define RTE_FOUND 0x2
231
232static struct mfc *mfctable[MFCTBLSIZ];
233static u_char nexpire[MFCTBLSIZ];
234static struct vif viftable[MAXVIFS];
235static 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
240static u_int tbfdebug = 0; /* tbf debug level */
241static u_int rsvpdebug = 0; /* rsvp debug level */
242
1c79356b
A
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
251static 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 */
262static 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 */
268static 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 */
285static vifi_t numvifs = 0;
286static 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 */
292static u_long last_encap_src;
293static struct vif *last_encap_vif;
294
91447636
A
295static u_long X_ip_mcast_src(int vifi);
296static int X_ip_mforward(struct ip *ip, struct ifnet *ifp, struct mbuf *m, struct ip_moptions *imo);
297static int X_ip_mrouter_done(void);
298static int X_ip_mrouter_get(struct socket *so, struct sockopt *m);
299static int X_ip_mrouter_set(struct socket *so, struct sockopt *m);
300static int X_legal_vif_num(int vif);
301static int X_mrt_ioctl(int cmd, caddr_t data);
1c79356b
A
302
303static int get_sg_cnt(struct sioc_sg_req *);
304static int get_vif_cnt(struct sioc_vif_req *);
305static int ip_mrouter_init(struct socket *, int);
306static int add_vif(struct vifctl *);
307static int del_vif(vifi_t);
308static int add_mfc(struct mfcctl *);
309static int del_mfc(struct mfcctl *);
310static int socket_send(struct socket *, struct mbuf *, struct sockaddr_in *);
311static int set_assert(int);
312static void expire_upcalls(void *);
313static int ip_mdq(struct mbuf *, struct ifnet *, struct mfc *,
314 vifi_t);
315static void phyint_send(struct ip *, struct vif *, struct mbuf *);
316static void encap_send(struct ip *, struct vif *, struct mbuf *);
317static void tbf_control(struct vif *, struct mbuf *, struct ip *, u_long);
318static void tbf_queue(struct vif *, struct mbuf *);
319static void tbf_process_q(struct vif *);
320static void tbf_reprocess_q(void *);
321static int tbf_dq_sel(struct vif *, struct ip *);
322static void tbf_send_packet(struct vif *, struct mbuf *);
323static void tbf_update_tokens(struct vif *);
324static int priority(struct vif *, struct ip *);
325void multiencap_decap(struct mbuf *);
326
327/*
328 * whether or not special PIM assert processing is enabled.
329 */
330static 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
392u_long upcall_data[51];
393static void collate(struct timeval *);
394#endif /* UPCALL_TIMING */
395
396
397/*
398 * Handle MRT setsockopt commands to modify the multicast routing tables.
399 */
400static int
401X_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
9bccf70c 467#if !defined(MROUTE_LKM) || !MROUTE_LKM
1c79356b
A
468int (*ip_mrouter_set)(struct socket *, struct sockopt *) = X_ip_mrouter_set;
469#endif
470
471/*
472 * Handle MRT getsockopt commands
473 */
474static int
475X_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
9bccf70c 497#if !defined(MROUTE_LKM) || !MROUTE_LKM
1c79356b
A
498int (*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 */
504static int
505X_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
9bccf70c 525#if !defined(MROUTE_LKM) || !MROUTE_LKM
1c79356b
A
526int (*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 */
532static int
533get_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 */
555static int
556get_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 */
574static int
575ip_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 */
609static int
610X_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
9bccf70c 681#if !defined(MROUTE_LKM) || !MROUTE_LKM
1c79356b
A
682int (*ip_mrouter_done)(void) = X_ip_mrouter_done;
683#endif
684
685/*
686 * Set PIM assert processing global
687 */
688static int
689set_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 */
703static int
704add_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;
91447636
A
722 ifafree(ifa);
723 ifa = NULL;
1c79356b
A
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 */
807static int
808del_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 */
862static int
863add_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 */
1010static void collate(t)
1011register 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 */
1035static int
1036del_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 */
1081static int
1082socket_send(s, mm, src)
1083 struct socket *s;
1084 struct mbuf *mm;
1085 struct sockaddr_in *src;
1086{
91447636 1087 socket_lock(s, 1);
1c79356b
A
1088 if (s) {
1089 if (sbappendaddr(&s->so_rcv,
1090 (struct sockaddr *)src,
91447636 1091 mm, (struct mbuf *)0, NULL) != 0) {
1c79356b 1092 sorwakeup(s);
91447636 1093 socket_unlock(s, 1);
1c79356b
A
1094 return 0;
1095 }
1096 }
91447636 1097 socket_unlock(s, 1);
1c79356b
A
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
1116static int
1117X_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
9bccf70c 1335#if !defined(MROUTE_LKM) || !MROUTE_LKM
1c79356b
A
1336int (*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 */
1343static void
1344expire_upcalls(void *unused)
1345{
1346 struct rtdetq *rte;
1347 struct mfc *mfc, **nptr;
1348 int i;
1349 int s;
1c79356b 1350
1c79356b
A
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);
1c79356b
A
1393}
1394
1395/*
1396 * Packet forwarding routine once entry in the cache is made
1397 */
1398static int
1399ip_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 */
1517static int
1518X_legal_vif_num(vif)
1519 int vif;
1520{
1521 if (vif >= 0 && vif < numvifs)
1522 return(1);
1523 else
1524 return(0);
1525}
1526
9bccf70c 1527#if !defined(MROUTE_LKM) || !MROUTE_LKM
1c79356b
A
1528int (*legal_vif_num)(int) = X_legal_vif_num;
1529#endif
1530
1531/*
1532 * Return the local address used by this vif
1533 */
1534static u_long
1535X_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
9bccf70c 1544#if !defined(MROUTE_LKM) || !MROUTE_LKM
1c79356b
A
1545u_long (*ip_mcast_src)(int) = X_ip_mcast_src;
1546#endif
1547
1548static void
1549phyint_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
1574static void
1575encap_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;
9bccf70c
A
1612#if RANDOM_IP_ID
1613 ip_copy->ip_id = ip_randomid();
1614#else
1c79356b 1615 ip_copy->ip_id = htons(ip_id++);
9bccf70c 1616#endif
1c79356b
A
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 */
1644void
1645#if MROUTE_LKM
1646X_ipip_input(m, iphlen)
1647#else
1648ipip_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;
1c79356b
A
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;
91447636
A
1706
1707 proto_inject(PF_INET, m);
1c79356b
A
1708}
1709
1710/*
1711 * Token bucket filter module
1712 */
1713
1714static void
1715tbf_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 */
1768static void
1769tbf_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 */
1803static void
1804tbf_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
1840static void
1841tbf_reprocess_q(xvifp)
1842 void *xvifp;
1843{
1844 register struct vif *vifp = xvifp;
1c79356b 1845
1c79356b 1846 if (ip_mrouter == NULL) {
1c79356b
A
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);
1c79356b
A
1856}
1857
1858/* function that will selectively discard a member of the queue
1859 * based on the precedence value and the priority
1860 */
1861static int
1862tbf_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
1898static void
1899tbf_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 */
1938static void
1939tbf_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
1969static int
1970priority(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
2013int
2014ip_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
2062int
2063ip_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
2107void
2108ip_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
2140void
2141rsvp_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
1c79356b
A
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. */
9bccf70c 2175 for (vifi = 0; vifi < numvifs; vifi++)
1c79356b 2176 if (viftable[vifi].v_ifp == ifp)
9bccf70c 2177 break;
1c79356b 2178
9bccf70c
A
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) {
1c79356b 2186 if (rsvpdebug)
9bccf70c
A
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);
1c79356b 2194 m_freem(m);
9bccf70c
A
2195 }
2196 splx(s);
2197 return;
1c79356b
A
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
9bccf70c 2205 if (socket_send(viftable[vifi].v_rsvpd, m, &rsvp_src) < 0) {
1c79356b
A
2206 if (rsvpdebug)
2207 printf("rsvp_input: Failed to append to socket\n");
9bccf70c 2208 } else {
1c79356b
A
2209 if (rsvpdebug)
2210 printf("rsvp_input: send packet up\n");
9bccf70c
A
2211 }
2212
1c79356b
A
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
2222MOD_MISC("ip_mroute_mod")
2223
2224static int
2225ip_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
2281int
2282ip_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 */