- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, interface, sizeof(ifr.ifr_name)-1);
- ioctl(fd, SIOCGIFINDEX, &ifr);
- idx = ifr.ifr_ifindex;
- close(fd);
-
- if (ifr.ifr_ifindex == 0) {
- DBG("Cannot find device %s", interface);
- return -1;
- }
-
- netconfig_inet_prefix_s dst;
-
- ret = __netconfig_get_prefix(&dst, ip_addr, req.r.rtm_family);
- if (ret < 0)
- return -1;
-
- req.r.rtm_dst_len = dst.bitlen;
- if (dst.bytelen) {
- ret = addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen);
- if (ret < 0)
- return -1;
- }
-
- ret = addattr_l(&req.n, sizeof(req), RTA_OIF, &idx, sizeof(uint32_t));
- if (ret < 0)
- return -1;
-
- if (__netconfig_rtnl_talk(&rth, &req.n, 0, 0, NULL) < 0) {
- DBG("__netconfig_rtnl_talk failed");
- return -1;
- }
-
- return 0;
-}
-
-static void __netconfig_rtnl_close()
-{
- if (rth.fd >= 0) {
- close(rth.fd);
- rth.fd = -1;
- }
-}
-
-static int __netconfig_rtnl_open(netconfig_rtnl_s *rth, unsigned subscriptions,
- int protocol)
-{
- socklen_t addr_len;
- int sndbuf = 32768;
- int rcvbuf = 1024 * 1024;
- char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
-
- memset(rth, 0, sizeof(*rth));
-
- rth->fd = socket(AF_NETLINK, SOCK_RAW, protocol);
- if (rth->fd < 0) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Failed to open netlink socket: %s", error_buf);
- return -1;
- }
-
- if (setsockopt(rth->fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf)) < 0) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Failed to set option(SO_SNDBUF) on socket [Error: %s]", error_buf);
- return -1;
- }
-
- if (setsockopt(rth->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)) < 0) {
- strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
- DBG("Failed to set option(SO_RCVBUF) on socket [Error: %s]", error_buf);
- return -1;
- }
-
- memset(&rth->local, 0, sizeof(rth->local));
- rth->local.nl_family = AF_NETLINK;
- rth->local.nl_groups = subscriptions;