There is no need to have vport interface for MTU as linux net-dev-ioctl can be used to get/set MTU for linux device. Following patch removes kernel vport interface for MTU and fixes netdev->get_mtu by linux net-dev ioctl. netdev->set_mtu is also added so that MTU set can be done from OVS userspace.
Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- datapath/datapath.c | 57 ------------------------------- datapath/datapath.h | 2 - datapath/dp_notify.c | 5 --- datapath/vport-internal_dev.c | 23 ------------ datapath/vport-internal_dev.h | 2 - datapath/vport-netdev.c | 14 ------- datapath/vport-netdev.h | 2 - datapath/vport.c | 46 ------------------------- datapath/vport.h | 9 ----- include/openvswitch/datapath-protocol.h | 4 -- lib/dpif-linux.c | 10 ----- lib/dpif-linux.h | 1 - lib/netdev-dummy.c | 11 ++++++ lib/netdev-linux.c | 38 +++++++++++++++++---- lib/netdev-provider.h | 8 ++++- lib/netdev-vport.c | 20 +++++----- lib/netdev.c | 29 ++++++++++++--- lib/netdev.h | 1 + vswitchd/bridge.c | 2 +- 19 files changed, 84 insertions(+), 200 deletions(-) diff --git a/datapath/datapath.c b/datapath/datapath.c index b92c198..aa33f63 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -130,7 +130,6 @@ static inline size_t br_nlmsg_size(void) + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ + nla_total_size(4) /* IFLA_MASTER */ - + nla_total_size(4) /* IFLA_MTU */ + nla_total_size(4) /* IFLA_LINK */ + nla_total_size(1); /* IFLA_OPERSTATE */ } @@ -163,7 +162,6 @@ static int dp_fill_ifinfo(struct sk_buff *skb, NLA_PUT_STRING(skb, IFLA_IFNAME, vport_get_name(port)); NLA_PUT_U32(skb, IFLA_MASTER, vport_get_ifindex(get_vport_protected(dp, OVSP_LOCAL))); - NLA_PUT_U32(skb, IFLA_MTU, vport_get_mtu(port)); #ifdef IFLA_OPERSTATE NLA_PUT_U8(skb, IFLA_OPERSTATE, vport_is_running(port) @@ -765,52 +763,6 @@ static void get_dp_stats(struct datapath *dp, struct ovs_dp_stats *stats) } } -/* MTU of the dp pseudo-device: ETH_DATA_LEN or the minimum of the ports. - * Called with RTNL lock. - */ -int dp_min_mtu(const struct datapath *dp) -{ - struct vport *p; - int mtu = 0; - - ASSERT_RTNL(); - - list_for_each_entry (p, &dp->port_list, node) { - int dev_mtu; - - /* Skip any internal ports, since that's what we're trying to - * set. */ - if (is_internal_vport(p)) - continue; - - dev_mtu = vport_get_mtu(p); - if (!dev_mtu) - continue; - if (!mtu || dev_mtu < mtu) - mtu = dev_mtu; - } - - return mtu ? mtu : ETH_DATA_LEN; -} - -/* Sets the MTU of all datapath devices to the minimum of the ports - * Called with RTNL lock. - */ -void set_internal_devs_mtu(const struct datapath *dp) -{ - struct vport *p; - int mtu; - - ASSERT_RTNL(); - - mtu = dp_min_mtu(dp); - - list_for_each_entry (p, &dp->port_list, node) { - if (is_internal_vport(p)) - vport_set_mtu(p, mtu); - } -} - static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = { [OVS_FLOW_ATTR_KEY] = { .type = NLA_NESTED }, [OVS_FLOW_ATTR_ACTIONS] = { .type = NLA_NESTED }, @@ -1585,7 +1537,6 @@ static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = { [OVS_VPORT_ATTR_STATS] = { .minlen = sizeof(struct rtnl_link_stats64) }, [OVS_VPORT_ATTR_ADDRESS] = { .minlen = ETH_ALEN }, #endif - [OVS_VPORT_ATTR_MTU] = { .type = NLA_U32 }, [OVS_VPORT_ATTR_OPTIONS] = { .type = NLA_NESTED }, }; @@ -1608,7 +1559,6 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, struct ovs_header *ovs_header; struct nlattr *nla; int ifindex; - int mtu; int err; ovs_header = genlmsg_put(skb, pid, seq, &dp_vport_genl_family, @@ -1630,10 +1580,6 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, NLA_PUT(skb, OVS_VPORT_ATTR_ADDRESS, ETH_ALEN, vport_get_addr(vport)); - mtu = vport_get_mtu(vport); - if (mtu) - NLA_PUT_U32(skb, OVS_VPORT_ATTR_MTU, mtu); - err = vport_get_options(vport, skb); if (err == -EMSGSIZE) goto error; @@ -1713,8 +1659,6 @@ static int change_vport(struct vport *vport, struct nlattr *a[OVS_VPORT_ATTR_MAX err = vport_set_stats(vport, nla_data(a[OVS_VPORT_ATTR_STATS])); if (!err && a[OVS_VPORT_ATTR_ADDRESS]) err = vport_set_addr(vport, nla_data(a[OVS_VPORT_ATTR_ADDRESS])); - if (!err && a[OVS_VPORT_ATTR_MTU]) - err = vport_set_mtu(vport, nla_get_u32(a[OVS_VPORT_ATTR_MTU])); return err; } @@ -1777,7 +1721,6 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info) if (IS_ERR(vport)) goto exit_unlock; - set_internal_devs_mtu(dp); dp_sysfs_add_if(vport); err = change_vport(vport, a); diff --git a/datapath/datapath.h b/datapath/datapath.h index 93be155..2e8305f 100644 --- a/datapath/datapath.h +++ b/datapath/datapath.h @@ -150,8 +150,6 @@ extern int (*dp_ioctl_hook)(struct net_device *dev, struct ifreq *rq, int cmd); void dp_process_received_packet(struct vport *, struct sk_buff *); int dp_detach_port(struct vport *); int dp_upcall(struct datapath *, struct sk_buff *, const struct dp_upcall_info *); -int dp_min_mtu(const struct datapath *dp); -void set_internal_devs_mtu(const struct datapath *dp); struct datapath *get_dp(int dp_idx); const char *dp_name(const struct datapath *dp); diff --git a/datapath/dp_notify.c b/datapath/dp_notify.c index 7b3b219..942d628 100644 --- a/datapath/dp_notify.c +++ b/datapath/dp_notify.c @@ -59,11 +59,6 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event, dp_sysfs_add_if(vport); } break; - - case NETDEV_CHANGEMTU: - if (!is_internal_dev(dev)) - set_internal_devs_mtu(dp); - break; } return NOTIFY_DONE; } diff --git a/datapath/vport-internal_dev.c b/datapath/vport-internal_dev.c index f777637..492bef7 100644 --- a/datapath/vport-internal_dev.c +++ b/datapath/vport-internal_dev.c @@ -115,20 +115,6 @@ static const struct ethtool_ops internal_dev_ethtool_ops = { .set_tso = ethtool_op_set_tso, }; -static int internal_dev_change_mtu(struct net_device *netdev, int new_mtu) -{ - struct vport *vport = internal_dev_get_vport(netdev); - - if (new_mtu < 68) - return -EINVAL; - - if (new_mtu > dp_min_mtu(vport->dp)) - return -EINVAL; - - netdev->mtu = new_mtu; - return 0; -} - static int internal_dev_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { if (dp_ioctl_hook) @@ -152,7 +138,6 @@ static const struct net_device_ops internal_dev_netdev_ops = { .ndo_start_xmit = internal_dev_xmit, .ndo_set_mac_address = internal_dev_mac_addr, .ndo_do_ioctl = internal_dev_do_ioctl, - .ndo_change_mtu = internal_dev_change_mtu, .ndo_get_stats = internal_dev_sys_stats, }; #endif @@ -170,7 +155,6 @@ static void do_setup(struct net_device *netdev) netdev->open = internal_dev_open; netdev->stop = internal_dev_stop; netdev->set_mac_address = internal_dev_mac_addr; - netdev->change_mtu = internal_dev_change_mtu; #endif netdev->destructor = internal_dev_destructor; @@ -276,7 +260,6 @@ const struct vport_ops internal_vport_ops = { .flags = VPORT_F_REQUIRED | VPORT_F_GEN_STATS | VPORT_F_FLOW, .create = internal_dev_create, .destroy = internal_dev_destroy, - .set_mtu = netdev_set_mtu, .set_addr = netdev_set_addr, .get_name = netdev_get_name, .get_addr = netdev_get_addr, @@ -285,7 +268,6 @@ const struct vport_ops internal_vport_ops = { .is_running = netdev_is_running, .get_operstate = netdev_get_operstate, .get_ifindex = netdev_get_ifindex, - .get_mtu = netdev_get_mtu, .send = internal_dev_recv, }; @@ -298,11 +280,6 @@ int is_internal_dev(const struct net_device *netdev) #endif } -int is_internal_vport(const struct vport *vport) -{ - return vport->ops == &internal_vport_ops; -} - struct vport *internal_dev_get_vport(struct net_device *netdev) { if (!is_internal_dev(netdev)) diff --git a/datapath/vport-internal_dev.h b/datapath/vport-internal_dev.h index 7c76520..e8dadc0 100644 --- a/datapath/vport-internal_dev.h +++ b/datapath/vport-internal_dev.h @@ -12,8 +12,6 @@ #include "datapath.h" #include "vport.h" -int is_internal_vport(const struct vport *); - int is_internal_dev(const struct net_device *); struct vport *internal_dev_get_vport(struct net_device *); diff --git a/datapath/vport-netdev.c b/datapath/vport-netdev.c index dbc8db2..ca20ce5 100644 --- a/datapath/vport-netdev.c +++ b/datapath/vport-netdev.c @@ -191,12 +191,6 @@ static int netdev_destroy(struct vport *vport) return 0; } -int netdev_set_mtu(struct vport *vport, int mtu) -{ - struct netdev_vport *netdev_vport = netdev_vport_priv(vport); - return dev_set_mtu(netdev_vport->dev, mtu); -} - int netdev_set_addr(struct vport *vport, const unsigned char *addr) { struct netdev_vport *netdev_vport = netdev_vport_priv(vport); @@ -257,12 +251,6 @@ int netdev_get_ifindex(const struct vport *vport) return netdev_vport->dev->ifindex; } -int netdev_get_mtu(const struct vport *vport) -{ - const struct netdev_vport *netdev_vport = netdev_vport_priv(vport); - return netdev_vport->dev->mtu; -} - /* Must be called with rcu_read_lock. */ static void netdev_port_receive(struct vport *vport, struct sk_buff *skb) { @@ -428,7 +416,6 @@ const struct vport_ops netdev_vport_ops = { .exit = netdev_exit, .create = netdev_create, .destroy = netdev_destroy, - .set_mtu = netdev_set_mtu, .set_addr = netdev_set_addr, .get_name = netdev_get_name, .get_addr = netdev_get_addr, @@ -438,7 +425,6 @@ const struct vport_ops netdev_vport_ops = { .is_running = netdev_is_running, .get_operstate = netdev_get_operstate, .get_ifindex = netdev_get_ifindex, - .get_mtu = netdev_get_mtu, .send = netdev_send, }; diff --git a/datapath/vport-netdev.h b/datapath/vport-netdev.h index 3f64767..e521b2d 100644 --- a/datapath/vport-netdev.h +++ b/datapath/vport-netdev.h @@ -25,7 +25,6 @@ netdev_vport_priv(const struct vport *vport) return vport_priv(vport); } -int netdev_set_mtu(struct vport *, int mtu); int netdev_set_addr(struct vport *, const unsigned char *addr); const char *netdev_get_name(const struct vport *); const unsigned char *netdev_get_addr(const struct vport *); @@ -36,6 +35,5 @@ unsigned netdev_get_dev_flags(const struct vport *); int netdev_is_running(const struct vport *); unsigned char netdev_get_operstate(const struct vport *); int netdev_get_ifindex(const struct vport *); -int netdev_get_mtu(const struct vport *); #endif /* vport_netdev.h */ diff --git a/datapath/vport.c b/datapath/vport.c index bf6297e..791c0f5 100644 --- a/datapath/vport.c +++ b/datapath/vport.c @@ -285,36 +285,6 @@ int vport_del(struct vport *vport) } /** - * vport_set_mtu - set device MTU (for kernel callers) - * - * @vport: vport on which to set MTU. - * @mtu: New MTU. - * - * Sets the MTU of the given device. Some devices may not support setting the - * MTU, in which case the result will always be -EOPNOTSUPP. RTNL lock must - * be held. - */ -int vport_set_mtu(struct vport *vport, int mtu) -{ - ASSERT_RTNL(); - - if (mtu < 68) - return -EINVAL; - - if (vport->ops->set_mtu) { - int ret; - - ret = vport->ops->set_mtu(vport, mtu); - - if (!ret && !is_internal_vport(vport)) - set_internal_devs_mtu(vport->dp); - - return ret; - } else - return -EOPNOTSUPP; -} - -/** * vport_set_addr - set device Ethernet address (for kernel callers) * * @vport: vport on which to set Ethernet address. @@ -577,22 +547,6 @@ int vport_get_ifindex(const struct vport *vport) } /** - * vport_get_mtu - retrieve device MTU - * - * @vport: vport from which to retrieve MTU - * - * Retrieves the MTU of the given device. Returns 0 if @vport does not have an - * MTU (as e.g. some tunnels do not). Either RTNL lock or rcu_read_lock must - * be held. - */ -int vport_get_mtu(const struct vport *vport) -{ - if (!vport->ops->get_mtu) - return 0; - return vport->ops->get_mtu(vport); -} - -/** * vport_get_options - retrieve device options * * @vport: vport from which to retrieve the options. diff --git a/datapath/vport.h b/datapath/vport.h index 0a6d831..e4b6c62 100644 --- a/datapath/vport.h +++ b/datapath/vport.h @@ -30,7 +30,6 @@ int vport_del(struct vport *); struct vport *vport_locate(const char *name); -int vport_set_mtu(struct vport *, int mtu); int vport_set_addr(struct vport *, const unsigned char *); int vport_set_stats(struct vport *, struct rtnl_link_stats64 *); @@ -47,8 +46,6 @@ unsigned char vport_get_operstate(const struct vport *); int vport_get_ifindex(const struct vport *); -int vport_get_mtu(const struct vport *); - int vport_set_options(struct vport *, struct nlattr *options); int vport_get_options(const struct vport *, struct sk_buff *); @@ -156,7 +153,6 @@ struct vport_parms { * @get_options: Appends vport-specific attributes for the configuration of an * existing vport to a &struct sk_buff. May be %NULL for a vport that does not * have any configuration. - * @set_mtu: Set the device's MTU. May be null if not supported. * @set_addr: Set the device's MAC address. May be null if not supported. * @get_name: Get the device's name. * @get_addr: Get the device's MAC address. @@ -171,8 +167,6 @@ struct vport_parms { * @get_operstate: Get the device's operating state. * @get_ifindex: Get the system interface index associated with the device. * May be null if the device does not have an ifindex. - * @get_mtu: Get the device's MTU. May be %NULL if the device does not have an - * MTU (as e.g. some tunnels do not). * @send: Send a packet on the device. Returns the length of the packet sent. */ struct vport_ops { @@ -190,7 +184,6 @@ struct vport_ops { int (*set_options)(struct vport *, struct nlattr *); int (*get_options)(const struct vport *, struct sk_buff *); - int (*set_mtu)(struct vport *, int mtu); int (*set_addr)(struct vport *, const unsigned char *); /* Called with rcu_read_lock or RTNL lock. */ @@ -206,8 +199,6 @@ struct vport_ops { int (*get_ifindex)(const struct vport *); - int (*get_mtu)(const struct vport *); - int (*send)(struct vport *, struct sk_buff *); }; diff --git a/include/openvswitch/datapath-protocol.h b/include/openvswitch/datapath-protocol.h index 97a7c04..adc39d1 100644 --- a/include/openvswitch/datapath-protocol.h +++ b/include/openvswitch/datapath-protocol.h @@ -222,8 +222,6 @@ enum ovs_vport_cmd { * @OVS_VPORT_ATTR_STATS: A &struct rtnl_link_stats64 giving statistics for * packets sent or received through the vport. * @OVS_VPORT_ATTR_ADDRESS: A 6-byte Ethernet address for the vport. - * @OVS_VPORT_ATTR_MTU: MTU for the vport. Omitted if the vport does not have - * an MTU as, e.g., some tunnels do not. * @OVS_VPORT_ATTR_IFINDEX: ifindex of the underlying network device, if any. * * These attributes follow the &struct ovs_header within the Generic Netlink @@ -238,7 +236,6 @@ enum ovs_vport_cmd { * optional; if not specified a free port number is automatically selected. * Whether %OVS_VPORT_ATTR_OPTIONS is required or optional depends on the type * of vport. %OVS_VPORT_ATTR_STATS, %OVS_VPORT_ATTR_ADDRESS, and - * %OVS_VPORT_ATTR_MTU are optional, and other attributes are ignored. * * For other requests, if %OVS_VPORT_ATTR_NAME is specified then it is used to * look up the vport to operate on; otherwise dp_idx from the &struct @@ -251,7 +248,6 @@ enum ovs_vport_attr { OVS_VPORT_ATTR_NAME, /* string name, up to IFNAMSIZ bytes long */ OVS_VPORT_ATTR_STATS, /* struct rtnl_link_stats64 */ OVS_VPORT_ATTR_ADDRESS, /* hardware address */ - OVS_VPORT_ATTR_MTU, /* 32-bit maximum transmission unit */ OVS_VPORT_ATTR_OPTIONS, /* nested attributes, varies by vport type */ OVS_VPORT_ATTR_IFINDEX, /* 32-bit ifindex of backing netdev */ __OVS_VPORT_ATTR_MAX diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 8d655f3..9533e14 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -1238,7 +1238,6 @@ dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport, .min_len = ETH_ADDR_LEN, .max_len = ETH_ADDR_LEN, .optional = true }, - [OVS_VPORT_ATTR_MTU] = { .type = NL_A_U32, .optional = true }, [OVS_VPORT_ATTR_OPTIONS] = { .type = NL_A_NESTED, .optional = true }, [OVS_VPORT_ATTR_IFINDEX] = { .type = NL_A_U32, .optional = true }, }; @@ -1273,11 +1272,6 @@ dpif_linux_vport_from_ofpbuf(struct dpif_linux_vport *vport, if (a[OVS_VPORT_ATTR_ADDRESS]) { vport->address = nl_attr_get(a[OVS_VPORT_ATTR_ADDRESS]); } - if (a[OVS_VPORT_ATTR_MTU]) { - vport->mtu = nl_attr_get_u32(a[OVS_VPORT_ATTR_MTU]); - } else { - vport->mtu = INT_MAX; - } if (a[OVS_VPORT_ATTR_OPTIONS]) { vport->options = nl_attr_get(a[OVS_VPORT_ATTR_OPTIONS]); vport->options_len = nl_attr_get_size(a[OVS_VPORT_ATTR_OPTIONS]); @@ -1324,10 +1318,6 @@ dpif_linux_vport_to_ofpbuf(const struct dpif_linux_vport *vport, vport->address, ETH_ADDR_LEN); } - if (vport->mtu && vport->mtu != INT_MAX) { - nl_msg_put_u32(buf, OVS_VPORT_ATTR_MTU, vport->mtu); - } - if (vport->options) { nl_msg_put_nested(buf, OVS_VPORT_ATTR_OPTIONS, vport->options, vport->options_len); diff --git a/lib/dpif-linux.h b/lib/dpif-linux.h index 3a2c816..c673bee 100644 --- a/lib/dpif-linux.h +++ b/lib/dpif-linux.h @@ -36,7 +36,6 @@ struct dpif_linux_vport { const char *name; /* OVS_VPORT_ATTR_NAME. */ const struct rtnl_link_stats64 *stats; /* OVS_VPORT_ATTR_STATS. */ const uint8_t *address; /* OVS_VPORT_ATTR_ADDRESS. */ - int mtu; /* OVS_VPORT_ATTR_MTU. */ const struct nlattr *options; /* OVS_VPORT_ATTR_OPTIONS. */ size_t options_len; int ifindex; /* OVS_VPORT_ATTR_IFINDEX. */ diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index 4fb1151..c2c5311 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -172,6 +172,16 @@ netdev_dummy_get_mtu(const struct netdev *netdev, int *mtup) } static int +netdev_dummy_set_mtu(const struct netdev *netdev, int mtu) +{ + struct netdev_dev_dummy *dev = + netdev_dev_dummy_cast(netdev_get_dev(netdev)); + + dev->mtu = mtu; + return 0; +} + +static int netdev_dummy_get_stats(const struct netdev *netdev, struct netdev_stats *stats) { const struct netdev_dev_dummy *dev = @@ -259,6 +269,7 @@ static const struct netdev_class dummy_class = { netdev_dummy_set_etheraddr, netdev_dummy_get_etheraddr, netdev_dummy_get_mtu, + netdev_dummy_set_mtu, NULL, /* get_ifindex */ NULL, /* get_carrier */ NULL, /* get_miimon */ diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 6d44581..fc61d45 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -1000,6 +1000,29 @@ netdev_linux_get_mtu(const struct netdev *netdev_, int *mtup) return 0; } +/* Sets the maximum size of transmitted (MTU) for given device using linux + * networking ioctl interface. + */ +static int +netdev_linux_set_mtu(const struct netdev *netdev_, int mtu) +{ + struct netdev_dev_linux *netdev_dev = + netdev_dev_linux_cast(netdev_get_dev(netdev_)); + struct ifreq ifr; + int error; + + ifr.ifr_mtu = mtu; + error = netdev_linux_do_ioctl(netdev_get_name(netdev_), &ifr, + SIOCSIFMTU, "SIOCSIFMTU"); + if (error) { + return error; + } + + netdev_dev->mtu = ifr.ifr_mtu; + netdev_dev->cache_valid |= VALID_MTU; + return 0; +} + /* Returns the ifindex of 'netdev', if successful, as a positive number. * On failure, returns a negative errno value. */ static int @@ -2269,6 +2292,7 @@ netdev_linux_change_seq(const struct netdev *netdev) netdev_linux_set_etheraddr, \ netdev_linux_get_etheraddr, \ netdev_linux_get_mtu, \ + netdev_linux_set_mtu, \ netdev_linux_get_ifindex, \ netdev_linux_get_carrier, \ netdev_linux_set_miimon_interval, \ @@ -2412,11 +2436,11 @@ htb_setup_class__(struct netdev *netdev, unsigned int handle, int error; int mtu; - netdev_get_mtu(netdev, &mtu); - if (mtu == INT_MAX) { + error = netdev_get_mtu(netdev, &mtu); + if (error) { VLOG_WARN_RL(&rl, "cannot set up HTB on device %s that lacks MTU", netdev_get_name(netdev)); - return EINVAL; + return error; } memset(&opt, 0, sizeof opt); @@ -2535,13 +2559,13 @@ htb_parse_class_details__(struct netdev *netdev, const char *max_rate_s = shash_find_data(details, "max-rate"); const char *burst_s = shash_find_data(details, "burst"); const char *priority_s = shash_find_data(details, "priority"); - int mtu; + int mtu, error; - netdev_get_mtu(netdev, &mtu); - if (mtu == INT_MAX) { + error = netdev_get_mtu(netdev, &mtu); + if (error) { VLOG_WARN_RL(&rl, "cannot parse HTB class on device %s that lacks MTU", netdev_get_name(netdev)); - return EINVAL; + return error; } /* HTB requires at least an mtu sized min-rate to send any traffic even diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h index 5214be3..d38dd5f 100644 --- a/lib/netdev-provider.h +++ b/lib/netdev-provider.h @@ -248,9 +248,15 @@ struct netdev_class { * bytes for Ethernet devices. * * If 'netdev' does not have an MTU (e.g. as some tunnels do not), then - * this function should set '*mtup' to INT_MAX. */ + * this function should return ENOTSUP. */ int (*get_mtu)(const struct netdev *netdev, int *mtup); + /* Sets 'netdev''s MTU to 'mtu'. + * + * If 'netdev' does not have an MTU (e.g. as some tunnels do not), then + * this function should return ENOTSUP. */ + int (*set_mtu)(const struct netdev *netdev, int mtu); + /* Returns the ifindex of 'netdev', if successful, as a positive number. * On failure, returns a negative errno value. * diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index 15bf8bd..3bdb022 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -362,18 +362,17 @@ netdev_vport_get_etheraddr(const struct netdev *netdev, } static int -netdev_vport_get_mtu(const struct netdev *netdev, int *mtup) +netdev_vport_get_mtu(const struct netdev *netdev OVS_UNUSED, + int *mtup OVS_UNUSED) { - struct dpif_linux_vport reply; - struct ofpbuf *buf; - int error; + return ENOTSUP; +} - error = dpif_linux_vport_get(netdev_get_name(netdev), &reply, &buf); - if (!error) { - *mtup = reply.mtu; - ofpbuf_delete(buf); - } - return error; +static int +netdev_vport_set_mtu(const struct netdev *netdev OVS_UNUSED, + int mtu OVS_UNUSED) +{ + return ENOTSUP; } int @@ -876,6 +875,7 @@ unparse_patch_config(const char *name OVS_UNUSED, const char *type OVS_UNUSED, netdev_vport_set_etheraddr, \ netdev_vport_get_etheraddr, \ netdev_vport_get_mtu, \ + netdev_vport_set_mtu, \ NULL, /* get_ifindex */ \ NULL, /* get_carrier */ \ NULL, /* get_miimon */ \ diff --git a/lib/netdev.c b/lib/netdev.c index 12ac81d..4295f6b 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -510,19 +510,36 @@ netdev_get_name(const struct netdev *netdev) * (and received) packets, in bytes, not including the hardware header; thus, * this is typically 1500 bytes for Ethernet devices. * - * If successful, returns 0 and stores the MTU size in '*mtup'. Stores INT_MAX - * in '*mtup' if 'netdev' does not have an MTU (as e.g. some tunnels do not).On - * failure, returns a positive errno value and stores ETH_PAYLOAD_MAX (1500) in - * '*mtup'. */ + * If successful, returns 0 and stores the MTU size in '*mtup'. returns + * ENOTSUP if 'netdev' does not have an MTU (as e.g. some tunnels do not). On + * other failure, returns a positive errno value. */ int netdev_get_mtu(const struct netdev *netdev, int *mtup) { int error = netdev_get_dev(netdev)->netdev_class->get_mtu(netdev, mtup); - if (error) { + if (error && error != ENOTSUP) { + VLOG_WARN_RL(&rl, "failed to retrieve MTU for network device %s: %s", + netdev_get_name(netdev), strerror(error)); + } + return error; +} + +/* Sets the MTU of 'netdev'. The MTU is the maximum size of transmitted + * (and received) packets, in bytes. + * + * If successful, returns 0. returns ENOTSUP if 'netdev' does not have an + * MTU (as e.g. some tunnels do not). On other failure, returns a positive + * errno value. */ +int +netdev_set_mtu(const struct netdev *netdev, int mtu) +{ + int error = netdev_get_dev(netdev)->netdev_class->set_mtu(netdev, mtu); + + if (error && error != ENOTSUP) { VLOG_WARN_RL(&rl, "failed to retrieve MTU for network device %s: %s", netdev_get_name(netdev), strerror(error)); - *mtup = ETH_PAYLOAD_MAX; } + return error; } diff --git a/lib/netdev.h b/lib/netdev.h index 13d2ee7..2644708 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -100,6 +100,7 @@ int netdev_get_config(const struct netdev *, struct shash *); const char *netdev_get_name(const struct netdev *); const char *netdev_get_type(const struct netdev *); int netdev_get_mtu(const struct netdev *, int *mtup); +int netdev_set_mtu(const struct netdev *, int mtu); int netdev_get_ifindex(const struct netdev *); /* Packet send and receive. */ diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 2bfd926..5d342e3 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1245,7 +1245,7 @@ iface_refresh_status(struct iface *iface) iface_get_carrier(iface) ? "up" : "down"); error = netdev_get_mtu(iface->netdev, &mtu); - if (!error && mtu != INT_MAX) { + if (!error) { mtu_64 = mtu; ovsrec_interface_set_mtu(iface->cfg, &mtu_64, 1); } -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev