Linux-WireGuard
view release on metacpan or search on metacpan
libwireguard.c view on Meta::CPAN
if (ret != MNL_CB_OK)
return ret;
if (interface.name && interface.is_wireguard)
ret = string_list_add(list, interface.name);
if (ret < 0)
return ret;
if (nlh->nlmsg_type != NLMSG_DONE)
return MNL_CB_OK + 1;
return MNL_CB_OK;
}
static int fetch_device_names(struct string_list *list)
{
struct mnl_socket *nl = NULL;
char *rtnl_buffer = NULL;
size_t message_len;
unsigned int portid, seq;
ssize_t len;
int ret = 0;
struct nlmsghdr *nlh;
struct ifinfomsg *ifm;
ret = -ENOMEM;
rtnl_buffer = calloc(mnl_ideal_socket_buffer_size(), 1);
if (!rtnl_buffer)
goto cleanup;
nl = mnl_socket_open(NETLINK_ROUTE);
if (!nl) {
ret = -errno;
goto cleanup;
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
ret = -errno;
goto cleanup;
}
seq = time(NULL);
portid = mnl_socket_get_portid(nl);
nlh = mnl_nlmsg_put_header(rtnl_buffer);
nlh->nlmsg_type = RTM_GETLINK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_DUMP;
nlh->nlmsg_seq = seq;
ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
ifm->ifi_family = AF_UNSPEC;
message_len = nlh->nlmsg_len;
if (mnl_socket_sendto(nl, rtnl_buffer, message_len) < 0) {
ret = -errno;
goto cleanup;
}
another:
if ((len = mnl_socket_recvfrom(nl, rtnl_buffer, mnl_ideal_socket_buffer_size())) < 0) {
ret = -errno;
goto cleanup;
}
if ((len = mnl_cb_run(rtnl_buffer, len, seq, portid, read_devices_cb, list)) < 0) {
/* Netlink returns NLM_F_DUMP_INTR if the set of all tunnels changed
* during the dump. That's unfortunate, but is pretty common on busy
* systems that are adding and removing tunnels all the time. Rather
* than retrying, potentially indefinitely, we just work with the
* partial results. */
if (errno != EINTR) {
ret = -errno;
goto cleanup;
}
}
if (len == MNL_CB_OK + 1)
goto another;
ret = 0;
cleanup:
free(rtnl_buffer);
if (nl)
mnl_socket_close(nl);
return ret;
}
static int add_del_iface(const char *ifname, bool add)
{
struct mnl_socket *nl = NULL;
char *rtnl_buffer;
ssize_t len;
int ret;
struct nlmsghdr *nlh;
struct ifinfomsg *ifm;
struct nlattr *nest;
rtnl_buffer = calloc(mnl_ideal_socket_buffer_size(), 1);
if (!rtnl_buffer) {
ret = -ENOMEM;
goto cleanup;
}
nl = mnl_socket_open(NETLINK_ROUTE);
if (!nl) {
ret = -errno;
goto cleanup;
}
if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
ret = -errno;
goto cleanup;
}
nlh = mnl_nlmsg_put_header(rtnl_buffer);
nlh->nlmsg_type = add ? RTM_NEWLINK : RTM_DELLINK;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | (add ? NLM_F_CREATE | NLM_F_EXCL : 0);
nlh->nlmsg_seq = time(NULL);
ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
ifm->ifi_family = AF_UNSPEC;
mnl_attr_put_strz(nlh, IFLA_IFNAME, ifname);
nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
mnl_attr_put_strz(nlh, IFLA_INFO_KIND, WG_GENL_NAME);
mnl_attr_nest_end(nlh, nest);
if (mnl_socket_sendto(nl, rtnl_buffer, nlh->nlmsg_len) < 0) {
ret = -errno;
goto cleanup;
( run in 0.779 second using v1.01-cache-2.11-cpan-39bf76dae61 )