Hi Florian, On Thu, Nov 15, 2012 at 04:55:15PM +0100, Florian Westphal wrote: > Signed-off-by: Florian Westphal <fw@xxxxxxxxx> > --- > include/net/netfilter/nf_conntrack_labels.h | 3 ++ > net/netfilter/nf_conntrack_labels.c | 34 +++++++++++++++++++++++++++ > net/netfilter/nf_conntrack_netlink.c | 23 ++++++++++++++++++ > 3 files changed, 60 insertions(+), 0 deletions(-) > > diff --git a/include/net/netfilter/nf_conntrack_labels.h b/include/net/netfilter/nf_conntrack_labels.h > index fdd88fb..e058b2b 100644 > --- a/include/net/netfilter/nf_conntrack_labels.h > +++ b/include/net/netfilter/nf_conntrack_labels.h > @@ -52,3 +52,6 @@ static inline void nf_conntrack_labels_fini(struct net *net) {} > > bool nf_connlabel_match(const struct nf_conn *ct, u16 bit); > int nf_connlabel_set(struct nf_conn *ct, u16 bit); > + > +int nfnetlink_connlabel_set(struct nf_conn *ct, const void *data, > + unsigned int length); > diff --git a/net/netfilter/nf_conntrack_labels.c b/net/netfilter/nf_conntrack_labels.c > index fe9c0c6..8bff33c 100644 > --- a/net/netfilter/nf_conntrack_labels.c > +++ b/net/netfilter/nf_conntrack_labels.c > @@ -52,6 +52,40 @@ int nf_connlabel_set(struct nf_conn *ct, u16 bit) > } > EXPORT_SYMBOL_GPL(nf_connlabel_set); > > +#if IS_ENABLED(CONFIG_NF_CT_NETLINK) > +int nfnetlink_connlabel_set(struct nf_conn *ct, const void *data, unsigned int length) > +{ > + const size_t maxblen = (1024 / BITS_PER_LONG) * sizeof(long); > + struct nf_conn_labels *labels; > + unsigned int size; > + > + if (length > maxblen) > + return -EMSGSIZE; > + > + labels = nf_ct_labels_find(ct); > + if (!labels) > + return -ENOSPC; > + > + size = labels->words * sizeof(long); > + > + if (size < length) > + length = size; > + > + if (length) > + memcpy(labels->bits, data, length); > + > + if (size > length) { > + unsigned int pad = size - length; > + char *mem = (void *) labels->bits; > + memset(mem + pad, 0, pad); > + } > + > + nf_conntrack_event_cache(IPCT_LABEL, ct); > + return 0; > +} Via ctnetlink_new_conntrack, we should be able to create and set the connlabel if we want to support state-sync of connlabels. That requires calling _ext_add(...) to allocate the label, based on cda[CTA_LABELS], and set it. In that case we're safe to memcpy without interfering with any ongoing bit testing since that conntrack is not in the hashes yet. For the update case, I think we'll have to iterate over the mask and use xchg to update words, thus, we avoid any interference ongoing bit testing. > +EXPORT_SYMBOL_GPL(nfnetlink_connlabel_set); > +#endif > + > static struct nf_ct_ext_type labels_extend __read_mostly = { > .len = sizeof(struct nf_conn_labels), > .align = __alignof__(struct nf_conn_labels), > diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c > index 43a1247..834fe99 100644 > --- a/net/netfilter/nf_conntrack_netlink.c > +++ b/net/netfilter/nf_conntrack_netlink.c > @@ -1229,6 +1229,16 @@ ctnetlink_change_nat(struct nf_conn *ct, const struct nlattr * const cda[]) > } > > static inline int > +ctnetlink_attach_label(struct nf_conn *ct, const struct nlattr * const cda[]) > +{ > +#ifdef CONFIG_NF_CONNTRACK_LABELS > + return nfnetlink_connlabel_set(ct, nla_data(cda[CTA_LABELS]), nla_len(cda[CTA_LABELS])); > +#else > + return -EOPNOTSUPP; > +#endif > +} > + > +static inline int > ctnetlink_change_helper(struct nf_conn *ct, const struct nlattr * const cda[]) > { > struct nf_conntrack_helper *helper; > @@ -1441,6 +1451,11 @@ ctnetlink_change_conntrack(struct nf_conn *ct, > return err; > } > #endif > + if (cda[CTA_LABELS]) { > + err = ctnetlink_attach_label(ct, cda); > + if (err < 0) > + return err; > + } > > return 0; > } > @@ -1649,6 +1664,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb, > else > events = IPCT_NEW; > > + if (cda[CTA_LABELS] && ctnetlink_attach_label(ct, cda) == 0) > + events |= (1 << IPCT_LABEL); > + > nf_conntrack_eventmask_report((1 << IPCT_REPLY) | > (1 << IPCT_ASSURED) | > (1 << IPCT_HELPER) | > @@ -1946,6 +1964,11 @@ ctnetlink_nfqueue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct) > if (err < 0) > return err; > } > + if (cda[CTA_LABELS]) { > + err = ctnetlink_attach_label(ct, cda); > + if (err < 0) > + return err; > + } > #if defined(CONFIG_NF_CONNTRACK_MARK) > if (cda[CTA_MARK]) > ct->mark = ntohl(nla_get_be32(cda[CTA_MARK])); > -- > 1.7.8.6 > > -- > To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html