59 const int table = RT_TABLE_MAIN)
63 struct nlmsghdr nlmsg_info;
64 struct rtmsg rtmsg_info;
68 struct rtattr *rtattr_ptr;
70 struct sockaddr_nl peer;
71 struct msghdr msg_info;
72 struct iovec iov_info;
73 netlink_req_t netlink_req;
75 ::memset(&peer, 0,
sizeof(peer));
76 peer.nl_family = AF_NETLINK;
81 ::memset(&msg_info, 0,
sizeof(msg_info));
82 msg_info.msg_name = (
void *)&peer;
83 msg_info.msg_namelen =
sizeof(peer);
85 ::memset(&netlink_req, 0,
sizeof(netlink_req));
87 rtmsg_len =
sizeof(
struct rtmsg);
90 rtattr_ptr = (
struct rtattr *)netlink_req.buffer;
92 rtattr_ptr->rta_len =
sizeof(
struct rtattr) + route.addr.size_bytes();
93 route.
addr.to_byte_string_variable(((
unsigned char *)rtattr_ptr) +
sizeof(
struct rtattr));
94 rtmsg_len += rtattr_ptr->rta_len;
97 rtattr_ptr = (
struct rtattr *)(((
unsigned char *)rtattr_ptr) + rtattr_ptr->rta_len);
98 rtattr_ptr->rta_type = RTA_OIF;
99 rtattr_ptr->rta_len =
sizeof(
struct rtattr) + 4;
100 ::memcpy(((
unsigned char *)rtattr_ptr) +
sizeof(
struct rtattr), &
if_index, 4);
101 rtmsg_len += rtattr_ptr->rta_len;
103 netlink_req.nlmsg_info.nlmsg_len = NLMSG_LENGTH(rtmsg_len);
107 netlink_req.nlmsg_info.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE;
108 netlink_req.nlmsg_info.nlmsg_type = RTM_NEWROUTE;
112 netlink_req.nlmsg_info.nlmsg_flags = NLM_F_REQUEST;
113 netlink_req.nlmsg_info.nlmsg_type = RTM_DELROUTE;
116 netlink_req.rtmsg_info.rtm_family = route.
addr.family();
117 netlink_req.rtmsg_info.rtm_table = table;
118 netlink_req.rtmsg_info.rtm_dst_len = route.
prefix_len;
120 netlink_req.rtmsg_info.rtm_protocol = RTPROT_STATIC;
121 netlink_req.rtmsg_info.rtm_scope = RT_SCOPE_UNIVERSE;
122 netlink_req.rtmsg_info.rtm_type = RTN_UNICAST;
124 iov_info.iov_base = (
void *)&netlink_req.nlmsg_info;
125 iov_info.iov_len = netlink_req.nlmsg_info.nlmsg_len;
126 msg_info.msg_iov = &iov_info;
127 msg_info.msg_iovlen = 1;
129 const ssize_t status = ::sendmsg(
fd(), &msg_info, 0);
132 const int eno = errno;