Signed-off-by: Christopher Schenk <cschenk@mail.uni-paderborn.de>
Acked-by: Selva Nair <selva.nair@gmail.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Message-Id: <20200421154612.14140-1-cschenk@mail.uni-paderborn.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg19803.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
| ... | ... |
@@ -39,7 +39,8 @@ typedef enum {
|
| 39 | 39 |
msg_del_block_dns, |
| 40 | 40 |
msg_register_dns, |
| 41 | 41 |
msg_enable_dhcp, |
| 42 |
- msg_register_ring_buffers |
|
| 42 |
+ msg_register_ring_buffers, |
|
| 43 |
+ msg_set_mtu |
|
| 43 | 44 |
} message_type_t; |
| 44 | 45 |
|
| 45 | 46 |
typedef struct {
|
| ... | ... |
@@ -127,4 +128,11 @@ typedef struct {
|
| 127 | 127 |
HANDLE receive_tail_moved; |
| 128 | 128 |
} register_ring_buffers_message_t; |
| 129 | 129 |
|
| 130 |
+typedef struct {
|
|
| 131 |
+ message_header_t header; |
|
| 132 |
+ interface_t iface; |
|
| 133 |
+ short family; |
|
| 134 |
+ int mtu; |
|
| 135 |
+} set_mtu_message_t; |
|
| 136 |
+ |
|
| 130 | 137 |
#endif /* ifndef OPENVPN_MSG_H_ */ |
| ... | ... |
@@ -73,6 +73,10 @@ static void netsh_ifconfig(const struct tuntap_options *to, |
| 73 | 73 |
const in_addr_t netmask, |
| 74 | 74 |
const unsigned int flags); |
| 75 | 75 |
|
| 76 |
+static void windows_set_mtu(const int iface_index, |
|
| 77 |
+ const short family, |
|
| 78 |
+ const int mtu); |
|
| 79 |
+ |
|
| 76 | 80 |
static void netsh_set_dns6_servers(const struct in6_addr *addr_list, |
| 77 | 81 |
const int addr_len, |
| 78 | 82 |
const char *flex_name); |
| ... | ... |
@@ -214,6 +218,47 @@ out: |
| 214 | 214 |
return ret; |
| 215 | 215 |
} |
| 216 | 216 |
|
| 217 |
+static bool |
|
| 218 |
+do_set_mtu_service(const struct tuntap *tt, const short family, const int mtu) |
|
| 219 |
+{
|
|
| 220 |
+ DWORD len; |
|
| 221 |
+ bool ret = false; |
|
| 222 |
+ ack_message_t ack; |
|
| 223 |
+ struct gc_arena gc = gc_new(); |
|
| 224 |
+ HANDLE pipe = tt->options.msg_channel; |
|
| 225 |
+ const char *family_name = (family == AF_INET6) ? "IPv6" : "IPv4"; |
|
| 226 |
+ set_mtu_message_t mtu_msg = {
|
|
| 227 |
+ .header = {
|
|
| 228 |
+ msg_set_mtu, |
|
| 229 |
+ sizeof(set_mtu_message_t), |
|
| 230 |
+ 0 |
|
| 231 |
+ }, |
|
| 232 |
+ .iface = {.index = tt->adapter_index,.name = tt->actual_name },
|
|
| 233 |
+ .mtu = mtu, |
|
| 234 |
+ .family = family |
|
| 235 |
+ }; |
|
| 236 |
+ |
|
| 237 |
+ if (!send_msg_iservice(pipe, &mtu_msg, sizeof(mtu_msg), &ack, "Set_mtu")) |
|
| 238 |
+ {
|
|
| 239 |
+ goto out; |
|
| 240 |
+ } |
|
| 241 |
+ |
|
| 242 |
+ if (ack.error_number != NO_ERROR) |
|
| 243 |
+ {
|
|
| 244 |
+ msg(M_NONFATAL, "TUN: setting %s mtu using service failed: %s [status=%u if_index=%d]", |
|
| 245 |
+ family_name, strerror_win32(ack.error_number, &gc), ack.error_number, mtu_msg.iface.index); |
|
| 246 |
+ } |
|
| 247 |
+ else |
|
| 248 |
+ {
|
|
| 249 |
+ msg(M_INFO, "%s MTU set to %d on interface %d using service", family_name, mtu, mtu_msg.iface.index); |
|
| 250 |
+ ret = true; |
|
| 251 |
+ } |
|
| 252 |
+ |
|
| 253 |
+out: |
|
| 254 |
+ gc_free(&gc); |
|
| 255 |
+ return ret; |
|
| 256 |
+} |
|
| 257 |
+ |
|
| 217 | 258 |
#endif /* ifdef _WIN32 */ |
| 218 | 259 |
|
| 219 | 260 |
#ifdef TARGET_SOLARIS |
| ... | ... |
@@ -1018,6 +1063,7 @@ do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu, |
| 1018 | 1018 |
do_address_service(true, AF_INET6, tt); |
| 1019 | 1019 |
add_route_connected_v6_net(tt, es); |
| 1020 | 1020 |
do_dns_service(true, AF_INET6, tt); |
| 1021 |
+ do_set_mtu_service(tt, AF_INET6, tun_mtu); |
|
| 1021 | 1022 |
} |
| 1022 | 1023 |
else |
| 1023 | 1024 |
{
|
| ... | ... |
@@ -1035,6 +1081,7 @@ do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu, |
| 1035 | 1035 |
add_route_connected_v6_net(tt, es); |
| 1036 | 1036 |
/* set ipv6 dns servers if any are specified */ |
| 1037 | 1037 |
netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, ifname); |
| 1038 |
+ windows_set_mtu(tt->adapter_index, AF_INET6, tun_mtu); |
|
| 1038 | 1039 |
} |
| 1039 | 1040 |
#else /* platforms we have no IPv6 code for */ |
| 1040 | 1041 |
msg(M_FATAL, "Sorry, but I don't know how to do IPv6 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script."); |
| ... | ... |
@@ -1404,6 +1451,14 @@ do_ifconfig_ipv4(struct tuntap *tt, const char *ifname, int tun_mtu, |
| 1404 | 1404 |
netsh_ifconfig(&tt->options, ifname, tt->local, |
| 1405 | 1405 |
tt->adapter_netmask, NI_IP_NETMASK|NI_OPTIONS); |
| 1406 | 1406 |
} |
| 1407 |
+ if (tt->options.msg_channel) |
|
| 1408 |
+ {
|
|
| 1409 |
+ do_set_mtu_service(tt, AF_INET, tun_mtu); |
|
| 1410 |
+ } |
|
| 1411 |
+ else |
|
| 1412 |
+ {
|
|
| 1413 |
+ windows_set_mtu(tt->adapter_index, AF_INET, tun_mtu); |
|
| 1414 |
+ } |
|
| 1407 | 1415 |
#else /* if defined(TARGET_LINUX) */ |
| 1408 | 1416 |
msg(M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script."); |
| 1409 | 1417 |
#endif /* if defined(TARGET_LINUX) */ |
| ... | ... |
@@ -5432,6 +5487,40 @@ out: |
| 5432 | 5432 |
return ret; |
| 5433 | 5433 |
} |
| 5434 | 5434 |
|
| 5435 |
+static void |
|
| 5436 |
+windows_set_mtu(const int iface_index, const short family, |
|
| 5437 |
+ const int mtu) |
|
| 5438 |
+{
|
|
| 5439 |
+ DWORD err = 0; |
|
| 5440 |
+ struct gc_arena gc = gc_new(); |
|
| 5441 |
+ MIB_IPINTERFACE_ROW ipiface; |
|
| 5442 |
+ InitializeIpInterfaceEntry(&ipiface); |
|
| 5443 |
+ const char *family_name = (family == AF_INET6) ? "IPv6" : "IPv4"; |
|
| 5444 |
+ ipiface.Family = family; |
|
| 5445 |
+ ipiface.InterfaceIndex = iface_index; |
|
| 5446 |
+ err = GetIpInterfaceEntry(&ipiface); |
|
| 5447 |
+ if (err == NO_ERROR) |
|
| 5448 |
+ {
|
|
| 5449 |
+ if (family == AF_INET) |
|
| 5450 |
+ {
|
|
| 5451 |
+ ipiface.SitePrefixLength = 0; |
|
| 5452 |
+ } |
|
| 5453 |
+ ipiface.NlMtu = mtu; |
|
| 5454 |
+ err = SetIpInterfaceEntry(&ipiface); |
|
| 5455 |
+ } |
|
| 5456 |
+ |
|
| 5457 |
+ if (err != NO_ERROR) |
|
| 5458 |
+ {
|
|
| 5459 |
+ msg(M_WARN, "TUN: Setting %s mtu failed: %s [status=%u if_index=%d]", |
|
| 5460 |
+ family_name, strerror_win32(err, &gc), err, iface_index); |
|
| 5461 |
+ } |
|
| 5462 |
+ else |
|
| 5463 |
+ {
|
|
| 5464 |
+ msg(M_INFO, "Successfully set %s mtu on interface %d", family_name, iface_index); |
|
| 5465 |
+ } |
|
| 5466 |
+} |
|
| 5467 |
+ |
|
| 5468 |
+ |
|
| 5435 | 5469 |
/* |
| 5436 | 5470 |
* Return a TAP name for netsh commands. |
| 5437 | 5471 |
*/ |
| ... | ... |
@@ -1286,6 +1286,29 @@ HandleRegisterRingBuffers(const register_ring_buffers_message_t *rrb, HANDLE ovp |
| 1286 | 1286 |
return err; |
| 1287 | 1287 |
} |
| 1288 | 1288 |
|
| 1289 |
+static DWORD |
|
| 1290 |
+HandleMTUMessage(const set_mtu_message_t *mtu) |
|
| 1291 |
+{
|
|
| 1292 |
+ DWORD err = 0; |
|
| 1293 |
+ MIB_IPINTERFACE_ROW ipiface; |
|
| 1294 |
+ InitializeIpInterfaceEntry(&ipiface); |
|
| 1295 |
+ ipiface.Family = mtu->family; |
|
| 1296 |
+ ipiface.InterfaceIndex = mtu->iface.index; |
|
| 1297 |
+ err = GetIpInterfaceEntry(&ipiface); |
|
| 1298 |
+ if (err != NO_ERROR) |
|
| 1299 |
+ {
|
|
| 1300 |
+ return err; |
|
| 1301 |
+ } |
|
| 1302 |
+ if (mtu->family == AF_INET) |
|
| 1303 |
+ {
|
|
| 1304 |
+ ipiface.SitePrefixLength = 0; |
|
| 1305 |
+ } |
|
| 1306 |
+ ipiface.NlMtu = mtu->mtu; |
|
| 1307 |
+ |
|
| 1308 |
+ err = SetIpInterfaceEntry(&ipiface); |
|
| 1309 |
+ return err; |
|
| 1310 |
+} |
|
| 1311 |
+ |
|
| 1289 | 1312 |
static VOID |
| 1290 | 1313 |
HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t *ring_buffer_handles, |
| 1291 | 1314 |
DWORD bytes, DWORD count, LPHANDLE events, undo_lists_t *lists) |
| ... | ... |
@@ -1300,6 +1323,7 @@ HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t *ring_buffer_ |
| 1300 | 1300 |
dns_cfg_message_t dns; |
| 1301 | 1301 |
enable_dhcp_message_t dhcp; |
| 1302 | 1302 |
register_ring_buffers_message_t rrb; |
| 1303 |
+ set_mtu_message_t mtu; |
|
| 1303 | 1304 |
} msg; |
| 1304 | 1305 |
ack_message_t ack = {
|
| 1305 | 1306 |
.header = {
|
| ... | ... |
@@ -1374,6 +1398,13 @@ HandleMessage(HANDLE pipe, HANDLE ovpn_proc, ring_buffer_handles_t *ring_buffer_ |
| 1374 | 1374 |
} |
| 1375 | 1375 |
break; |
| 1376 | 1376 |
|
| 1377 |
+ case msg_set_mtu: |
|
| 1378 |
+ if (msg.header.size == sizeof(msg.mtu)) |
|
| 1379 |
+ {
|
|
| 1380 |
+ ack.error_number = HandleMTUMessage(&msg.mtu); |
|
| 1381 |
+ } |
|
| 1382 |
+ break; |
|
| 1383 |
+ |
|
| 1377 | 1384 |
default: |
| 1378 | 1385 |
ack.error_number = ERROR_MESSAGE_TYPE; |
| 1379 | 1386 |
MsgToEventLog(MSG_FLAGS_ERROR, TEXT("Unknown message type %d"), msg.header.type);
|