diff mbox series

[ovs-dev] netdev-linux: Fix the bug when sending packets with multi segments.

Message ID 20240923084820.29688-1-sunyang.wu@jaguarmicro.com
State Superseded
Headers show
Series [ovs-dev] netdev-linux: Fix the bug when sending packets with multi segments. | expand

Checks

Context Check Description
ovsrobot/apply-robot warning apply and check: warning
ovsrobot/github-robot-_Build_and_Test fail github build: failed

Commit Message

Sunyang Wu Sept. 23, 2024, 8:48 a.m. UTC
When sending a packet with multiple segments, we use the length of the
entire message as the transmission length and the base address of the
first segment as the base address for the entire message. As a result,
the packet sent to the network device is incorrect, containing only the
content of the first segment.

Fixes: d19cf8bb798ff ("Replace sendmsg with sendmmsg in
netdev_linux_send")
Signed-off-by: Sunyang Wu <sunyang.wu@jaguarmicro.com>
---
 lib/dp-packet.h    | 39 +++++++++++++++++++++++++++++++++++++++
 lib/netdev-linux.c | 28 ++++++++++++++++++++++++++--
 2 files changed, 65 insertions(+), 2 deletions(-)

Comments

0-day Robot Sept. 23, 2024, 8:57 a.m. UTC | #1
References:  <20240923084820.29688-1-sunyang.wu@jaguarmicro.com>
 

Bleep bloop.  Greetings Sunyang Wu, I am a robot and I have tried out your patch.
Thanks for your contribution.

I encountered some error that I wasn't expecting.  See the details below.


checkpatch:
ERROR: "Fixes" tag is malformed.
Use the following format:
  git log -1 --pretty=format:"Fixes: %h (\"%s\")" --abbrev=12 COMMIT_REF

11: Fixes: d19cf8bb798ff ("Replace sendmsg with sendmmsg in

Lines checked: 119, Warnings: 0, Errors: 1


Please check this out.  If you feel there has been an error, please email aconole@redhat.com

Thanks,
0-day Robot
diff mbox series

Patch

diff --git a/lib/dp-packet.h b/lib/dp-packet.h
index 4afbbe722..10ae91145 100644
--- a/lib/dp-packet.h
+++ b/lib/dp-packet.h
@@ -699,6 +699,24 @@  dp_packet_size(const struct dp_packet *b)
     return b->mbuf.pkt_len;
 }
 
+static inline uint16_t
+dp_packet_nb_segs(const struct dp_packet *b)
+{
+    return b->mbuf.nb_segs;
+}
+
+static inline uint16_t
+dp_packet_data_size(const struct dp_packet *b)
+{
+    return b->mbuf.data_len;
+}
+
+static inline  struct dp_packet *
+dp_packet_next(const struct dp_packet *b )
+{
+    return (struct dp_packet *)(b->mbuf.next);
+}
+
 static inline void
 dp_packet_set_size(struct dp_packet *b, uint32_t v)
 {
@@ -778,6 +796,27 @@  dp_packet_size(const struct dp_packet *b)
     return b->size_;
 }
 
+static inline uint16_t
+dp_packet_nb_segs(const struct dp_packet *b)
+{
+    return 1;
+}
+
+static inline  struct dp_packet *
+dp_packet_next(const struct dp_packet *b )
+{
+    return NULL;
+}
+
+/*
+   only for compile
+*/
+static inline uint16_t
+dp_packet_data_size(const struct dp_packet *b)
+{
+    return b->size_;
+}
+
 static inline void
 dp_packet_set_size(struct dp_packet *b, uint32_t v)
 {
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
index 0cd0850a3..e26ebb6c0 100644
--- a/lib/netdev-linux.c
+++ b/lib/netdev-linux.c
@@ -1690,8 +1690,32 @@  netdev_linux_tap_batch_send(struct netdev *netdev_, int mtu,
 
         size = dp_packet_size(packet);
         do {
-            retval = write(netdev->tap_fd, dp_packet_data(packet), size);
-            error = retval < 0 ? errno : 0;
+            if (dp_packet_nb_segs(packet) > 1) {
+                int data_size = 0;
+                struct dp_packet *tmp_packet = packet;
+                void *buf = NULL;
+
+                while (tmp_packet) {
+                    data_size += dp_packet_data_size(tmp_packet);
+                    tmp_packet = dp_packet_next(tmp_packet);
+                }
+
+                buf = xmalloc(data_size);
+                data_size = 0;
+                while (packet) {
+                    memcpy(buf + data_size,
+                           dp_packet_data(packet),
+                           dp_packet_data_size(packet));
+                    data_size += dp_packet_data_size(packet);
+                    packet = dp_packet_next(packet);
+                }
+                retval = write(netdev->tap_fd, buf, data_size);
+                error = retval < 0 ? errno : 0;
+                free(buf);
+            } else {
+                retval = write(netdev->tap_fd, dp_packet_data(packet), size);
+                error = retval < 0 ? errno : 0;
+            }
         } while (error == EINTR);
 
         if (error) {