diff mbox

[ovs-dev,2/3] netdev-dummy: Fix setting length in recieve command.

Message ID 1500475921-4185-3-git-send-email-i.maximets@samsung.com
State Superseded
Headers show

Commit Message

Ilya Maximets July 19, 2017, 2:52 p.m. UTC
Currently, if '--len' option passed to 'netdev-dummy/receive' command,
only 'size' field of dp_packet will changes.

This is incorrect behaviour, because memory for that size is not
allocated and also packet headers not fixed to reflect the new size.
This leads to flow_extract() failure, because it checks the
'ip->tot_len' and stops further parsing if it doesn't match the
dp_packet_size(). As a result packets created while processing of the
'receive' command can't be parsed to the same flow.
Additionally this may lead to wrong memory accesses in case someone
will try to read or modify packets data.

Fix that by creating right packets using recently introduced option
'packet_size' for 'flow_compose()'.

CC: Andy Zhou <azhou@ovn.org>
Fixes: d8ada2368cbe ("netdev-dummy: Add --len option for netdev-dummy/receive command")
Signed-off-by: Ilya Maximets <i.maximets@samsung.com>
---
 lib/netdev-dummy.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)
diff mbox

Patch

diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index 6ee6a6a..481a7d7 100644
--- a/lib/netdev-dummy.c
+++ b/lib/netdev-dummy.c
@@ -1449,7 +1449,7 @@  eth_from_packet(const char *s)
 }
 
 static struct dp_packet *
-eth_from_flow(const char *s)
+eth_from_flow(const char *s, size_t packet_size)
 {
     enum odp_key_fitness fitness;
     struct dp_packet *packet;
@@ -1478,7 +1478,7 @@  eth_from_flow(const char *s)
     }
 
     packet = dp_packet_new(0);
-    flow_compose(packet, &flow, 0);
+    flow_compose(packet, &flow, packet_size);
 
     ofpbuf_uninit(&odp_key);
     return packet;
@@ -1556,20 +1556,26 @@  netdev_dummy_receive(struct unixctl_conn *conn,
         packet = eth_from_packet(argv[i]);
 
         if (!packet) {
+            int packet_size = 0;
+            const char *flow_str = argv[i];
+
+            /* Parse optional --len argument immediately follows a 'flow'.  */
+            if (argc >= i + 2 && !strcmp(argv[i + 1], "--len")) {
+                packet_size = strtol(argv[i + 2], NULL, 10);
+
+                if (packet_size < ETH_TOTAL_MIN) {
+                    unixctl_command_reply_error(conn, "too small packet len");
+                    goto exit;
+                }
+                i+=2;
+            }
             /* Try parse 'argv[i]' as odp flow. */
-            packet = eth_from_flow(argv[i]);
+            packet = eth_from_flow(flow_str, packet_size);
 
             if (!packet) {
                 unixctl_command_reply_error(conn, "bad packet or flow syntax");
                 goto exit;
             }
-
-            /* Parse optional --len argument immediately follows a 'flow'.  */
-            if (argc >= i + 2 && !strcmp(argv[i + 1], "--len")) {
-                int packet_size = strtol(argv[i + 2], NULL, 10);
-                dp_packet_set_size(packet, packet_size);
-                i+=2;
-            }
         }
 
         netdev_dummy_queue_packet(dummy_dev, packet, rx_qid);