aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2013-12-26 10:49:03 -0500
committerPablo Neira Ayuso <pablo@netfilter.org>2014-01-03 18:23:11 -0500
commitc9c8e485978a308c8a359140da187d55120f8fee (patch)
tree084673372c2f76b1cd2378985e750ab95b1b1055 /net
parent720e0dfa3a86de3482d82fc1d37090eba1c460eb (diff)
netfilter: nf_tables: dump sets in all existing families
This patch allows you to dump all sets available in all of the registered families. This allows you to use NFPROTO_UNSPEC to dump all existing sets, similarly to other existing table, chain and rule operations. This patch is based on original patch from Arturo Borrero González. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nf_tables_api.c87
1 files changed, 78 insertions, 9 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 37f0e6988ec4..0d4b42df3350 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1904,12 +1904,14 @@ static int nft_ctx_init_from_setattr(struct nft_ctx *ctx,
1904{ 1904{
1905 struct net *net = sock_net(skb->sk); 1905 struct net *net = sock_net(skb->sk);
1906 const struct nfgenmsg *nfmsg = nlmsg_data(nlh); 1906 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
1907 const struct nft_af_info *afi; 1907 const struct nft_af_info *afi = NULL;
1908 const struct nft_table *table = NULL; 1908 const struct nft_table *table = NULL;
1909 1909
1910 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false); 1910 if (nfmsg->nfgen_family != NFPROTO_UNSPEC) {
1911 if (IS_ERR(afi)) 1911 afi = nf_tables_afinfo_lookup(net, nfmsg->nfgen_family, false);
1912 return PTR_ERR(afi); 1912 if (IS_ERR(afi))
1913 return PTR_ERR(afi);
1914 }
1913 1915
1914 if (nla[NFTA_SET_TABLE] != NULL) { 1916 if (nla[NFTA_SET_TABLE] != NULL) {
1915 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]); 1917 table = nf_tables_table_lookup(afi, nla[NFTA_SET_TABLE]);
@@ -2078,8 +2080,8 @@ done:
2078 return skb->len; 2080 return skb->len;
2079} 2081}
2080 2082
2081static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb, 2083static int nf_tables_dump_sets_family(struct nft_ctx *ctx, struct sk_buff *skb,
2082 struct netlink_callback *cb) 2084 struct netlink_callback *cb)
2083{ 2085{
2084 const struct nft_set *set; 2086 const struct nft_set *set;
2085 unsigned int idx = 0, s_idx = cb->args[0]; 2087 unsigned int idx = 0, s_idx = cb->args[0];
@@ -2111,6 +2113,61 @@ done:
2111 return skb->len; 2113 return skb->len;
2112} 2114}
2113 2115
2116static int nf_tables_dump_sets_all(struct nft_ctx *ctx, struct sk_buff *skb,
2117 struct netlink_callback *cb)
2118{
2119 const struct nft_set *set;
2120 unsigned int idx, s_idx = cb->args[0];
2121 const struct nft_af_info *afi;
2122 struct nft_table *table, *cur_table = (struct nft_table *)cb->args[2];
2123 struct net *net = sock_net(skb->sk);
2124 int cur_family = cb->args[3];
2125
2126 if (cb->args[1])
2127 return skb->len;
2128
2129 list_for_each_entry(afi, &net->nft.af_info, list) {
2130 if (cur_family) {
2131 if (afi->family != cur_family)
2132 continue;
2133
2134 cur_family = 0;
2135 }
2136
2137 list_for_each_entry(table, &afi->tables, list) {
2138 if (cur_table) {
2139 if (cur_table != table)
2140 continue;
2141
2142 cur_table = NULL;
2143 }
2144
2145 ctx->table = table;
2146 ctx->afi = afi;
2147 idx = 0;
2148 list_for_each_entry(set, &ctx->table->sets, list) {
2149 if (idx < s_idx)
2150 goto cont;
2151 if (nf_tables_fill_set(skb, ctx, set,
2152 NFT_MSG_NEWSET,
2153 NLM_F_MULTI) < 0) {
2154 cb->args[0] = idx;
2155 cb->args[2] = (unsigned long) table;
2156 cb->args[3] = afi->family;
2157 goto done;
2158 }
2159cont:
2160 idx++;
2161 }
2162 if (s_idx)
2163 s_idx = 0;
2164 }
2165 }
2166 cb->args[1] = 1;
2167done:
2168 return skb->len;
2169}
2170
2114static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb) 2171static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
2115{ 2172{
2116 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh); 2173 const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
@@ -2127,9 +2184,12 @@ static int nf_tables_dump_sets(struct sk_buff *skb, struct netlink_callback *cb)
2127 if (err < 0) 2184 if (err < 0)
2128 return err; 2185 return err;
2129 2186
2130 if (ctx.table == NULL) 2187 if (ctx.table == NULL) {
2131 ret = nf_tables_dump_sets_all(&ctx, skb, cb); 2188 if (ctx.afi == NULL)
2132 else 2189 ret = nf_tables_dump_sets_all(&ctx, skb, cb);
2190 else
2191 ret = nf_tables_dump_sets_family(&ctx, skb, cb);
2192 } else
2133 ret = nf_tables_dump_sets_table(&ctx, skb, cb); 2193 ret = nf_tables_dump_sets_table(&ctx, skb, cb);
2134 2194
2135 return ret; 2195 return ret;
@@ -2142,6 +2202,7 @@ static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
2142 const struct nft_set *set; 2202 const struct nft_set *set;
2143 struct nft_ctx ctx; 2203 struct nft_ctx ctx;
2144 struct sk_buff *skb2; 2204 struct sk_buff *skb2;
2205 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2145 int err; 2206 int err;
2146 2207
2147 /* Verify existance before starting dump */ 2208 /* Verify existance before starting dump */
@@ -2156,6 +2217,10 @@ static int nf_tables_getset(struct sock *nlsk, struct sk_buff *skb,
2156 return netlink_dump_start(nlsk, skb, nlh, &c); 2217 return netlink_dump_start(nlsk, skb, nlh, &c);
2157 } 2218 }
2158 2219
2220 /* Only accept unspec with dump */
2221 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
2222 return -EAFNOSUPPORT;
2223
2159 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]); 2224 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
2160 if (IS_ERR(set)) 2225 if (IS_ERR(set))
2161 return PTR_ERR(set); 2226 return PTR_ERR(set);
@@ -2325,6 +2390,7 @@ static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb,
2325 const struct nlmsghdr *nlh, 2390 const struct nlmsghdr *nlh,
2326 const struct nlattr * const nla[]) 2391 const struct nlattr * const nla[])
2327{ 2392{
2393 const struct nfgenmsg *nfmsg = nlmsg_data(nlh);
2328 struct nft_set *set; 2394 struct nft_set *set;
2329 struct nft_ctx ctx; 2395 struct nft_ctx ctx;
2330 int err; 2396 int err;
@@ -2336,6 +2402,9 @@ static int nf_tables_delset(struct sock *nlsk, struct sk_buff *skb,
2336 if (err < 0) 2402 if (err < 0)
2337 return err; 2403 return err;
2338 2404
2405 if (nfmsg->nfgen_family == NFPROTO_UNSPEC)
2406 return -EAFNOSUPPORT;
2407
2339 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]); 2408 set = nf_tables_set_lookup(ctx.table, nla[NFTA_SET_NAME]);
2340 if (IS_ERR(set)) 2409 if (IS_ERR(set))
2341 return PTR_ERR(set); 2410 return PTR_ERR(set);