Use netlink when setting the default ipv4 gateway.
This commit is contained in:
parent
9de62e7b75
commit
8a24f74a11
115
ndhc/ifset.c
115
ndhc/ifset.c
@ -241,6 +241,58 @@ static ssize_t rtnl_addr_broadcast_send(int fd, int type, int ifa_flags,
|
|||||||
return rtnl_do_send(fd, request, header->nlmsg_len, __func__);
|
return rtnl_do_send(fd, request, header->nlmsg_len, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t rtnl_set_default_gw_v4(int fd, uint32_t gw4, int metric)
|
||||||
|
{
|
||||||
|
uint8_t request[NLMSG_ALIGN(sizeof(struct nlmsghdr)) +
|
||||||
|
NLMSG_ALIGN(sizeof(struct ifinfomsg)) +
|
||||||
|
RTA_LENGTH(sizeof(uint32_t))];
|
||||||
|
struct nlmsghdr *header;
|
||||||
|
struct rtmsg *rtmsg;
|
||||||
|
|
||||||
|
memset(&request, 0, sizeof request);
|
||||||
|
header = (struct nlmsghdr *)request;
|
||||||
|
header->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
|
||||||
|
header->nlmsg_type = RTM_NEWROUTE;
|
||||||
|
header->nlmsg_flags = NLM_F_REPLACE | NLM_F_ACK | NLM_F_REQUEST;
|
||||||
|
header->nlmsg_seq = ifset_nl_seq++;
|
||||||
|
|
||||||
|
rtmsg = NLMSG_DATA(header);
|
||||||
|
rtmsg->rtm_family = AF_INET;
|
||||||
|
rtmsg->rtm_table = RT_TABLE_DEFAULT;
|
||||||
|
rtmsg->rtm_protocol = RTPROT_STATIC;
|
||||||
|
rtmsg->rtm_scope = RT_SCOPE_UNIVERSE;
|
||||||
|
rtmsg->rtm_type = RTN_UNICAST;
|
||||||
|
|
||||||
|
uint32_t dstaddr4 = 0;
|
||||||
|
if (nl_add_rtattr(header, sizeof request, RTA_DST,
|
||||||
|
&dstaddr4, sizeof dstaddr4) < 0) {
|
||||||
|
log_line("%s: (%s) couldn't add RTA_DST to nlmsg",
|
||||||
|
client_config.interface, __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (nl_add_rtattr(header, sizeof request, RTA_OIF,
|
||||||
|
&client_config.ifindex,
|
||||||
|
sizeof client_config.ifindex) < 0) {
|
||||||
|
log_line("%s: (%s) couldn't add RTA_OIF to nlmsg",
|
||||||
|
client_config.interface, __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (nl_add_rtattr(header, sizeof request, RTA_GATEWAY,
|
||||||
|
&gw4, sizeof gw4) < 0) {
|
||||||
|
log_line("%s: (%s) couldn't add RTA_GATEWAY to nlmsg",
|
||||||
|
client_config.interface, __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (nl_add_rtattr(header, sizeof request, RTA_METRICS,
|
||||||
|
&metric, sizeof metric) < 0) {
|
||||||
|
log_line("%s: (%s) couldn't add RTA_METRICS to nlmsg",
|
||||||
|
client_config.interface, __func__);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtnl_do_send(fd, request, header->nlmsg_len, __func__);
|
||||||
|
}
|
||||||
|
|
||||||
struct link_flag_data {
|
struct link_flag_data {
|
||||||
int fd;
|
int fd;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
@ -478,50 +530,33 @@ void perform_ip_subnet_bcast(const char *str_ipaddr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void perform_router(const char *str, size_t len)
|
void perform_router(const char *str_router, size_t len)
|
||||||
{
|
{
|
||||||
struct rtentry rt;
|
if (!str_router)
|
||||||
struct sockaddr_in *dest;
|
return;
|
||||||
struct sockaddr_in *gateway;
|
if (len < 7)
|
||||||
struct sockaddr_in *mask;
|
return;
|
||||||
struct in_addr router;
|
struct in_addr router;
|
||||||
int fd;
|
if (inet_pton(AF_INET, str_router, &router) <= 0) {
|
||||||
|
log_line("%s: (%s) bad router ip address: '%s'",
|
||||||
if (!str)
|
client_config.interface, __func__, str_router);
|
||||||
return;
|
|
||||||
if (len < 4)
|
|
||||||
return;
|
|
||||||
if (inet_pton(AF_INET, str, &router) <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
memset(&rt, 0, sizeof(struct rtentry));
|
|
||||||
dest = (struct sockaddr_in *) &rt.rt_dst;
|
|
||||||
dest->sin_family = AF_INET;
|
|
||||||
dest->sin_addr.s_addr = 0x00000000;
|
|
||||||
gateway = (struct sockaddr_in *) &rt.rt_gateway;
|
|
||||||
gateway->sin_family = AF_INET;
|
|
||||||
gateway->sin_addr = router;
|
|
||||||
mask = (struct sockaddr_in *) &rt.rt_genmask;
|
|
||||||
mask->sin_family = AF_INET;
|
|
||||||
mask->sin_addr.s_addr = 0x00000000;
|
|
||||||
|
|
||||||
rt.rt_flags = RTF_UP | RTF_GATEWAY;
|
|
||||||
if (mask->sin_addr.s_addr == 0xffffffff) rt.rt_flags |= RTF_HOST;
|
|
||||||
rt.rt_dev = client_config.interface;
|
|
||||||
rt.rt_metric = 1;
|
|
||||||
|
|
||||||
fd = socket(AF_INET, SOCK_DGRAM, 0);
|
|
||||||
if (fd == -1) {
|
|
||||||
log_line("%s: (perform_router) failed to open interface socket: %s",
|
|
||||||
client_config.interface, strerror(errno));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ioctl(fd, SIOCADDRT, &rt)) {
|
|
||||||
if (errno != EEXIST)
|
int fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
||||||
log_line("%s: failed to set route: %s",
|
if (fd < 0) {
|
||||||
client_config.interface, strerror(errno));
|
log_line("%s: (%s) netlink socket open failed: %s",
|
||||||
} else
|
client_config.interface, __func__, strerror(errno));
|
||||||
log_line("Gateway router set to: '%s'", str);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: Probably need to clear out the old default gw.
|
||||||
|
|
||||||
|
if (rtnl_set_default_gw_v4(fd, router.s_addr, 1) < 0)
|
||||||
|
log_line("%s: (%s) failed to set route: %s",
|
||||||
|
client_config.interface, __func__, strerror(errno));
|
||||||
|
else
|
||||||
|
log_line("Gateway router set to: '%s'", str_router);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user