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 54 /*- 55 * Protocols express ordering constraints and affinity preferences by 56 * implementing one or neither of nh_m2flow and nh_m2cpuid, which are used by 57 * netisr to determine which per-CPU workstream to assign mbufs to. 58 * 59 * The following policies may be used by protocols: 60 * 61 * NETISR_POLICY_SOURCE - netisr should maintain source ordering without 62 * advice from the protocol. netisr will ignore any 63 * flow IDs present on the mbuf for the purposes of 64 * work placement. 65 * 66 * NETISR_POLICY_FLOW - netisr should maintain flow ordering as defined by 67 * the mbuf header flow ID field. If the protocol 68 * implements nh_m2flow, then netisr will query the 69 * protocol in the event that the mbuf doesn't have a 70 * flow ID, falling back on source ordering. 71 * 72 * NETISR_POLICY_CPU - netisr will delegate all work placement decisions to 73 * the protocol, querying nh_m2cpuid for each packet. 74 * 75 * Protocols might make decisions about work placement based on an existing 76 * calculated flow ID on the mbuf, such as one provided in hardware, the 77 * receive interface pointed to by the mbuf (if any), the optional source 78 * identifier passed at some dispatch points, or even parse packet headers to 79 * calculate a flow. Both protocol handlers may return a new mbuf pointer 80 * for the chain, or NULL if the packet proves invalid or m_pullup() fails. 81 * 82 * XXXRW: If we eventually support dynamic reconfiguration, there should be 83 * protocol handlers to notify them of CPU configuration changes so that they 84 * can rebalance work. 85 */ 86 struct mbuf; 87 typedef void netisr_handler_t (struct mbuf *m); 88 typedef struct mbuf *netisr_m2cpuid_t(struct mbuf *m, uintptr_t source, 89 u_int *cpuid); 90 typedef struct mbuf *netisr_m2flow_t(struct mbuf *m, uintptr_t source); 91 92 #define NETISR_POLICY_SOURCE 1 /* Maintain source ordering. */ 93 #define NETISR_POLICY_FLOW 2 /* Maintain flow ordering. */ 94 #define NETISR_POLICY_CPU 3 /* Protocol determines CPU placement. */ 95 96 /* 97 * Data structure describing a protocol handler. 98 */ 99 struct netisr_handler { 100 const char *nh_name; /* Character string protocol name. */ 101 netisr_handler_t *nh_handler; /* Protocol handler. */ 102 netisr_m2flow_t *nh_m2flow; /* Query flow for untagged packet. */ 103 netisr_m2cpuid_t *nh_m2cpuid; /* Query CPU to process mbuf on. */ 104 u_int nh_proto; /* Integer protocol ID. */ 105 u_int nh_qlimit; /* Maximum per-CPU queue depth. */ 106 u_int nh_policy; /* Work placement policy. */ 107 u_int nh_ispare[5]; /* For future use. */ 108 void *nh_pspare[4]; /* For future use. */ 109 }; 110 111 /* 112 * Register, unregister, and other netisr handler management functions. 113 */ 114 void netisr_clearqdrops(const struct netisr_handler *nhp); 115 void netisr_getqdrops(const struct netisr_handler *nhp, 116 u_int64_t *qdropsp); 117 void netisr_getqlimit(const struct netisr_handler *nhp, u_int *qlimitp); 118 void netisr_register(const struct netisr_handler *nhp); 119 int netisr_setqlimit(const struct netisr_handler *nhp, u_int qlimit); 120 void netisr_unregister(const struct netisr_handler *nhp); 121 122 /* 123 * Process a packet destined for a protocol, and attempt direct dispatch. 124 * Supplemental source ordering information can be passed using the _src 125 * variant. 126 */ 127 int netisr_dispatch(u_int proto, struct mbuf *m); 128 int netisr_dispatch_src(u_int proto, uintptr_t source, struct mbuf *m); 129 int netisr_queue(u_int proto, struct mbuf *m); 130 int netisr_queue_src(u_int proto, uintptr_t source, struct mbuf *m); 131 132 /* 133 * Provide a default implementation of "map an ID to a CPU ID". 134 */ 135 u_int netisr_default_flow2cpu(u_int flowid); 136 137 /* 138 * Utility routines to return the number of CPUs participting in netisr, and 139 * to return a mapping from a number to a CPU ID that can be used with the 140 * scheduler. 141 */ 142 u_int netisr_get_cpucount(void); 143 u_int netisr_get_cpuid(u_int cpunumber); 144 145 /* 146 * Interfaces between DEVICE_POLLING and netisr. 147 */ 148 void netisr_sched_poll(void); 149 void netisr_poll(void); 150 void netisr_pollmore(void); 151 152 #endif /* !_KERNEL */ 153 #endif /* !_NET_NETISR_H_ */ 154