Previously, if path MTU discovery was disabled we would use the
tunnel MTU instead of the underlying route's path MTU but otherwise
still do PMTUD. This doesn't make much sense because turning off
PMTUD really means to not check the size of the encapsulated packets
at all. This removes the disconnect and simplifies the logic.
Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
const struct tnl_mutable_config *mutable,
const struct rtable *rt, __be16 *frag_offp)
{
const struct tnl_mutable_config *mutable,
const struct rtable *rt, __be16 *frag_offp)
{
+ bool pmtud = mutable->flags & TNL_F_PMTUD;
+ __be16 frag_off = 0;
- frag_off = (mutable->flags & TNL_F_PMTUD) ? htons(IP_DF) : 0;
- if (frag_off)
+ if (pmtud) {
+ frag_off = htons(IP_DF);
+
mtu = dst_mtu(&rt_dst(rt))
- ETH_HLEN
- mutable->tunnel_hlen
mtu = dst_mtu(&rt_dst(rt))
- ETH_HLEN
- mutable->tunnel_hlen
- - (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q) ? VLAN_HLEN : 0);
- else
- mtu = mutable->mtu;
+ - (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q) ?
+ VLAN_HLEN : 0);
+ }
if (skb->protocol == htons(ETH_P_IP)) {
if (skb->protocol == htons(ETH_P_IP)) {
- struct iphdr *old_iph = ip_hdr(skb);
+ struct iphdr *iph = ip_hdr(skb);
+
+ frag_off |= iph->frag_off & htons(IP_DF);
- frag_off |= old_iph->frag_off & htons(IP_DF);
- mtu = max(mtu, IP_MIN_MTU);
+ if (pmtud && iph->frag_off & htons(IP_DF)) {
+ mtu = max(mtu, IP_MIN_MTU);
- if ((old_iph->frag_off & htons(IP_DF)) &&
- mtu < ntohs(old_iph->tot_len)) {
- if (tnl_frag_needed(vport, mutable, skb, mtu, OVS_CB(skb)->tun_id))
- goto drop;
+ if (ntohs(iph->tot_len) > mtu &&
+ tnl_frag_needed(vport, mutable, skb, mtu,
+ OVS_CB(skb)->tun_id))
+ return false;
}
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
else if (skb->protocol == htons(ETH_P_IPV6)) {
unsigned int packet_length = skb->len - ETH_HLEN
}
}
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
else if (skb->protocol == htons(ETH_P_IPV6)) {
unsigned int packet_length = skb->len - ETH_HLEN
- - (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q) ? VLAN_HLEN : 0);
-
- mtu = max(mtu, IPV6_MIN_MTU);
+ - (eth_hdr(skb)->h_proto == htons(ETH_P_8021Q) ?
+ VLAN_HLEN : 0);
/* IPv6 requires PMTUD if the packet is above the minimum MTU. */
if (packet_length > IPV6_MIN_MTU)
frag_off = htons(IP_DF);
/* IPv6 requires PMTUD if the packet is above the minimum MTU. */
if (packet_length > IPV6_MIN_MTU)
frag_off = htons(IP_DF);
- if (mtu < packet_length) {
- if (tnl_frag_needed(vport, mutable, skb, mtu, OVS_CB(skb)->tun_id))
- goto drop;
+ if (pmtud) {
+ mtu = max(mtu, IPV6_MIN_MTU);
+
+ if (packet_length > mtu &&
+ tnl_frag_needed(vport, mutable, skb, mtu,
+ OVS_CB(skb)->tun_id))
+ return false;
}
}
#endif
*frag_offp = frag_off;
return true;
}
}
#endif
*frag_offp = frag_off;
return true;
-
-drop:
- *frag_offp = 0;
- return false;
}
static void create_tunnel_header(const struct vport *vport,
}
static void create_tunnel_header(const struct vport *vport,
struct dst_entry *unattached_dst = NULL;
struct tnl_cache *cache;
int sent_len = 0;
struct dst_entry *unattached_dst = NULL;
struct tnl_cache *cache;
int sent_len = 0;
u8 ttl;
u8 inner_tos;
u8 tos;
u8 ttl;
u8 inner_tos;
u8 tos;