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
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to