diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/dpif-linux.c | 10 | ||||
| -rw-r--r-- | lib/dpif-linux.h | 1 | ||||
| -rw-r--r-- | lib/dpif-netdev.c | 4 | ||||
| -rw-r--r-- | lib/netdev-dummy.c | 11 | ||||
| -rw-r--r-- | lib/netdev-linux.c | 38 | ||||
| -rw-r--r-- | lib/netdev-provider.h | 8 | ||||
| -rw-r--r-- | lib/netdev-vport.c | 20 | ||||
| -rw-r--r-- | lib/netdev.c | 29 | ||||
| -rw-r--r-- | lib/netdev.h | 1 |
9 files changed, 85 insertions, 37 deletions
diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 8d655f355..9533e1489 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 3a2c816ab..c673beeb3 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/dpif-netdev.c b/lib/dpif-netdev.c index 8aefaf9b0..b48be8617 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -378,8 +378,8 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type, port->netdev = netdev; port->internal = internal; - netdev_get_mtu(netdev, &mtu); - if (mtu != INT_MAX && mtu > max_mtu) { + error = netdev_get_mtu(netdev, &mtu); + if (!error) { max_mtu = mtu; } diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index 4fb11514c..c2c531116 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 6d44581bf..fc61d452d 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 5214be3fd..b8f652919 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 EOPNOTSUPP. */ 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 EOPNOTSUPP. */ + 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 c4c1e6b8d..f215ec6e0 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 EOPNOTSUPP; +} - 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 EOPNOTSUPP; } int @@ -874,6 +873,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 12ac81d6e..9fba077b6 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 + * EOPNOTSUPP 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 != EOPNOTSUPP) { + 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 EOPNOTSUPP 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 != EOPNOTSUPP) { 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 13d2ee76e..2644708b3 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. */ |
