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 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright (c) 2016 by Delphix. All rights reserved.
26 */
27
28 /*
29 * Copyright (c) 2016, Joyent, Inc. All rights reserved.
30 */
31
32 /*
33 * The ipnet device defined here provides access to packets at the IP layer. To
34 * provide access to packets at this layer it registers a callback function in
35 * the ip module and when there are open instances of the device ip will pass
36 * packets into the device. Packets from ip are passed on the input, output and
37 * loopback paths. Internally the module returns to ip as soon as possible by
38 * deferring processing using a taskq.
39 *
40 * Management of the devices in /dev/ipnet/ is handled by the devname
41 * filesystem and use of the neti interfaces. This module registers for NIC
42 * events using the neti framework so that when IP interfaces are bought up,
43 * taken down etc. the ipnet module is notified and its view of the interfaces
44 * configured on the system adjusted. On attach, the module gets an initial
45 * view of the system again using the neti framework but as it has already
46 * registered for IP interface events, it is still up-to-date with any changes.
47 */
48
49 #include <sys/types.h>
2228 if (error != 0)
2229 goto regfail;
2230
2231 error = net_hook_register(ipst->ips_ip6_observe_pr, NH_OBSERVE,
2232 ipnet->ipnet_hook);
2233 if (error != 0) {
2234 (void) net_hook_unregister(ipst->ips_ip4_observe_pr,
2235 NH_OBSERVE, ipnet->ipnet_hook);
2236 goto regfail;
2237 }
2238
2239 *mhandle = (uintptr_t)ipnet;
2240 netstack_rele(ns);
2241
2242 return (0);
2243
2244 regfail:
2245 cmn_err(CE_WARN, "net_hook_register failed: %d", error);
2246 strfree(ipnet->ipnet_hook->h_name);
2247 hook_free(ipnet->ipnet_hook);
2248 netstack_rele(ns);
2249 return (error);
2250 }
2251
2252 void
2253 ipnet_promisc_remove(void *data)
2254 {
2255 ip_stack_t *ipst;
2256 ipnet_t *ipnet;
2257 hook_t *hook;
2258
2259 ipnet = data;
2260 ipst = ipnet->ipnet_ns->netstack_ip;
2261 hook = ipnet->ipnet_hook;
2262
2263 VERIFY(net_hook_unregister(ipst->ips_ip4_observe_pr, NH_OBSERVE,
2264 hook) == 0);
2265
2266 VERIFY(net_hook_unregister(ipst->ips_ip6_observe_pr, NH_OBSERVE,
2267 hook) == 0);
2268
2269 strfree(hook->h_name);
2270
2271 hook_free(hook);
2272
2273 kmem_free(ipnet, sizeof (*ipnet));
2274 }
2275
2276 /*
2277 * arg here comes from the ipnet_t allocated in ipnet_promisc_add.
2278 * An important field from that structure is "ipnet_data" that
2279 * contains the "data" pointer passed into ipnet_promisc_add: it needs
2280 * to be passed back to bpf when we call into ipnet_itap.
2281 *
2282 * ipnet_itap is set by ipnet_set_bpfattach, which in turn is called
2283 * from BPF.
2284 */
2285 /*ARGSUSED*/
2286 static int
2287 ipnet_bpf_bounce(hook_event_token_t token, hook_data_t info, void *arg)
2288 {
2289 hook_pkt_observe_t *hdr;
2290 ipnet_addrp_t src;
2291 ipnet_addrp_t dst;
2292 ipnet_stack_t *ips;
|
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 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright (c) 2016 by Delphix. All rights reserved.
26 */
27
28 /*
29 * Copyright 2021 Joyent, Inc.
30 */
31
32 /*
33 * The ipnet device defined here provides access to packets at the IP layer. To
34 * provide access to packets at this layer it registers a callback function in
35 * the ip module and when there are open instances of the device ip will pass
36 * packets into the device. Packets from ip are passed on the input, output and
37 * loopback paths. Internally the module returns to ip as soon as possible by
38 * deferring processing using a taskq.
39 *
40 * Management of the devices in /dev/ipnet/ is handled by the devname
41 * filesystem and use of the neti interfaces. This module registers for NIC
42 * events using the neti framework so that when IP interfaces are bought up,
43 * taken down etc. the ipnet module is notified and its view of the interfaces
44 * configured on the system adjusted. On attach, the module gets an initial
45 * view of the system again using the neti framework but as it has already
46 * registered for IP interface events, it is still up-to-date with any changes.
47 */
48
49 #include <sys/types.h>
2228 if (error != 0)
2229 goto regfail;
2230
2231 error = net_hook_register(ipst->ips_ip6_observe_pr, NH_OBSERVE,
2232 ipnet->ipnet_hook);
2233 if (error != 0) {
2234 (void) net_hook_unregister(ipst->ips_ip4_observe_pr,
2235 NH_OBSERVE, ipnet->ipnet_hook);
2236 goto regfail;
2237 }
2238
2239 *mhandle = (uintptr_t)ipnet;
2240 netstack_rele(ns);
2241
2242 return (0);
2243
2244 regfail:
2245 cmn_err(CE_WARN, "net_hook_register failed: %d", error);
2246 strfree(ipnet->ipnet_hook->h_name);
2247 hook_free(ipnet->ipnet_hook);
2248 ipnet_leave_allmulti(ifp, ns->netstack_ipnet);
2249 netstack_rele(ns);
2250 return (error);
2251 }
2252
2253 void
2254 ipnet_promisc_remove(void *data)
2255 {
2256 ip_stack_t *ipst;
2257 ipnet_t *ipnet;
2258 hook_t *hook;
2259
2260 ipnet = data;
2261 ipst = ipnet->ipnet_ns->netstack_ip;
2262 hook = ipnet->ipnet_hook;
2263
2264 VERIFY(net_hook_unregister(ipst->ips_ip4_observe_pr, NH_OBSERVE,
2265 hook) == 0);
2266
2267 VERIFY(net_hook_unregister(ipst->ips_ip6_observe_pr, NH_OBSERVE,
2268 hook) == 0);
2269
2270 strfree(hook->h_name);
2271
2272 hook_free(hook);
2273
2274 ipnet_leave_allmulti(ipnet->ipnet_if, ipnet->ipnet_ns->netstack_ipnet);
2275
2276 kmem_free(ipnet, sizeof (*ipnet));
2277 }
2278
2279 /*
2280 * arg here comes from the ipnet_t allocated in ipnet_promisc_add.
2281 * An important field from that structure is "ipnet_data" that
2282 * contains the "data" pointer passed into ipnet_promisc_add: it needs
2283 * to be passed back to bpf when we call into ipnet_itap.
2284 *
2285 * ipnet_itap is set by ipnet_set_bpfattach, which in turn is called
2286 * from BPF.
2287 */
2288 /*ARGSUSED*/
2289 static int
2290 ipnet_bpf_bounce(hook_event_token_t token, hook_data_t info, void *arg)
2291 {
2292 hook_pkt_observe_t *hdr;
2293 ipnet_addrp_t src;
2294 ipnet_addrp_t dst;
2295 ipnet_stack_t *ips;
|