Hello,
I am trying to walk-thru and understand some of the ovs code that gets
exercised when ovs is configured for user-space datapath (i.e.
datapath_type=netdev). I have a few questions on use of tap devices in this
case for switching data between multiple interfaces.
>From the net-device creation function 'netdev_linux_create_tap()',
definition and the function header, it looks like we open and bind to same
tap device (/dev/net/tun) for all interfaces i.e. a read from this device
could give us data available on any of the underlying bound interfaces. If
the understanding is correct, then in 'dpif_netdev_run()' where we traverse
the list of all ports and call 'netdev_recv()' we could potentially read
data on one port which actually came on a different port. Is this
understanding correct? If so then how do we apply port specific open-flow
rules in this case? In other words, how do we distinguish between data
received on one port from another in user-space mode.
I appreciate your time and any pointers that could help clarify.
++++++++++++For quick reference, below are the code snippets I have referred
to above +++++++++++++
/* For most types of netdevs we open the device for each call of
* netdev_open(). However, this is not the case with tap devices,
* since it is only possible to open the device once. In this
* situation we share a single file descriptor, and consequently
* buffers, across all readers. Therefore once data is read it will
* be unavailable to other reads for tap devices. */
static int
netdev_linux_create_tap(const struct netdev_class *class OVS_UNUSED,
const char *name, const struct shash *args,
struct netdev_dev **netdev_devp)
...
...
static void
dpif_netdev_run(struct dpif *dpif)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
struct dp_netdev_port *port;
struct ofpbuf packet;
ofpbuf_init(&packet, DP_NETDEV_HEADROOM + VLAN_ETH_HEADER_LEN +
max_mtu);
* LIST_FOR_EACH (port, node, &dp->port_list) {
* int error;
/* Reset packet contents. */
ofpbuf_clear(&packet);
ofpbuf_reserve(&packet, DP_NETDEV_HEADROOM);
* error = netdev_recv(port->netdev, &packet);
if (!error) {
dp_netdev_port_input(dp, port, &packet);
* } else if (error != EAGAIN && error != EOPNOTSUPP) {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
VLOG_ERR_RL(&rl, "error receiving data from %s: %s",
netdev_get_name(port->netdev), strerror(error));
}
}
ofpbuf_uninit(&packet);
}
Thanks,
-Madhav
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev