#include <time.h>
#include <stdarg.h>
#include <inttypes.h>
+#include <assert.h>
#include <xtables.h>
#include <libiptc/libxtc.h>
return ret;
}
+int nft_restart(struct nft_handle *h)
+{
+ mnl_socket_close(h->nl);
+
+ h->nl = mnl_socket_open(NETLINK_NETFILTER);
+ if (h->nl == NULL)
+ return -1;
+
+ if (mnl_socket_bind(h->nl, 0, MNL_SOCKET_AUTOPID) < 0)
+ return -1;
+
+ h->portid = mnl_socket_get_portid(h->nl);
+
+ return 0;
+}
+
int nft_init(struct nft_handle *h, struct builtin_table *t)
{
h->nl = mnl_socket_open(NETLINK_NETFILTER);
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct nftnl_chain_list *list;
+ int ret;
+retry:
list = nftnl_chain_list_alloc();
if (list == NULL) {
errno = ENOMEM;
nlh = nftnl_chain_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, h->family,
NLM_F_DUMP, h->seq);
- mnl_talk(h, nlh, nftnl_chain_list_cb, list);
+ ret = mnl_talk(h, nlh, nftnl_chain_list_cb, list);
+ if (ret < 0 && errno == EINTR) {
+ assert(nft_restart(h) >= 0);
+ nftnl_chain_list_free(list);
+ goto retry;
+ }
return list;
}
if (h->rule_cache)
return h->rule_cache;
+retry:
list = nftnl_rule_list_alloc();
if (list == NULL)
return 0;
ret = mnl_talk(h, nlh, nftnl_rule_list_cb, list);
if (ret < 0) {
+ if (errno == EINTR) {
+ assert(nft_restart(h) >= 0);
+ nftnl_rule_list_free(list);
+ goto retry;
+ }
+
nftnl_rule_list_free(list);
return NULL;
}
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
struct nftnl_table_list *list;
+ int ret;
+retry:
list = nftnl_table_list_alloc();
if (list == NULL)
return 0;
nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, h->family,
NLM_F_DUMP, h->seq);
- mnl_talk(h, nlh, nftnl_table_list_cb, list);
+ ret = mnl_talk(h, nlh, nftnl_table_list_cb, list);
+ if (ret < 0 && errno == EINTR) {
+ assert(nft_restart(h) >= 0);
+ nftnl_table_list_free(list);
+ goto retry;
+ }
return list;
}