xref: /freebsd/sys/dev/wtap/if_medium.c (revision 95ee2897e98f5d444f26ed2334cc7c439f9c16c6)
104d19802SAdrian Chadd /*-
2*4d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
3718cf2ccSPedro F. Giffuni  *
404d19802SAdrian Chadd  * Copyright (c) 2010-2011 Monthadar Al Jaberi, TerraNet AB
504d19802SAdrian Chadd  * All rights reserved.
604d19802SAdrian Chadd  *
704d19802SAdrian Chadd  * Redistribution and use in source and binary forms, with or without
804d19802SAdrian Chadd  * modification, are permitted provided that the following conditions
904d19802SAdrian Chadd  * are met:
1004d19802SAdrian Chadd  * 1. Redistributions of source code must retain the above copyright
1104d19802SAdrian Chadd  *    notice, this list of conditions and the following disclaimer,
1204d19802SAdrian Chadd  *    without modification.
1304d19802SAdrian Chadd  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
1404d19802SAdrian Chadd  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
1504d19802SAdrian Chadd  *    redistribution must be conditioned upon including a substantially
1604d19802SAdrian Chadd  *    similar Disclaimer requirement for further binary redistribution.
1704d19802SAdrian Chadd  *
1804d19802SAdrian Chadd  * NO WARRANTY
1904d19802SAdrian Chadd  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2004d19802SAdrian Chadd  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2104d19802SAdrian Chadd  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
2204d19802SAdrian Chadd  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
2304d19802SAdrian Chadd  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
2404d19802SAdrian Chadd  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2504d19802SAdrian Chadd  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2604d19802SAdrian Chadd  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
2704d19802SAdrian Chadd  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2804d19802SAdrian Chadd  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2904d19802SAdrian Chadd  * THE POSSIBILITY OF SUCH DAMAGES.
3004d19802SAdrian Chadd  */
3104d19802SAdrian Chadd #include "if_wtapvar.h"
3204d19802SAdrian Chadd #include "if_medium.h"
3304d19802SAdrian Chadd 
3404d19802SAdrian Chadd void
init_medium(struct wtap_medium * md)3504d19802SAdrian Chadd init_medium(struct wtap_medium *md)
3604d19802SAdrian Chadd {
3704d19802SAdrian Chadd 
3804d19802SAdrian Chadd 	DWTAP_PRINTF("%s\n", __func__);
3904d19802SAdrian Chadd 	STAILQ_INIT(&md->md_pktbuf);
4004d19802SAdrian Chadd 	mtx_init(&md->md_mtx, "wtap_medium mtx", NULL, MTX_DEF | MTX_RECURSE);
4104d19802SAdrian Chadd 
4204d19802SAdrian Chadd 	/* Event handler for sending packets between wtaps */
4304d19802SAdrian Chadd 	struct eventhandler *eh = (struct eventhandler *)
4404d19802SAdrian Chadd 	    malloc(sizeof(struct eventhandler), M_WTAP, M_NOWAIT | M_ZERO);
4504d19802SAdrian Chadd 	eh->tq = taskqueue_create("wtap_tx_taskq",  M_NOWAIT | M_ZERO,
4604d19802SAdrian Chadd 	    taskqueue_thread_enqueue, &eh->tq);
4704d19802SAdrian Chadd 	taskqueue_start_threads(&eh->tq, 1, PI_NET, "%s taskq", "wtap_medium");
4804d19802SAdrian Chadd 	md->tx_handler = eh;
4904d19802SAdrian Chadd 	/* Mark medium closed by default */
5004d19802SAdrian Chadd 	md->open = 0;
5104d19802SAdrian Chadd }
5204d19802SAdrian Chadd 
5304d19802SAdrian Chadd void
deinit_medium(struct wtap_medium * md)5404d19802SAdrian Chadd deinit_medium(struct wtap_medium *md)
5504d19802SAdrian Chadd {
5604d19802SAdrian Chadd 
5704d19802SAdrian Chadd 	DWTAP_PRINTF("%s\n", __func__);
5804d19802SAdrian Chadd 	taskqueue_free(md->tx_handler->tq);
5904d19802SAdrian Chadd 	free(md->tx_handler, M_WTAP);
6004d19802SAdrian Chadd }
6104d19802SAdrian Chadd 
6204d19802SAdrian Chadd int
medium_transmit(struct wtap_medium * md,int id,struct mbuf * m)6304d19802SAdrian Chadd medium_transmit(struct wtap_medium *md, int id, struct mbuf*m)
6404d19802SAdrian Chadd {
6504d19802SAdrian Chadd 
6604d19802SAdrian Chadd 	mtx_lock(&md->md_mtx);
6704d19802SAdrian Chadd 	if (md->open == 0){
6804d19802SAdrian Chadd 		DWTAP_PRINTF("[%d] dropping m=%p\n", id, m);
6904d19802SAdrian Chadd 		m_free(m);
7004d19802SAdrian Chadd 		mtx_unlock(&md->md_mtx);
7104d19802SAdrian Chadd 		return 0;
7204d19802SAdrian Chadd 	}
7304d19802SAdrian Chadd 
7404d19802SAdrian Chadd 	DWTAP_PRINTF("[%d] transmiting m=%p\n", id, m);
7504d19802SAdrian Chadd 	struct packet *p = (struct packet *)malloc(sizeof(struct packet),
7604d19802SAdrian Chadd 	    M_WTAP_PACKET, M_ZERO | M_NOWAIT);
7704d19802SAdrian Chadd 	p->id = id;
7804d19802SAdrian Chadd 	p->m = m;
7904d19802SAdrian Chadd 
8004d19802SAdrian Chadd 	STAILQ_INSERT_TAIL(&md->md_pktbuf, p, pf_list);
8104d19802SAdrian Chadd 	taskqueue_enqueue(md->tx_handler->tq, &md->tx_handler->proc);
8204d19802SAdrian Chadd 	mtx_unlock(&md->md_mtx);
8304d19802SAdrian Chadd 
8404d19802SAdrian Chadd       return 0;
8504d19802SAdrian Chadd }
8604d19802SAdrian Chadd 
8704d19802SAdrian Chadd struct packet *
medium_get_next_packet(struct wtap_medium * md)8804d19802SAdrian Chadd medium_get_next_packet(struct wtap_medium *md)
8904d19802SAdrian Chadd {
9004d19802SAdrian Chadd 	struct packet *p;
9104d19802SAdrian Chadd 
9204d19802SAdrian Chadd 	mtx_lock(&md->md_mtx);
9304d19802SAdrian Chadd 	p = STAILQ_FIRST(&md->md_pktbuf);
9404d19802SAdrian Chadd 	if (p == NULL){
9504d19802SAdrian Chadd 		mtx_unlock(&md->md_mtx);
9604d19802SAdrian Chadd 		return NULL;
9704d19802SAdrian Chadd 	}
9804d19802SAdrian Chadd 
9904d19802SAdrian Chadd 	STAILQ_REMOVE_HEAD(&md->md_pktbuf, pf_list);
10004d19802SAdrian Chadd 	mtx_unlock(&md->md_mtx);
10104d19802SAdrian Chadd 	return p;
10204d19802SAdrian Chadd }
10304d19802SAdrian Chadd 
10404d19802SAdrian Chadd void
medium_open(struct wtap_medium * md)10504d19802SAdrian Chadd medium_open(struct wtap_medium *md)
10604d19802SAdrian Chadd {
10704d19802SAdrian Chadd 
10804d19802SAdrian Chadd 	mtx_lock(&md->md_mtx);
10904d19802SAdrian Chadd 	md->open = 1;
11004d19802SAdrian Chadd 	mtx_unlock(&md->md_mtx);
11104d19802SAdrian Chadd }
11204d19802SAdrian Chadd 
11304d19802SAdrian Chadd void
medium_close(struct wtap_medium * md)11404d19802SAdrian Chadd medium_close(struct wtap_medium *md)
11504d19802SAdrian Chadd {
11604d19802SAdrian Chadd 
11704d19802SAdrian Chadd 	mtx_lock(&md->md_mtx);
11804d19802SAdrian Chadd 	md->open = 0;
11904d19802SAdrian Chadd 	mtx_unlock(&md->md_mtx);
12004d19802SAdrian Chadd }
121