mirror of
https://github.com/openvswitch/ovs
synced 2025-08-30 22:05:19 +00:00
gre: Add support for path MTU discovery.
This allows path MTU discovery to properly work when used with bridging. While there was previously support for PMTUD it used the kernel's IP stack. This works fine for routing but when bridging it is possible that a complete network is operating over the bridge that the kernel has no knowledge of and the ICMP fragmentation needed packets are lost. When a packet arrives that is above the MTU of the tunnel, an ICMP message is synthesized and send back on the device that the original packet came from. This does not rely on the kernel IP stack and is therefore independent of the routing table. Both IPv4 and IPv6 are supported, including over VLANs. Other types of packets that are over the MTU are encapsulated and the outer packets are fragmented. This entire functionality is a layer violation since bridging operates at layer 2 and fragmentation is a function of layer 3. For this reason it is possible to disable PMTUD, which will provide complete transparency but will cause the outer IP packets to be fragmented.
This commit is contained in:
@@ -128,6 +128,7 @@ struct gre_config {
|
||||
bool have_out_key;
|
||||
bool in_csum;
|
||||
bool out_csum;
|
||||
bool pmtud;
|
||||
};
|
||||
|
||||
static struct {
|
||||
@@ -257,7 +258,6 @@ setup_gre_netlink(const char *name OVS_UNUSED,
|
||||
struct nlattr *info_data_hdr;
|
||||
uint16_t iflags = 0;
|
||||
uint16_t oflags = 0;
|
||||
uint8_t pmtudisc = 0;
|
||||
|
||||
VLOG_DBG("%s: attempting to create gre device using netlink", name);
|
||||
|
||||
@@ -316,7 +316,7 @@ setup_gre_netlink(const char *name OVS_UNUSED,
|
||||
nl_msg_put_u16(&request, IFLA_GRE_OFLAGS, oflags);
|
||||
nl_msg_put_u32(&request, IFLA_GRE_LOCAL, config->local_ip);
|
||||
nl_msg_put_u32(&request, IFLA_GRE_REMOTE, config->remote_ip);
|
||||
nl_msg_put_u8(&request, IFLA_GRE_PMTUDISC, pmtudisc);
|
||||
nl_msg_put_u8(&request, IFLA_GRE_PMTUDISC, config->pmtud);
|
||||
nl_msg_put_u8(&request, IFLA_GRE_TTL, IPDEFTTL);
|
||||
nl_msg_put_u8(&request, IFLA_GRE_TOS, config->tos);
|
||||
|
||||
@@ -376,6 +376,10 @@ setup_gre_ioctl(const char *name, struct gre_config *config, bool create)
|
||||
p.o_flags |= GRE_CSUM;
|
||||
}
|
||||
|
||||
if (config->pmtud) {
|
||||
p.iph.frag_off = htons(IP_DONT_FRAGMENT);
|
||||
}
|
||||
|
||||
strncpy(ifr.ifr_name, create ? GRE_IOCTL_DEVICE : name, IFNAMSIZ);
|
||||
ifr.ifr_ifru.ifru_data = (void *)&p;
|
||||
|
||||
@@ -489,6 +493,7 @@ setup_gre(const char *name, const struct shash *args, bool create)
|
||||
memset(&config, 0, sizeof config);
|
||||
config.in_csum = true;
|
||||
config.out_csum = true;
|
||||
config.pmtud = true;
|
||||
|
||||
SHASH_FOR_EACH (node, args) {
|
||||
if (!strcmp(node->name, "remote_ip")) {
|
||||
@@ -521,6 +526,10 @@ setup_gre(const char *name, const struct shash *args, bool create)
|
||||
config.in_csum = false;
|
||||
config.out_csum = false;
|
||||
}
|
||||
} else if (!strcmp(node->name, "pmtud")) {
|
||||
if (!strcmp(node->data, "false")) {
|
||||
config.pmtud = false;
|
||||
}
|
||||
} else {
|
||||
VLOG_WARN("unknown gre argument '%s'", node->name);
|
||||
}
|
||||
|
Reference in New Issue
Block a user