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