Skip to content

Commit 9f8d418

Browse files
zhhyu7xiaoxiang781216
authored andcommitted
forward: copy iob when broadcast forward
since iob offload, ipvx_dev_forward will remove d_iob, if there are multiple devices, d_iob will be NULL when dev_forward is entered second time. and the device that receives the packet cannot process the packet after forwarding it so the iob copy is added. Signed-off-by: zhanghongyu <[email protected]>
1 parent bd12291 commit 9f8d418

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

net/ipforward/ipv4_forward.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,7 @@ int ipv4_forward_callback(FAR struct net_driver_s *fwddev, FAR void *arg)
341341
{
342342
FAR struct net_driver_s *dev = (FAR struct net_driver_s *)arg;
343343
FAR struct ipv4_hdr_s *ipv4;
344+
FAR struct iob_s *iob;
344345
int ret;
345346

346347
DEBUGASSERT(fwddev != NULL);
@@ -360,6 +361,24 @@ int ipv4_forward_callback(FAR struct net_driver_s *fwddev, FAR void *arg)
360361

361362
if (fwddev != dev)
362363
{
364+
/* Backup the forward IP packet */
365+
366+
iob = iob_tryalloc(true);
367+
if (iob == NULL)
368+
{
369+
nerr("ERROR: iob alloc failed when forward broadcast\n");
370+
return -ENOMEM;
371+
}
372+
373+
iob_reserve(iob, CONFIG_NET_LL_GUARDSIZE);
374+
ret = iob_clone_partial(dev->d_iob, dev->d_iob->io_pktlen, 0,
375+
iob, 0, true, false);
376+
if (ret < 0)
377+
{
378+
iob_free_chain(iob);
379+
return ret;
380+
}
381+
363382
/* Recover the pointer to the IPv4 header in the receiving device's
364383
* d_buf.
365384
*/
@@ -371,9 +390,14 @@ int ipv4_forward_callback(FAR struct net_driver_s *fwddev, FAR void *arg)
371390
ret = ipv4_dev_forward(dev, fwddev, ipv4);
372391
if (ret < 0)
373392
{
393+
iob_free_chain(iob);
374394
nwarn("WARNING: ipv4_dev_forward failed: %d\n", ret);
375395
return ret;
376396
}
397+
398+
/* Restore device iob with backup iob */
399+
400+
netdev_iob_replace(dev, iob);
377401
}
378402

379403
return OK;

net/ipforward/ipv6_forward.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ int ipv6_forward_callback(FAR struct net_driver_s *fwddev, FAR void *arg)
468468
{
469469
FAR struct net_driver_s *dev = (FAR struct net_driver_s *)arg;
470470
FAR struct ipv6_hdr_s *ipv6;
471+
FAR struct iob_s *iob;
471472
int ret;
472473

473474
DEBUGASSERT(fwddev != NULL);
@@ -487,6 +488,24 @@ int ipv6_forward_callback(FAR struct net_driver_s *fwddev, FAR void *arg)
487488

488489
if (fwddev != dev)
489490
{
491+
/* Backup the forward IP packet */
492+
493+
iob = iob_tryalloc(true);
494+
if (iob == NULL)
495+
{
496+
nerr("ERROR: iob alloc failed when forward broadcast\n");
497+
return -ENOMEM;
498+
}
499+
500+
iob_reserve(iob, CONFIG_NET_LL_GUARDSIZE);
501+
ret = iob_clone_partial(dev->d_iob, dev->d_iob->io_pktlen, 0,
502+
iob, 0, true, false);
503+
if (ret < 0)
504+
{
505+
iob_free_chain(iob);
506+
return ret;
507+
}
508+
490509
/* Recover the pointer to the IPv6 header in the receiving device's
491510
* d_buf.
492511
*/
@@ -498,9 +517,14 @@ int ipv6_forward_callback(FAR struct net_driver_s *fwddev, FAR void *arg)
498517
ret = ipv6_dev_forward(dev, fwddev, ipv6);
499518
if (ret < 0)
500519
{
520+
iob_free_chain(iob);
501521
nwarn("WARNING: ipv6_dev_forward failed: %d\n", ret);
502522
return ret;
503523
}
524+
525+
/* Restore device iob with backup iob */
526+
527+
netdev_iob_replace(dev, iob);
504528
}
505529

506530
return OK;

0 commit comments

Comments
 (0)