1*49ed6e97SBjoern A. Zeeb /*- 2*49ed6e97SBjoern A. Zeeb * Copyright (c) 2020-2021 The FreeBSD Foundation 3*49ed6e97SBjoern A. Zeeb * Copyright (c) 2021 Bjoern A. Zeeb 4*49ed6e97SBjoern A. Zeeb * 5*49ed6e97SBjoern A. Zeeb * This software was developed by Björn Zeeb under sponsorship from 6*49ed6e97SBjoern A. Zeeb * the FreeBSD Foundation. 7*49ed6e97SBjoern A. Zeeb * 8*49ed6e97SBjoern A. Zeeb * Redistribution and use in source and binary forms, with or without 9*49ed6e97SBjoern A. Zeeb * modification, are permitted provided that the following conditions 10*49ed6e97SBjoern A. Zeeb * are met: 11*49ed6e97SBjoern A. Zeeb * 1. Redistributions of source code must retain the above copyright 12*49ed6e97SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer. 13*49ed6e97SBjoern A. Zeeb * 2. Redistributions in binary form must reproduce the above copyright 14*49ed6e97SBjoern A. Zeeb * notice, this list of conditions and the following disclaimer in the 15*49ed6e97SBjoern A. Zeeb * documentation and/or other materials provided with the distribution. 16*49ed6e97SBjoern A. Zeeb * 17*49ed6e97SBjoern A. Zeeb * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18*49ed6e97SBjoern A. Zeeb * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*49ed6e97SBjoern A. Zeeb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*49ed6e97SBjoern A. Zeeb * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21*49ed6e97SBjoern A. Zeeb * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*49ed6e97SBjoern A. Zeeb * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*49ed6e97SBjoern A. Zeeb * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*49ed6e97SBjoern A. Zeeb * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*49ed6e97SBjoern A. Zeeb * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*49ed6e97SBjoern A. Zeeb * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*49ed6e97SBjoern A. Zeeb * SUCH DAMAGE. 28*49ed6e97SBjoern A. Zeeb * 29*49ed6e97SBjoern A. Zeeb * $FreeBSD$ 30*49ed6e97SBjoern A. Zeeb */ 31*49ed6e97SBjoern A. Zeeb 32*49ed6e97SBjoern A. Zeeb /* 33*49ed6e97SBjoern A. Zeeb * NOTE: this socket buffer compatibility code is highly EXPERIMENTAL. 34*49ed6e97SBjoern A. Zeeb * Do not rely on the internals of this implementation. They are highly 35*49ed6e97SBjoern A. Zeeb * likely to change as we will improve the integration to FreeBSD mbufs. 36*49ed6e97SBjoern A. Zeeb */ 37*49ed6e97SBjoern A. Zeeb 38*49ed6e97SBjoern A. Zeeb #include <sys/cdefs.h> 39*49ed6e97SBjoern A. Zeeb __FBSDID("$FreeBSD$"); 40*49ed6e97SBjoern A. Zeeb 41*49ed6e97SBjoern A. Zeeb #include <sys/param.h> 42*49ed6e97SBjoern A. Zeeb #include <sys/types.h> 43*49ed6e97SBjoern A. Zeeb #include <sys/kernel.h> 44*49ed6e97SBjoern A. Zeeb #include <sys/malloc.h> 45*49ed6e97SBjoern A. Zeeb 46*49ed6e97SBjoern A. Zeeb #include <linux/skbuff.h> 47*49ed6e97SBjoern A. Zeeb #include <linux/slab.h> 48*49ed6e97SBjoern A. Zeeb 49*49ed6e97SBjoern A. Zeeb static MALLOC_DEFINE(M_LKPISKB, "lkpiskb", "Linux KPI skbuff compat"); 50*49ed6e97SBjoern A. Zeeb 51*49ed6e97SBjoern A. Zeeb struct sk_buff * 52*49ed6e97SBjoern A. Zeeb linuxkpi_alloc_skb(size_t size, gfp_t gfp) 53*49ed6e97SBjoern A. Zeeb { 54*49ed6e97SBjoern A. Zeeb struct sk_buff *skb; 55*49ed6e97SBjoern A. Zeeb size_t len; 56*49ed6e97SBjoern A. Zeeb 57*49ed6e97SBjoern A. Zeeb len = sizeof(*skb) + size + sizeof(struct skb_shared_info); 58*49ed6e97SBjoern A. Zeeb /* 59*49ed6e97SBjoern A. Zeeb * Using or own type here not backing my kmalloc. 60*49ed6e97SBjoern A. Zeeb * We assume no one calls kfree directly on the skb. 61*49ed6e97SBjoern A. Zeeb */ 62*49ed6e97SBjoern A. Zeeb skb = malloc(len, M_LKPISKB, linux_check_m_flags(gfp) | M_ZERO); 63*49ed6e97SBjoern A. Zeeb if (skb == NULL) 64*49ed6e97SBjoern A. Zeeb return (skb); 65*49ed6e97SBjoern A. Zeeb skb->_alloc_len = size; 66*49ed6e97SBjoern A. Zeeb skb->truesize = size; 67*49ed6e97SBjoern A. Zeeb 68*49ed6e97SBjoern A. Zeeb skb->head = skb->data = skb->tail = (uint8_t *)(skb+1); 69*49ed6e97SBjoern A. Zeeb skb->end = skb->head + size; 70*49ed6e97SBjoern A. Zeeb 71*49ed6e97SBjoern A. Zeeb skb->shinfo = (struct skb_shared_info *)(skb->end); 72*49ed6e97SBjoern A. Zeeb 73*49ed6e97SBjoern A. Zeeb SKB_TRACE_FMT(skb, "data %p size %zu", skb->data, size); 74*49ed6e97SBjoern A. Zeeb return (skb); 75*49ed6e97SBjoern A. Zeeb } 76*49ed6e97SBjoern A. Zeeb 77*49ed6e97SBjoern A. Zeeb void 78*49ed6e97SBjoern A. Zeeb linuxkpi_kfree_skb(struct sk_buff *skb) 79*49ed6e97SBjoern A. Zeeb { 80*49ed6e97SBjoern A. Zeeb struct skb_shared_info *shinfo; 81*49ed6e97SBjoern A. Zeeb uint16_t fragno; 82*49ed6e97SBjoern A. Zeeb 83*49ed6e97SBjoern A. Zeeb SKB_TRACE(skb); 84*49ed6e97SBjoern A. Zeeb if (skb == NULL) 85*49ed6e97SBjoern A. Zeeb return; 86*49ed6e97SBjoern A. Zeeb 87*49ed6e97SBjoern A. Zeeb /* 88*49ed6e97SBjoern A. Zeeb * XXX TODO this will go away once we have skb backed by mbuf. 89*49ed6e97SBjoern A. Zeeb * currently we allow the mbuf to stay around and use a private 90*49ed6e97SBjoern A. Zeeb * free function to allow secondary resources to be freed along. 91*49ed6e97SBjoern A. Zeeb */ 92*49ed6e97SBjoern A. Zeeb if (skb->m != NULL) { 93*49ed6e97SBjoern A. Zeeb void *m; 94*49ed6e97SBjoern A. Zeeb 95*49ed6e97SBjoern A. Zeeb m = skb->m; 96*49ed6e97SBjoern A. Zeeb skb->m = NULL; 97*49ed6e97SBjoern A. Zeeb 98*49ed6e97SBjoern A. Zeeb KASSERT(skb->m_free_func != NULL, ("%s: skb %p has m %p but no " 99*49ed6e97SBjoern A. Zeeb "m_free_func %p\n", __func__, skb, m, skb->m_free_func)); 100*49ed6e97SBjoern A. Zeeb skb->m_free_func(m); 101*49ed6e97SBjoern A. Zeeb } 102*49ed6e97SBjoern A. Zeeb KASSERT(skb->m == NULL, 103*49ed6e97SBjoern A. Zeeb ("%s: skb %p m %p != NULL\n", __func__, skb, skb->m)); 104*49ed6e97SBjoern A. Zeeb 105*49ed6e97SBjoern A. Zeeb shinfo = skb->shinfo; 106*49ed6e97SBjoern A. Zeeb for (fragno = 0; fragno < nitems(shinfo->frags); fragno++) { 107*49ed6e97SBjoern A. Zeeb 108*49ed6e97SBjoern A. Zeeb if (shinfo->frags[fragno].page != NULL) 109*49ed6e97SBjoern A. Zeeb __free_page(shinfo->frags[fragno].page); 110*49ed6e97SBjoern A. Zeeb } 111*49ed6e97SBjoern A. Zeeb 112*49ed6e97SBjoern A. Zeeb free(skb, M_LKPISKB); 113*49ed6e97SBjoern A. Zeeb } 114