This manifested as a memory leak in test 898 "ofproto-dpif - sFlow packet
sampling - tunnel set", which included an output to a tunnel vport that
doesn't have an implementation of netdev_send().
Reported-by: William Tu <u9012063@gmail.com>
Reported-at: http://openvswitch.org/pipermail/dev/2016-February/065873.html
Signed-off-by: Ben Pfaff <blp@ovn.org>
- * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
+ * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* If the function returns a non-zero value, some of the packets might have
* been sent anyway.
*
* If the function returns a non-zero value, some of the packets might have
* been sent anyway.
*
- * To retain ownership of 'buffers' caller can set may_steal to false.
+ * If 'may_steal' is false, the caller retains ownership of all the
+ * packets. If 'may_steal' is true, the caller transfers ownership of all
+ * the packets to the network device, regardless of success.
*
* The network device is expected to maintain one or more packet
* transmission queues, so that the caller does not ordinarily have to
*
* The network device is expected to maintain one or more packet
* transmission queues, so that the caller does not ordinarily have to
- * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014 Nicira, Inc.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2016 Nicira, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* If the function returns a non-zero value, some of the packets might have
* been sent anyway.
*
* If the function returns a non-zero value, some of the packets might have
* been sent anyway.
*
- * To retain ownership of 'buffer' caller can set may_steal to false.
+ * If 'may_steal' is false, the caller retains ownership of all the packets.
+ * If 'may_steal' is true, the caller transfers ownership of all the packets
+ * to the network device, regardless of success.
*
* The network device is expected to maintain one or more packet
* transmission queues, so that the caller does not ordinarily have to
*
* The network device is expected to maintain one or more packet
* transmission queues, so that the caller does not ordinarily have to
netdev_send(struct netdev *netdev, int qid, struct dp_packet **buffers,
int cnt, bool may_steal)
{
netdev_send(struct netdev *netdev, int qid, struct dp_packet **buffers,
int cnt, bool may_steal)
{
+ if (!netdev->netdev_class->send) {
+ if (may_steal) {
+ for (int i = 0; i < cnt; i++) {
+ dp_packet_delete(buffers[i]);
+ }
+ }
+ return EOPNOTSUPP;
+ }
- error = (netdev->netdev_class->send
- ? netdev->netdev_class->send(netdev, qid, buffers, cnt, may_steal)
- : EOPNOTSUPP);
+ int error = netdev->netdev_class->send(netdev, qid, buffers, cnt,
+ may_steal);
if (!error) {
COVERAGE_INC(netdev_sent);
}
if (!error) {
COVERAGE_INC(netdev_sent);
}