From 03bd10ed88fe714d0665f2b7f600851297c486cd Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Mon, 17 Mar 2014 03:16:02 -0400 Subject: [PATCH] When setting the MTU via netlink, we must be careful to preserve the link flags or bad things will happen (such as the link being set down). --- ndhc/ifset.c | 67 +++++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/ndhc/ifset.c b/ndhc/ifset.c index 107570a..46c029a 100644 --- a/ndhc/ifset.c +++ b/ndhc/ifset.c @@ -182,35 +182,6 @@ static ssize_t rtnl_if_flags_send(int fd, int type, int ifi_flags) return rtnl_do_send(fd, request, header->nlmsg_len, __func__); } -static ssize_t rtnl_if_mtu_set(int fd, unsigned int mtu) -{ - uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + - NLMSG_ALIGN(sizeof(struct ifinfomsg)) + - RTA_LENGTH(sizeof(unsigned int))]; - struct nlmsghdr *header; - struct ifinfomsg *ifinfomsg; - - memset(&request, 0, sizeof request); - header = (struct nlmsghdr *)request; - header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); - header->nlmsg_type = RTM_SETLINK; - header->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST; - header->nlmsg_seq = ifset_nl_seq++; - - ifinfomsg = NLMSG_DATA(header); - ifinfomsg->ifi_index = client_config.ifindex; - ifinfomsg->ifi_change = 0xffffffff; - - if (nl_add_rtattr(header, sizeof request, IFLA_MTU, - &mtu, sizeof mtu) < 0) { - log_line("%s: (%s) couldn't add IFLA_MTU to nlmsg", - client_config.interface, __func__); - return -1; - } - - return rtnl_do_send(fd, request, header->nlmsg_len, __func__); -} - static ssize_t rtnl_addr_broadcast_send(int fd, int type, int ifa_flags, int ifa_scope, uint32_t *ipaddr, uint32_t *bcast, uint8_t prefixlen) @@ -468,6 +439,44 @@ static int ipbcpfx_clear_others(int fd, uint32_t ipaddr, uint32_t bcast, return ipx.already_ok ? 1 : 0; } +static ssize_t rtnl_if_mtu_set(int fd, unsigned int mtu) +{ + uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + + NLMSG_ALIGN(sizeof(struct ifinfomsg)) + + RTA_LENGTH(sizeof(unsigned int))]; + struct nlmsghdr *header; + struct ifinfomsg *ifinfomsg; + uint32_t oldflags; + + int r = link_flags_get(fd, &oldflags); + if (r < 0) { + log_line("%s: (%s) failed to get old link flags: %u", + client_config.interface, __func__, r); + return -1; + } + + memset(&request, 0, sizeof request); + header = (struct nlmsghdr *)request; + header->nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)); + header->nlmsg_type = RTM_SETLINK; + header->nlmsg_flags = NLM_F_ACK | NLM_F_REQUEST; + header->nlmsg_seq = ifset_nl_seq++; + + ifinfomsg = NLMSG_DATA(header); + ifinfomsg->ifi_flags = oldflags; + ifinfomsg->ifi_index = client_config.ifindex; + ifinfomsg->ifi_change = 0xffffffff; + + if (nl_add_rtattr(header, sizeof request, IFLA_MTU, + &mtu, sizeof mtu) < 0) { + log_line("%s: (%s) couldn't add IFLA_MTU to nlmsg", + client_config.interface, __func__); + return -1; + } + + return rtnl_do_send(fd, request, header->nlmsg_len, __func__); +} + // str_bcast is optional. void perform_ip_subnet_bcast(const char *str_ipaddr, const char *str_subnet, const char *str_bcast)