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

Ilya Maximets i.maximets at samsung.com
Wed Jul 19 14:52:00 UTC 2017


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 at ovn.org>
Fixes: d8ada2368cbe ("netdev-dummy: Add --len option for netdev-dummy/receive command")
Signed-off-by: Ilya Maximets <i.maximets at samsung.com>
---
 lib/netdev-dummy.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

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);
-- 
2.7.4



More information about the dev mailing list