if_medium.c revision 229970
1/*- 2 * Copyright (c) 2010-2011 Monthadar Al Jaberi, TerraNet AB 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer, 10 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 * 29 * $FreeBSD: head/sys/dev/wtap/if_medium.c 229970 2012-01-11 17:41:14Z adrian $ 30 */ 31#include "if_wtapvar.h" 32#include "if_medium.h" 33 34void 35init_medium(struct wtap_medium *md) 36{ 37 38 DWTAP_PRINTF("%s\n", __func__); 39 STAILQ_INIT(&md->md_pktbuf); 40 mtx_init(&md->md_mtx, "wtap_medium mtx", NULL, MTX_DEF | MTX_RECURSE); 41 42 /* Event handler for sending packets between wtaps */ 43 struct eventhandler *eh = (struct eventhandler *) 44 malloc(sizeof(struct eventhandler), M_WTAP, M_NOWAIT | M_ZERO); 45 eh->tq = taskqueue_create("wtap_tx_taskq", M_NOWAIT | M_ZERO, 46 taskqueue_thread_enqueue, &eh->tq); 47 taskqueue_start_threads(&eh->tq, 1, PI_NET, "%s taskq", "wtap_medium"); 48 md->tx_handler = eh; 49 /* Mark medium closed by default */ 50 md->open = 0; 51} 52 53void 54deinit_medium(struct wtap_medium *md) 55{ 56 57 DWTAP_PRINTF("%s\n", __func__); 58 taskqueue_free(md->tx_handler->tq); 59 free(md->tx_handler, M_WTAP); 60} 61 62int 63medium_transmit(struct wtap_medium *md, int id, struct mbuf*m) 64{ 65 66 mtx_lock(&md->md_mtx); 67 if (md->open == 0){ 68 DWTAP_PRINTF("[%d] dropping m=%p\n", id, m); 69 m_free(m); 70 mtx_unlock(&md->md_mtx); 71 return 0; 72 } 73 74 DWTAP_PRINTF("[%d] transmiting m=%p\n", id, m); 75 struct packet *p = (struct packet *)malloc(sizeof(struct packet), 76 M_WTAP_PACKET, M_ZERO | M_NOWAIT); 77 p->id = id; 78 p->m = m; 79 80 STAILQ_INSERT_TAIL(&md->md_pktbuf, p, pf_list); 81 taskqueue_enqueue(md->tx_handler->tq, &md->tx_handler->proc); 82 mtx_unlock(&md->md_mtx); 83 84 return 0; 85} 86 87struct packet * 88medium_get_next_packet(struct wtap_medium *md) 89{ 90 struct packet *p; 91 92 mtx_lock(&md->md_mtx); 93 p = STAILQ_FIRST(&md->md_pktbuf); 94 if (p == NULL){ 95 mtx_unlock(&md->md_mtx); 96 return NULL; 97 } 98 99 STAILQ_REMOVE_HEAD(&md->md_pktbuf, pf_list); 100 mtx_unlock(&md->md_mtx); 101 return p; 102} 103 104void 105medium_open(struct wtap_medium *md) 106{ 107 108 mtx_lock(&md->md_mtx); 109 md->open = 1; 110 mtx_unlock(&md->md_mtx); 111} 112 113void 114medium_close(struct wtap_medium *md) 115{ 116 117 mtx_lock(&md->md_mtx); 118 md->open = 0; 119 mtx_unlock(&md->md_mtx); 120} 121