summaryrefslogtreecommitdiff
path: root/lib/netdev-dummy.c
diff options
context:
space:
mode:
authorIlya Maximets <i.maximets@samsung.com>2017-07-25 16:02:01 +0300
committerAndy Zhou <azhou@ovn.org>2017-07-25 14:42:11 -0700
commit1e2eecbbf727456b93acc4901c3d61d8a95f6fbb (patch)
tree59594a5182f22d410fc39d8a60164c69337e5f76 /lib/netdev-dummy.c
parent3476ce3ad7832e88e039893da96fa956a2aae18e (diff)
downloadopenvswitch-1e2eecbbf727456b93acc4901c3d61d8a95f6fbb.tar.gz
netdev-dummy: Fix setting length in recieve command.
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 'flow_compose_size()'. 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> Signed-off-by: Andy Zhou <azhou@ovn.org>
Diffstat (limited to 'lib/netdev-dummy.c')
-rw-r--r--lib/netdev-dummy.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
index 51d29d54a..83e30b37c 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;
@@ -1479,6 +1479,7 @@ eth_from_flow(const char *s)
packet = dp_packet_new(0);
flow_compose(packet, &flow);
+ flow_compose_size(packet, &flow, packet_size);
ofpbuf_uninit(&odp_key);
return packet;
@@ -1556,20 +1557,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);