xref: /illumos-gate/usr/src/uts/common/io/bpf/bpf_mac.c (revision 0a0e9771ca0211c15f3ac4466b661c145feeb9e4)
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 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <sys/types.h>
28 #include <sys/stream.h>
29 #include <net/bpf.h>
30 #include <net/bpfdesc.h>
31 
32 /*
33  * This file provides the link to the functions required from the mac
34  * module. It is currently in bpf, rather than mac (like ipnet_bpf)
35  * because of the mac/dls split. The bpf driver needs to know when
36  * interfaces appear and disappear and the best place for that is in
37  * dls. Unfortunately all of the other functions used here are found
38  * in the mac module, making it seem ill suited to being at home in
39  * dls. Similarly it has even less purpose being in mac as it is
40  * today.
41  */
42 static int	mac_bpf_open(const char *, uintptr_t *, zoneid_t);
43 static void	mac_bpf_close(uintptr_t);
44 static const char *mac_bpf_name(uintptr_t);
45 static int	mac_bpf_type(uintptr_t);
46 static void	mac_bpf_sdu_get(uintptr_t, uint_t *);
47 static int	mac_bpf_tx(uintptr_t, mblk_t *);
48 static uintptr_t mac_bpf_promisc_add(uintptr_t, int, void *, uintptr_t *, int);
49 static void	mac_bpf_promisc_remove(uintptr_t);
50 static int	mac_bpf_client_open(uintptr_t, uintptr_t *);
51 static void	mac_bpf_client_close(uintptr_t);
52 static const char *mac_bpf_client_name(uintptr_t);
53 static int	mac_bpf_getlinkid(const char *, datalink_id_t *, zoneid_t);
54 
55 bpf_provider_t bpf_mac = {
56 	BPR_MAC,
57 	mac_bpf_open,
58 	mac_bpf_close,
59 	mac_bpf_name,
60 	mac_bpf_type,
61 	mac_bpf_sdu_get,
62 	mac_bpf_tx,
63 	mac_bpf_promisc_add,
64 	mac_bpf_promisc_remove,
65 	mac_bpf_getlinkid,
66 	mac_bpf_client_close,
67 	mac_bpf_client_name,
68 	mac_bpf_client_open
69 };
70 
71 /*ARGSUSED*/
72 static int
73 mac_bpf_open(const char *name, uintptr_t *mhandlep, zoneid_t zoneid)
74 {
75 	return (mac_open(name, (mac_handle_t *)mhandlep));
76 }
77 
78 static void
79 mac_bpf_close(uintptr_t mhandle)
80 {
81 	mac_close((mac_handle_t)mhandle);
82 }
83 
84 static const char *
85 mac_bpf_name(uintptr_t mhandle)
86 {
87 	return (mac_name((mac_handle_t)mhandle));
88 }
89 
90 static int
91 mac_bpf_type(uintptr_t mhandle)
92 {
93 	return (mac_type((mac_handle_t)mhandle));
94 }
95 
96 static void
97 mac_bpf_sdu_get(uintptr_t mhandle, uint_t *mtup)
98 {
99 	mac_sdu_get((mac_handle_t)mhandle, NULL, mtup);
100 }
101 
102 static int
103 mac_bpf_tx(uintptr_t chandle, mblk_t *pkt)
104 {
105 	/*
106 	 * If the mac layer cannot deliver a packet as requested by BPF then
107 	 * simply have the mac layer drop it. BPF isn't interested in doing
108 	 * any amount of retry - that's left to the application.
109 	 */
110 	return (mac_tx((mac_client_handle_t)chandle, pkt, 0,
111 	    MAC_DROP_ON_NO_DESC, NULL));
112 }
113 
114 static uintptr_t
115 mac_bpf_promisc_add(uintptr_t chandle, int how, void *arg, uintptr_t *promisc,
116     int flags)
117 {
118 	return (mac_promisc_add((mac_client_handle_t)chandle, how, bpf_mtap,
119 	    arg, (mac_promisc_handle_t *)promisc, flags));
120 }
121 
122 static void
123 mac_bpf_promisc_remove(uintptr_t phandle)
124 {
125 	mac_promisc_remove((mac_promisc_handle_t)phandle);
126 }
127 
128 static int
129 mac_bpf_client_open(uintptr_t mhandle, uintptr_t *chandlep)
130 {
131 	return (mac_client_open((mac_handle_t)mhandle,
132 	    (mac_client_handle_t *)chandlep,  NULL,
133 	    MAC_OPEN_FLAGS_USE_DATALINK_NAME));
134 }
135 
136 static void
137 mac_bpf_client_close(uintptr_t chandle)
138 {
139 	mac_client_close((mac_client_handle_t)chandle, 0);
140 }
141 
142 static const char *
143 mac_bpf_client_name(uintptr_t chandle)
144 {
145 	return (mac_client_name((mac_client_handle_t)chandle));
146 }
147 
148 /*ARGSUSED*/
149 static int
150 mac_bpf_getlinkid(const char *name, datalink_id_t *idp, zoneid_t zoneid)
151 {
152 	int error;
153 
154 	/*
155 	 * If at first we don't succeed, try again, just in case it is in
156 	 * hiding. The first call requires the datalink management daemon
157 	 * (the authorative source of information about name to id mapping)
158 	 * to be present and answering upcalls, the seond does not.
159 	 */
160 	error = dls_mgmt_get_linkid(name, idp);
161 	if (error != 0)
162 		error = dls_devnet_macname2linkid(name, idp);
163 
164 	return (error);
165 }
166