continue;
dev_mtu = vport_get_mtu(p);
+ if (!dev_mtu)
+ continue;
if (!mtu || dev_mtu < mtu)
mtu = dev_mtu;
}
struct odp_header *odp_header;
struct nlattr *nla;
int ifindex, iflink;
+ int mtu;
int err;
odp_header = genlmsg_put(skb, pid, seq, &dp_vport_genl_family,
NLA_PUT(skb, ODP_VPORT_ATTR_ADDRESS, ETH_ALEN, vport_get_addr(vport));
- NLA_PUT_U32(skb, ODP_VPORT_ATTR_MTU, vport_get_mtu(vport));
+ mtu = vport_get_mtu(vport);
+ if (mtu)
+ NLA_PUT_U32(skb, ODP_VPORT_ATTR_MTU, mtu);
err = vport_get_options(vport, skb);
if (err == -EMSGSIZE)
}
#endif
- total_length = min(total_length, mutable->mtu);
payload_length = total_length - header_length;
nskb = dev_alloc_skb(NET_IP_ALIGN + eth_hdr_len + header_length +
}
vport_gen_rand_ether_addr(mutable->eth_addr);
- mutable->mtu = ETH_DATA_LEN;
get_random_bytes(&initial_frag_id, sizeof(int));
atomic_set(&tnl_vport->frag_id, initial_frag_id);
old_mutable = rtnl_dereference(tnl_vport->mutable);
mutable->seq = old_mutable->seq + 1;
memcpy(mutable->eth_addr, old_mutable->eth_addr, ETH_ALEN);
- mutable->mtu = old_mutable->mtu;
/* Parse the others configured by userspace. */
err = tnl_set_config(options, tnl_vport->tnl_ops, vport, mutable);
return 0;
}
-int tnl_set_mtu(struct vport *vport, int mtu)
-{
- struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
- struct tnl_mutable_config *mutable;
-
- mutable = kmemdup(rtnl_dereference(tnl_vport->mutable),
- sizeof(struct tnl_mutable_config), GFP_KERNEL);
- if (!mutable)
- return -ENOMEM;
-
- mutable->mtu = mtu;
- assign_config_rcu(vport, mutable);
-
- return 0;
-}
-
int tnl_set_addr(struct vport *vport, const unsigned char *addr)
{
struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
return rcu_dereference_rtnl(tnl_vport->mutable)->eth_addr;
}
-int tnl_get_mtu(const struct vport *vport)
-{
- const struct tnl_vport *tnl_vport = tnl_vport_priv(vport);
- return rcu_dereference_rtnl(tnl_vport->mutable)->mtu;
-}
-
void tnl_free_linked_skbs(struct sk_buff *skb)
{
if (unlikely(!skb))
* @tunnel_hlen: Tunnel header length.
* @eth_addr: Source address for packets generated by tunnel itself
* (e.g. ICMP fragmentation needed messages).
- * @mtu: MTU of tunnel.
* @in_key: Key to match on input, 0 for wildcard.
* @out_key: Key to use on output, 0 if this tunnel has no fixed output key.
* @flags: TNL_F_* flags.
unsigned tunnel_hlen;
unsigned char eth_addr[ETH_ALEN];
- unsigned mtu;
/* Configured via ODP_TUNNEL_ATTR_* attributes. */
__be64 in_key;
int tnl_set_options(struct vport *, struct nlattr *);
int tnl_get_options(const struct vport *, struct sk_buff *);
-int tnl_set_mtu(struct vport *vport, int mtu);
int tnl_set_addr(struct vport *vport, const unsigned char *addr);
const char *tnl_get_name(const struct vport *vport);
const unsigned char *tnl_get_addr(const struct vport *vport);
-int tnl_get_mtu(const struct vport *vport);
int tnl_send(struct vport *vport, struct sk_buff *skb);
void tnl_rcv(struct vport *vport, struct sk_buff *skb);
.exit = capwap_exit,
.create = capwap_create,
.destroy = tnl_destroy,
- .set_mtu = tnl_set_mtu,
.set_addr = tnl_set_addr,
.get_name = tnl_get_name,
.get_addr = tnl_get_addr,
.get_dev_flags = vport_gen_get_dev_flags,
.is_running = vport_gen_is_running,
.get_operstate = vport_gen_get_operstate,
- .get_mtu = tnl_get_mtu,
.send = tnl_send,
};
.exit = gre_exit,
.create = gre_create,
.destroy = tnl_destroy,
- .set_mtu = tnl_set_mtu,
.set_addr = tnl_set_addr,
.get_name = tnl_get_name,
.get_addr = tnl_get_addr,
.get_dev_flags = vport_gen_get_dev_flags,
.is_running = vport_gen_is_running,
.get_operstate = vport_gen_get_operstate,
- .get_mtu = tnl_get_mtu,
.send = tnl_send,
};
char peer_name[IFNAMSIZ];
unsigned char eth_addr[ETH_ALEN];
- unsigned int mtu;
};
struct patch_vport {
vport_gen_rand_ether_addr(patchconf->eth_addr);
- /* Make the default MTU fairly large so that it doesn't become the
- * bottleneck on systems using jumbo frames. */
- patchconf->mtu = 65535;
-
rcu_assign_pointer(patch_vport->patchconf, patchconf);
peer_name = patchconf->peer_name;
}
}
-static int patch_set_mtu(struct vport *vport, int mtu)
-{
- struct patch_vport *patch_vport = patch_vport_priv(vport);
- struct patch_config *patchconf;
-
- patchconf = kmemdup(rtnl_dereference(patch_vport->patchconf),
- sizeof(struct patch_config), GFP_KERNEL);
- if (!patchconf)
- return -ENOMEM;
-
- patchconf->mtu = mtu;
- assign_config_rcu(vport, patchconf);
-
- return 0;
-}
-
static int patch_set_addr(struct vport *vport, const unsigned char *addr)
{
struct patch_vport *patch_vport = patch_vport_priv(vport);
return nla_put_string(skb, ODP_PATCH_ATTR_PEER, patchconf->peer_name);
}
-static int patch_get_mtu(const struct vport *vport)
-{
- const struct patch_vport *patch_vport = patch_vport_priv(vport);
- return rcu_dereference_rtnl(patch_vport->patchconf)->mtu;
-}
-
static int patch_send(struct vport *vport, struct sk_buff *skb)
{
struct patch_vport *patch_vport = patch_vport_priv(vport);
.exit = patch_exit,
.create = patch_create,
.destroy = patch_destroy,
- .set_mtu = patch_set_mtu,
.set_addr = patch_set_addr,
.get_name = patch_get_name,
.get_addr = patch_get_addr,
.get_dev_flags = vport_gen_get_dev_flags,
.is_running = vport_gen_is_running,
.get_operstate = vport_gen_get_operstate,
- .get_mtu = patch_get_mtu,
.send = patch_send,
};
*
* @vport: vport from which to retrieve MTU
*
- * Retrieves the MTU of the given device.
- *
- * Must be called with RTNL lock or rcu_read_lock.
+ * 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);
}
int sent;
mtu = vport_get_mtu(vport);
- if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) {
+ if (mtu && unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) {
if (net_ratelimit())
pr_warn("%s: dropped over-mtu packet: %d > %d\n",
dp_name(vport->dp), packet_length(skb), mtu);
* @get_iflink: Get the system interface index associated with the device that
* will be used to send packets (may be different than ifindex for tunnels).
* May be null if the device does not have an iflink.
- * @get_mtu: Get the device's MTU.
+ * @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 {
* @ODP_VPORT_ATTR_STATS: A &struct rtnl_link_stats64 giving statistics for
* packets sent or received through the vport.
* @ODP_VPORT_ATTR_ADDRESS: A 6-byte Ethernet address for the vport.
- * @ODP_VPORT_ATTR_MTU: MTU for the vport.
+ * @ODP_VPORT_ATTR_MTU: MTU for the vport. Omitted if the vport does not have
+ * an MTU as, e.g., some tunnels do not.
* @ODP_VPORT_ATTR_IFINDEX: ifindex of the underlying network device, if any.
* @ODP_VPORT_ATTR_IFLINK: ifindex of the device on which packets are sent (for
* tunnels), if any.
/*
- * Copyright (c) 2008, 2009, 2010 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
const char *cli_name = dhclient_get_name(cli);
uint8_t cli_mac[ETH_ADDR_LEN];
struct ofpbuf b;
- int mtu;
- netdev_get_mtu(cli->netdev, &mtu);
- ofpbuf_init(&b, mtu + VLAN_ETH_HEADER_LEN);
+ ofpbuf_init(&b, ETH_TOTAL_MAX + VLAN_ETH_HEADER_LEN);
netdev_get_etheraddr(cli->netdev, cli_mac);
for (; cli->received < 50; cli->received++) {
const struct ip_header *ip;
}
if (a[ODP_VPORT_ATTR_MTU]) {
vport->mtu = nl_attr_get_u32(a[ODP_VPORT_ATTR_MTU]);
+ } else {
+ vport->mtu = INT_MAX;
}
if (a[ODP_VPORT_ATTR_OPTIONS]) {
vport->options = nl_attr_get(a[ODP_VPORT_ATTR_OPTIONS]);
vport->address, ETH_ADDR_LEN);
}
- if (vport->mtu) {
+ if (vport->mtu && vport->mtu != INT_MAX) {
nl_msg_put_u32(buf, ODP_VPORT_ATTR_MTU, vport->mtu);
}
port->internal = internal;
netdev_get_mtu(netdev, &mtu);
- if (mtu > max_mtu) {
+ if (mtu != INT_MAX && mtu > max_mtu) {
max_mtu = mtu;
}
int mtu;
netdev_get_mtu(netdev, &mtu);
+ if (mtu == INT_MAX) {
+ VLOG_WARN_RL(&rl, "cannot set up HTB on device %s that lacks MTU",
+ netdev_get_name(netdev));
+ return EINVAL;
+ }
memset(&opt, 0, sizeof opt);
tc_fill_rate(&opt.rate, class->min_rate, mtu);
const char *priority_s = shash_find_data(details, "priority");
int mtu;
+ netdev_get_mtu(netdev, &mtu);
+ if (mtu == INT_MAX) {
+ VLOG_WARN_RL(&rl, "cannot parse HTB class on device %s that lacks MTU",
+ netdev_get_name(netdev));
+ return EINVAL;
+ }
+
/* min-rate. Don't allow a min-rate below 1500 bytes/s. */
if (!min_rate_s) {
/* min-rate is required. */
* doesn't include the Ethernet header, we need to add at least 14 (18?) to
* the MTU. We actually add 64, instead of 14, as a guard against
* additional headers get tacked on somewhere that we're not aware of. */
- netdev_get_mtu(netdev, &mtu);
hc->burst = burst_s ? strtoull(burst_s, NULL, 10) / 8 : 0;
hc->burst = MAX(hc->burst, mtu + 64);
/*
- * Copyright (c) 2009, 2010 Nicira Networks.
+ * Copyright (c) 2009, 2010, 2011 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
* The MTU is the maximum size of transmitted (and received) packets, in
* bytes, not including the hardware header; thus, this is typically 1500
- * bytes for Ethernet devices.*/
+ * 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. */
int (*get_mtu)(const struct netdev *netdev, int *mtup);
/* Returns the ifindex of 'netdev', if successful, as a positive number.
/*
- * Copyright (c) 2008, 2009, 2010 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* (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'. On failure,
- * returns a positive errno value and stores ETH_PAYLOAD_MAX (1500) in
+ * 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'. */
int
netdev_get_mtu(const struct netdev *netdev, int *mtup)
? "up" : "down");
error = netdev_get_mtu(iface->netdev, &mtu);
- if (!error) {
+ if (!error && mtu != INT_MAX) {
mtu_64 = mtu;
ovsrec_interface_set_mtu(iface->cfg, &mtu_64, 1);
}
and many kinds of virtual interfaces can be configured with
higher MTUs.
</p>
+ <p>
+ This column will be empty for an interface that does not
+ have an MTU as, for example, some kinds of tunnels do not.
+ </p>
</column>
<column name="status">