@@ -924,12 +924,14 @@ static struct net_pkt_alloc_stats_slab *find_alloc_stats(struct k_mem_slab *slab
924924#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
925925static struct net_buf * pkt_alloc_buffer (struct net_pkt * pkt ,
926926 struct net_buf_pool * pool ,
927- size_t size , k_timeout_t timeout ,
927+ size_t size , size_t headroom ,
928+ k_timeout_t timeout ,
928929 const char * caller , int line )
929930#else
930931static struct net_buf * pkt_alloc_buffer (struct net_pkt * pkt ,
931932 struct net_buf_pool * pool ,
932- size_t size , k_timeout_t timeout )
933+ size_t size , size_t headroom ,
934+ k_timeout_t timeout )
933935#endif
934936{
935937#if defined(CONFIG_NET_PKT_ALLOC_STATS )
@@ -958,11 +960,25 @@ static struct net_buf *pkt_alloc_buffer(struct net_pkt *pkt,
958960 }
959961
960962 current = new ;
961- if (current -> size > size ) {
962- current -> size = size ;
963- }
964963
965- size -= current -> size ;
964+ /* If there is headroom reserved, then allocate that to the
965+ * first buf.
966+ */
967+ if (current == first && headroom > 0 ) {
968+ if (current -> size > (headroom + size )) {
969+ current -> size = size + headroom ;
970+
971+ size = 0U ;
972+ } else {
973+ size -= current -> size ;
974+ }
975+ } else {
976+ if (current -> size > size ) {
977+ current -> size = size ;
978+ }
979+
980+ size -= current -> size ;
981+ }
966982
967983 timeout = sys_timepoint_timeout (end );
968984
@@ -1003,12 +1019,14 @@ static struct net_buf *pkt_alloc_buffer(struct net_pkt *pkt,
10031019#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
10041020static struct net_buf * pkt_alloc_buffer (struct net_pkt * pkt ,
10051021 struct net_buf_pool * pool ,
1006- size_t size , k_timeout_t timeout ,
1022+ size_t size , size_t headroom ,
1023+ k_timeout_t timeout ,
10071024 const char * caller , int line )
10081025#else
10091026static struct net_buf * pkt_alloc_buffer (struct net_pkt * pkt ,
10101027 struct net_buf_pool * pool ,
1011- size_t size , k_timeout_t timeout )
1028+ size_t size , size_t headroom ,
1029+ k_timeout_t timeout )
10121030#endif
10131031{
10141032 struct net_buf * buf ;
@@ -1019,6 +1037,7 @@ static struct net_buf *pkt_alloc_buffer(struct net_pkt *pkt,
10191037#else
10201038 ARG_UNUSED (pkt );
10211039#endif
1040+ ARG_UNUSED (headroom );
10221041
10231042 buf = net_buf_alloc_len (pool , size , timeout );
10241043
@@ -1231,17 +1250,19 @@ int net_pkt_remove_tail(struct net_pkt *pkt, size_t length)
12311250}
12321251
12331252#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
1234- int net_pkt_alloc_buffer_debug (struct net_pkt * pkt ,
1235- size_t size ,
1236- enum net_ip_protocol proto ,
1237- k_timeout_t timeout ,
1238- const char * caller ,
1239- int line )
1253+ int net_pkt_alloc_buffer_with_reserve_debug (struct net_pkt * pkt ,
1254+ size_t size ,
1255+ size_t reserve ,
1256+ enum net_ip_protocol proto ,
1257+ k_timeout_t timeout ,
1258+ const char * caller ,
1259+ int line )
12401260#else
1241- int net_pkt_alloc_buffer (struct net_pkt * pkt ,
1242- size_t size ,
1243- enum net_ip_protocol proto ,
1244- k_timeout_t timeout )
1261+ int net_pkt_alloc_buffer_with_reserve (struct net_pkt * pkt ,
1262+ size_t size ,
1263+ size_t reserve ,
1264+ enum net_ip_protocol proto ,
1265+ k_timeout_t timeout )
12451266#endif
12461267{
12471268 struct net_buf_pool * pool = NULL ;
@@ -1271,8 +1292,8 @@ int net_pkt_alloc_buffer(struct net_pkt *pkt,
12711292 /* Calculate the maximum that can be allocated depending on size */
12721293 alloc_len = pkt_buffer_length (pkt , size + hdr_len , proto , alloc_len );
12731294
1274- NET_DBG ("Data allocation maximum size %zu (requested %zu)" ,
1275- alloc_len , size );
1295+ NET_DBG ("Data allocation maximum size %zu (requested %zu, reserve %zu )" ,
1296+ alloc_len , size , reserve );
12761297
12771298 if (pkt -> context ) {
12781299 pool = get_data_pool (pkt -> context );
@@ -1283,26 +1304,92 @@ int net_pkt_alloc_buffer(struct net_pkt *pkt,
12831304 }
12841305
12851306#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
1286- buf = pkt_alloc_buffer (pkt , pool , alloc_len , timeout , caller , line );
1307+ buf = pkt_alloc_buffer (pkt , pool , alloc_len , reserve ,
1308+ timeout , caller , line );
12871309#else
1288- buf = pkt_alloc_buffer (pkt , pool , alloc_len , timeout );
1310+ buf = pkt_alloc_buffer (pkt , pool , alloc_len , reserve , timeout );
12891311#endif
12901312
12911313 if (!buf ) {
12921314#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
1293- NET_ERR ("Data buffer (%zd ) allocation failed (%s:%d)" ,
1294- alloc_len , caller , line );
1315+ NET_ERR ("Data buffer (%zu ) allocation failed (%s:%d)" ,
1316+ alloc_len + reserve , caller , line );
12951317#else
1296- NET_ERR ("Data buffer (%zd) allocation failed." , alloc_len );
1318+ NET_ERR ("Data buffer (%zu) allocation failed." ,
1319+ alloc_len + reserve );
12971320#endif
12981321 return - ENOMEM ;
12991322 }
13001323
13011324 net_pkt_append_buffer (pkt , buf );
13021325
1326+ /* Hide the link layer header for now. The space is used when
1327+ * link layer header needs to be written to the packet by L2 send.
1328+ */
1329+ if (reserve > 0U ) {
1330+ NET_DBG ("Reserving %zu bytes for L2 header" , reserve );
1331+
1332+ net_buf_reserve (pkt -> buffer , reserve );
1333+
1334+ net_pkt_cursor_init (pkt );
1335+ }
1336+
13031337 return 0 ;
13041338}
13051339
1340+ #if NET_LOG_LEVEL >= LOG_LEVEL_DBG
1341+ int net_pkt_alloc_buffer_debug (struct net_pkt * pkt ,
1342+ size_t size ,
1343+ enum net_ip_protocol proto ,
1344+ k_timeout_t timeout ,
1345+ const char * caller ,
1346+ int line )
1347+ #else
1348+ int net_pkt_alloc_buffer (struct net_pkt * pkt ,
1349+ size_t size ,
1350+ enum net_ip_protocol proto ,
1351+ k_timeout_t timeout )
1352+ #endif
1353+ {
1354+ struct net_if * iface ;
1355+ int ret ;
1356+
1357+ if (!size && proto == 0 && net_pkt_family (pkt ) == AF_UNSPEC ) {
1358+ return 0 ;
1359+ }
1360+
1361+ if (k_is_in_isr ()) {
1362+ timeout = K_NO_WAIT ;
1363+ }
1364+
1365+ iface = net_pkt_iface (pkt );
1366+
1367+ if (iface != NULL && net_if_l2 (iface )-> alloc != NULL ) {
1368+ ret = net_if_l2 (iface )-> alloc (iface , pkt , size , proto , timeout );
1369+ if (ret != - ENOTSUP ) {
1370+ return ret ;
1371+ }
1372+ }
1373+
1374+ #if NET_LOG_LEVEL >= LOG_LEVEL_DBG
1375+ ret = net_pkt_alloc_buffer_with_reserve_debug (pkt ,
1376+ size ,
1377+ 0U ,
1378+ proto ,
1379+ timeout ,
1380+ caller ,
1381+ line );
1382+ #else
1383+ ret = net_pkt_alloc_buffer_with_reserve (pkt ,
1384+ size ,
1385+ 0U ,
1386+ proto ,
1387+ timeout );
1388+ #endif
1389+
1390+ return ret ;
1391+ }
1392+
13061393
13071394#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
13081395int net_pkt_alloc_buffer_raw_debug (struct net_pkt * pkt , size_t size ,
@@ -1335,9 +1422,9 @@ int net_pkt_alloc_buffer_raw(struct net_pkt *pkt, size_t size,
13351422 }
13361423
13371424#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
1338- buf = pkt_alloc_buffer (pkt , pool , size , timeout , caller , line );
1425+ buf = pkt_alloc_buffer (pkt , pool , size , 0U , timeout , caller , line );
13391426#else
1340- buf = pkt_alloc_buffer (pkt , pool , size , timeout );
1427+ buf = pkt_alloc_buffer (pkt , pool , size , 0U , timeout );
13411428#endif
13421429
13431430 if (!buf ) {
@@ -1569,7 +1656,7 @@ pkt_alloc_with_buffer(struct k_mem_slab *slab,
15691656 struct net_pkt * pkt ;
15701657 int ret ;
15711658
1572- NET_DBG ("On iface %p size %zu" , iface , size );
1659+ NET_DBG ("On iface %d (%p) size %zu" , net_if_get_by_iface ( iface ) , iface , size );
15731660
15741661#if NET_LOG_LEVEL >= LOG_LEVEL_DBG
15751662 pkt = pkt_alloc_on_iface (slab , iface , timeout , caller , line );
0 commit comments