1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 * 25 * Copyright 2018, Joyent, Inc. 26 */ 27 28 #ifndef _SYS_NETI_H 29 #define _SYS_NETI_H 30 31 #include <netinet/in.h> 32 #include <sys/int_types.h> 33 #include <sys/queue.h> 34 #include <sys/hook_impl.h> 35 #include <sys/netstack.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 struct msgb; /* avoiding sys/stream.h here */ 42 43 #define NETINFO_VERSION 1 44 45 /* 46 * Network hooks framework stack protocol name 47 */ 48 #define NHF_INET "NHF_INET" 49 #define NHF_INET6 "NHF_INET6" 50 #define NHF_ARP "NHF_ARP" 51 #define NHF_VIONA "NHF_VIONA" 52 53 /* 54 * Event identification 55 */ 56 #define NH_PHYSICAL_IN "PHYSICAL_IN" 57 #define NH_PHYSICAL_OUT "PHYSICAL_OUT" 58 #define NH_FORWARDING "FORWARDING" 59 #define NH_LOOPBACK_IN "LOOPBACK_IN" 60 #define NH_LOOPBACK_OUT "LOOPBACK_OUT" 61 #define NH_NIC_EVENTS "NIC_EVENTS" 62 #define NH_OBSERVE "OBSERVING" 63 64 /* 65 * Network NIC hardware checksum capability 66 */ 67 #define NET_HCK_NONE 0x00 68 #define NET_HCK_L3_FULL 0x01 69 #define NET_HCK_L3_PART 0x02 70 #define NET_HCK_L4_FULL 0x10 71 #define NET_HCK_L4_PART 0x20 72 73 #define NET_IS_HCK_L3_FULL(n, x) \ 74 ((net_ispartialchecksum(n, x) & NET_HCK_L3_FULL) == NET_HCK_L3_FULL) 75 #define NET_IS_HCK_L3_PART(n, x) \ 76 ((net_ispartialchecksum(n, x) & NET_HCK_L3_PART) == NET_HCK_L3_PART) 77 #define NET_IS_HCK_L4_FULL(n, x) \ 78 ((net_ispartialchecksum(n, x) & NET_HCK_L4_FULL) == NET_HCK_L4_FULL) 79 #define NET_IS_HCK_L4_PART(n, x) \ 80 ((net_ispartialchecksum(n, x) & NET_HCK_L4_PART) == NET_HCK_L4_PART) 81 #define NET_IS_HCK_L34_FULL(n, x) \ 82 ((net_ispartialchecksum(n, x) & (NET_HCK_L3_FULL|NET_HCK_L4_FULL)) \ 83 == (NET_HCK_L3_FULL | NET_HCK_L4_FULL)) 84 85 typedef uintptr_t phy_if_t; 86 typedef intptr_t lif_if_t; 87 typedef uintptr_t net_ifdata_t; 88 typedef id_t netid_t; 89 90 /* 91 * Netinfo interface specification 92 * 93 * Netinfo provides an extensible and easy to use interface for 94 * accessing data and functionality already embedded within network 95 * code that exists within the kernel. 96 */ 97 typedef enum net_ifaddr { 98 NA_ADDRESS = 1, 99 NA_PEER, 100 NA_BROADCAST, 101 NA_NETMASK 102 } net_ifaddr_t; 103 104 105 typedef enum inject { 106 NI_QUEUE_IN = 1, 107 NI_QUEUE_OUT, 108 NI_DIRECT_OUT 109 } inject_t; 110 111 /* 112 * net_inject - public interface 113 */ 114 typedef struct net_inject { 115 int ni_version; 116 netid_t ni_netid; 117 struct msgb *ni_packet; 118 struct sockaddr_storage ni_addr; 119 phy_if_t ni_physical; 120 } net_inject_t; 121 122 typedef struct net_data *net_handle_t; 123 124 /* 125 * net_protocol_t private interface 126 */ 127 struct net_protocol_s { 128 int netp_version; 129 char *netp_name; 130 int (*netp_getifname)(net_handle_t, phy_if_t, char *, 131 const size_t); 132 int (*netp_getmtu)(net_handle_t, phy_if_t, lif_if_t); 133 int (*netp_getpmtuenabled)(net_handle_t); 134 int (*netp_getlifaddr)(net_handle_t, phy_if_t, lif_if_t, 135 size_t, net_ifaddr_t [], void *); 136 int (*neti_getlifzone)(net_handle_t, phy_if_t, lif_if_t, 137 zoneid_t *); 138 int (*neti_getlifflags)(net_handle_t, phy_if_t, lif_if_t, 139 uint64_t *); 140 phy_if_t (*netp_phygetnext)(net_handle_t, phy_if_t); 141 phy_if_t (*netp_phylookup)(net_handle_t, const char *); 142 lif_if_t (*netp_lifgetnext)(net_handle_t, phy_if_t, lif_if_t); 143 int (*netp_inject)(net_handle_t, inject_t, net_inject_t *); 144 phy_if_t (*netp_routeto)(net_handle_t, struct sockaddr *, 145 struct sockaddr *); 146 int (*netp_ispartialchecksum)(net_handle_t, struct msgb *); 147 int (*netp_isvalidchecksum)(net_handle_t, struct msgb *); 148 }; 149 typedef struct net_protocol_s net_protocol_t; 150 151 152 /* 153 * Private data structures 154 */ 155 struct net_data { 156 LIST_ENTRY(net_data) netd_list; 157 net_protocol_t netd_info; 158 int netd_refcnt; 159 hook_family_int_t *netd_hooks; 160 struct neti_stack_s *netd_stack; 161 int netd_condemned; 162 }; 163 164 165 typedef struct injection_s { 166 net_inject_t inj_data; 167 boolean_t inj_isv6; 168 void * inj_ptr; 169 } injection_t; 170 171 /* 172 * The ipif_id space is [0,MAX) but this interface wants to return [1,MAX] as 173 * a valid range of logical interface numbers so that it can return 0 to mean 174 * "end of list" with net_lifgetnext. Changing ipif_id's to use the [1,MAX] 175 * space is something to be considered for the future, if it is worthwhile. 176 */ 177 #define MAP_IPIF_ID(x) ((x) + 1) 178 #define UNMAP_IPIF_ID(x) (((x) > 0) ? (x) - 1 : (x)) 179 180 struct net_instance_s { 181 int nin_version; 182 char *nin_name; 183 void *(*nin_create)(const netid_t); 184 void (*nin_destroy)(const netid_t, void *); 185 void (*nin_shutdown)(const netid_t, void *); 186 }; 187 typedef struct net_instance_s net_instance_t; 188 189 struct net_instance_int_s { 190 LIST_ENTRY(net_instance_int_s) nini_next; 191 uint_t nini_ref; 192 void *nini_created; 193 struct net_instance_int_s *nini_parent; 194 net_instance_t *nini_instance; 195 hook_notify_t nini_notify; 196 uint32_t nini_flags; 197 kcondvar_t nini_cv; 198 boolean_t nini_condemned; 199 }; 200 typedef struct net_instance_int_s net_instance_int_t; 201 LIST_HEAD(nini_head_s, net_instance_int_s); 202 typedef struct nini_head_s nini_head_t; 203 204 #define nini_version nini_instance->nin_version 205 #define nini_name nini_instance->nin_name 206 #define nini_create nini_instance->nin_create 207 #define nini_destroy nini_instance->nin_destroy 208 #define nini_shutdown nini_instance->nin_shutdown 209 210 /* 211 * netinfo stack instances 212 */ 213 struct neti_stack_s { 214 kmutex_t nts_lock; 215 LIST_ENTRY(neti_stack_s) nts_next; 216 netid_t nts_id; 217 zoneid_t nts_zoneid; 218 netstackid_t nts_stackid; 219 netstack_t *nts_netstack; 220 nini_head_t nts_instances; 221 uint32_t nts_flags; 222 kcondvar_t nts_cv; 223 /* list of net_handle_t */ 224 LIST_HEAD(netd_listhead, net_data) nts_netd_head; 225 }; 226 typedef struct neti_stack_s neti_stack_t; 227 LIST_HEAD(neti_stack_head_s, neti_stack_s); 228 typedef struct neti_stack_head_s neti_stack_head_t; 229 230 /* 231 * Internal functions that need to be exported within the module. 232 */ 233 extern void neti_init(void); 234 extern void neti_fini(void); 235 extern neti_stack_t *net_getnetistackbyid(netid_t); 236 extern netstackid_t net_getnetstackidbynetid(netid_t); 237 extern netid_t net_getnetidbynetstackid(netstackid_t); 238 extern netid_t net_zoneidtonetid(zoneid_t); 239 extern zoneid_t net_getzoneidbynetid(netid_t); 240 241 /* 242 * Functions available for public use. 243 */ 244 extern hook_event_token_t net_event_register(net_handle_t, hook_event_t *); 245 extern int net_event_shutdown(net_handle_t, hook_event_t *); 246 extern int net_event_unregister(net_handle_t, hook_event_t *); 247 extern int net_event_notify_register(net_handle_t, char *, 248 hook_notify_fn_t, void *); 249 extern int net_event_notify_unregister(net_handle_t, char *, hook_notify_fn_t); 250 251 extern int net_family_register(net_handle_t, hook_family_t *); 252 extern int net_family_shutdown(net_handle_t, hook_family_t *); 253 extern int net_family_unregister(net_handle_t, hook_family_t *); 254 255 extern int net_hook_register(net_handle_t, char *, hook_t *); 256 extern int net_hook_unregister(net_handle_t, char *, hook_t *); 257 258 extern int net_inject(net_handle_t, inject_t, net_inject_t *); 259 extern net_inject_t *net_inject_alloc(const int); 260 extern void net_inject_free(net_inject_t *); 261 262 extern net_instance_t *net_instance_alloc(const int version); 263 extern void net_instance_free(net_instance_t *); 264 extern int net_instance_register(net_instance_t *); 265 extern int net_instance_unregister(net_instance_t *); 266 extern int net_instance_notify_register(netid_t, hook_notify_fn_t, void *); 267 extern int net_instance_notify_unregister(netid_t netid, hook_notify_fn_t); 268 269 extern kstat_t *net_kstat_create(netid_t, char *, int, char *, char *, 270 uchar_t, ulong_t, uchar_t); 271 extern void net_kstat_delete(netid_t, kstat_t *); 272 273 extern net_handle_t net_protocol_lookup(netid_t, const char *); 274 extern net_handle_t net_protocol_register(netid_t, const net_protocol_t *); 275 extern int net_protocol_release(net_handle_t); 276 extern int net_protocol_unregister(net_handle_t); 277 extern net_handle_t net_protocol_walk(netid_t, net_handle_t); 278 extern int net_protocol_notify_register(net_handle_t, hook_notify_fn_t, void *); 279 extern int net_protocol_notify_unregister(net_handle_t, hook_notify_fn_t); 280 281 282 extern int net_getifname(net_handle_t, phy_if_t, char *, const size_t); 283 extern int net_getmtu(net_handle_t, phy_if_t, lif_if_t); 284 extern int net_getpmtuenabled(net_handle_t); 285 extern int net_getlifaddr(net_handle_t, phy_if_t, lif_if_t, 286 int, net_ifaddr_t [], void *); 287 extern zoneid_t net_getlifzone(net_handle_t, phy_if_t, lif_if_t, zoneid_t *); 288 extern int net_getlifflags(net_handle_t, phy_if_t, lif_if_t, uint64_t *); 289 extern phy_if_t net_phygetnext(net_handle_t, phy_if_t); 290 extern phy_if_t net_phylookup(net_handle_t, const char *); 291 extern lif_if_t net_lifgetnext(net_handle_t, phy_if_t, lif_if_t); 292 extern phy_if_t net_routeto(net_handle_t, struct sockaddr *, 293 struct sockaddr *); 294 extern int net_ispartialchecksum(net_handle_t, struct msgb *); 295 extern int net_isvalidchecksum(net_handle_t, struct msgb *); 296 297 #ifdef __cplusplus 298 } 299 #endif 300 301 #endif /* _SYS_NETI_H */ 302