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