Commit 86ca02e7 authored by Joe Stringer's avatar Joe Stringer Committed by David S. Miller

netfilter: connlabels: Export setting connlabel length

Add functions to change connlabel length into nf_conntrack_labels.c so
they may be reused by other modules like OVS and nftables without
needing to jump through xt_match_check() hoops.
Suggested-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarJoe Stringer <joestringer@nicira.com>
Acked-by: default avatarFlorian Westphal <fw@strlen.de>
Acked-by: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 55e5713f
...@@ -54,7 +54,11 @@ int nf_connlabels_replace(struct nf_conn *ct, ...@@ -54,7 +54,11 @@ int nf_connlabels_replace(struct nf_conn *ct,
#ifdef CONFIG_NF_CONNTRACK_LABELS #ifdef CONFIG_NF_CONNTRACK_LABELS
int nf_conntrack_labels_init(void); int nf_conntrack_labels_init(void);
void nf_conntrack_labels_fini(void); void nf_conntrack_labels_fini(void);
int nf_connlabels_get(struct net *net, unsigned int n_bits);
void nf_connlabels_put(struct net *net);
#else #else
static inline int nf_conntrack_labels_init(void) { return 0; } static inline int nf_conntrack_labels_init(void) { return 0; }
static inline void nf_conntrack_labels_fini(void) {} static inline void nf_conntrack_labels_fini(void) {}
static inline int nf_connlabels_get(struct net *net, unsigned int n_bits) { return 0; }
static inline void nf_connlabels_put(struct net *net) {}
#endif #endif
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <net/netfilter/nf_conntrack_ecache.h> #include <net/netfilter/nf_conntrack_ecache.h>
#include <net/netfilter/nf_conntrack_labels.h> #include <net/netfilter/nf_conntrack_labels.h>
static spinlock_t nf_connlabels_lock;
static unsigned int label_bits(const struct nf_conn_labels *l) static unsigned int label_bits(const struct nf_conn_labels *l)
{ {
unsigned int longs = l->words; unsigned int longs = l->words;
...@@ -89,6 +91,35 @@ int nf_connlabels_replace(struct nf_conn *ct, ...@@ -89,6 +91,35 @@ int nf_connlabels_replace(struct nf_conn *ct,
} }
EXPORT_SYMBOL_GPL(nf_connlabels_replace); EXPORT_SYMBOL_GPL(nf_connlabels_replace);
int nf_connlabels_get(struct net *net, unsigned int n_bits)
{
size_t words;
if (n_bits > (NF_CT_LABELS_MAX_SIZE * BITS_PER_BYTE))
return -ERANGE;
words = BITS_TO_LONGS(n_bits);
spin_lock(&nf_connlabels_lock);
net->ct.labels_used++;
if (words > net->ct.label_words)
net->ct.label_words = words;
spin_unlock(&nf_connlabels_lock);
return 0;
}
EXPORT_SYMBOL_GPL(nf_connlabels_get);
void nf_connlabels_put(struct net *net)
{
spin_lock(&nf_connlabels_lock);
net->ct.labels_used--;
if (net->ct.labels_used == 0)
net->ct.label_words = 0;
spin_unlock(&nf_connlabels_lock);
}
EXPORT_SYMBOL_GPL(nf_connlabels_put);
static struct nf_ct_ext_type labels_extend __read_mostly = { static struct nf_ct_ext_type labels_extend __read_mostly = {
.len = sizeof(struct nf_conn_labels), .len = sizeof(struct nf_conn_labels),
.align = __alignof__(struct nf_conn_labels), .align = __alignof__(struct nf_conn_labels),
...@@ -97,6 +128,7 @@ static struct nf_ct_ext_type labels_extend __read_mostly = { ...@@ -97,6 +128,7 @@ static struct nf_ct_ext_type labels_extend __read_mostly = {
int nf_conntrack_labels_init(void) int nf_conntrack_labels_init(void)
{ {
spin_lock_init(&nf_connlabels_lock);
return nf_ct_extend_register(&labels_extend); return nf_ct_extend_register(&labels_extend);
} }
......
...@@ -42,10 +42,6 @@ static int connlabel_mt_check(const struct xt_mtchk_param *par) ...@@ -42,10 +42,6 @@ static int connlabel_mt_check(const struct xt_mtchk_param *par)
XT_CONNLABEL_OP_SET; XT_CONNLABEL_OP_SET;
struct xt_connlabel_mtinfo *info = par->matchinfo; struct xt_connlabel_mtinfo *info = par->matchinfo;
int ret; int ret;
size_t words;
if (info->bit > XT_CONNLABEL_MAXBIT)
return -ERANGE;
if (info->options & ~options) { if (info->options & ~options) {
pr_err("Unknown options in mask %x\n", info->options); pr_err("Unknown options in mask %x\n", info->options);
...@@ -59,19 +55,15 @@ static int connlabel_mt_check(const struct xt_mtchk_param *par) ...@@ -59,19 +55,15 @@ static int connlabel_mt_check(const struct xt_mtchk_param *par)
return ret; return ret;
} }
par->net->ct.labels_used++; ret = nf_connlabels_get(par->net, info->bit + 1);
words = BITS_TO_LONGS(info->bit+1); if (ret < 0)
if (words > par->net->ct.label_words) nf_ct_l3proto_module_put(par->family);
par->net->ct.label_words = words;
return ret; return ret;
} }
static void connlabel_mt_destroy(const struct xt_mtdtor_param *par) static void connlabel_mt_destroy(const struct xt_mtdtor_param *par)
{ {
par->net->ct.labels_used--; nf_connlabels_put(par->net);
if (par->net->ct.labels_used == 0)
par->net->ct.label_words = 0;
nf_ct_l3proto_module_put(par->family); nf_ct_l3proto_module_put(par->family);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment