From 9c541721d318598db45986ee2fd61491fadb53d0 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 29 Dec 2012 20:05:55 +0100 Subject: nft: adapt chain rename to recent Patrick's updates This patch gets existing code in sync with Patrick's chain renaming new approach. Signed-off-by: Pablo Neira Ayuso --- include/linux/netfilter/nf_tables.h | 3 +- iptables/nft.c | 55 +++++++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h index 837bab32..bdab3f2e 100644 --- a/include/linux/netfilter/nf_tables.h +++ b/include/linux/netfilter/nf_tables.h @@ -73,11 +73,12 @@ enum nft_table_attributes { enum nft_chain_attributes { NFTA_CHAIN_UNSPEC, NFTA_CHAIN_TABLE, + NFTA_CHAIN_HANDLE, NFTA_CHAIN_NAME, NFTA_CHAIN_HOOK, NFTA_CHAIN_POLICY, NFTA_CHAIN_USE, - NFTA_CHAIN_NEW_NAME, + NFTA_CHAIN_TYPE, __NFTA_CHAIN_MAX }; #define NFTA_CHAIN_MAX (__NFTA_CHAIN_MAX - 1) diff --git a/iptables/nft.c b/iptables/nft.c index 1f5ecb70..46c8c948 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -1686,17 +1686,66 @@ err: return ret == 0 ? 1 : 0; } +static struct nft_chain * +nft_chain_find(struct nft_handle *h, const char *table, const char *chain) +{ + struct nft_chain_list *list; + struct nft_chain_list_iter *iter; + struct nft_chain *c; + + list = nft_chain_list_get(h); + if (list == NULL) { + DEBUGP("cannot allocate chain list\n"); + return NULL; + } + + iter = nft_chain_list_iter_create(list); + if (iter == NULL) { + DEBUGP("cannot allocate rule list iterator\n"); + return NULL; + } + + c = nft_chain_list_iter_next(iter); + while (c != NULL) { + const char *table_name = + nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_TABLE); + const char *chain_name = + nft_chain_attr_get_str(c, NFT_CHAIN_ATTR_NAME); + + if (strcmp(table, table_name) != 0) + goto next; + + if (strcmp(chain, chain_name) != 0) + goto next; + + return c; +next: + c = nft_chain_list_iter_next(iter); + } + return NULL; +} + int nft_chain_user_rename(struct nft_handle *h,const char *chain, const char *table, const char *newname) { char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; struct nft_chain *c; + uint64_t handle; int ret; /* If built-in chains don't exist for this table, create them */ nft_chain_builtin_init(h, table, NULL, NF_ACCEPT); + /* Find the old chain to be renamed */ + c = nft_chain_find(h, table, chain); + if (c == NULL) { + errno = ENOENT; + return -1; + } + handle = nft_chain_attr_get_u64(c, NFT_CHAIN_ATTR_HANDLE); + + /* Now prepare the new name for the chain */ c = nft_chain_alloc(); if (c == NULL) { DEBUGP("cannot allocate chain\n"); @@ -1704,11 +1753,11 @@ int nft_chain_user_rename(struct nft_handle *h,const char *chain, } nft_chain_attr_set(c, NFT_CHAIN_ATTR_TABLE, (char *)table); - nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)chain); - nft_chain_attr_set(c, NFT_CHAIN_ATTR_NEW_NAME, (char *)newname); + nft_chain_attr_set(c, NFT_CHAIN_ATTR_NAME, (char *)newname); + nft_chain_attr_set_u64(c, NFT_CHAIN_ATTR_HANDLE, handle); nlh = nft_chain_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN, AF_INET, - NLM_F_ACK|NLM_F_REPLACE, h->seq); + NLM_F_ACK, h->seq); nft_chain_nlmsg_build_payload(nlh, c); nft_chain_free(c); -- cgit v1.2.3