|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1993-1989 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26: /*
27: * Author: David B. Golub, Carnegie Mellon University
28: * Date: 3/98
29: *
30: * Network IO.
31: *
32: * Packet filter code taken from vaxif/enet.c written
33: * CMU and Stanford.
34: */
35:
36: /*
37: * Note: don't depend on anything in this file.
38: * It may change a lot real soon. -cmaeda 11 June 1993
39: */
40:
41: #include <norma_ether.h>
42: #include <mach_ttd.h>
43:
44: #include <sys/types.h>
45: #include <device/net_status.h>
46: #include <machine/machspl.h> /* spl definitions */
47: #include <device/net_io.h>
48: #include <device/if_hdr.h>
49: /*#include <device/io_req.h> */
50: #include <device/ds_routines.h>
51:
52: #include <mach/boolean.h>
53: #include <mach/vm_param.h>
54:
55: #include <ipc/ipc_port.h>
56: #include <ipc/ipc_kmsg.h>
57: #include <ipc/ipc_mqueue.h>
58:
59: #include <kern/counters.h>
60: #include <kern/lock.h>
61: #include <kern/queue.h>
62: #include <kern/sched_prim.h>
63: #include <kern/thread.h>
64:
65: #if NORMA_ETHER
66: #include <norma/ipc_ether.h>
67: #endif /*NORMA_ETHER*/
68:
69: #include <machine/machspl.h>
70:
71: #if MACH_TTD
72: #include <ttd/ttd_stub.h>
73: #endif /* MACH_TTD */
74:
75: #if MACH_TTD
76: int kttd_async_counter= 0;
77: #endif /* MACH_TTD */
78:
79:
80: /*
81: * Packet Buffer Management
82: *
83: * This module manages a private pool of kmsg buffers.
84: */
85:
86: /*
87: * List of net kmsgs queued to be sent to users.
88: * Messages can be high priority or low priority.
89: * The network thread processes high priority messages first.
90: */
91: decl_simple_lock_data(,net_queue_lock)
92: boolean_t net_thread_awake = FALSE;
93: struct ipc_kmsg_queue net_queue_high;
94: int net_queue_high_size = 0;
95: int net_queue_high_max = 0; /* for debugging */
96: struct ipc_kmsg_queue net_queue_low;
97: int net_queue_low_size = 0;
98: int net_queue_low_max = 0; /* for debugging */
99:
100: /*
101: * List of net kmsgs that can be touched at interrupt level.
102: * If it is empty, we will also steal low priority messages.
103: */
104: decl_simple_lock_data(,net_queue_free_lock)
105: struct ipc_kmsg_queue net_queue_free;
106: int net_queue_free_size = 0; /* on free list */
107: int net_queue_free_max = 0; /* for debugging */
108:
109: /*
110: * This value is critical to network performance.
111: * At least this many buffers should be sitting in net_queue_free.
112: * If this is set too small, we will drop network packets.
113: * Even a low drop rate (<1%) can cause severe network throughput problems.
114: * We add one to net_queue_free_min for every filter.
115: */
116: int net_queue_free_min = 3;
117:
118: int net_queue_free_hits = 0; /* for debugging */
119: int net_queue_free_steals = 0; /* for debugging */
120: int net_queue_free_misses = 0; /* for debugging */
121:
122: int net_kmsg_send_high_hits = 0; /* for debugging */
123: int net_kmsg_send_low_hits = 0; /* for debugging */
124: int net_kmsg_send_high_misses = 0; /* for debugging */
125: int net_kmsg_send_low_misses = 0; /* for debugging */
126:
127: int net_thread_awaken = 0; /* for debugging */
128: int net_ast_taken = 0; /* for debugging */
129:
130: decl_simple_lock_data(,net_kmsg_total_lock)
131: int net_kmsg_total = 0; /* total allocated */
132: int net_kmsg_max; /* initialized below */
133:
134: vm_size_t net_kmsg_size; /* initialized below */
135:
136: /*
137: * We want more buffers when there aren't enough in the free queue
138: * and the low priority queue. However, we don't want to allocate
139: * more than net_kmsg_max.
140: */
141:
142: #define net_kmsg_want_more() \
143: (((net_queue_free_size + net_queue_low_size) < net_queue_free_min) && \
144: (net_kmsg_total < net_kmsg_max))
145:
146: ipc_kmsg_t
147: net_kmsg_get(void)
148: {
149: register ipc_kmsg_t kmsg;
150: spl_t s;
151:
152: /*
153: * First check the list of free buffers.
154: */
155: s = splimp();
156: simple_lock(&net_queue_free_lock);
157: kmsg = ipc_kmsg_queue_first(&net_queue_free);
158: if (kmsg != IKM_NULL) {
159: ipc_kmsg_rmqueue_first_macro(&net_queue_free, kmsg);
160: net_queue_free_size--;
161: net_queue_free_hits++;
162: }
163: simple_unlock(&net_queue_free_lock);
164:
165: if (kmsg == IKM_NULL) {
166: /*
167: * Try to steal from the low priority queue.
168: */
169: simple_lock(&net_queue_lock);
170: kmsg = ipc_kmsg_queue_first(&net_queue_low);
171: if (kmsg != IKM_NULL) {
172: ipc_kmsg_rmqueue_first_macro(&net_queue_low, kmsg);
173: net_queue_low_size--;
174: net_queue_free_steals++;
175: }
176: simple_unlock(&net_queue_lock);
177: }
178:
179: if (kmsg == IKM_NULL)
180: net_queue_free_misses++;
181: (void) splx(s);
182:
183: if (net_kmsg_want_more() || (kmsg == IKM_NULL)) {
184: boolean_t awake;
185:
186: s = splimp();
187: simple_lock(&net_queue_lock);
188: awake = net_thread_awake;
189: net_thread_awake = TRUE;
190: simple_unlock(&net_queue_lock);
191: (void) splx(s);
192:
193: if (!awake)
194: thread_wakeup((event_t) &net_thread_awake);
195: }
196:
197: return kmsg;
198: }
199:
200: void
201: net_kmsg_put(register ipc_kmsg_t kmsg)
202: {
203: spl_t s;
204:
205: s = splimp();
206: simple_lock(&net_queue_free_lock);
207: ipc_kmsg_enqueue_macro(&net_queue_free, kmsg);
208: if (++net_queue_free_size > net_queue_free_max)
209: net_queue_free_max = net_queue_free_size;
210: simple_unlock(&net_queue_free_lock);
211: (void) splx(s);
212: }
213:
214: void
215: net_kmsg_collect(void)
216: {
217: register ipc_kmsg_t kmsg;
218: spl_t s;
219:
220: s = splimp();
221: simple_lock(&net_queue_free_lock);
222: while (net_queue_free_size > net_queue_free_min) {
223: kmsg = ipc_kmsg_dequeue(&net_queue_free);
224: net_queue_free_size--;
225: simple_unlock(&net_queue_free_lock);
226: (void) splx(s);
227:
228: net_kmsg_free(kmsg);
229: simple_lock(&net_kmsg_total_lock);
230: net_kmsg_total--;
231: simple_unlock(&net_kmsg_total_lock);
232:
233: s = splimp();
234: simple_lock(&net_queue_free_lock);
235: }
236: simple_unlock(&net_queue_free_lock);
237: (void) splx(s);
238: }
239:
240: void
241: net_kmsg_more(void)
242: {
243: register ipc_kmsg_t kmsg;
244:
245: /*
246: * Replenish net kmsg pool if low. We don't have the locks
247: * necessary to look at these variables, but that's OK because
248: * misread values aren't critical. The danger in this code is
249: * that while we allocate buffers, interrupts are happening
250: * which take buffers out of the free list. If we are not
251: * careful, we will sit in the loop and allocate a zillion
252: * buffers while a burst of packets arrives. So we count
253: * buffers in the low priority queue as available, because
254: * net_kmsg_get will make use of them, and we cap the total
255: * number of buffers we are willing to allocate.
256: */
257:
258: while (net_kmsg_want_more()) {
259: simple_lock(&net_kmsg_total_lock);
260: net_kmsg_total++;
261: simple_unlock(&net_kmsg_total_lock);
262: kmsg = net_kmsg_alloc();
263: net_kmsg_put(kmsg);
264: }
265: }
266:
267: /*
268: * Packet Filter Data Structures
269: *
270: * Each network interface has a set of packet filters
271: * that are run on incoming packets.
272: *
273: * Each packet filter may represent a single network
274: * session or multiple network sessions. For example,
275: * all application level TCP sessions would be represented
276: * by a single packet filter data structure.
277: *
278: * If a packet filter has a single session, we use a
279: * struct net_rcv_port to represent it. If the packet
280: * filter represents multiple sessions, we use a
281: * struct net_hash_header to represent it.
282: */
283:
284: /*
285: * Each interface has a write port and a set of read ports.
286: * Each read port has one or more filters to determine what packets
287: * should go to that port.
288: */
289:
290: /*
291: * Receive port for net, with packet filter.
292: * This data structure by itself represents a packet
293: * filter for a single session.
294: */
295: struct net_rcv_port {
296: queue_chain_t chain; /* list of open_descriptors */
297: ipc_port_t rcv_port; /* port to send packet to */
298: int rcv_qlimit; /* port's qlimit */
299: int rcv_count; /* number of packets received */
300: int priority; /* priority for filter */
301: filter_t *filter_end; /* pointer to end of filter */
302: filter_t filter[NET_MAX_FILTER];
303: /* filter operations */
304: };
305: typedef struct net_rcv_port *net_rcv_port_t;
306:
307: zone_t net_rcv_zone; /* zone of net_rcv_port structs */
308:
309:
310: #define NET_HASH_SIZE 256
311: #define N_NET_HASH 4
312: #define N_NET_HASH_KEYS 4
313:
314: unsigned int bpf_hash (int, unsigned int *);
315:
316: /*
317: * A single hash entry.
318: */
319: struct net_hash_entry {
320: queue_chain_t chain; /* list of entries with same hval */
321: #define he_next chain.next
322: #define he_prev chain.prev
323: ipc_port_t rcv_port; /* destination port */
324: int rcv_qlimit; /* qlimit for the port */
325: unsigned int keys[N_NET_HASH_KEYS];
326: };
327: typedef struct net_hash_entry *net_hash_entry_t;
328:
329: zone_t net_hash_entry_zone;
330:
331: /*
332: * This structure represents a packet filter with multiple sessions.
333: *
334: * For example, all application level TCP sessions might be
335: * represented by one of these structures. It looks like a
336: * net_rcv_port struct so that both types can live on the
337: * same packet filter queues.
338: */
339: struct net_hash_header {
340: struct net_rcv_port rcv;
341: int n_keys; /* zero if not used */
342: int ref_count; /* reference count */
343: net_hash_entry_t table[NET_HASH_SIZE];
344: } filter_hash_header[N_NET_HASH];
345:
346: typedef struct net_hash_header *net_hash_header_t;
347:
348: decl_simple_lock_data(,net_hash_header_lock)
349:
350: #define HASH_ITERATE(head, elt) (elt) = (net_hash_entry_t) (head); do {
351: #define HASH_ITERATE_END(head, elt) \
352: (elt) = (net_hash_entry_t) queue_next((queue_entry_t) (elt)); \
353: } while ((elt) != (head));
354:
355:
356: #define FILTER_ITERATE(ifp, fp, nextfp) \
357: for ((fp) = (net_rcv_port_t) queue_first(&(ifp)->if_rcv_port_list);\
358: !queue_end(&(ifp)->if_rcv_port_list, (queue_entry_t)(fp)); \
359: (fp) = (nextfp)) { \
360: (nextfp) = (net_rcv_port_t) queue_next(&(fp)->chain);
361: #define FILTER_ITERATE_END }
362:
363: /* entry_p must be net_rcv_port_t or net_hash_entry_t */
364: #define ENQUEUE_DEAD(dead, entry_p) { \
365: queue_next(&(entry_p)->chain) = (queue_entry_t) (dead); \
366: (dead) = (queue_entry_t)(entry_p); \
367: }
368:
369: extern boolean_t net_do_filter(); /* CSPF */
370: extern int bpf_do_filter(); /* BPF */
371:
372:
373: /*
374: * ethernet_priority:
375: *
376: * This function properly belongs in the ethernet interfaces;
377: * it should not be called by this module. (We get packet
378: * priorities as an argument to net_filter.) It is here
379: * to avoid massive code duplication.
380: *
381: * Returns TRUE for high-priority packets.
382: */
383:
384: boolean_t ethernet_priority(kmsg)
385: ipc_kmsg_t kmsg;
386: {
387: register unsigned char *addr =
388: (unsigned char *) net_kmsg(kmsg)->header;
389:
390: /*
391: * A simplistic check for broadcast packets.
392: */
393:
394: if ((addr[0] == 0xff) && (addr[1] == 0xff) &&
395: (addr[2] == 0xff) && (addr[3] == 0xff) &&
396: (addr[4] == 0xff) && (addr[5] == 0xff))
397: return FALSE;
398: else
399: return TRUE;
400: }
401:
402: mach_msg_type_t header_type = {
403: MACH_MSG_TYPE_BYTE,
404: 8,
405: NET_HDW_HDR_MAX,
406: TRUE,
407: FALSE,
408: FALSE,
409: 0
410: };
411:
412: mach_msg_type_t packet_type = {
413: MACH_MSG_TYPE_BYTE, /* name */
414: 8, /* size */
415: 0, /* number */
416: TRUE, /* inline */
417: FALSE, /* longform */
418: FALSE /* deallocate */
419: };
420:
421: /*
422: * net_deliver:
423: *
424: * Called and returns holding net_queue_lock, at splimp.
425: * Dequeues a message and delivers it at spl0.
426: * Returns FALSE if no messages.
427: */
428: boolean_t net_deliver(nonblocking)
429: boolean_t nonblocking;
430: {
431: register ipc_kmsg_t kmsg;
432: boolean_t high_priority;
433: struct ipc_kmsg_queue send_list;
434:
435: /*
436: * Pick up a pending network message and deliver it.
437: * Deliver high priority messages before low priority.
438: */
439:
440: if ((kmsg = ipc_kmsg_dequeue(&net_queue_high)) != IKM_NULL) {
441: net_queue_high_size--;
442: high_priority = TRUE;
443: } else if ((kmsg = ipc_kmsg_dequeue(&net_queue_low)) != IKM_NULL) {
444: net_queue_low_size--;
445: high_priority = FALSE;
446: } else
447: return FALSE;
448: simple_unlock(&net_queue_lock);
449: (void) spl0();
450:
451: /*
452: * Run the packet through the filters,
453: * getting back a queue of packets to send.
454: */
455: net_filter(kmsg, &send_list);
456:
457: if (!nonblocking) {
458: /*
459: * There is a danger of running out of available buffers
460: * because they all get moved into the high priority queue
461: * or a port queue. In particular, we might need to
462: * allocate more buffers as we pull (previously available)
463: * buffers out of the low priority queue. But we can only
464: * allocate if we are allowed to block.
465: */
466: net_kmsg_more();
467: }
468:
469: while ((kmsg = ipc_kmsg_dequeue(&send_list)) != IKM_NULL) {
470: int count;
471:
472: /*
473: * Fill in the rest of the kmsg.
474: */
475: count = net_kmsg(kmsg)->net_rcv_msg_packet_count;
476:
477: ikm_init_special(kmsg, IKM_SIZE_NETWORK);
478:
479: kmsg->ikm_header.msgh_bits =
480: MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0);
481: /* remember message sizes must be rounded up */
482: kmsg->ikm_header.msgh_size =
483: ((mach_msg_size_t) (sizeof(struct net_rcv_msg)
484: - NET_RCV_MAX + count))+3 &~ 3;
485: kmsg->ikm_header.msgh_local_port = MACH_PORT_NULL;
486: kmsg->ikm_header.msgh_kind = MACH_MSGH_KIND_NORMAL;
487: kmsg->ikm_header.msgh_id = NET_RCV_MSG_ID;
488:
489: net_kmsg(kmsg)->header_type = header_type;
490: net_kmsg(kmsg)->packet_type = packet_type;
491: net_kmsg(kmsg)->net_rcv_msg_packet_count = count;
492:
493: /*
494: * Send the packet to the destination port. Drop it
495: * if the destination port is over its backlog.
496: */
497:
498: if (ipc_mqueue_send(kmsg, MACH_SEND_TIMEOUT, 0) ==
499: MACH_MSG_SUCCESS) {
500: if (high_priority)
501: net_kmsg_send_high_hits++;
502: else
503: net_kmsg_send_low_hits++;
504: /* the receiver is responsible for the message now */
505: } else {
506: if (high_priority)
507: net_kmsg_send_high_misses++;
508: else
509: net_kmsg_send_low_misses++;
510: ipc_kmsg_destroy(kmsg);
511: }
512: }
513:
514: (void) splimp();
515: simple_lock(&net_queue_lock);
516: return TRUE;
517: }
518:
519: /*
520: * We want to deliver packets using ASTs, so we can avoid the
521: * thread_wakeup/thread_block needed to get to the network
522: * thread. However, we can't allocate memory in the AST handler,
523: * because memory allocation might block. Hence we have the
524: * network thread to allocate memory. The network thread also
525: * delivers packets, so it can be allocating and delivering for a
526: * burst. net_thread_awake is protected by net_queue_lock
527: * (instead of net_queue_free_lock) so that net_packet and
528: * net_ast can safely determine if the network thread is running.
529: * This prevents a race that might leave a packet sitting without
530: * being delivered. It is possible for net_kmsg_get to think
531: * the network thread is awake, and so avoid a wakeup, and then
532: * have the network thread sleep without allocating. The next
533: * net_kmsg_get will do a wakeup.
534: */
535:
536: void net_ast()
537: {
538: spl_t s;
539:
540: net_ast_taken++;
541:
542: /*
543: * If the network thread is awake, then we would
544: * rather deliver messages from it, because
545: * it can also allocate memory.
546: */
547:
548: s = splimp();
549: simple_lock(&net_queue_lock);
550: while (!net_thread_awake && net_deliver(TRUE))
551: continue;
552:
553: /*
554: * Prevent an unnecessary AST. Either the network
555: * thread will deliver the messages, or there are
556: * no messages left to deliver.
557: */
558:
559: simple_unlock(&net_queue_lock);
560: (void) splsched();
561: ast_off(cpu_number(), AST_NETWORK);
562: (void) splx(s);
563: }
564:
565: void net_thread_continue()
566: {
567: for (;;) {
568: spl_t s;
569:
570: net_thread_awaken++;
571:
572: /*
573: * First get more buffers.
574: */
575: net_kmsg_more();
576:
577: s = splimp();
578: simple_lock(&net_queue_lock);
579: while (net_deliver(FALSE))
580: continue;
581:
582: net_thread_awake = FALSE;
583: assert_wait(&net_thread_awake, FALSE);
584: simple_unlock(&net_queue_lock);
585: (void) splx(s);
586: counter(c_net_thread_block++);
587: thread_block(net_thread_continue);
588: }
589: }
590:
591: void net_thread()
592: {
593: spl_t s;
594:
595: /*
596: * We should be very high priority.
597: */
598:
599: thread_set_own_priority(0);
600:
601: /*
602: * We sleep initially, so that we don't allocate any buffers
603: * unless the network is really in use and they are needed.
604: */
605:
606: s = splimp();
607: simple_lock(&net_queue_lock);
608: net_thread_awake = FALSE;
609: assert_wait(&net_thread_awake, FALSE);
610: simple_unlock(&net_queue_lock);
611: (void) splx(s);
612: counter(c_net_thread_block++);
613: thread_block(net_thread_continue);
614: net_thread_continue();
615: /*NOTREACHED*/
616: }
617:
618: void
619: reorder_queue(first, last)
620: register queue_t first, last;
621: {
622: register queue_entry_t prev, next;
623:
624: prev = first->prev;
625: next = last->next;
626:
627: prev->next = last;
628: next->prev = first;
629:
630: last->prev = prev;
631: last->next = first;
632:
633: first->next = next;
634: first->prev = last;
635: }
636:
637: /*
638: * Initialize send and receive queues on an interface.
639: */
640: void if_init_queues(ifp)
641: register struct ifnet *ifp;
642: {
643: #if 0
644: IFQ_INIT(&ifp->if_snd);
645: #endif
646: queue_init(&ifp->if_rcv_port_list);
647: simple_lock_init(&ifp->if_rcv_port_list_lock);
648: }
649:
650:
651: /*
652: * Incoming packet. Header has already been moved to proper place.
653: * We are already at splimp.
654: */
655: void
656: net_packet(ifp, kmsg, count, priority)
657: register struct ifnet *ifp;
658: register ipc_kmsg_t kmsg;
659: unsigned int count;
660: boolean_t priority;
661: {
662: boolean_t awake;
663:
664: #if NORMA_ETHER
665: if (netipc_net_packet(kmsg, count)) {
666: return;
667: }
668: #endif /* NORMA_ETHER */
669:
670: #if MACH_TTD
671: /*
672: * Do a quick check to see if it is a kernel TTD packet.
673: *
674: * Only check if KernelTTD is enabled, ie. the current
675: * device driver supports TTD, and the bootp succeded.
676: */
677: if (kttd_enabled && kttd_handle_async(kmsg)) {
678: /*
679: * Packet was a valid ttd packet and
680: * doesn't need to be passed up to filter.
681: * The ttd code put the used kmsg buffer
682: * back onto the free list.
683: */
684: if (kttd_debug)
685: printf("**%x**", kttd_async_counter++);
686: return;
687: }
688: #endif /* MACH_TTD */
689:
690: kmsg->ikm_header.msgh_remote_port = (mach_port_t) ifp;
691: net_kmsg(kmsg)->net_rcv_msg_packet_count = count;
692:
693: simple_lock(&net_queue_lock);
694: if (priority) {
695: ipc_kmsg_enqueue(&net_queue_high, kmsg);
696: if (++net_queue_high_size > net_queue_high_max)
697: net_queue_high_max = net_queue_high_size;
698: } else {
699: ipc_kmsg_enqueue(&net_queue_low, kmsg);
700: if (++net_queue_low_size > net_queue_low_max)
701: net_queue_low_max = net_queue_low_size;
702: }
703: /*
704: * If the network thread is awake, then we don't
705: * need to take an AST, because the thread will
706: * deliver the packet.
707: */
708: awake = net_thread_awake;
709: simple_unlock(&net_queue_lock);
710:
711: if (!awake) {
712: spl_t s = splsched();
713: ast_on(cpu_number(), AST_NETWORK);
714: (void) splx(s);
715: }
716: }
717:
718: int net_filter_queue_reorder = 0; /* non-zero to enable reordering */
719:
720: /*
721: * Run a packet through the filters, returning a list of messages.
722: * We are *not* called at interrupt level.
723: */
724: void
725: net_filter(kmsg, send_list)
726: register ipc_kmsg_t kmsg;
727: ipc_kmsg_queue_t send_list;
728: {
729: register struct ifnet *ifp;
730: register net_rcv_port_t infp, nextfp;
731: register ipc_kmsg_t new_kmsg;
732:
733: net_hash_entry_t entp, *hash_headp;
734: ipc_port_t dest;
735: queue_entry_t dead_infp = (queue_entry_t) 0;
736: queue_entry_t dead_entp = (queue_entry_t) 0;
737: unsigned int ret_count;
738:
739: int count = net_kmsg(kmsg)->net_rcv_msg_packet_count;
740: ifp = (struct ifnet *) kmsg->ikm_header.msgh_remote_port;
741: ipc_kmsg_queue_init(send_list);
742:
743: /*
744: * Unfortunately we can't allocate or deallocate memory
745: * while holding this lock. And we can't drop the lock
746: * while examining the filter list.
747: */
748: simple_lock(&ifp->if_rcv_port_list_lock);
749: FILTER_ITERATE(ifp, infp, nextfp)
750: {
751: entp = (net_hash_entry_t) 0;
752: if (infp->filter[0] == NETF_BPF) {
753: ret_count = bpf_do_filter(infp, net_kmsg(kmsg)->packet, count,
754: net_kmsg(kmsg)->header,
755: &hash_headp, &entp);
756: if (entp == (net_hash_entry_t) 0)
757: dest = infp->rcv_port;
758: else
759: dest = entp->rcv_port;
760: } else {
761: ret_count = net_do_filter(infp, net_kmsg(kmsg)->packet, count,
762: net_kmsg(kmsg)->header);
763: if (ret_count)
764: ret_count = count;
765: dest = infp->rcv_port;
766: }
767:
768: if (ret_count) {
769:
770: /*
771: * Make a send right for the destination.
772: */
773:
774: dest = ipc_port_copy_send(dest);
775: if (!IP_VALID(dest)) {
776: /*
777: * This filter is dead. We remove it from the
778: * filter list and set it aside for deallocation.
779: */
780:
781: if (entp == (net_hash_entry_t) 0) {
782: queue_remove(&ifp->if_rcv_port_list, infp,
783: net_rcv_port_t, chain);
784: ENQUEUE_DEAD(dead_infp, infp);
785: continue;
786: } else {
787: hash_ent_remove (ifp,
788: (net_hash_header_t)infp,
789: FALSE, /* no longer used */
790: hash_headp,
791: entp,
792: &dead_entp);
793: continue;
794: }
795: }
796:
797: /*
798: * Deliver copy of packet to this channel.
799: */
800: if (ipc_kmsg_queue_empty(send_list)) {
801: /*
802: * Only receiver, so far
803: */
804: new_kmsg = kmsg;
805: } else {
806: /*
807: * Other receivers - must allocate message and copy.
808: */
809: new_kmsg = net_kmsg_get();
810: if (new_kmsg == IKM_NULL) {
811: ipc_port_release_send(dest);
812: break;
813: }
814:
815: bcopy(
816: net_kmsg(kmsg)->packet,
817: net_kmsg(new_kmsg)->packet,
818: ret_count);
819: bcopy(
820: net_kmsg(kmsg)->header,
821: net_kmsg(new_kmsg)->header,
822: NET_HDW_HDR_MAX);
823: }
824: net_kmsg(new_kmsg)->net_rcv_msg_packet_count = ret_count;
825: new_kmsg->ikm_header.msgh_remote_port = (mach_port_t) dest;
826: ipc_kmsg_enqueue(send_list, new_kmsg);
827:
828: {
829: register net_rcv_port_t prevfp;
830: int rcount = ++infp->rcv_count;
831:
832: /*
833: * See if ordering of filters is wrong
834: */
835: if (infp->priority >= NET_HI_PRI) {
836: prevfp = (net_rcv_port_t) queue_prev(&infp->chain);
837: /*
838: * If infp is not the first element on the queue,
839: * and the previous element is at equal priority
840: * but has a lower count, then promote infp to
841: * be in front of prevfp.
842: */
843: if ((queue_t)prevfp != &ifp->if_rcv_port_list &&
844: infp->priority == prevfp->priority) {
845: /*
846: * Threshold difference to prevent thrashing
847: */
848: if (net_filter_queue_reorder
849: && (100 + prevfp->rcv_count < rcount))
850: reorder_queue(&prevfp->chain, &infp->chain);
851: }
852: /*
853: * High-priority filter -> no more deliveries
854: */
855: break;
856: }
857: }
858: }
859: }
860: FILTER_ITERATE_END
861:
862: simple_unlock(&ifp->if_rcv_port_list_lock);
863:
864: /*
865: * Deallocate dead filters.
866: */
867: if (dead_infp != 0)
868: net_free_dead_infp(dead_infp);
869: if (dead_entp != 0)
870: net_free_dead_entp(dead_entp);
871:
872: if (ipc_kmsg_queue_empty(send_list)) {
873: /* Not sent - recycle */
874: net_kmsg_put(kmsg);
875: }
876: }
877:
878: boolean_t
879: net_do_filter(infp, data, data_count, header)
880: net_rcv_port_t infp;
881: char * data;
882: unsigned int data_count;
883: char * header;
884: {
885: int stack[NET_FILTER_STACK_DEPTH+1];
886: register int *sp;
887: register filter_t *fp, *fpe;
888: register unsigned int op, arg;
889:
890: /*
891: * The filter accesses the header and data
892: * as unsigned short words.
893: */
894: data_count /= sizeof(unsigned short);
895:
896: #define data_word ((unsigned short *)data)
897: #define header_word ((unsigned short *)header)
898:
899: sp = &stack[NET_FILTER_STACK_DEPTH];
900: fp = &infp->filter[0];
901: fpe = infp->filter_end;
902:
903: *sp = TRUE;
904:
905: while (fp < fpe) {
906: arg = *fp++;
907: op = NETF_OP(arg);
908: arg = NETF_ARG(arg);
909:
910: switch (arg) {
911: case NETF_NOPUSH:
912: arg = *sp++;
913: break;
914: case NETF_PUSHZERO:
915: arg = 0;
916: break;
917: case NETF_PUSHLIT:
918: arg = *fp++;
919: break;
920: case NETF_PUSHIND:
921: arg = *sp++;
922: if (arg >= data_count)
923: return FALSE;
924: arg = data_word[arg];
925: break;
926: case NETF_PUSHHDRIND:
927: arg = *sp++;
928: if (arg >= NET_HDW_HDR_MAX/sizeof(unsigned short))
929: return FALSE;
930: arg = header_word[arg];
931: break;
932: default:
933: if (arg >= NETF_PUSHSTK) {
934: arg = sp[arg - NETF_PUSHSTK];
935: }
936: else if (arg >= NETF_PUSHHDR) {
937: arg = header_word[arg - NETF_PUSHHDR];
938: }
939: else {
940: arg -= NETF_PUSHWORD;
941: if (arg >= data_count)
942: return FALSE;
943: arg = data_word[arg];
944: }
945: break;
946:
947: }
948: switch (op) {
949: case NETF_OP(NETF_NOP):
950: *--sp = arg;
951: break;
952: case NETF_OP(NETF_AND):
953: *sp &= arg;
954: break;
955: case NETF_OP(NETF_OR):
956: *sp |= arg;
957: break;
958: case NETF_OP(NETF_XOR):
959: *sp ^= arg;
960: break;
961: case NETF_OP(NETF_EQ):
962: *sp = (*sp == arg);
963: break;
964: case NETF_OP(NETF_NEQ):
965: *sp = (*sp != arg);
966: break;
967: case NETF_OP(NETF_LT):
968: *sp = (*sp < arg);
969: break;
970: case NETF_OP(NETF_LE):
971: *sp = (*sp <= arg);
972: break;
973: case NETF_OP(NETF_GT):
974: *sp = (*sp > arg);
975: break;
976: case NETF_OP(NETF_GE):
977: *sp = (*sp >= arg);
978: break;
979: case NETF_OP(NETF_COR):
980: if (*sp++ == arg)
981: return (TRUE);
982: break;
983: case NETF_OP(NETF_CAND):
984: if (*sp++ != arg)
985: return (FALSE);
986: break;
987: case NETF_OP(NETF_CNOR):
988: if (*sp++ == arg)
989: return (FALSE);
990: break;
991: case NETF_OP(NETF_CNAND):
992: if (*sp++ != arg)
993: return (TRUE);
994: break;
995: case NETF_OP(NETF_LSH):
996: *sp <<= arg;
997: break;
998: case NETF_OP(NETF_RSH):
999: *sp >>= arg;
1000: break;
1001: case NETF_OP(NETF_ADD):
1002: *sp += arg;
1003: break;
1004: case NETF_OP(NETF_SUB):
1005: *sp -= arg;
1006: break;
1007: }
1008: }
1009: return ((*sp) ? TRUE : FALSE);
1010:
1011: #undef data_word
1012: #undef header_word
1013: }
1014:
1015: /*
1016: * Check filter for invalid operations or stack over/under-flow.
1017: */
1018: boolean_t
1019: parse_net_filter(filter, count)
1020: register filter_t *filter;
1021: unsigned int count;
1022: {
1023: register int sp;
1024: register filter_t *fpe = &filter[count];
1025: register filter_t op, arg;
1026:
1027: sp = NET_FILTER_STACK_DEPTH;
1028:
1029: for (; filter < fpe; filter++) {
1030: op = NETF_OP(*filter);
1031: arg = NETF_ARG(*filter);
1032:
1033: switch (arg) {
1034: case NETF_NOPUSH:
1035: break;
1036: case NETF_PUSHZERO:
1037: sp--;
1038: break;
1039: case NETF_PUSHLIT:
1040: filter++;
1041: if (filter >= fpe)
1042: return (FALSE); /* literal value not in filter */
1043: sp--;
1044: break;
1045: case NETF_PUSHIND:
1046: case NETF_PUSHHDRIND:
1047: break;
1048: default:
1049: if (arg >= NETF_PUSHSTK) {
1050: if (arg - NETF_PUSHSTK + sp > NET_FILTER_STACK_DEPTH)
1051: return FALSE;
1052: }
1053: else if (arg >= NETF_PUSHHDR) {
1054: if (arg - NETF_PUSHHDR >=
1055: NET_HDW_HDR_MAX/sizeof(unsigned short))
1056: return FALSE;
1057: }
1058: /* else... cannot check for packet bounds
1059: without packet */
1060: sp--;
1061: break;
1062: }
1063: if (sp < 2) {
1064: return (FALSE); /* stack overflow */
1065: }
1066: if (op == NETF_OP(NETF_NOP))
1067: continue;
1068:
1069: /*
1070: * all non-NOP operators are binary.
1071: */
1072: if (sp > NET_MAX_FILTER-2)
1073: return (FALSE);
1074:
1075: sp++;
1076: switch (op) {
1077: case NETF_OP(NETF_AND):
1078: case NETF_OP(NETF_OR):
1079: case NETF_OP(NETF_XOR):
1080: case NETF_OP(NETF_EQ):
1081: case NETF_OP(NETF_NEQ):
1082: case NETF_OP(NETF_LT):
1083: case NETF_OP(NETF_LE):
1084: case NETF_OP(NETF_GT):
1085: case NETF_OP(NETF_GE):
1086: case NETF_OP(NETF_COR):
1087: case NETF_OP(NETF_CAND):
1088: case NETF_OP(NETF_CNOR):
1089: case NETF_OP(NETF_CNAND):
1090: case NETF_OP(NETF_LSH):
1091: case NETF_OP(NETF_RSH):
1092: case NETF_OP(NETF_ADD):
1093: case NETF_OP(NETF_SUB):
1094: break;
1095: default:
1096: return (FALSE);
1097: }
1098: }
1099: return (TRUE);
1100: }
1101:
1102: /*
1103: * Set a filter for a network interface.
1104: *
1105: * We are given a naked send right for the rcv_port.
1106: * If we are successful, we must consume that right.
1107: */
1108: io_return_t
1109: net_set_filter(ifp, rcv_port, priority, filter, filter_count)
1110: struct ifnet *ifp;
1111: ipc_port_t rcv_port;
1112: int priority;
1113: filter_t *filter;
1114: unsigned int filter_count;
1115: {
1116: int filter_bytes;
1117: bpf_insn_t match;
1118: register net_rcv_port_t infp, my_infp;
1119: net_rcv_port_t nextfp;
1120: net_hash_header_t hhp;
1121: register net_hash_entry_t entp, hash_entp;
1122: net_hash_entry_t *head, nextentp;
1123: queue_entry_t dead_infp, dead_entp;
1124: int i;
1125: int ret, is_new_infp;
1126: io_return_t rval;
1127:
1128: /*
1129: * Check the filter syntax.
1130: */
1131:
1132: filter_bytes = CSPF_BYTES(filter_count);
1133: match = (bpf_insn_t) 0;
1134:
1135: if (filter_count > 0 && filter[0] == NETF_BPF) {
1136: ret = bpf_validate((bpf_insn_t)filter, filter_bytes, &match);
1137: if (!ret)
1138: return (D_INVALID_OPERATION);
1139: } else {
1140: if (!parse_net_filter(filter, filter_count))
1141: return (D_INVALID_OPERATION);
1142: }
1143:
1144: rval = D_SUCCESS; /* default return value */
1145: dead_infp = dead_entp = 0;
1146:
1147: if (match == (bpf_insn_t) 0) {
1148: /*
1149: * If there is no match instruction, we allocate
1150: * a normal packet filter structure.
1151: */
1152: my_infp = (net_rcv_port_t) zalloc(net_rcv_zone);
1153: my_infp->rcv_port = rcv_port;
1154: is_new_infp = TRUE;
1155: } else {
1156: /*
1157: * If there is a match instruction, we assume there will
1158: * multiple session with a common substructure and allocate
1159: * a hash table to deal with them.
1160: */
1161: my_infp = 0;
1162: hash_entp = (net_hash_entry_t) zalloc(net_hash_entry_zone);
1163: is_new_infp = FALSE;
1164: }
1165:
1166: /*
1167: * Look for an existing filter on the same reply port.
1168: * Look for filters with dead ports (for GC).
1169: * Look for a filter with the same code except KEY insns.
1170: */
1171:
1172: simple_lock(&ifp->if_rcv_port_list_lock);
1173:
1174: FILTER_ITERATE(ifp, infp, nextfp)
1175: {
1176: if (infp->rcv_port == MACH_PORT_NULL) {
1177: if (match != 0
1178: && infp->priority == priority
1179: && my_infp == 0
1180: && (infp->filter_end - infp->filter) == filter_count
1181: && bpf_eq((bpf_insn_t)infp->filter,
1182: filter, filter_bytes))
1183: {
1184: my_infp = infp;
1185: }
1186:
1187: for (i = 0; i < NET_HASH_SIZE; i++) {
1188: head = &((net_hash_header_t) infp)->table[i];
1189: if (*head == 0)
1190: continue;
1191:
1192: /*
1193: * Check each hash entry to make sure the
1194: * destination port is still valid. Remove
1195: * any invalid entries.
1196: */
1197: entp = *head;
1198: do {
1199: nextentp = (net_hash_entry_t) entp->he_next;
1200:
1201: /* checked without
1202: ip_lock(entp->rcv_port) */
1203: if (entp->rcv_port == rcv_port
1204: || !IP_VALID(entp->rcv_port)
1205: || !ip_active(entp->rcv_port)) {
1206:
1207: ret = hash_ent_remove (ifp,
1208: (net_hash_header_t)infp,
1209: (my_infp == infp),
1210: head,
1211: entp,
1212: &dead_entp);
1213: if (ret)
1214: goto hash_loop_end;
1215: }
1216:
1217: entp = nextentp;
1218: /* While test checks head since hash_ent_remove
1219: might modify it.
1220: */
1221: } while (*head != 0 && entp != *head);
1222: }
1223: hash_loop_end:
1224: ;
1225:
1226: } else if (infp->rcv_port == rcv_port
1227: || !IP_VALID(infp->rcv_port)
1228: || !ip_active(infp->rcv_port)) {
1229: /* Remove the old filter from list */
1230: remqueue(&ifp->if_rcv_port_list, (queue_entry_t)infp);
1231: ENQUEUE_DEAD(dead_infp, infp);
1232: }
1233: }
1234: FILTER_ITERATE_END
1235:
1236: if (my_infp == 0) {
1237: /* Allocate a dummy infp */
1238: simple_lock(&net_hash_header_lock);
1239: for (i = 0; i < N_NET_HASH; i++) {
1240: if (filter_hash_header[i].n_keys == 0)
1241: break;
1242: }
1243: if (i == N_NET_HASH) {
1244: simple_unlock(&net_hash_header_lock);
1245: simple_unlock(&ifp->if_rcv_port_list_lock);
1246:
1247: ipc_port_release_send(rcv_port);
1248: if (match != 0)
1249: zfree (net_hash_entry_zone, (vm_offset_t)hash_entp);
1250:
1251: rval = D_NO_MEMORY;
1252: goto clean_and_return;
1253: }
1254:
1255: hhp = &filter_hash_header[i];
1256: hhp->n_keys = match->jt;
1257: simple_unlock(&net_hash_header_lock);
1258:
1259: hhp->ref_count = 0;
1260: for (i = 0; i < NET_HASH_SIZE; i++)
1261: hhp->table[i] = 0;
1262:
1263: my_infp = (net_rcv_port_t)hhp;
1264: my_infp->rcv_port = MACH_PORT_NULL; /* indication of dummy */
1265: is_new_infp = TRUE;
1266: }
1267:
1268: if (is_new_infp) {
1269: my_infp->priority = priority;
1270: my_infp->rcv_count = 0;
1271:
1272: /* Copy filter program. */
1273: bcopy ((vm_offset_t)filter, (vm_offset_t)my_infp->filter,
1274: filter_bytes);
1275: my_infp->filter_end =
1276: (filter_t *)((char *)my_infp->filter + filter_bytes);
1277:
1278: if (match == 0) {
1279: my_infp->rcv_qlimit = net_add_q_info(rcv_port);
1280: } else {
1281: my_infp->rcv_qlimit = 0;
1282: }
1283:
1284: /* Insert my_infp according to priority */
1285: queue_iterate(&ifp->if_rcv_port_list, infp, net_rcv_port_t, chain)
1286: if (priority > infp->priority)
1287: break;
1288: enqueue_tail((queue_t)&infp->chain, (queue_entry_t)my_infp);
1289: }
1290:
1291: if (match != 0)
1292: { /* Insert to hash list */
1293: net_hash_entry_t *p;
1294: int j;
1295:
1296: hash_entp->rcv_port = rcv_port;
1297: for (i = 0; i < match->jt; i++) /* match->jt is n_keys */
1298: hash_entp->keys[i] = match[i+1].k;
1299: p = &((net_hash_header_t)my_infp)->
1300: table[bpf_hash(match->jt, hash_entp->keys)];
1301:
1302: /* Not checking for the same key values */
1303: if (*p == 0) {
1304: queue_init ((queue_t) hash_entp);
1305: *p = hash_entp;
1306: } else {
1307: enqueue_tail((queue_t)*p, hash_entp);
1308: }
1309:
1310: ((net_hash_header_t)my_infp)->ref_count++;
1311: hash_entp->rcv_qlimit = net_add_q_info(rcv_port);
1312:
1313: }
1314:
1315: simple_unlock(&ifp->if_rcv_port_list_lock);
1316:
1317: clean_and_return:
1318: /* No locks are held at this point. */
1319:
1320: if (dead_infp != 0)
1321: net_free_dead_infp(dead_infp);
1322: if (dead_entp != 0)
1323: net_free_dead_entp(dead_entp);
1324:
1325: if (rval == D_SUCCESS)
1326: /*
1327: * Make sure now that we have some buffers allocated.
1328: * Before any packets at all have been received, the
1329: * net_thread has never run to allocate buffers.
1330: * The very first packet received will be dropped before
1331: * waking up the net_thread to allocate buffers.
1332: * Now that someone is actually listening for packets,
1333: * we should eagerly allocate so we don't drop any.
1334: */
1335: net_kmsg_more();
1336:
1337: return (rval);
1338: }
1339:
1340: #if 0
1341: /*
1342: * Other network operations
1343: */
1344: io_return_t
1345: net_getstat(ifp, flavor, status, count)
1346: struct ifnet *ifp;
1347: dev_flavor_t flavor;
1348: dev_status_t status; /* pointer to OUT array */
1349: natural_t *count; /* OUT */
1350: {
1351: switch (flavor) {
1352: case NET_STATUS:
1353: {
1354: register struct net_status *ns = (struct net_status *)status;
1355:
1356: if (*count < NET_STATUS_COUNT)
1357: return (D_INVALID_OPERATION);
1358:
1359: ns->min_packet_size = ifp->if_header_size;
1360: ns->max_packet_size = ifp->if_header_size + ifp->if_mtu;
1361: ns->header_format = ifp->if_header_format;
1362: ns->header_size = ifp->if_header_size;
1363: ns->address_size = ifp->if_address_size;
1364: ns->flags = ifp->if_flags;
1365: ns->mapped_size = 0;
1366:
1367: *count = NET_STATUS_COUNT;
1368: break;
1369: }
1370: case NET_ADDRESS:
1371: {
1372: register int addr_byte_count;
1373: register int addr_int_count;
1374: register int i;
1375:
1376: addr_byte_count = ifp->if_address_size;
1377: addr_int_count = (addr_byte_count + (sizeof(int)-1))
1378: / sizeof(int);
1379:
1380: if (*count < addr_int_count)
1381: {
1382: /* XXX debug hack. */
1383: printf ("net_getstat: count: %d, addr_int_count: %d\n",
1384: *count, addr_int_count);
1385: return (D_INVALID_OPERATION);
1386: }
1387:
1388: bcopy((char *)ifp->if_address,
1389: (char *)status,
1390: (unsigned) addr_byte_count);
1391: if (addr_byte_count < addr_int_count * sizeof(int))
1392: bzero((char *)status + addr_byte_count,
1393: (unsigned) (addr_int_count * sizeof(int)
1394: - addr_byte_count));
1395:
1396: for (i = 0; i < addr_int_count; i++) {
1397: register int word;
1398:
1399: word = status[i];
1400: status[i] = htonl(word);
1401: }
1402: *count = addr_int_count;
1403: break;
1404: }
1405: default:
1406: return (D_INVALID_OPERATION);
1407: }
1408: return (D_SUCCESS);
1409: }
1410:
1411: io_return_t
1412: net_write(ifp, start, ior)
1413: register struct ifnet *ifp;
1414: int (*start)();
1415: io_req_t ior;
1416: {
1417: spl_t s;
1418: kern_return_t rc;
1419: boolean_t wait;
1420:
1421: /*
1422: * Reject the write if the interface is down.
1423: */
1424: if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
1425: return (D_DEVICE_DOWN);
1426:
1427: /*
1428: * Reject the write if the packet is too large or too small.
1429: */
1430: if (ior->io_count < ifp->if_header_size ||
1431: ior->io_count > ifp->if_header_size + ifp->if_mtu)
1432: return (D_INVALID_SIZE);
1433:
1434: /*
1435: * Wire down the memory.
1436: */
1437:
1438: rc = device_write_get(ior, &wait);
1439: if (rc != KERN_SUCCESS)
1440: return (rc);
1441:
1442: /*
1443: * Network interfaces can't cope with VM continuations.
1444: * If wait is set, just panic.
1445: */
1446: if (wait) {
1447: panic("net_write: VM continuation");
1448: }
1449:
1450: /*
1451: * Queue the packet on the output queue, and
1452: * start the device.
1453: */
1454: s = splimp();
1455: IF_ENQUEUE(&ifp->if_snd, ior);
1456: (*start)(ifp->if_unit);
1457: splx(s);
1458:
1459: return (D_IO_QUEUED);
1460: }
1461:
1462: #ifdef FIPC
1463: /* This gets called by nefoutput for dev_ops->d_port_death ... */
1464:
1465: io_return_t
1466: net_fwrite(ifp, start, ior)
1467: register struct ifnet *ifp;
1468: int (*start)();
1469: io_req_t ior;
1470: {
1471: spl_t s;
1472: kern_return_t rc;
1473: boolean_t wait;
1474:
1475: /*
1476: * Reject the write if the interface is down.
1477: */
1478: if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
1479: return (D_DEVICE_DOWN);
1480:
1481: /*
1482: * Reject the write if the packet is too large or too small.
1483: */
1484: if (ior->io_count < ifp->if_header_size ||
1485: ior->io_count > ifp->if_header_size + ifp->if_mtu)
1486: return (D_INVALID_SIZE);
1487:
1488: /*
1489: * DON'T Wire down the memory.
1490: */
1491: #if 0
1492: rc = device_write_get(ior, &wait);
1493: if (rc != KERN_SUCCESS)
1494: return (rc);
1495: #endif
1496: /*
1497: * Network interfaces can't cope with VM continuations.
1498: * If wait is set, just panic.
1499: */
1500: /* I'll have to figure out who was setting wait...*/
1501: #if 0
1502: if (wait) {
1503: panic("net_write: VM continuation");
1504: }
1505: #endif
1506: /*
1507: * Queue the packet on the output queue, and
1508: * start the device.
1509: */
1510: s = splimp();
1511: IF_ENQUEUE(&ifp->if_snd, ior);
1512: (*start)(ifp->if_unit);
1513: splx(s);
1514:
1515: return (D_IO_QUEUED);
1516: }
1517: #endif /* FIPC */
1518:
1519: #endif
1520:
1521:
1522: /*
1523: * Initialize the whole package.
1524: */
1525: void
1526: net_io_init()
1527: {
1528: register vm_size_t size;
1529:
1530: size = sizeof(struct net_rcv_port);
1531: net_rcv_zone = zinit(size,
1532: size * 1000,
1533: PAGE_SIZE,
1534: FALSE,
1535: "net_rcv_port");
1536:
1537: size = sizeof(struct net_hash_entry);
1538: net_hash_entry_zone = zinit(size,
1539: size * 100,
1540: PAGE_SIZE,
1541: FALSE,
1542: "net_hash_entry");
1543:
1544: size = ikm_plus_overhead(sizeof(struct net_rcv_msg));
1545: net_kmsg_size = round_page(size);
1546:
1547: /*
1548: * net_kmsg_max caps the number of buffers
1549: * we are willing to allocate. By default,
1550: * we allow for net_queue_free_min plus
1551: * the queue limit for each filter.
1552: * (Added as the filters are added.)
1553: */
1554:
1555: simple_lock_init(&net_kmsg_total_lock);
1556: if (net_kmsg_max == 0)
1557: net_kmsg_max = net_queue_free_min;
1558:
1559: simple_lock_init(&net_queue_free_lock);
1560: ipc_kmsg_queue_init(&net_queue_free);
1561:
1562: simple_lock_init(&net_queue_lock);
1563: ipc_kmsg_queue_init(&net_queue_high);
1564: ipc_kmsg_queue_init(&net_queue_low);
1565:
1566: simple_lock_init(&net_hash_header_lock);
1567: }
1568:
1569:
1570: /* ======== BPF: Berkeley Packet Filter ======== */
1571:
1572: /*-
1573: * Copyright (c) 1990-1991 The Regents of the University of California.
1574: * All rights reserved.
1575: *
1576: * This code is derived from the Stanford/CMU enet packet filter,
1577: * (net/enet.c) distributed as part of 4.3BSD, and code contributed
1578: * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
1579: * Berkeley Laboratory.
1580: *
1581: * Redistribution and use in source and binary forms, with or without
1582: * modification, are permitted provided that the following conditions
1583: * are met:
1584: * 1. Redistributions of source code must retain the above copyright
1585: * notice, this list of conditions and the following disclaimer.
1586: * 2. Redistributions in binary form must reproduce the above copyright
1587: * notice, this list of conditions and the following disclaimer in the
1588: * documentation and/or other materials provided with the distribution.
1589: * 4. Neither the name of the University nor the names of its contributors
1590: * may be used to endorse or promote products derived from this software
1591: * without specific prior written permission.
1592: *
1593: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1594: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1595: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1596: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1597: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1598: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1599: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1600: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1601: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1602: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1603: * SUCH DAMAGE.
1604: *
1605: * @(#)bpf.c 7.5 (Berkeley) 7/15/91
1606: */
1607:
1608: #include <oskit/types.h>
1609:
1610: #if defined(sparc) || defined(mips) || defined(ibm032) || defined(alpha)
1611: #define BPF_ALIGN
1612: #endif
1613:
1614: #ifndef BPF_ALIGN
1615: #define EXTRACT_SHORT(p) ((oskit_u16_t)ntohs(*(oskit_u16_t *)p))
1616: #define EXTRACT_LONG(p) (ntohl(*(oskit_u32_t *)p))
1617: #else
1618: #define EXTRACT_SHORT(p)\
1619: ((oskit_u16_t)\
1620: ((oskit_u16_t)*((u_char *)p+0)<<8|\
1621: (oskit_u16_t)*((u_char *)p+1)<<0))
1622: #define EXTRACT_LONG(p)\
1623: ((oskit_u32_t)*((u_char *)p+0)<<24|\
1624: (oskit_u32_t)*((u_char *)p+1)<<16|\
1625: (oskit_u32_t)*((u_char *)p+2)<<8|\
1626: (oskit_u32_t)*((u_char *)p+3)<<0)
1627: #endif
1628:
1629: /*
1630: * Execute the filter program starting at pc on the packet p
1631: * wirelen is the length of the original packet
1632: * buflen is the amount of data present
1633: */
1634:
1635: int
1636: bpf_do_filter(infp, p, wirelen, header, hash_headpp, entpp)
1637: net_rcv_port_t infp;
1638: char * p; /* packet data */
1639: unsigned int wirelen; /* data_count (in bytes) */
1640: char * header;
1641: net_hash_entry_t **hash_headpp, *entpp; /* out */
1642: {
1643: register bpf_insn_t pc, pc_end;
1644: register unsigned int buflen;
1645:
1646: register oskit_u32_t A, X;
1647: register int k;
1648: oskit_s32_t mem[BPF_MEMWORDS];
1649:
1650: pc = ((bpf_insn_t) infp->filter) + 1;
1651: /* filter[0].code is BPF_BEGIN */
1652: pc_end = (bpf_insn_t)infp->filter_end;
1653: buflen = NET_RCV_MAX;
1654: *entpp = 0; /* default */
1655:
1656: #ifdef lint
1657: A = 0;
1658: X = 0;
1659: #endif
1660: for (; pc < pc_end; ++pc) {
1661: switch (pc->code) {
1662:
1663: default:
1664: #ifdef KERNEL
1665: return 0;
1666: #else
1667: abort();
1668: #endif
1669: case BPF_RET|BPF_K:
1670: if (infp->rcv_port == MACH_PORT_NULL &&
1671: *entpp == 0) {
1672: return 0;
1673: }
1674: return ((u_int)pc->k <= wirelen) ?
1675: pc->k : wirelen;
1676:
1677: case BPF_RET|BPF_A:
1678: if (infp->rcv_port == MACH_PORT_NULL &&
1679: *entpp == 0) {
1680: return 0;
1681: }
1682: return ((u_int)A <= wirelen) ?
1683: A : wirelen;
1684:
1685: case BPF_RET|BPF_MATCH_IMM:
1686: if (bpf_match ((net_hash_header_t)infp, pc->jt, mem,
1687: hash_headpp, entpp)) {
1688: return ((u_int)pc->k <= wirelen) ?
1689: pc->k : wirelen;
1690: }
1691: return 0;
1692:
1693: case BPF_LD|BPF_W|BPF_ABS:
1694: k = pc->k;
1695: if ((u_int)k + sizeof(oskit_s32_t) <= buflen) {
1696: #ifdef BPF_ALIGN
1697: if (((int)(p + k) & 3) != 0)
1698: A = EXTRACT_LONG(&p[k]);
1699: else
1700: #endif
1701: A = ntohl(*(oskit_s32_t *)(p + k));
1702: continue;
1703: }
1704:
1705: k -= BPF_DLBASE;
1706: if ((u_int)k + sizeof(oskit_s32_t) <= NET_HDW_HDR_MAX) {
1707: #ifdef BPF_ALIGN
1708: if (((int)(header + k) & 3) != 0)
1709: A = EXTRACT_LONG(&header[k]);
1710: else
1711: #endif
1712: A = ntohl(*(oskit_s32_t *)(header + k));
1713: continue;
1714: } else {
1715: return 0;
1716: }
1717:
1718: case BPF_LD|BPF_H|BPF_ABS:
1719: k = pc->k;
1720: if ((u_int)k + sizeof(short) <= buflen) {
1721: A = EXTRACT_SHORT(&p[k]);
1722: continue;
1723: }
1724:
1725: k -= BPF_DLBASE;
1726: if ((u_int)k + sizeof(short) <= NET_HDW_HDR_MAX) {
1727: A = EXTRACT_SHORT(&header[k]);
1728: continue;
1729: } else {
1730: return 0;
1731: }
1732:
1733: case BPF_LD|BPF_B|BPF_ABS:
1734: k = pc->k;
1735: if ((u_int)k < buflen) {
1736: A = p[k];
1737: continue;
1738: }
1739:
1740: k -= BPF_DLBASE;
1741: if ((u_int)k < NET_HDW_HDR_MAX) {
1742: A = header[k];
1743: continue;
1744: } else {
1745: return 0;
1746: }
1747:
1748: case BPF_LD|BPF_W|BPF_LEN:
1749: A = wirelen;
1750: continue;
1751:
1752: case BPF_LDX|BPF_W|BPF_LEN:
1753: X = wirelen;
1754: continue;
1755:
1756: case BPF_LD|BPF_W|BPF_IND:
1757: k = X + pc->k;
1758: if (k + sizeof(oskit_s32_t) > buflen)
1759: return 0;
1760: #ifdef BPF_ALIGN
1761: if (((int)(p + k) & 3) != 0)
1762: A = EXTRACT_LONG(&p[k]);
1763: else
1764: #endif
1765: A = ntohl(*(oskit_s32_t *)(p + k));
1766: continue;
1767:
1768: case BPF_LD|BPF_H|BPF_IND:
1769: k = X + pc->k;
1770: if (k + sizeof(short) > buflen)
1771: return 0;
1772: A = EXTRACT_SHORT(&p[k]);
1773: continue;
1774:
1775: case BPF_LD|BPF_B|BPF_IND:
1776: k = X + pc->k;
1777: if (k >= buflen)
1778: return 0;
1779: A = p[k];
1780: continue;
1781:
1782: case BPF_LDX|BPF_MSH|BPF_B:
1783: k = pc->k;
1784: if (k >= buflen)
1785: return 0;
1786: X = (p[pc->k] & 0xf) << 2;
1787: continue;
1788:
1789: case BPF_LD|BPF_IMM:
1790: A = pc->k;
1791: continue;
1792:
1793: case BPF_LDX|BPF_IMM:
1794: X = pc->k;
1795: continue;
1796:
1797: case BPF_LD|BPF_MEM:
1798: A = mem[pc->k];
1799: continue;
1800:
1801: case BPF_LDX|BPF_MEM:
1802: X = mem[pc->k];
1803: continue;
1804:
1805: case BPF_ST:
1806: mem[pc->k] = A;
1807: continue;
1808:
1809: case BPF_STX:
1810: mem[pc->k] = X;
1811: continue;
1812:
1813: case BPF_JMP|BPF_JA:
1814: pc += pc->k;
1815: continue;
1816:
1817: case BPF_JMP|BPF_JGT|BPF_K:
1818: pc += (A > pc->k) ? pc->jt : pc->jf;
1819: continue;
1820:
1821: case BPF_JMP|BPF_JGE|BPF_K:
1822: pc += (A >= pc->k) ? pc->jt : pc->jf;
1823: continue;
1824:
1825: case BPF_JMP|BPF_JEQ|BPF_K:
1826: pc += (A == pc->k) ? pc->jt : pc->jf;
1827: continue;
1828:
1829: case BPF_JMP|BPF_JSET|BPF_K:
1830: pc += (A & pc->k) ? pc->jt : pc->jf;
1831: continue;
1832:
1833: case BPF_JMP|BPF_JGT|BPF_X:
1834: pc += (A > X) ? pc->jt : pc->jf;
1835: continue;
1836:
1837: case BPF_JMP|BPF_JGE|BPF_X:
1838: pc += (A >= X) ? pc->jt : pc->jf;
1839: continue;
1840:
1841: case BPF_JMP|BPF_JEQ|BPF_X:
1842: pc += (A == X) ? pc->jt : pc->jf;
1843: continue;
1844:
1845: case BPF_JMP|BPF_JSET|BPF_X:
1846: pc += (A & X) ? pc->jt : pc->jf;
1847: continue;
1848:
1849: case BPF_ALU|BPF_ADD|BPF_X:
1850: A += X;
1851: continue;
1852:
1853: case BPF_ALU|BPF_SUB|BPF_X:
1854: A -= X;
1855: continue;
1856:
1857: case BPF_ALU|BPF_MUL|BPF_X:
1858: A *= X;
1859: continue;
1860:
1861: case BPF_ALU|BPF_DIV|BPF_X:
1862: if (X == 0)
1863: return 0;
1864: A /= X;
1865: continue;
1866:
1867: case BPF_ALU|BPF_AND|BPF_X:
1868: A &= X;
1869: continue;
1870:
1871: case BPF_ALU|BPF_OR|BPF_X:
1872: A |= X;
1873: continue;
1874:
1875: case BPF_ALU|BPF_LSH|BPF_X:
1876: A <<= X;
1877: continue;
1878:
1879: case BPF_ALU|BPF_RSH|BPF_X:
1880: A >>= X;
1881: continue;
1882:
1883: case BPF_ALU|BPF_ADD|BPF_K:
1884: A += pc->k;
1885: continue;
1886:
1887: case BPF_ALU|BPF_SUB|BPF_K:
1888: A -= pc->k;
1889: continue;
1890:
1891: case BPF_ALU|BPF_MUL|BPF_K:
1892: A *= pc->k;
1893: continue;
1894:
1895: case BPF_ALU|BPF_DIV|BPF_K:
1896: A /= pc->k;
1897: continue;
1898:
1899: case BPF_ALU|BPF_AND|BPF_K:
1900: A &= pc->k;
1901: continue;
1902:
1903: case BPF_ALU|BPF_OR|BPF_K:
1904: A |= pc->k;
1905: continue;
1906:
1907: case BPF_ALU|BPF_LSH|BPF_K:
1908: A <<= pc->k;
1909: continue;
1910:
1911: case BPF_ALU|BPF_RSH|BPF_K:
1912: A >>= pc->k;
1913: continue;
1914:
1915: case BPF_ALU|BPF_NEG:
1916: A = -A;
1917: continue;
1918:
1919: case BPF_MISC|BPF_TAX:
1920: X = A;
1921: continue;
1922:
1923: case BPF_MISC|BPF_TXA:
1924: A = X;
1925: continue;
1926: }
1927: }
1928:
1929: return 0;
1930: }
1931:
1932: /*
1933: * Return 1 if the 'f' is a valid filter program without a MATCH
1934: * instruction. Return 2 if it is a valid filter program with a MATCH
1935: * instruction. Otherwise, return 0.
1936: * The constraints are that each jump be forward and to a valid
1937: * code. The code must terminate with either an accept or reject.
1938: * 'valid' is an array for use by the routine (it must be at least
1939: * 'len' bytes long).
1940: *
1941: * The kernel needs to be able to verify an application's filter code.
1942: * Otherwise, a bogus program could easily crash the system.
1943: */
1944: int
1945: bpf_validate(f, bytes, match)
1946: bpf_insn_t f;
1947: int bytes;
1948: bpf_insn_t *match;
1949: {
1950: register int i, j, len;
1951: register bpf_insn_t p;
1952:
1953: len = BPF_BYTES2LEN(bytes);
1954: /* f[0].code is already checked to be BPF_BEGIN. So skip f[0]. */
1955:
1956: for (i = 1; i < len; ++i) {
1957: /*
1958: * Check that that jumps are forward, and within
1959: * the code block.
1960: */
1961: p = &f[i];
1962: if (BPF_CLASS(p->code) == BPF_JMP) {
1963: register int from = i + 1;
1964:
1965: if (BPF_OP(p->code) == BPF_JA) {
1966: if (from + p->k >= len)
1967: return 0;
1968: }
1969: else if (from + p->jt >= len || from + p->jf >= len)
1970: return 0;
1971: }
1972: /*
1973: * Check that memory operations use valid addresses.
1974: */
1975: if ((BPF_CLASS(p->code) == BPF_ST ||
1976: (BPF_CLASS(p->code) == BPF_LD &&
1977: (p->code & 0xe0) == BPF_MEM)) &&
1978: (p->k >= BPF_MEMWORDS || p->k < 0))
1979: return 0;
1980: /*
1981: * Check for constant division by 0.
1982: */
1983: if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
1984: return 0;
1985: /*
1986: * Check for match instruction.
1987: * Only one match instruction per filter is allowed.
1988: */
1989: if (p->code == (BPF_RET|BPF_MATCH_IMM)) {
1990: if (*match != 0 ||
1991: p->jt == 0 ||
1992: p->jt > N_NET_HASH_KEYS)
1993: return 0;
1994: i += p->jt; /* skip keys */
1995: if (i + 1 > len)
1996: return 0;
1997:
1998: for (j = 1; j <= p->jt; j++) {
1999: if (p[j].code != (BPF_MISC|BPF_KEY))
2000: return 0;
2001: }
2002:
2003: *match = p;
2004: }
2005: }
2006: if (BPF_CLASS(f[len - 1].code) == BPF_RET)
2007: return ((*match == 0) ? 1 : 2);
2008: else
2009: return 0;
2010: }
2011:
2012: int
2013: bpf_eq (f1, f2, bytes)
2014: register bpf_insn_t f1, f2;
2015: register int bytes;
2016: {
2017: register int count;
2018:
2019: count = BPF_BYTES2LEN(bytes);
2020: for (; count--; f1++, f2++) {
2021: if (!BPF_INSN_EQ(f1, f2)) {
2022: if ( f1->code == (BPF_MISC|BPF_KEY) &&
2023: f2->code == (BPF_MISC|BPF_KEY) )
2024: continue;
2025: return FALSE;
2026: }
2027: };
2028: return TRUE;
2029: }
2030:
2031: unsigned int
2032: bpf_hash (n, keys)
2033: register int n;
2034: register unsigned int *keys;
2035: {
2036: register unsigned int hval = 0;
2037:
2038: while (n--) {
2039: hval += *keys++;
2040: }
2041: return (hval % NET_HASH_SIZE);
2042: }
2043:
2044:
2045: int
2046: bpf_match (hash, n_keys, keys, hash_headpp, entpp)
2047: net_hash_header_t hash;
2048: register int n_keys;
2049: register unsigned int *keys;
2050: net_hash_entry_t **hash_headpp, *entpp;
2051: {
2052: register net_hash_entry_t head, entp;
2053: register int i;
2054:
2055: if (n_keys != hash->n_keys)
2056: return FALSE;
2057:
2058: *hash_headpp = &hash->table[bpf_hash(n_keys, keys)];
2059: head = **hash_headpp;
2060:
2061: if (head == 0)
2062: return FALSE;
2063:
2064: HASH_ITERATE (head, entp)
2065: {
2066: for (i = 0; i < n_keys; i++) {
2067: if (keys[i] != entp->keys[i])
2068: break;
2069: }
2070: if (i == n_keys) {
2071: *entpp = entp;
2072: return TRUE;
2073: }
2074: }
2075: HASH_ITERATE_END (head, entp)
2076: return FALSE;
2077: }
2078:
2079:
2080: /*
2081: * Removes a hash entry (ENTP) from its queue (HEAD).
2082: * If the reference count of filter (HP) becomes zero and not USED,
2083: * HP is removed from ifp->if_rcv_port_list and is freed.
2084: */
2085:
2086: int
2087: hash_ent_remove (ifp, hp, used, head, entp, dead_p)
2088: struct ifnet *ifp;
2089: net_hash_header_t hp;
2090: int used;
2091: net_hash_entry_t *head, entp;
2092: queue_entry_t *dead_p;
2093: {
2094: hp->ref_count--;
2095:
2096: if (*head == entp) {
2097:
2098: if (queue_empty((queue_t) entp)) {
2099: *head = 0;
2100: ENQUEUE_DEAD(*dead_p, entp);
2101: if (hp->ref_count == 0 && !used) {
2102: remqueue((queue_t) &ifp->if_rcv_port_list,
2103: (queue_entry_t)hp);
2104: hp->n_keys = 0;
2105: return TRUE;
2106: }
2107: return FALSE;
2108: } else {
2109: *head = (net_hash_entry_t)queue_next((queue_t) entp);
2110: }
2111: }
2112:
2113: remqueue((queue_t)*head, (queue_entry_t)entp);
2114: ENQUEUE_DEAD(*dead_p, entp);
2115: return FALSE;
2116: }
2117:
2118: int
2119: net_add_q_info (rcv_port)
2120: ipc_port_t rcv_port;
2121: {
2122: mach_port_msgcount_t qlimit = 0;
2123:
2124: /*
2125: * We use a new port, so increase net_queue_free_min
2126: * and net_kmsg_max to allow for more queued messages.
2127: */
2128:
2129: if (IP_VALID(rcv_port)) {
2130: ip_lock(rcv_port);
2131: if (ip_active(rcv_port))
2132: qlimit = rcv_port->ip_qlimit;
2133: ip_unlock(rcv_port);
2134: }
2135:
2136: simple_lock(&net_kmsg_total_lock);
2137: net_queue_free_min++;
2138: net_kmsg_max += qlimit + 1;
2139: simple_unlock(&net_kmsg_total_lock);
2140:
2141: return (int)qlimit;
2142: }
2143:
2144: net_del_q_info (qlimit)
2145: int qlimit;
2146: {
2147: simple_lock(&net_kmsg_total_lock);
2148: net_queue_free_min--;
2149: net_kmsg_max -= qlimit + 1;
2150: simple_unlock(&net_kmsg_total_lock);
2151: }
2152:
2153:
2154: /*
2155: * net_free_dead_infp (dead_infp)
2156: * queue_entry_t dead_infp; list of dead net_rcv_port_t.
2157: *
2158: * Deallocates dead net_rcv_port_t.
2159: * No locks should be held when called.
2160: */
2161: net_free_dead_infp (dead_infp)
2162: queue_entry_t dead_infp;
2163: {
2164: register net_rcv_port_t infp, nextfp;
2165:
2166: for (infp = (net_rcv_port_t) dead_infp; infp != 0; infp = nextfp)
2167: {
2168: nextfp = (net_rcv_port_t) queue_next(&infp->chain);
2169: ipc_port_release_send(infp->rcv_port);
2170: net_del_q_info(infp->rcv_qlimit);
2171: zfree(net_rcv_zone, (vm_offset_t) infp);
2172: }
2173: }
2174:
2175: /*
2176: * net_free_dead_entp (dead_entp)
2177: * queue_entry_t dead_entp; list of dead net_hash_entry_t.
2178: *
2179: * Deallocates dead net_hash_entry_t.
2180: * No locks should be held when called.
2181: */
2182: net_free_dead_entp (dead_entp)
2183: queue_entry_t dead_entp;
2184: {
2185: register net_hash_entry_t entp, nextentp;
2186:
2187: for (entp = (net_hash_entry_t)dead_entp; entp != 0; entp = nextentp)
2188: {
2189: nextentp = (net_hash_entry_t) queue_next(&entp->chain);
2190:
2191: ipc_port_release_send(entp->rcv_port);
2192: net_del_q_info(entp->rcv_qlimit);
2193: zfree(net_hash_entry_zone, (vm_offset_t) entp);
2194: }
2195: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.