static int nft_meta_bridge_get_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_meta *priv = nft_expr_priv(expr); int err; priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); switch (priv->key) { case NFT_META_BRI_IIFNAME: case NFT_META_BRI_OIFNAME: break; default: return nft_meta_get_init(ctx, expr, tb); } priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); err = nft_validate_output_register(priv->dreg); if (err < 0) return err; err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE); if (err < 0) return err; return 0; }
static int nft_meta_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_meta *priv = nft_expr_priv(expr); int err; priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); if (tb[NFTA_META_DREG]) { err = nft_meta_init_validate_get(priv->key); if (err < 0) return err; priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); err = nft_validate_output_register(priv->dreg); if (err < 0) return err; return nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE); } err = nft_meta_init_validate_set(priv->key); if (err < 0) return err; priv->sreg = ntohl(nla_get_be32(tb[NFTA_META_SREG])); err = nft_validate_input_register(priv->sreg); if (err < 0) return err; return 0; }
static int nft_immediate_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_immediate_expr *priv = nft_expr_priv(expr); struct nft_data_desc desc; int err; if (tb[NFTA_IMMEDIATE_DREG] == NULL || tb[NFTA_IMMEDIATE_DATA] == NULL) return -EINVAL; priv->dreg = ntohl(nla_get_be32(tb[NFTA_IMMEDIATE_DREG])); err = nft_validate_output_register(priv->dreg); if (err < 0) return err; err = nft_data_init(ctx, &priv->data, &desc, tb[NFTA_IMMEDIATE_DATA]); if (err < 0) return err; priv->dlen = desc.len; err = nft_validate_data_load(ctx, priv->dreg, &priv->data, desc.type); if (err < 0) goto err1; return 0; err1: nft_data_uninit(&priv->data, desc.type); return err; }
int nft_meta_get_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_meta *priv = nft_expr_priv(expr); int err; priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY])); switch (priv->key) { case NFT_META_LEN: case NFT_META_PROTOCOL: case NFT_META_NFPROTO: case NFT_META_L4PROTO: case NFT_META_PRIORITY: case NFT_META_MARK: case NFT_META_IIF: case NFT_META_OIF: case NFT_META_IIFNAME: case NFT_META_OIFNAME: case NFT_META_IIFTYPE: case NFT_META_OIFTYPE: case NFT_META_SKUID: case NFT_META_SKGID: #ifdef CONFIG_IP_ROUTE_CLASSID case NFT_META_RTCLASSID: #endif #ifdef CONFIG_NETWORK_SECMARK case NFT_META_SECMARK: #endif case NFT_META_PKTTYPE: case NFT_META_CPU: case NFT_META_IIFGROUP: case NFT_META_OIFGROUP: break; default: return -EOPNOTSUPP; } priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); err = nft_validate_output_register(priv->dreg); if (err < 0) return err; err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE); if (err < 0) return err; return 0; }
static int nft_lookup_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_lookup *priv = nft_expr_priv(expr); struct nft_set *set; int err; if (tb[NFTA_LOOKUP_SET] == NULL || tb[NFTA_LOOKUP_SREG] == NULL) return -EINVAL; set = nf_tables_set_lookup(ctx->table, tb[NFTA_LOOKUP_SET]); if (IS_ERR(set)) return PTR_ERR(set); priv->sreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_SREG])); err = nft_validate_input_register(priv->sreg); if (err < 0) return err; if (tb[NFTA_LOOKUP_DREG] != NULL) { if (!(set->flags & NFT_SET_MAP)) return -EINVAL; priv->dreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_DREG])); err = nft_validate_output_register(priv->dreg); if (err < 0) return err; if (priv->dreg == NFT_REG_VERDICT) { if (set->dtype != NFT_DATA_VERDICT) return -EINVAL; } else if (set->dtype == NFT_DATA_VERDICT) return -EINVAL; } else if (set->flags & NFT_SET_MAP) return -EINVAL; err = nf_tables_bind_set(ctx, set, &priv->binding); if (err < 0) return err; priv->set = set; return 0; }
static int nft_ct_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_ct *priv = nft_expr_priv(expr); int err; if (tb[NFTA_CT_DREG] == NULL || tb[NFTA_CT_KEY] == NULL) return -EINVAL; priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY])); if (tb[NFTA_CT_DIRECTION] != NULL) { priv->dir = nla_get_u8(tb[NFTA_CT_DIRECTION]); switch (priv->dir) { case IP_CT_DIR_ORIGINAL: case IP_CT_DIR_REPLY: break; default: return -EINVAL; } } switch (priv->key) { case NFT_CT_STATE: case NFT_CT_DIRECTION: case NFT_CT_STATUS: #ifdef CONFIG_NF_CONNTRACK_MARK case NFT_CT_MARK: #endif #ifdef CONFIG_NF_CONNTRACK_SECMARK case NFT_CT_SECMARK: #endif case NFT_CT_EXPIRATION: case NFT_CT_HELPER: if (tb[NFTA_CT_DIRECTION] != NULL) return -EINVAL; break; case NFT_CT_PROTOCOL: case NFT_CT_SRC: case NFT_CT_DST: case NFT_CT_PROTO_SRC: case NFT_CT_PROTO_DST: if (tb[NFTA_CT_DIRECTION] == NULL) return -EINVAL; break; default: return -EOPNOTSUPP; } err = nf_ct_l3proto_try_module_get(ctx->afi->family); if (err < 0) return err; priv->family = ctx->afi->family; priv->dreg = ntohl(nla_get_be32(tb[NFTA_CT_DREG])); err = nft_validate_output_register(priv->dreg); if (err < 0) goto err1; err = nft_validate_data_load(ctx, priv->dreg, NULL, NFT_DATA_VALUE); if (err < 0) goto err1; return 0; err1: nf_ct_l3proto_module_put(ctx->afi->family); return err; }