1 /*- 2 * Copyright (c) 2007-2009 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 29 #ifndef _NET_NETISR_H_ 30 #define _NET_NETISR_H_ 31 #ifdef _KERNEL 32 33 /* 34 * The netisr (network interrupt service routine) provides a deferred 35 * execution evironment in which (generally inbound) network processing can 36 * take place. Protocols register handlers which will be executed directly, 37 * or via deferred dispatch, depending on the circumstances. 38 * 39 * Historically, this was implemented by the BSD software ISR facility; it is 40 * now implemented via a software ithread (SWI). 41 */ 42 #define NETISR_IP 1 43 #define NETISR_IGMP 2 /* IGMPv3 output queue */ 44 #define NETISR_ROUTE 3 /* routing socket */ 45 #define NETISR_AARP 4 /* Appletalk ARP */ 46 #define NETISR_ATALK2 5 /* Appletalk phase 2 */ 47 #define NETISR_ATALK1 6 /* Appletalk phase 1 */ 48 #define NETISR_ARP 7 /* same as AF_LINK */ 49 #define NETISR_IPX 8 /* same as AF_IPX */ 50 #define NETISR_ETHER 9 /* ethernet input */ 51 #define NETISR_IPV6 10 52 #define NETISR_NATM 11 53 #define NETISR_EPAIR 12 /* if_epair(4) */ 54 55 /*- 56 * Protocols express ordering constraints and affinity preferences by 57 * implementing one or neither of nh_m2flow and nh_m2cpuid, which are used by 58 * netisr to determine which per-CPU workstream to assign mbufs to. 59 * 60 * The following policies may be used by protocols: 61 * 62 * NETISR_POLICY_SOURCE - netisr should maintain source ordering without 63 * advice from the protocol. netisr will ignore any 64 * flow IDs present on the mbuf for the purposes of 65 * work placement. 66 * 67 * NETISR_POLICY_FLOW - netisr should maintain flow ordering as defined by 68 * the mbuf header flow ID field. If the protocol 69 * implements nh_m2flow, then netisr will query the 70 * protocol in the event that the mbuf doesn't have a 71 * flow ID, falling back on source ordering. 72 * 73 * NETISR_POLICY_CPU - netisr will delegate all work placement decisions to 74 * the protocol, querying nh_m2cpuid for each packet. 75 * 76 * Protocols might make decisions about work placement based on an existing 77 * calculated flow ID on the mbuf, such as one provided in hardware, the 78 * receive interface pointed to by the mbuf (if any), the optional source 79 * identifier passed at some dispatch points, or even parse packet headers to 80 * calculate a flow. Both protocol handlers may return a new mbuf pointer 81 * for the chain, or NULL if the packet proves invalid or m_pullup() fails. 82 * 83 * XXXRW: If we eventually support dynamic reconfiguration, there should be 84 * protocol handlers to notify them of CPU configuration changes so that they 85 * can rebalance work. 86 */ 87 struct mbuf; 88 typedef void netisr_handler_t (struct mbuf *m); 89 typedef struct mbuf *netisr_m2cpuid_t(struct mbuf *m, uintptr_t source, 90 u_int *cpuid); 91 typedef struct mbuf *netisr_m2flow_t(struct mbuf *m, uintptr_t source); 92 typedef void netisr_drainedcpu_t(u_int cpuid); 93 94 #define NETISR_POLICY_SOURCE 1 /* Maintain source ordering. */ 95 #define NETISR_POLICY_FLOW 2 /* Maintain flow ordering. */ 96 #define NETISR_POLICY_CPU 3 /* Protocol determines CPU placement. */ 97 98 /* 99 * Data structure describing a protocol handler. 100 */ 101 struct netisr_handler { 102 const char *nh_name; /* Character string protocol name. */ 103 netisr_handler_t *nh_handler; /* Protocol handler. */ 104 netisr_m2flow_t *nh_m2flow; /* Query flow for untagged packet. */ 105 netisr_m2cpuid_t *nh_m2cpuid; /* Query CPU to process mbuf on. */ 106 netisr_drainedcpu_t *nh_drainedcpu; /* Callback when drained a queue. */ 107 u_int nh_proto; /* Integer protocol ID. */ 108 u_int nh_qlimit; /* Maximum per-CPU queue depth. */ 109 u_int nh_policy; /* Work placement policy. */ 110 u_int nh_ispare[5]; /* For future use. */ 111 void *nh_pspare[4]; /* For future use. */ 112 }; 113 114 /* 115 * Register, unregister, and other netisr handler management functions. 116 */ 117 void netisr_clearqdrops(const struct netisr_handler *nhp); 118 void netisr_getqdrops(const struct netisr_handler *nhp, 119 u_int64_t *qdropsp); 120 void netisr_getqlimit(const struct netisr_handler *nhp, u_int *qlimitp); 121 void netisr_register(const struct netisr_handler *nhp); 122 int netisr_setqlimit(const struct netisr_handler *nhp, u_int qlimit); 123 void netisr_unregister(const struct netisr_handler *nhp); 124 125 /* 126 * Process a packet destined for a protocol, and attempt direct dispatch. 127 * Supplemental source ordering information can be passed using the _src 128 * variant. 129 */ 130 int netisr_dispatch(u_int proto, struct mbuf *m); 131 int netisr_dispatch_src(u_int proto, uintptr_t source, struct mbuf *m); 132 int netisr_queue(u_int proto, struct mbuf *m); 133 int netisr_queue_src(u_int proto, uintptr_t source, struct mbuf *m); 134 135 /* 136 * Provide a default implementation of "map an ID to a CPU ID". 137 */ 138 u_int netisr_default_flow2cpu(u_int flowid); 139 140 /* 141 * Utility routines to return the number of CPUs participting in netisr, and 142 * to return a mapping from a number to a CPU ID that can be used with the 143 * scheduler. 144 */ 145 u_int netisr_get_cpucount(void); 146 u_int netisr_get_cpuid(u_int cpunumber); 147 148 /* 149 * Interfaces between DEVICE_POLLING and netisr. 150 */ 151 void netisr_sched_poll(void); 152 void netisr_poll(void); 153 void netisr_pollmore(void); 154 155 #endif /* !_KERNEL */ 156 #endif /* !_NET_NETISR_H_ */ 157