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