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