Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/bpf/bpf_mod.c
+++ new/usr/src/uts/common/io/bpf/bpf_mod.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 */
26 26
27 27 #include <sys/types.h>
28 28 #include <sys/param.h>
29 29 #include <sys/stat.h>
30 30 #include <sys/errno.h>
31 31 #include <sys/uio.h>
32 32 #include <sys/buf.h>
33 33 #include <sys/modctl.h>
34 34 #include <sys/open.h>
35 35 #include <sys/kmem.h>
36 36 #include <sys/conf.h>
37 37 #include <sys/cmn_err.h>
38 38 #include <sys/cred.h>
39 39 #include <sys/sunddi.h>
40 40 #include <sys/mac_provider.h>
41 41 #include <sys/dls_impl.h>
42 42 #include <inet/ipnet.h>
43 43
44 44 extern int bpfopen(dev_t *devp, int flag, int otyp, cred_t *cred);
45 45 extern int bpfclose(dev_t dev, int flag, int otyp, cred_t *cred);
46 46 extern int bpfread(dev_t dev, struct uio *uio_p, cred_t *cred_p);
47 47 extern int bpfwrite(dev_t dev, struct uio *uio, cred_t *cred);
48 48 extern int bpfchpoll(dev_t, short, int, short *, struct pollhead **);
49 49 extern int bpfioctl(dev_t, int, intptr_t, int, cred_t *, int *);
50 50 extern int bpfilterattach(void);
51 51 extern int bpfilterdetach(void);
52 52
53 53 extern bpf_provider_t bpf_mac;
54 54 extern bpf_provider_t bpf_ipnet;
55 55
56 56 static int bpf_attach(dev_info_t *, ddi_attach_cmd_t);
57 57 static void *bpf_create_inst(const netid_t);
58 58 static void bpf_destroy_inst(const netid_t, void *);
59 59 static int bpf_detach(dev_info_t *, ddi_detach_cmd_t);
60 60 static int bpf_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
61 61 static int bpf_provider_add(bpf_provider_t *);
62 62 static int bpf_provider_remove(bpf_provider_t *);
63 63 static void bpf_shutdown_inst(const netid_t, void *);
64 64
65 65 extern void bpfdetach(uintptr_t);
66 66 extern int bpf_bufsize;
67 67 extern int bpf_maxbufsize;
68 68
69 69 bpf_provider_head_t bpf_providers;
70 70
71 71 static struct cb_ops bpf_cb_ops = {
72 72 bpfopen,
73 73 bpfclose,
74 74 nodev, /* strategy */
75 75 nodev, /* print */
76 76 nodev, /* dump */
77 77 bpfread,
78 78 bpfwrite, /* write */
79 79 bpfioctl, /* ioctl */
80 80 nodev, /* devmap */
81 81 nodev, /* mmap */
82 82 nodev, /* segmap */
83 83 bpfchpoll, /* poll */
84 84 ddi_prop_op,
85 85 NULL,
86 86 D_MTSAFE,
87 87 CB_REV,
88 88 nodev, /* aread */
89 89 nodev, /* awrite */
90 90 };
91 91
92 92 static struct dev_ops bpf_ops = {
93 93 DEVO_REV,
94 94 0,
95 95 bpf_getinfo,
96 96 nulldev,
97 97 nulldev,
98 98 bpf_attach,
↓ open down ↓ |
98 lines elided |
↑ open up ↑ |
99 99 bpf_detach,
100 100 nodev, /* reset */
101 101 &bpf_cb_ops,
102 102 (struct bus_ops *)0
103 103 };
104 104
105 105 extern struct mod_ops mod_driverops;
106 106 static struct modldrv bpfmod = {
107 107 &mod_driverops, "Berkely Packet Filter", &bpf_ops
108 108 };
109 -static struct modlinkage modlink1 = { MODREV_1, &bpfmod, NULL };
109 +static struct modlinkage modlink1 = { MODREV_1, { &bpfmod, NULL } };
110 110
111 111 static dev_info_t *bpf_dev_info = NULL;
112 112 static net_instance_t *bpf_inst = NULL;
113 113
114 114 int
115 115 _init()
116 116 {
117 117 int bpfinst;
118 118
119 119 bpfinst = mod_install(&modlink1);
120 120 return (bpfinst);
121 121 }
122 122
123 123 int
124 124 _fini(void)
125 125 {
126 126 int bpfinst;
127 127
128 128 bpfinst = mod_remove(&modlink1);
129 129 return (bpfinst);
130 130 }
131 131
132 132 int
133 133 _info(struct modinfo *modinfop)
134 134 {
135 135 int bpfinst;
136 136
137 137 bpfinst = mod_info(&modlink1, modinfop);
138 138 return (bpfinst);
139 139 }
140 140
141 141 static int
142 142 bpf_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
143 143 {
144 144
145 145 switch (cmd) {
146 146 case DDI_ATTACH:
147 147 /*
148 148 * Default buffer size from bpf's driver.conf file
149 149 */
150 150 bpf_bufsize = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
151 151 "buf_size", 32 * 1024);
152 152 /*
153 153 * Maximum buffer size from bpf's driver.conf file
154 154 */
155 155 bpf_maxbufsize = ddi_prop_get_int(DDI_DEV_T_ANY, dip, 0,
156 156 "max_buf_size", 16 * 1024 * 1024);
157 157
158 158 if (ddi_create_minor_node(dip, "bpf", S_IFCHR, 0,
159 159 DDI_PSEUDO, 0) == DDI_FAILURE) {
160 160 ddi_remove_minor_node(dip, NULL);
161 161 goto attach_failed;
162 162 }
163 163 bpf_dev_info = dip;
164 164 ddi_report_dev(dip);
165 165
166 166 LIST_INIT(&bpf_providers);
167 167
168 168 if (bpfilterattach() != 0)
169 169 goto attach_failed;
170 170
171 171 ipnet_set_itap(bpf_itap);
172 172 VERIFY(bpf_provider_add(&bpf_ipnet) == 0);
173 173 VERIFY(bpf_provider_add(&bpf_mac) == 0);
174 174
175 175 /*
176 176 * Set up to be notified about zones coming and going
177 177 * so that proper interaction with ipnet is possible.
178 178 */
179 179 bpf_inst = net_instance_alloc(NETINFO_VERSION);
180 180 if (bpf_inst == NULL)
181 181 goto attach_failed;
182 182 bpf_inst->nin_name = "bpf";
183 183 bpf_inst->nin_create = bpf_create_inst;
184 184 bpf_inst->nin_destroy = bpf_destroy_inst;
185 185 bpf_inst->nin_shutdown = bpf_shutdown_inst;
186 186 if (net_instance_register(bpf_inst) != 0) {
187 187 net_instance_free(bpf_inst);
188 188 goto attach_failed;
189 189 }
190 190
191 191 return (DDI_SUCCESS);
192 192 /* NOTREACHED */
193 193 case DDI_RESUME:
194 194 return (DDI_SUCCESS);
195 195 /* NOTREACHED */
196 196 default:
197 197 break;
198 198 }
199 199
200 200 attach_failed:
201 201
202 202 /*
203 203 * Use our own detach routine to toss
204 204 * away any stuff we allocated above.
205 205 */
206 206 (void) bpfilterdetach();
207 207 (void) bpf_detach(dip, DDI_DETACH);
208 208 return (DDI_FAILURE);
209 209 }
210 210
211 211 static int
212 212 bpf_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
213 213 {
214 214 int error;
215 215
216 216 switch (cmd) {
217 217 case DDI_DETACH:
218 218 if (net_instance_unregister(bpf_inst) != 0)
219 219 return (DDI_FAILURE);
220 220 net_instance_free(bpf_inst);
221 221
222 222 ipnet_set_itap(NULL);
223 223 error = bpfilterdetach();
224 224 if (error != 0)
225 225 return (DDI_FAILURE);
226 226 VERIFY(bpf_provider_remove(&bpf_ipnet) == 0);
227 227 VERIFY(bpf_provider_remove(&bpf_mac) == 0);
228 228
229 229 ASSERT(LIST_EMPTY(&bpf_providers));
230 230
231 231 ddi_prop_remove_all(dip);
232 232
233 233 return (DDI_SUCCESS);
234 234 /* NOTREACHED */
235 235 case DDI_SUSPEND:
236 236 case DDI_PM_SUSPEND:
237 237 return (DDI_SUCCESS);
238 238 /* NOTREACHED */
239 239 default:
240 240 break;
241 241 }
242 242 return (DDI_FAILURE);
243 243 }
244 244
245 245 /*ARGSUSED*/
246 246 static int
247 247 bpf_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
248 248 {
249 249 int error = DDI_FAILURE;
250 250
251 251 switch (infocmd) {
252 252 case DDI_INFO_DEVT2DEVINFO:
253 253 *result = bpf_dev_info;
254 254 error = DDI_SUCCESS;
255 255 break;
256 256 case DDI_INFO_DEVT2INSTANCE:
257 257 *result = (void *)0;
258 258 error = DDI_SUCCESS;
259 259 break;
260 260 default:
261 261 break;
262 262 }
263 263 return (error);
264 264 }
265 265
266 266 /*
267 267 * The two functions below work with and manage a list of providers that
268 268 * supply BPF with packets. Their addition and removal is only happens
269 269 * when the bpf module is attaching/detaching, thus there is no race
270 270 * condition to guard against with using locks as the kernel module system
271 271 * takes care of this for us. Similarly, bpf_provider_tickle() is called
272 272 * from bpf_setif, which implies an open file descriptor that would get
273 273 * in the way of detach being active.
274 274 */
275 275 static int
276 276 bpf_provider_add(bpf_provider_t *provider)
277 277 {
278 278 bpf_provider_list_t *bp;
279 279
280 280 LIST_FOREACH(bp, &bpf_providers, bpl_next) {
281 281 if (bp->bpl_what == provider)
282 282 return (EEXIST);
283 283 }
284 284
285 285
286 286 bp = kmem_alloc(sizeof (*bp), KM_SLEEP);
287 287 bp->bpl_what = provider;
288 288 LIST_INSERT_HEAD(&bpf_providers, bp, bpl_next);
289 289
290 290 return (0);
291 291 }
292 292
293 293 static int
294 294 bpf_provider_remove(bpf_provider_t *provider)
295 295 {
296 296 bpf_provider_list_t *bp;
297 297
298 298 LIST_FOREACH(bp, &bpf_providers, bpl_next) {
299 299 if (bp->bpl_what == provider)
300 300 break;
301 301 }
302 302
303 303 if (bp == NULL)
304 304 return (ESRCH);
305 305
306 306 LIST_REMOVE(bp, bpl_next);
307 307
308 308 kmem_free(bp, sizeof (*bp));
309 309
310 310 return (0);
311 311 }
312 312
313 313 /*
314 314 * return a pointer to the structure that holds all of the functions
315 315 * available to be used to support a particular packet provider.
316 316 */
317 317 bpf_provider_t *
318 318 bpf_find_provider_by_id(int who)
319 319 {
320 320 bpf_provider_list_t *b;
321 321
322 322 LIST_FOREACH(b, &bpf_providers, bpl_next) {
323 323 if (b->bpl_what->bpr_unit == who)
324 324 return (b->bpl_what);
325 325 }
326 326
327 327 return (NULL);
328 328 }
329 329
330 330 /*
331 331 * This function is used by bpf_setif() to force an open() to be called on
332 332 * a given device name. If a device has been unloaded by the kernel, but it
333 333 * is still recognised, then calling this function will hopefully cause it
334 334 * to be loaded back into the kernel. When this function is called, it is
335 335 * not known which packet provider the name belongs to so all are tried.
336 336 */
337 337 int
338 338 bpf_provider_tickle(char *name, zoneid_t zone)
339 339 {
340 340 bpf_provider_list_t *bp;
341 341 uintptr_t handle;
342 342 int tickled = 0;
343 343
344 344 LIST_FOREACH(bp, &bpf_providers, bpl_next) {
345 345 handle = 0;
346 346 if (bp->bpl_what->bpr_open(name, &handle, zone) == 0) {
347 347 bp->bpl_what->bpr_close(handle);
348 348 tickled++;
349 349 } else if (bp->bpl_what->bpr_unit == BPR_MAC) {
350 350 /*
351 351 * For mac devices, sometimes the open/close is not
352 352 * enough. In that case, further provocation is
353 353 * attempted by fetching the linkid and trying to
354 354 * use that as the key for open, rather than the
355 355 * name.
356 356 */
357 357 datalink_id_t id;
358 358
359 359 if (bp->bpl_what->bpr_getlinkid(name, &id,
360 360 zone) == 0) {
361 361 if (bp->bpl_what->bpr_open(name, &handle,
362 362 zone) == 0) {
363 363 bp->bpl_what->bpr_close(handle);
364 364 tickled++;
365 365 } else {
366 366 mac_handle_t mh;
367 367
368 368 if (mac_open_by_linkid(id, &mh) == 0) {
369 369 mac_close(mh);
370 370 tickled++;
371 371 }
372 372 }
373 373 }
374 374 }
375 375
376 376 }
377 377
378 378 if (tickled != 0)
379 379 return (EWOULDBLOCK);
380 380
381 381 return (ENXIO);
382 382 }
383 383
384 384 /*
385 385 * The following three functions provide the necessary callbacks into
386 386 * the netinfo API. This API is primarily used to trigger awareness of
387 387 * when a zone is being torn down, allowing BPF to drive IPNET to
388 388 * tell it which interfaces need to go away.
389 389 */
390 390 /*ARGSUSED*/
391 391 static void *
392 392 bpf_create_inst(const netid_t netid)
393 393 {
394 394 /*
395 395 * BPF does not keep any per-instance state, its list of
396 396 * interfaces is global, as is its device hash table.
397 397 */
398 398 return ((void *)bpf_itap);
399 399 }
400 400
401 401 /*ARGSUSED*/
402 402 static void
403 403 bpf_shutdown_inst(const netid_t netid, void *arg)
404 404 {
405 405 }
406 406
407 407 /*ARGSUSED*/
408 408 static void
409 409 bpf_destroy_inst(const netid_t netid, void *arg)
410 410 {
411 411 }
↓ open down ↓ |
292 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX