|
|
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: * Incoming packet. Header has already been moved to proper place.
639: * We are already at splimp.
640: */
641: void
642: net_packet(ifp, kmsg, count, priority)
643: register struct ifnet *ifp;
644: register ipc_kmsg_t kmsg;
645: unsigned int count;
646: boolean_t priority;
647: {
648: boolean_t awake;
649:
650: #if NORMA_ETHER
651: if (netipc_net_packet(kmsg, count)) {
652: return;
653: }
1.1.1.2 ! root 654: #endif /* NORMA_ETHER */
1.1 root 655:
656: #if MACH_TTD
657: /*
658: * Do a quick check to see if it is a kernel TTD packet.
659: *
660: * Only check if KernelTTD is enabled, ie. the current
661: * device driver supports TTD, and the bootp succeded.
662: */
663: if (kttd_enabled && kttd_handle_async(kmsg)) {
664: /*
665: * Packet was a valid ttd packet and
666: * doesn't need to be passed up to filter.
667: * The ttd code put the used kmsg buffer
668: * back onto the free list.
669: */
670: if (kttd_debug)
671: printf("**%x**", kttd_async_counter++);
672: return;
673: }
674: #endif /* MACH_TTD */
675:
676: kmsg->ikm_header.msgh_remote_port = (mach_port_t) ifp;
677: net_kmsg(kmsg)->net_rcv_msg_packet_count = count;
678:
679: simple_lock(&net_queue_lock);
680: if (priority) {
681: ipc_kmsg_enqueue(&net_queue_high, kmsg);
682: if (++net_queue_high_size > net_queue_high_max)
683: net_queue_high_max = net_queue_high_size;
684: } else {
685: ipc_kmsg_enqueue(&net_queue_low, kmsg);
686: if (++net_queue_low_size > net_queue_low_max)
687: net_queue_low_max = net_queue_low_size;
688: }
689: /*
690: * If the network thread is awake, then we don't
691: * need to take an AST, because the thread will
692: * deliver the packet.
693: */
694: awake = net_thread_awake;
695: simple_unlock(&net_queue_lock);
696:
697: if (!awake) {
698: spl_t s = splsched();
699: ast_on(cpu_number(), AST_NETWORK);
700: (void) splx(s);
701: }
702: }
703:
704: int net_filter_queue_reorder = 0; /* non-zero to enable reordering */
705:
706: /*
707: * Run a packet through the filters, returning a list of messages.
708: * We are *not* called at interrupt level.
709: */
710: void
711: net_filter(kmsg, send_list)
712: register ipc_kmsg_t kmsg;
713: ipc_kmsg_queue_t send_list;
714: {
715: register struct ifnet *ifp;
716: register net_rcv_port_t infp, nextfp;
717: register ipc_kmsg_t new_kmsg;
718:
719: net_hash_entry_t entp, *hash_headp;
720: ipc_port_t dest;
721: queue_entry_t dead_infp = (queue_entry_t) 0;
722: queue_entry_t dead_entp = (queue_entry_t) 0;
723: unsigned int ret_count;
724:
725: int count = net_kmsg(kmsg)->net_rcv_msg_packet_count;
726: ifp = (struct ifnet *) kmsg->ikm_header.msgh_remote_port;
727: ipc_kmsg_queue_init(send_list);
728:
729: /*
730: * Unfortunately we can't allocate or deallocate memory
731: * while holding this lock. And we can't drop the lock
732: * while examining the filter list.
733: */
734: simple_lock(&ifp->if_rcv_port_list_lock);
735: FILTER_ITERATE(ifp, infp, nextfp)
736: {
737: entp = (net_hash_entry_t) 0;
738: if (infp->filter[0] == NETF_BPF) {
739: ret_count = bpf_do_filter(infp, net_kmsg(kmsg)->packet, count,
740: net_kmsg(kmsg)->header,
741: &hash_headp, &entp);
742: if (entp == (net_hash_entry_t) 0)
743: dest = infp->rcv_port;
744: else
745: dest = entp->rcv_port;
746: } else {
747: ret_count = net_do_filter(infp, net_kmsg(kmsg)->packet, count,
748: net_kmsg(kmsg)->header);
749: if (ret_count)
750: ret_count = count;
751: dest = infp->rcv_port;
752: }
753:
754: if (ret_count) {
755:
756: /*
757: * Make a send right for the destination.
758: */
759:
760: dest = ipc_port_copy_send(dest);
761: if (!IP_VALID(dest)) {
762: /*
763: * This filter is dead. We remove it from the
764: * filter list and set it aside for deallocation.
765: */
766:
767: if (entp == (net_hash_entry_t) 0) {
768: queue_remove(&ifp->if_rcv_port_list, infp,
769: net_rcv_port_t, chain);
770: ENQUEUE_DEAD(dead_infp, infp);
771: continue;
772: } else {
773: hash_ent_remove (ifp,
774: (net_hash_header_t)infp,
775: FALSE, /* no longer used */
776: hash_headp,
777: entp,
778: &dead_entp);
779: continue;
780: }
781: }
782:
783: /*
784: * Deliver copy of packet to this channel.
785: */
786: if (ipc_kmsg_queue_empty(send_list)) {
787: /*
788: * Only receiver, so far
789: */
790: new_kmsg = kmsg;
791: } else {
792: /*
793: * Other receivers - must allocate message and copy.
794: */
795: new_kmsg = net_kmsg_get();
796: if (new_kmsg == IKM_NULL) {
797: ipc_port_release_send(dest);
798: break;
799: }
800:
801: bcopy(
802: net_kmsg(kmsg)->packet,
803: net_kmsg(new_kmsg)->packet,
804: ret_count);
805: bcopy(
806: net_kmsg(kmsg)->header,
807: net_kmsg(new_kmsg)->header,
808: NET_HDW_HDR_MAX);
809: }
810: net_kmsg(new_kmsg)->net_rcv_msg_packet_count = ret_count;
811: new_kmsg->ikm_header.msgh_remote_port = (mach_port_t) dest;
812: ipc_kmsg_enqueue(send_list, new_kmsg);
813:
814: {
815: register net_rcv_port_t prevfp;
816: int rcount = ++infp->rcv_count;
817:
818: /*
819: * See if ordering of filters is wrong
820: */
821: if (infp->priority >= NET_HI_PRI) {
822: prevfp = (net_rcv_port_t) queue_prev(&infp->chain);
823: /*
824: * If infp is not the first element on the queue,
825: * and the previous element is at equal priority
826: * but has a lower count, then promote infp to
827: * be in front of prevfp.
828: */
829: if ((queue_t)prevfp != &ifp->if_rcv_port_list &&
830: infp->priority == prevfp->priority) {
831: /*
832: * Threshold difference to prevent thrashing
833: */
834: if (net_filter_queue_reorder
835: && (100 + prevfp->rcv_count < rcount))
836: reorder_queue(&prevfp->chain, &infp->chain);
837: }
838: /*
839: * High-priority filter -> no more deliveries
840: */
841: break;
842: }
843: }
844: }
845: }
846: FILTER_ITERATE_END
847:
848: simple_unlock(&ifp->if_rcv_port_list_lock);
849:
850: /*
851: * Deallocate dead filters.
852: */
853: if (dead_infp != 0)
854: net_free_dead_infp(dead_infp);
855: if (dead_entp != 0)
856: net_free_dead_entp(dead_entp);
857:
858: if (ipc_kmsg_queue_empty(send_list)) {
859: /* Not sent - recycle */
860: net_kmsg_put(kmsg);
861: }
862: }
863:
864: boolean_t
865: net_do_filter(infp, data, data_count, header)
866: net_rcv_port_t infp;
867: char * data;
868: unsigned int data_count;
869: char * header;
870: {
871: int stack[NET_FILTER_STACK_DEPTH+1];
872: register int *sp;
873: register filter_t *fp, *fpe;
874: register unsigned int op, arg;
875:
876: /*
877: * The filter accesses the header and data
878: * as unsigned short words.
879: */
880: data_count /= sizeof(unsigned short);
881:
882: #define data_word ((unsigned short *)data)
883: #define header_word ((unsigned short *)header)
884:
885: sp = &stack[NET_FILTER_STACK_DEPTH];
886: fp = &infp->filter[0];
887: fpe = infp->filter_end;
888:
889: *sp = TRUE;
890:
891: while (fp < fpe) {
892: arg = *fp++;
893: op = NETF_OP(arg);
894: arg = NETF_ARG(arg);
895:
896: switch (arg) {
897: case NETF_NOPUSH:
898: arg = *sp++;
899: break;
900: case NETF_PUSHZERO:
901: arg = 0;
902: break;
903: case NETF_PUSHLIT:
904: arg = *fp++;
905: break;
906: case NETF_PUSHIND:
907: arg = *sp++;
908: if (arg >= data_count)
909: return FALSE;
910: arg = data_word[arg];
911: break;
912: case NETF_PUSHHDRIND:
913: arg = *sp++;
914: if (arg >= NET_HDW_HDR_MAX/sizeof(unsigned short))
915: return FALSE;
916: arg = header_word[arg];
917: break;
918: default:
919: if (arg >= NETF_PUSHSTK) {
920: arg = sp[arg - NETF_PUSHSTK];
921: }
922: else if (arg >= NETF_PUSHHDR) {
923: arg = header_word[arg - NETF_PUSHHDR];
924: }
925: else {
926: arg -= NETF_PUSHWORD;
927: if (arg >= data_count)
928: return FALSE;
929: arg = data_word[arg];
930: }
931: break;
932:
933: }
934: switch (op) {
935: case NETF_OP(NETF_NOP):
936: *--sp = arg;
937: break;
938: case NETF_OP(NETF_AND):
939: *sp &= arg;
940: break;
941: case NETF_OP(NETF_OR):
942: *sp |= arg;
943: break;
944: case NETF_OP(NETF_XOR):
945: *sp ^= arg;
946: break;
947: case NETF_OP(NETF_EQ):
948: *sp = (*sp == arg);
949: break;
950: case NETF_OP(NETF_NEQ):
951: *sp = (*sp != arg);
952: break;
953: case NETF_OP(NETF_LT):
954: *sp = (*sp < arg);
955: break;
956: case NETF_OP(NETF_LE):
957: *sp = (*sp <= arg);
958: break;
959: case NETF_OP(NETF_GT):
960: *sp = (*sp > arg);
961: break;
962: case NETF_OP(NETF_GE):
963: *sp = (*sp >= arg);
964: break;
965: case NETF_OP(NETF_COR):
966: if (*sp++ == arg)
967: return (TRUE);
968: break;
969: case NETF_OP(NETF_CAND):
970: if (*sp++ != arg)
971: return (FALSE);
972: break;
973: case NETF_OP(NETF_CNOR):
974: if (*sp++ == arg)
975: return (FALSE);
976: break;
977: case NETF_OP(NETF_CNAND):
978: if (*sp++ != arg)
979: return (TRUE);
980: break;
981: case NETF_OP(NETF_LSH):
982: *sp <<= arg;
983: break;
984: case NETF_OP(NETF_RSH):
985: *sp >>= arg;
986: break;
987: case NETF_OP(NETF_ADD):
988: *sp += arg;
989: break;
990: case NETF_OP(NETF_SUB):
991: *sp -= arg;
992: break;
993: }
994: }
995: return ((*sp) ? TRUE : FALSE);
996:
997: #undef data_word
998: #undef header_word
999: }
1000:
1001: /*
1002: * Check filter for invalid operations or stack over/under-flow.
1003: */
1004: boolean_t
1005: parse_net_filter(filter, count)
1006: register filter_t *filter;
1007: unsigned int count;
1008: {
1009: register int sp;
1010: register filter_t *fpe = &filter[count];
1011: register filter_t op, arg;
1012:
1013: sp = NET_FILTER_STACK_DEPTH;
1014:
1015: for (; filter < fpe; filter++) {
1016: op = NETF_OP(*filter);
1017: arg = NETF_ARG(*filter);
1018:
1019: switch (arg) {
1020: case NETF_NOPUSH:
1021: break;
1022: case NETF_PUSHZERO:
1023: sp--;
1024: break;
1025: case NETF_PUSHLIT:
1026: filter++;
1027: if (filter >= fpe)
1028: return (FALSE); /* literal value not in filter */
1029: sp--;
1030: break;
1031: case NETF_PUSHIND:
1032: case NETF_PUSHHDRIND:
1033: break;
1034: default:
1035: if (arg >= NETF_PUSHSTK) {
1036: if (arg - NETF_PUSHSTK + sp > NET_FILTER_STACK_DEPTH)
1037: return FALSE;
1038: }
1039: else if (arg >= NETF_PUSHHDR) {
1040: if (arg - NETF_PUSHHDR >=
1041: NET_HDW_HDR_MAX/sizeof(unsigned short))
1042: return FALSE;
1043: }
1044: /* else... cannot check for packet bounds
1045: without packet */
1046: sp--;
1047: break;
1048: }
1049: if (sp < 2) {
1050: return (FALSE); /* stack overflow */
1051: }
1052: if (op == NETF_OP(NETF_NOP))
1053: continue;
1054:
1055: /*
1056: * all non-NOP operators are binary.
1057: */
1058: if (sp > NET_MAX_FILTER-2)
1059: return (FALSE);
1060:
1061: sp++;
1062: switch (op) {
1063: case NETF_OP(NETF_AND):
1064: case NETF_OP(NETF_OR):
1065: case NETF_OP(NETF_XOR):
1066: case NETF_OP(NETF_EQ):
1067: case NETF_OP(NETF_NEQ):
1068: case NETF_OP(NETF_LT):
1069: case NETF_OP(NETF_LE):
1070: case NETF_OP(NETF_GT):
1071: case NETF_OP(NETF_GE):
1072: case NETF_OP(NETF_COR):
1073: case NETF_OP(NETF_CAND):
1074: case NETF_OP(NETF_CNOR):
1075: case NETF_OP(NETF_CNAND):
1076: case NETF_OP(NETF_LSH):
1077: case NETF_OP(NETF_RSH):
1078: case NETF_OP(NETF_ADD):
1079: case NETF_OP(NETF_SUB):
1080: break;
1081: default:
1082: return (FALSE);
1083: }
1084: }
1085: return (TRUE);
1086: }
1087:
1088: /*
1089: * Set a filter for a network interface.
1090: *
1091: * We are given a naked send right for the rcv_port.
1092: * If we are successful, we must consume that right.
1093: */
1094: io_return_t
1095: net_set_filter(ifp, rcv_port, priority, filter, filter_count)
1096: struct ifnet *ifp;
1097: ipc_port_t rcv_port;
1098: int priority;
1099: filter_t *filter;
1100: unsigned int filter_count;
1101: {
1102: int filter_bytes;
1103: bpf_insn_t match;
1104: register net_rcv_port_t infp, my_infp;
1105: net_rcv_port_t nextfp;
1106: net_hash_header_t hhp;
1107: register net_hash_entry_t entp, hash_entp;
1108: net_hash_entry_t *head, nextentp;
1109: queue_entry_t dead_infp, dead_entp;
1110: int i;
1111: int ret, is_new_infp;
1112: io_return_t rval;
1113:
1114: /*
1115: * Check the filter syntax.
1116: */
1117:
1118: filter_bytes = CSPF_BYTES(filter_count);
1119: match = (bpf_insn_t) 0;
1120:
1121: if (filter_count > 0 && filter[0] == NETF_BPF) {
1122: ret = bpf_validate((bpf_insn_t)filter, filter_bytes, &match);
1123: if (!ret)
1124: return (D_INVALID_OPERATION);
1125: } else {
1126: if (!parse_net_filter(filter, filter_count))
1127: return (D_INVALID_OPERATION);
1128: }
1129:
1130: rval = D_SUCCESS; /* default return value */
1131: dead_infp = dead_entp = 0;
1132:
1133: if (match == (bpf_insn_t) 0) {
1134: /*
1135: * If there is no match instruction, we allocate
1136: * a normal packet filter structure.
1137: */
1138: my_infp = (net_rcv_port_t) zalloc(net_rcv_zone);
1139: my_infp->rcv_port = rcv_port;
1140: is_new_infp = TRUE;
1141: } else {
1142: /*
1143: * If there is a match instruction, we assume there will
1144: * multiple session with a common substructure and allocate
1145: * a hash table to deal with them.
1146: */
1147: my_infp = 0;
1148: hash_entp = (net_hash_entry_t) zalloc(net_hash_entry_zone);
1149: is_new_infp = FALSE;
1150: }
1151:
1152: /*
1153: * Look for an existing filter on the same reply port.
1154: * Look for filters with dead ports (for GC).
1155: * Look for a filter with the same code except KEY insns.
1156: */
1157:
1158: simple_lock(&ifp->if_rcv_port_list_lock);
1159:
1160: FILTER_ITERATE(ifp, infp, nextfp)
1161: {
1162: if (infp->rcv_port == MACH_PORT_NULL) {
1163: if (match != 0
1164: && infp->priority == priority
1165: && my_infp == 0
1166: && (infp->filter_end - infp->filter) == filter_count
1167: && bpf_eq((bpf_insn_t)infp->filter,
1168: filter, filter_bytes))
1169: {
1170: my_infp = infp;
1171: }
1172:
1173: for (i = 0; i < NET_HASH_SIZE; i++) {
1174: head = &((net_hash_header_t) infp)->table[i];
1175: if (*head == 0)
1176: continue;
1177:
1178: /*
1179: * Check each hash entry to make sure the
1180: * destination port is still valid. Remove
1181: * any invalid entries.
1182: */
1183: entp = *head;
1184: do {
1185: nextentp = (net_hash_entry_t) entp->he_next;
1186:
1187: /* checked without
1188: ip_lock(entp->rcv_port) */
1189: if (entp->rcv_port == rcv_port
1190: || !IP_VALID(entp->rcv_port)
1191: || !ip_active(entp->rcv_port)) {
1192:
1193: ret = hash_ent_remove (ifp,
1194: (net_hash_header_t)infp,
1195: (my_infp == infp),
1196: head,
1197: entp,
1198: &dead_entp);
1199: if (ret)
1200: goto hash_loop_end;
1201: }
1202:
1203: entp = nextentp;
1204: /* While test checks head since hash_ent_remove
1205: might modify it.
1206: */
1207: } while (*head != 0 && entp != *head);
1208: }
1209: hash_loop_end:
1210: ;
1211:
1212: } else if (infp->rcv_port == rcv_port
1213: || !IP_VALID(infp->rcv_port)
1214: || !ip_active(infp->rcv_port)) {
1215: /* Remove the old filter from list */
1216: remqueue(&ifp->if_rcv_port_list, (queue_entry_t)infp);
1217: ENQUEUE_DEAD(dead_infp, infp);
1218: }
1219: }
1220: FILTER_ITERATE_END
1221:
1222: if (my_infp == 0) {
1223: /* Allocate a dummy infp */
1224: simple_lock(&net_hash_header_lock);
1225: for (i = 0; i < N_NET_HASH; i++) {
1226: if (filter_hash_header[i].n_keys == 0)
1227: break;
1228: }
1229: if (i == N_NET_HASH) {
1230: simple_unlock(&net_hash_header_lock);
1231: simple_unlock(&ifp->if_rcv_port_list_lock);
1232:
1233: ipc_port_release_send(rcv_port);
1234: if (match != 0)
1235: zfree (net_hash_entry_zone, (vm_offset_t)hash_entp);
1236:
1237: rval = D_NO_MEMORY;
1238: goto clean_and_return;
1239: }
1240:
1241: hhp = &filter_hash_header[i];
1242: hhp->n_keys = match->jt;
1243: simple_unlock(&net_hash_header_lock);
1244:
1245: hhp->ref_count = 0;
1246: for (i = 0; i < NET_HASH_SIZE; i++)
1247: hhp->table[i] = 0;
1248:
1249: my_infp = (net_rcv_port_t)hhp;
1250: my_infp->rcv_port = MACH_PORT_NULL; /* indication of dummy */
1251: is_new_infp = TRUE;
1252: }
1253:
1254: if (is_new_infp) {
1255: my_infp->priority = priority;
1256: my_infp->rcv_count = 0;
1257:
1258: /* Copy filter program. */
1259: bcopy ((vm_offset_t)filter, (vm_offset_t)my_infp->filter,
1260: filter_bytes);
1261: my_infp->filter_end =
1262: (filter_t *)((char *)my_infp->filter + filter_bytes);
1263:
1264: if (match == 0) {
1265: my_infp->rcv_qlimit = net_add_q_info(rcv_port);
1266: } else {
1267: my_infp->rcv_qlimit = 0;
1268: }
1269:
1270: /* Insert my_infp according to priority */
1271: queue_iterate(&ifp->if_rcv_port_list, infp, net_rcv_port_t, chain)
1272: if (priority > infp->priority)
1273: break;
1274: enqueue_tail((queue_t)&infp->chain, (queue_entry_t)my_infp);
1275: }
1276:
1277: if (match != 0)
1278: { /* Insert to hash list */
1279: net_hash_entry_t *p;
1280: int j;
1281:
1282: hash_entp->rcv_port = rcv_port;
1283: for (i = 0; i < match->jt; i++) /* match->jt is n_keys */
1284: hash_entp->keys[i] = match[i+1].k;
1285: p = &((net_hash_header_t)my_infp)->
1286: table[bpf_hash(match->jt, hash_entp->keys)];
1287:
1288: /* Not checking for the same key values */
1289: if (*p == 0) {
1290: queue_init ((queue_t) hash_entp);
1291: *p = hash_entp;
1292: } else {
1293: enqueue_tail((queue_t)*p, hash_entp);
1294: }
1295:
1296: ((net_hash_header_t)my_infp)->ref_count++;
1297: hash_entp->rcv_qlimit = net_add_q_info(rcv_port);
1298:
1299: }
1300:
1301: simple_unlock(&ifp->if_rcv_port_list_lock);
1302:
1303: clean_and_return:
1304: /* No locks are held at this point. */
1305:
1306: if (dead_infp != 0)
1307: net_free_dead_infp(dead_infp);
1308: if (dead_entp != 0)
1309: net_free_dead_entp(dead_entp);
1310:
1311: return (rval);
1312: }
1313:
1314: /*
1315: * Other network operations
1316: */
1317: io_return_t
1318: net_getstat(ifp, flavor, status, count)
1319: struct ifnet *ifp;
1320: dev_flavor_t flavor;
1321: dev_status_t status; /* pointer to OUT array */
1322: natural_t *count; /* OUT */
1323: {
1324: switch (flavor) {
1325: case NET_STATUS:
1326: {
1327: register struct net_status *ns = (struct net_status *)status;
1328:
1329: if (*count < NET_STATUS_COUNT)
1330: return (D_INVALID_OPERATION);
1331:
1332: ns->min_packet_size = ifp->if_header_size;
1333: ns->max_packet_size = ifp->if_header_size + ifp->if_mtu;
1334: ns->header_format = ifp->if_header_format;
1335: ns->header_size = ifp->if_header_size;
1336: ns->address_size = ifp->if_address_size;
1337: ns->flags = ifp->if_flags;
1338: ns->mapped_size = 0;
1339:
1340: *count = NET_STATUS_COUNT;
1341: break;
1342: }
1343: case NET_ADDRESS:
1344: {
1345: register int addr_byte_count;
1346: register int addr_int_count;
1347: register int i;
1348:
1349: addr_byte_count = ifp->if_address_size;
1350: addr_int_count = (addr_byte_count + (sizeof(int)-1))
1351: / sizeof(int);
1352:
1353: if (*count < addr_int_count)
1354: {
1355: /* XXX debug hack. */
1356: printf ("net_getstat: count: %d, addr_int_count: %d\n",
1357: *count, addr_int_count);
1358: return (D_INVALID_OPERATION);
1359: }
1360:
1361: bcopy((char *)ifp->if_address,
1362: (char *)status,
1363: (unsigned) addr_byte_count);
1364: if (addr_byte_count < addr_int_count * sizeof(int))
1365: bzero((char *)status + addr_byte_count,
1366: (unsigned) (addr_int_count * sizeof(int)
1367: - addr_byte_count));
1368:
1369: for (i = 0; i < addr_int_count; i++) {
1370: register int word;
1371:
1372: word = status[i];
1373: status[i] = htonl(word);
1374: }
1375: *count = addr_int_count;
1376: break;
1377: }
1378: default:
1379: return (D_INVALID_OPERATION);
1380: }
1381: return (D_SUCCESS);
1382: }
1383:
1384: io_return_t
1385: net_write(ifp, start, ior)
1386: register struct ifnet *ifp;
1387: int (*start)();
1388: io_req_t ior;
1389: {
1390: spl_t s;
1391: kern_return_t rc;
1392: boolean_t wait;
1393:
1394: /*
1395: * Reject the write if the interface is down.
1396: */
1397: if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
1398: return (D_DEVICE_DOWN);
1399:
1400: /*
1401: * Reject the write if the packet is too large or too small.
1402: */
1403: if (ior->io_count < ifp->if_header_size ||
1404: ior->io_count > ifp->if_header_size + ifp->if_mtu)
1405: return (D_INVALID_SIZE);
1406:
1407: /*
1408: * Wire down the memory.
1409: */
1410:
1411: rc = device_write_get(ior, &wait);
1412: if (rc != KERN_SUCCESS)
1413: return (rc);
1414:
1415: /*
1416: * Network interfaces can't cope with VM continuations.
1417: * If wait is set, just panic.
1418: */
1419: if (wait) {
1420: panic("net_write: VM continuation");
1421: }
1422:
1423: /*
1424: * Queue the packet on the output queue, and
1425: * start the device.
1426: */
1427: s = splimp();
1428: IF_ENQUEUE(&ifp->if_snd, ior);
1429: (*start)(ifp->if_unit);
1430: splx(s);
1431:
1432: return (D_IO_QUEUED);
1433: }
1434:
1435: #ifdef FIPC
1436: /* This gets called by nefoutput for dev_ops->d_port_death ... */
1437:
1438: io_return_t
1439: net_fwrite(ifp, start, ior)
1440: register struct ifnet *ifp;
1441: int (*start)();
1442: io_req_t ior;
1443: {
1444: spl_t s;
1445: kern_return_t rc;
1446: boolean_t wait;
1447:
1448: /*
1449: * Reject the write if the interface is down.
1450: */
1451: if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
1452: return (D_DEVICE_DOWN);
1453:
1454: /*
1455: * Reject the write if the packet is too large or too small.
1456: */
1457: if (ior->io_count < ifp->if_header_size ||
1458: ior->io_count > ifp->if_header_size + ifp->if_mtu)
1459: return (D_INVALID_SIZE);
1460:
1461: /*
1462: * DON'T Wire down the memory.
1463: */
1464: #if 0
1465: rc = device_write_get(ior, &wait);
1466: if (rc != KERN_SUCCESS)
1467: return (rc);
1468: #endif
1469: /*
1470: * Network interfaces can't cope with VM continuations.
1471: * If wait is set, just panic.
1472: */
1473: /* I'll have to figure out who was setting wait...*/
1474: #if 0
1475: if (wait) {
1476: panic("net_write: VM continuation");
1477: }
1478: #endif
1479: /*
1480: * Queue the packet on the output queue, and
1481: * start the device.
1482: */
1483: s = splimp();
1484: IF_ENQUEUE(&ifp->if_snd, ior);
1485: (*start)(ifp->if_unit);
1486: splx(s);
1487:
1488: return (D_IO_QUEUED);
1489: }
1490: #endif /* FIPC */
1491:
1492: /*
1493: * Initialize the whole package.
1494: */
1495: void
1496: net_io_init()
1497: {
1498: register vm_size_t size;
1499:
1500: size = sizeof(struct net_rcv_port);
1501: net_rcv_zone = zinit(size,
1502: size * 1000,
1503: PAGE_SIZE,
1504: FALSE,
1505: "net_rcv_port");
1506:
1507: size = sizeof(struct net_hash_entry);
1508: net_hash_entry_zone = zinit(size,
1509: size * 100,
1510: PAGE_SIZE,
1511: FALSE,
1512: "net_hash_entry");
1513:
1514: size = ikm_plus_overhead(sizeof(struct net_rcv_msg));
1515: net_kmsg_size = round_page(size);
1516:
1517: /*
1518: * net_kmsg_max caps the number of buffers
1519: * we are willing to allocate. By default,
1520: * we allow for net_queue_free_min plus
1521: * the queue limit for each filter.
1522: * (Added as the filters are added.)
1523: */
1524:
1525: simple_lock_init(&net_kmsg_total_lock);
1526: if (net_kmsg_max == 0)
1527: net_kmsg_max = net_queue_free_min;
1528:
1529: simple_lock_init(&net_queue_free_lock);
1530: ipc_kmsg_queue_init(&net_queue_free);
1531:
1532: simple_lock_init(&net_queue_lock);
1533: ipc_kmsg_queue_init(&net_queue_high);
1534: ipc_kmsg_queue_init(&net_queue_low);
1535:
1536: simple_lock_init(&net_hash_header_lock);
1537: }
1538:
1539:
1540: /* ======== BPF: Berkeley Packet Filter ======== */
1541:
1542: /*-
1543: * Copyright (c) 1990-1991 The Regents of the University of California.
1544: * All rights reserved.
1545: *
1546: * This code is derived from the Stanford/CMU enet packet filter,
1547: * (net/enet.c) distributed as part of 4.3BSD, and code contributed
1548: * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
1549: * Berkeley Laboratory.
1550: *
1551: * Redistribution and use in source and binary forms, with or without
1552: * modification, are permitted provided that the following conditions
1553: * are met:
1554: * 1. Redistributions of source code must retain the above copyright
1555: * notice, this list of conditions and the following disclaimer.
1556: * 2. Redistributions in binary form must reproduce the above copyright
1557: * notice, this list of conditions and the following disclaimer in the
1558: * documentation and/or other materials provided with the distribution.
1559: * 3. All advertising materials mentioning features or use of this software
1560: * must display the following acknowledgement:
1561: * This product includes software developed by the University of
1562: * California, Berkeley and its contributors.
1563: * 4. Neither the name of the University nor the names of its contributors
1564: * may be used to endorse or promote products derived from this software
1565: * without specific prior written permission.
1566: *
1567: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1568: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1569: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1570: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1571: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1572: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1573: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1574: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1575: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1576: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1577: * SUCH DAMAGE.
1578: *
1579: * @(#)bpf.c 7.5 (Berkeley) 7/15/91
1580: */
1581:
1582: #if defined(sparc) || defined(mips) || defined(ibm032) || defined(alpha)
1583: #define BPF_ALIGN
1584: #endif
1585:
1586: #ifndef BPF_ALIGN
1587: #define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
1588: #define EXTRACT_LONG(p) (ntohl(*(u_long *)p))
1589: #else
1590: #define EXTRACT_SHORT(p)\
1591: ((u_short)\
1592: ((u_short)*((u_char *)p+0)<<8|\
1593: (u_short)*((u_char *)p+1)<<0))
1594: #define EXTRACT_LONG(p)\
1595: ((u_long)*((u_char *)p+0)<<24|\
1596: (u_long)*((u_char *)p+1)<<16|\
1597: (u_long)*((u_char *)p+2)<<8|\
1598: (u_long)*((u_char *)p+3)<<0)
1599: #endif
1600:
1601: /*
1602: * Execute the filter program starting at pc on the packet p
1603: * wirelen is the length of the original packet
1604: * buflen is the amount of data present
1605: */
1606:
1607: int
1608: bpf_do_filter(infp, p, wirelen, header, hash_headpp, entpp)
1609: net_rcv_port_t infp;
1610: char * p; /* packet data */
1611: unsigned int wirelen; /* data_count (in bytes) */
1612: char * header;
1613: net_hash_entry_t **hash_headpp, *entpp; /* out */
1614: {
1615: register bpf_insn_t pc, pc_end;
1616: register unsigned int buflen;
1617:
1618: register unsigned long A, X;
1619: register int k;
1620: long mem[BPF_MEMWORDS];
1621:
1622: pc = ((bpf_insn_t) infp->filter) + 1;
1623: /* filter[0].code is BPF_BEGIN */
1624: pc_end = (bpf_insn_t)infp->filter_end;
1625: buflen = NET_RCV_MAX;
1626: *entpp = 0; /* default */
1627:
1628: #ifdef lint
1629: A = 0;
1630: X = 0;
1631: #endif
1632: for (; pc < pc_end; ++pc) {
1633: switch (pc->code) {
1634:
1635: default:
1636: #ifdef KERNEL
1637: return 0;
1638: #else
1639: abort();
1640: #endif
1641: case BPF_RET|BPF_K:
1642: if (infp->rcv_port == MACH_PORT_NULL &&
1643: *entpp == 0) {
1644: return 0;
1645: }
1646: return ((u_int)pc->k <= wirelen) ?
1647: pc->k : wirelen;
1648:
1649: case BPF_RET|BPF_A:
1650: if (infp->rcv_port == MACH_PORT_NULL &&
1651: *entpp == 0) {
1652: return 0;
1653: }
1654: return ((u_int)A <= wirelen) ?
1655: A : wirelen;
1656:
1657: case BPF_RET|BPF_MATCH_IMM:
1658: if (bpf_match ((net_hash_header_t)infp, pc->jt, mem,
1659: hash_headpp, entpp)) {
1660: return ((u_int)pc->k <= wirelen) ?
1661: pc->k : wirelen;
1662: }
1663: return 0;
1664:
1665: case BPF_LD|BPF_W|BPF_ABS:
1666: k = pc->k;
1667: if ((u_int)k + sizeof(long) <= buflen) {
1668: #ifdef BPF_ALIGN
1669: if (((int)(p + k) & 3) != 0)
1670: A = EXTRACT_LONG(&p[k]);
1671: else
1672: #endif
1673: A = ntohl(*(long *)(p + k));
1674: continue;
1675: }
1676:
1677: k -= BPF_DLBASE;
1678: if ((u_int)k + sizeof(long) <= NET_HDW_HDR_MAX) {
1679: #ifdef BPF_ALIGN
1680: if (((int)(header + k) & 3) != 0)
1681: A = EXTRACT_LONG(&header[k]);
1682: else
1683: #endif
1684: A = ntohl(*(long *)(header + k));
1685: continue;
1686: } else {
1687: return 0;
1688: }
1689:
1690: case BPF_LD|BPF_H|BPF_ABS:
1691: k = pc->k;
1692: if ((u_int)k + sizeof(short) <= buflen) {
1693: A = EXTRACT_SHORT(&p[k]);
1694: continue;
1695: }
1696:
1697: k -= BPF_DLBASE;
1698: if ((u_int)k + sizeof(short) <= NET_HDW_HDR_MAX) {
1699: A = EXTRACT_SHORT(&header[k]);
1700: continue;
1701: } else {
1702: return 0;
1703: }
1704:
1705: case BPF_LD|BPF_B|BPF_ABS:
1706: k = pc->k;
1707: if ((u_int)k < buflen) {
1708: A = p[k];
1709: continue;
1710: }
1711:
1712: k -= BPF_DLBASE;
1713: if ((u_int)k < NET_HDW_HDR_MAX) {
1714: A = header[k];
1715: continue;
1716: } else {
1717: return 0;
1718: }
1719:
1720: case BPF_LD|BPF_W|BPF_LEN:
1721: A = wirelen;
1722: continue;
1723:
1724: case BPF_LDX|BPF_W|BPF_LEN:
1725: X = wirelen;
1726: continue;
1727:
1728: case BPF_LD|BPF_W|BPF_IND:
1729: k = X + pc->k;
1730: if (k + sizeof(long) > buflen)
1731: return 0;
1732: #ifdef BPF_ALIGN
1733: if (((int)(p + k) & 3) != 0)
1734: A = EXTRACT_LONG(&p[k]);
1735: else
1736: #endif
1737: A = ntohl(*(long *)(p + k));
1738: continue;
1739:
1740: case BPF_LD|BPF_H|BPF_IND:
1741: k = X + pc->k;
1742: if (k + sizeof(short) > buflen)
1743: return 0;
1744: A = EXTRACT_SHORT(&p[k]);
1745: continue;
1746:
1747: case BPF_LD|BPF_B|BPF_IND:
1748: k = X + pc->k;
1749: if (k >= buflen)
1750: return 0;
1751: A = p[k];
1752: continue;
1753:
1754: case BPF_LDX|BPF_MSH|BPF_B:
1755: k = pc->k;
1756: if (k >= buflen)
1757: return 0;
1758: X = (p[pc->k] & 0xf) << 2;
1759: continue;
1760:
1761: case BPF_LD|BPF_IMM:
1762: A = pc->k;
1763: continue;
1764:
1765: case BPF_LDX|BPF_IMM:
1766: X = pc->k;
1767: continue;
1768:
1769: case BPF_LD|BPF_MEM:
1770: A = mem[pc->k];
1771: continue;
1772:
1773: case BPF_LDX|BPF_MEM:
1774: X = mem[pc->k];
1775: continue;
1776:
1777: case BPF_ST:
1778: mem[pc->k] = A;
1779: continue;
1780:
1781: case BPF_STX:
1782: mem[pc->k] = X;
1783: continue;
1784:
1785: case BPF_JMP|BPF_JA:
1786: pc += pc->k;
1787: continue;
1788:
1789: case BPF_JMP|BPF_JGT|BPF_K:
1790: pc += (A > pc->k) ? pc->jt : pc->jf;
1791: continue;
1792:
1793: case BPF_JMP|BPF_JGE|BPF_K:
1794: pc += (A >= pc->k) ? pc->jt : pc->jf;
1795: continue;
1796:
1797: case BPF_JMP|BPF_JEQ|BPF_K:
1798: pc += (A == pc->k) ? pc->jt : pc->jf;
1799: continue;
1800:
1801: case BPF_JMP|BPF_JSET|BPF_K:
1802: pc += (A & pc->k) ? pc->jt : pc->jf;
1803: continue;
1804:
1805: case BPF_JMP|BPF_JGT|BPF_X:
1806: pc += (A > X) ? pc->jt : pc->jf;
1807: continue;
1808:
1809: case BPF_JMP|BPF_JGE|BPF_X:
1810: pc += (A >= X) ? pc->jt : pc->jf;
1811: continue;
1812:
1813: case BPF_JMP|BPF_JEQ|BPF_X:
1814: pc += (A == X) ? pc->jt : pc->jf;
1815: continue;
1816:
1817: case BPF_JMP|BPF_JSET|BPF_X:
1818: pc += (A & X) ? pc->jt : pc->jf;
1819: continue;
1820:
1821: case BPF_ALU|BPF_ADD|BPF_X:
1822: A += X;
1823: continue;
1824:
1825: case BPF_ALU|BPF_SUB|BPF_X:
1826: A -= X;
1827: continue;
1828:
1829: case BPF_ALU|BPF_MUL|BPF_X:
1830: A *= X;
1831: continue;
1832:
1833: case BPF_ALU|BPF_DIV|BPF_X:
1834: if (X == 0)
1835: return 0;
1836: A /= X;
1837: continue;
1838:
1839: case BPF_ALU|BPF_AND|BPF_X:
1840: A &= X;
1841: continue;
1842:
1843: case BPF_ALU|BPF_OR|BPF_X:
1844: A |= X;
1845: continue;
1846:
1847: case BPF_ALU|BPF_LSH|BPF_X:
1848: A <<= X;
1849: continue;
1850:
1851: case BPF_ALU|BPF_RSH|BPF_X:
1852: A >>= X;
1853: continue;
1854:
1855: case BPF_ALU|BPF_ADD|BPF_K:
1856: A += pc->k;
1857: continue;
1858:
1859: case BPF_ALU|BPF_SUB|BPF_K:
1860: A -= pc->k;
1861: continue;
1862:
1863: case BPF_ALU|BPF_MUL|BPF_K:
1864: A *= pc->k;
1865: continue;
1866:
1867: case BPF_ALU|BPF_DIV|BPF_K:
1868: A /= pc->k;
1869: continue;
1870:
1871: case BPF_ALU|BPF_AND|BPF_K:
1872: A &= pc->k;
1873: continue;
1874:
1875: case BPF_ALU|BPF_OR|BPF_K:
1876: A |= pc->k;
1877: continue;
1878:
1879: case BPF_ALU|BPF_LSH|BPF_K:
1880: A <<= pc->k;
1881: continue;
1882:
1883: case BPF_ALU|BPF_RSH|BPF_K:
1884: A >>= pc->k;
1885: continue;
1886:
1887: case BPF_ALU|BPF_NEG:
1888: A = -A;
1889: continue;
1890:
1891: case BPF_MISC|BPF_TAX:
1892: X = A;
1893: continue;
1894:
1895: case BPF_MISC|BPF_TXA:
1896: A = X;
1897: continue;
1898: }
1899: }
1900:
1901: return 0;
1902: }
1903:
1904: /*
1905: * Return 1 if the 'f' is a valid filter program without a MATCH
1906: * instruction. Return 2 if it is a valid filter program with a MATCH
1907: * instruction. Otherwise, return 0.
1908: * The constraints are that each jump be forward and to a valid
1909: * code. The code must terminate with either an accept or reject.
1910: * 'valid' is an array for use by the routine (it must be at least
1911: * 'len' bytes long).
1912: *
1913: * The kernel needs to be able to verify an application's filter code.
1914: * Otherwise, a bogus program could easily crash the system.
1915: */
1916: int
1917: bpf_validate(f, bytes, match)
1918: bpf_insn_t f;
1919: int bytes;
1920: bpf_insn_t *match;
1921: {
1922: register int i, j, len;
1923: register bpf_insn_t p;
1924:
1925: len = BPF_BYTES2LEN(bytes);
1926: /* f[0].code is already checked to be BPF_BEGIN. So skip f[0]. */
1927:
1928: for (i = 1; i < len; ++i) {
1929: /*
1930: * Check that that jumps are forward, and within
1931: * the code block.
1932: */
1933: p = &f[i];
1934: if (BPF_CLASS(p->code) == BPF_JMP) {
1935: register int from = i + 1;
1936:
1937: if (BPF_OP(p->code) == BPF_JA) {
1938: if (from + p->k >= len)
1939: return 0;
1940: }
1941: else if (from + p->jt >= len || from + p->jf >= len)
1942: return 0;
1943: }
1944: /*
1945: * Check that memory operations use valid addresses.
1946: */
1947: if ((BPF_CLASS(p->code) == BPF_ST ||
1948: (BPF_CLASS(p->code) == BPF_LD &&
1949: (p->code & 0xe0) == BPF_MEM)) &&
1950: (p->k >= BPF_MEMWORDS || p->k < 0))
1951: return 0;
1952: /*
1953: * Check for constant division by 0.
1954: */
1955: if (p->code == (BPF_ALU|BPF_DIV|BPF_K) && p->k == 0)
1956: return 0;
1957: /*
1958: * Check for match instruction.
1959: * Only one match instruction per filter is allowed.
1960: */
1961: if (p->code == (BPF_RET|BPF_MATCH_IMM)) {
1962: if (*match != 0 ||
1963: p->jt == 0 ||
1964: p->jt > N_NET_HASH_KEYS)
1965: return 0;
1966: i += p->jt; /* skip keys */
1967: if (i + 1 > len)
1968: return 0;
1969:
1970: for (j = 1; j <= p->jt; j++) {
1971: if (p[j].code != (BPF_MISC|BPF_KEY))
1972: return 0;
1973: }
1974:
1975: *match = p;
1976: }
1977: }
1978: if (BPF_CLASS(f[len - 1].code) == BPF_RET)
1979: return ((*match == 0) ? 1 : 2);
1980: else
1981: return 0;
1982: }
1983:
1984: int
1985: bpf_eq (f1, f2, bytes)
1986: register bpf_insn_t f1, f2;
1987: register int bytes;
1988: {
1989: register int count;
1990:
1991: count = BPF_BYTES2LEN(bytes);
1992: for (; count--; f1++, f2++) {
1993: if (!BPF_INSN_EQ(f1, f2)) {
1994: if ( f1->code == (BPF_MISC|BPF_KEY) &&
1995: f2->code == (BPF_MISC|BPF_KEY) )
1996: continue;
1997: return FALSE;
1998: }
1999: };
2000: return TRUE;
2001: }
2002:
2003: unsigned int
2004: bpf_hash (n, keys)
2005: register int n;
2006: register unsigned int *keys;
2007: {
2008: register unsigned int hval = 0;
2009:
2010: while (n--) {
2011: hval += *keys++;
2012: }
2013: return (hval % NET_HASH_SIZE);
2014: }
2015:
2016:
2017: int
2018: bpf_match (hash, n_keys, keys, hash_headpp, entpp)
2019: net_hash_header_t hash;
2020: register int n_keys;
2021: register unsigned int *keys;
2022: net_hash_entry_t **hash_headpp, *entpp;
2023: {
2024: register net_hash_entry_t head, entp;
2025: register int i;
2026:
2027: if (n_keys != hash->n_keys)
2028: return FALSE;
2029:
2030: *hash_headpp = &hash->table[bpf_hash(n_keys, keys)];
2031: head = **hash_headpp;
2032:
2033: if (head == 0)
2034: return FALSE;
2035:
2036: HASH_ITERATE (head, entp)
2037: {
2038: for (i = 0; i < n_keys; i++) {
2039: if (keys[i] != entp->keys[i])
2040: break;
2041: }
2042: if (i == n_keys) {
2043: *entpp = entp;
2044: return TRUE;
2045: }
2046: }
2047: HASH_ITERATE_END (head, entp)
2048: return FALSE;
2049: }
2050:
2051:
2052: /*
2053: * Removes a hash entry (ENTP) from its queue (HEAD).
2054: * If the reference count of filter (HP) becomes zero and not USED,
2055: * HP is removed from ifp->if_rcv_port_list and is freed.
2056: */
2057:
2058: int
2059: hash_ent_remove (ifp, hp, used, head, entp, dead_p)
2060: struct ifnet *ifp;
2061: net_hash_header_t hp;
2062: int used;
2063: net_hash_entry_t *head, entp;
2064: queue_entry_t *dead_p;
2065: {
2066: hp->ref_count--;
2067:
2068: if (*head == entp) {
2069:
2070: if (queue_empty((queue_t) entp)) {
2071: *head = 0;
2072: ENQUEUE_DEAD(*dead_p, entp);
2073: if (hp->ref_count == 0 && !used) {
2074: remqueue((queue_t) &ifp->if_rcv_port_list,
2075: (queue_entry_t)hp);
2076: hp->n_keys = 0;
2077: return TRUE;
2078: }
2079: return FALSE;
2080: } else {
2081: *head = (net_hash_entry_t)queue_next((queue_t) entp);
2082: }
2083: }
2084:
2085: remqueue((queue_t)*head, (queue_entry_t)entp);
2086: ENQUEUE_DEAD(*dead_p, entp);
2087: return FALSE;
2088: }
2089:
2090: int
2091: net_add_q_info (rcv_port)
2092: ipc_port_t rcv_port;
2093: {
2094: mach_port_msgcount_t qlimit = 0;
2095:
2096: /*
2097: * We use a new port, so increase net_queue_free_min
2098: * and net_kmsg_max to allow for more queued messages.
2099: */
2100:
2101: if (IP_VALID(rcv_port)) {
2102: ip_lock(rcv_port);
2103: if (ip_active(rcv_port))
2104: qlimit = rcv_port->ip_qlimit;
2105: ip_unlock(rcv_port);
2106: }
2107:
2108: simple_lock(&net_kmsg_total_lock);
2109: net_queue_free_min++;
2110: net_kmsg_max += qlimit + 1;
2111: simple_unlock(&net_kmsg_total_lock);
2112:
2113: return (int)qlimit;
2114: }
2115:
2116: net_del_q_info (qlimit)
2117: int qlimit;
2118: {
2119: simple_lock(&net_kmsg_total_lock);
2120: net_queue_free_min--;
2121: net_kmsg_max -= qlimit + 1;
2122: simple_unlock(&net_kmsg_total_lock);
2123: }
2124:
2125:
2126: /*
2127: * net_free_dead_infp (dead_infp)
2128: * queue_entry_t dead_infp; list of dead net_rcv_port_t.
2129: *
2130: * Deallocates dead net_rcv_port_t.
2131: * No locks should be held when called.
2132: */
2133: net_free_dead_infp (dead_infp)
2134: queue_entry_t dead_infp;
2135: {
2136: register net_rcv_port_t infp, nextfp;
2137:
2138: for (infp = (net_rcv_port_t) dead_infp; infp != 0; infp = nextfp)
2139: {
2140: nextfp = (net_rcv_port_t) queue_next(&infp->chain);
2141: ipc_port_release_send(infp->rcv_port);
2142: net_del_q_info(infp->rcv_qlimit);
2143: zfree(net_rcv_zone, (vm_offset_t) infp);
2144: }
2145: }
2146:
2147: /*
2148: * net_free_dead_entp (dead_entp)
2149: * queue_entry_t dead_entp; list of dead net_hash_entry_t.
2150: *
2151: * Deallocates dead net_hash_entry_t.
2152: * No locks should be held when called.
2153: */
2154: net_free_dead_entp (dead_entp)
2155: queue_entry_t dead_entp;
2156: {
2157: register net_hash_entry_t entp, nextentp;
2158:
2159: for (entp = (net_hash_entry_t)dead_entp; entp != 0; entp = nextentp)
2160: {
2161: nextentp = (net_hash_entry_t) queue_next(&entp->chain);
2162:
2163: ipc_port_release_send(entp->rcv_port);
2164: net_del_q_info(entp->rcv_qlimit);
2165: zfree(net_hash_entry_zone, (vm_offset_t) entp);
2166: }
2167: }
2168:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.