net/netfilter/nft_objref.c

Source file repositories/reference/linux-study-clean/net/netfilter/nft_objref.c

File Facts

System
Linux kernel
Corpus path
net/netfilter/nft_objref.c
Extension
.c
Size
7086 bytes
Lines
281
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct nft_objref_map {
	struct nft_set		*set;
	u8			sreg;
	struct nft_set_binding	binding;
};

void nft_objref_map_eval(const struct nft_expr *expr,
			 struct nft_regs *regs,
			 const struct nft_pktinfo *pkt)
{
	struct nft_objref_map *priv = nft_expr_priv(expr);
	const struct nft_set *set = priv->set;
	struct net *net = nft_net(pkt);
	const struct nft_set_ext *ext;
	struct nft_object *obj;

	ext = nft_set_do_lookup(net, set, &regs->data[priv->sreg]);
	if (!ext) {
		ext = nft_set_catchall_lookup(net, set);
		if (!ext) {
			regs->verdict.code = NFT_BREAK;
			return;
		}
	}
	obj = *nft_set_ext_obj(ext);
	obj->ops->eval(obj, regs, pkt);
}

static int nft_objref_map_init(const struct nft_ctx *ctx,
			       const struct nft_expr *expr,
			       const struct nlattr * const tb[])
{
	struct nft_objref_map *priv = nft_expr_priv(expr);
	u8 genmask = nft_genmask_next(ctx->net);
	struct nft_set *set;
	int err;

	set = nft_set_lookup_global(ctx->net, ctx->table,
				    tb[NFTA_OBJREF_SET_NAME],
				    tb[NFTA_OBJREF_SET_ID], genmask);
	if (IS_ERR(set))
		return PTR_ERR(set);

	if (!(set->flags & NFT_SET_OBJECT))
		return -EINVAL;

	err = nft_parse_register_load(ctx, tb[NFTA_OBJREF_SET_SREG], &priv->sreg,
				      set->klen);
	if (err < 0)
		return err;

	priv->binding.flags = set->flags & NFT_SET_OBJECT;

	err = nf_tables_bind_set(ctx, set, &priv->binding);
	if (err < 0)
		return err;

	priv->set = set;
	return 0;
}

static int nft_objref_map_dump(struct sk_buff *skb,
			       const struct nft_expr *expr, bool reset)
{
	const struct nft_objref_map *priv = nft_expr_priv(expr);

	if (nft_dump_register(skb, NFTA_OBJREF_SET_SREG, priv->sreg) ||
	    nla_put_string(skb, NFTA_OBJREF_SET_NAME, priv->set->name))
		goto nla_put_failure;

	return 0;

nla_put_failure:
	return -1;
}

static void nft_objref_map_deactivate(const struct nft_ctx *ctx,
				      const struct nft_expr *expr,
				      enum nft_trans_phase phase)
{
	struct nft_objref_map *priv = nft_expr_priv(expr);

	nf_tables_deactivate_set(ctx, priv->set, &priv->binding, phase);
}

static void nft_objref_map_activate(const struct nft_ctx *ctx,
				    const struct nft_expr *expr)
{
	struct nft_objref_map *priv = nft_expr_priv(expr);

Annotation

Implementation Notes