From: Justin Pettit Date: Sat, 1 Aug 2009 07:09:56 +0000 (-0700) Subject: datapath: Support jumbo frames in the datapath device X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1dcf111b1cb66fe1f3ed2e45f66ab6f5659a6527;p=openvswitch datapath: Support jumbo frames in the datapath device The datapath has no problems switching jumbo frames (frames with a payload greater than 1500 bytes), but it has not supported sending and receiving them to the device itself. With this commit, the MTU can be set as large as the minimum MTU size of the devices that are directly attached, or 1500 bytes if there are none. This mimics the behavior of the Linux bridge. Feature #1736 --- diff --git a/datapath/datapath.c b/datapath/datapath.c index 5e1a352c..43d96fbd 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -1184,6 +1184,29 @@ get_dp_stats(struct datapath *dp, struct odp_stats __user *statsp) return copy_to_user(statsp, &stats, sizeof stats) ? -EFAULT : 0; } +/* MTU of the dp pseudo-device: ETH_DATA_LEN or the minimum of the ports */ +int dp_min_mtu(const struct datapath *dp) +{ + struct net_bridge_port *p; + int mtu = 0; + + ASSERT_RTNL(); + + list_for_each_entry_rcu (p, &dp->port_list, node) { + struct net_device *dev = p->dev; + + /* Skip any internal ports, since that's what we're trying to + * set. */ + if (is_dp_dev(dev)) + continue; + + if (!mtu || dev->mtu < mtu) + mtu = dev->mtu; + } + + return mtu ? mtu : ETH_DATA_LEN; +} + static int put_port(const struct net_bridge_port *p, struct odp_port __user *uop) { diff --git a/datapath/datapath.h b/datapath/datapath.h index 455580f0..a03597d8 100644 --- a/datapath/datapath.h +++ b/datapath/datapath.h @@ -122,6 +122,7 @@ int dp_table_foreach(struct dp_table *table, void dp_process_received_packet(struct sk_buff *, struct net_bridge_port *); int dp_del_port(struct net_bridge_port *); int dp_output_control(struct datapath *, struct sk_buff *, int, u32 arg); +int dp_min_mtu(const struct datapath *dp); struct datapath *get_dp(int dp_idx); diff --git a/datapath/dp_dev.c b/datapath/dp_dev.c index 3902a8c5..422af020 100644 --- a/datapath/dp_dev.c +++ b/datapath/dp_dev.c @@ -130,6 +130,15 @@ static struct ethtool_ops dp_ethtool_ops = { .get_tso = ethtool_op_get_tso, }; +static int dp_dev_change_mtu(struct net_device *dev, int new_mtu) +{ + if (new_mtu < 68 || new_mtu > dp_min_mtu(dp_dev_get_dp(dev))) + return -EINVAL; + + dev->mtu = new_mtu; + return 0; +} + static int dp_dev_init(struct net_device *netdev) { struct dp_dev *dp_dev = dp_dev_priv(netdev); @@ -162,6 +171,7 @@ do_setup(struct net_device *netdev) netdev->stop = dp_dev_stop; netdev->tx_queue_len = 0; netdev->set_mac_address = dp_dev_mac_addr; + netdev->change_mtu = dp_dev_change_mtu; netdev->init = dp_dev_init; netdev->destructor = dp_dev_free;