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