Example #1
0
static int ovs_ct_set_labels(struct sk_buff *skb, struct sw_flow_key *key,
			     const struct ovs_key_ct_labels *labels,
			     const struct ovs_key_ct_labels *mask)
{
	enum ip_conntrack_info ctinfo;
	struct nf_conn_labels *cl;
	struct nf_conn *ct;
	int err;

	/* The connection could be invalid, in which case set_label is no-op.*/
	ct = nf_ct_get(skb, &ctinfo);
	if (!ct)
		return 0;

	cl = nf_ct_labels_find(ct);
	if (!cl) {
		nf_ct_labels_ext_add(ct);
		cl = nf_ct_labels_find(ct);
	}
	if (!cl || cl->words * sizeof(long) < OVS_CT_LABELS_LEN)
		return -ENOSPC;

	err = nf_connlabels_replace(ct, (u32 *)labels, (u32 *)mask,
				    OVS_CT_LABELS_LEN / sizeof(u32));
	if (err)
		return err;

	ovs_ct_get_labels(ct, &key->ct.labels);
	return 0;
}
static void nft_ct_set_eval(const struct nft_expr *expr,
                            struct nft_regs *regs,
                            const struct nft_pktinfo *pkt)
{
    const struct nft_ct *priv = nft_expr_priv(expr);
    struct sk_buff *skb = pkt->skb;
#ifdef CONFIG_NF_CONNTRACK_MARK
    u32 value = regs->data[priv->sreg];
#endif
    enum ip_conntrack_info ctinfo;
    struct nf_conn *ct;

    ct = nf_ct_get(skb, &ctinfo);
    if (ct == NULL)
        return;

    switch (priv->key) {
#ifdef CONFIG_NF_CONNTRACK_MARK
    case NFT_CT_MARK:
        if (ct->mark != value) {
            ct->mark = value;
            nf_conntrack_event_cache(IPCT_MARK, ct);
        }
        break;
#endif
#ifdef CONFIG_NF_CONNTRACK_LABELS
    case NFT_CT_LABELS:
        nf_connlabels_replace(ct,
                              &regs->data[priv->sreg],
                              &regs->data[priv->sreg],
                              NF_CT_LABELS_MAX_SIZE / sizeof(u32));
        break;
#endif
    default:
        break;
    }
}