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