static int nft_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_nat *priv = nft_expr_priv(expr); int err; if (tb[NFTA_NAT_TYPE] == NULL) return -EINVAL; switch (ntohl(nla_get_be32(tb[NFTA_NAT_TYPE]))) { case NFT_NAT_SNAT: priv->type = NF_NAT_MANIP_SRC; break; case NFT_NAT_DNAT: priv->type = NF_NAT_MANIP_DST; break; default: return -EINVAL; } if (tb[NFTA_NAT_ADDR_MIN]) { priv->sreg_addr_min = ntohl(nla_get_be32(tb[NFTA_NAT_ADDR_MIN])); err = nft_validate_input_register(priv->sreg_addr_min); if (err < 0) return err; } if (tb[NFTA_NAT_ADDR_MAX]) { priv->sreg_addr_max = ntohl(nla_get_be32(tb[NFTA_NAT_ADDR_MAX])); err = nft_validate_input_register(priv->sreg_addr_max); if (err < 0) return err; } else priv->sreg_addr_max = priv->sreg_addr_min; if (tb[NFTA_NAT_PROTO_MIN]) { priv->sreg_proto_min = ntohl(nla_get_be32(tb[NFTA_NAT_PROTO_MIN])); err = nft_validate_input_register(priv->sreg_proto_min); if (err < 0) return err; } if (tb[NFTA_NAT_PROTO_MAX]) { priv->sreg_proto_max = ntohl(nla_get_be32(tb[NFTA_NAT_PROTO_MAX])); err = nft_validate_input_register(priv->sreg_proto_max); if (err < 0) return err; } else priv->sreg_proto_max = priv->sreg_proto_min; 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; }
int nft_redir_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_redir *priv = nft_expr_priv(expr); int err; err = nft_chain_validate_dependency(ctx->chain, NFT_CHAIN_T_NAT); if (err < 0) return err; if (tb[NFTA_REDIR_REG_PROTO_MIN]) { priv->sreg_proto_min = ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN])); err = nft_validate_input_register(priv->sreg_proto_min); if (err < 0) return err; if (tb[NFTA_REDIR_REG_PROTO_MAX]) { priv->sreg_proto_max = ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX])); err = nft_validate_input_register(priv->sreg_proto_max); if (err < 0) return err; } else { priv->sreg_proto_max = priv->sreg_proto_min; } } if (tb[NFTA_REDIR_FLAGS]) { priv->flags = ntohl(nla_get_be32(tb[NFTA_REDIR_FLAGS])); if (priv->flags & ~NF_NAT_RANGE_MASK) return -EINVAL; } 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; }
int nft_meta_set_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_MARK: case NFT_META_PRIORITY: case NFT_META_NFTRACE: break; default: return -EOPNOTSUPP; } 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_nat_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) { struct nft_nat *priv = nft_expr_priv(expr); u32 family; int err; if (tb[NFTA_NAT_TYPE] == NULL || (tb[NFTA_NAT_REG_ADDR_MIN] == NULL && tb[NFTA_NAT_REG_PROTO_MIN] == NULL)) return -EINVAL; switch (ntohl(nla_get_be32(tb[NFTA_NAT_TYPE]))) { case NFT_NAT_SNAT: priv->type = NF_NAT_MANIP_SRC; break; case NFT_NAT_DNAT: priv->type = NF_NAT_MANIP_DST; break; default: return -EINVAL; } err = nft_nat_validate(ctx, expr, NULL); if (err < 0) return err; if (tb[NFTA_NAT_FAMILY] == NULL) return -EINVAL; family = ntohl(nla_get_be32(tb[NFTA_NAT_FAMILY])); if (family != AF_INET && family != AF_INET6) return -EAFNOSUPPORT; if (family != ctx->afi->family) return -EOPNOTSUPP; priv->family = family; if (tb[NFTA_NAT_REG_ADDR_MIN]) { priv->sreg_addr_min = ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MIN])); err = nft_validate_input_register(priv->sreg_addr_min); if (err < 0) return err; if (tb[NFTA_NAT_REG_ADDR_MAX]) { priv->sreg_addr_max = ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MAX])); err = nft_validate_input_register(priv->sreg_addr_max); if (err < 0) return err; } else { priv->sreg_addr_max = priv->sreg_addr_min; } } if (tb[NFTA_NAT_REG_PROTO_MIN]) { priv->sreg_proto_min = ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MIN])); err = nft_validate_input_register(priv->sreg_proto_min); if (err < 0) return err; if (tb[NFTA_NAT_REG_PROTO_MAX]) { priv->sreg_proto_max = ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MAX])); err = nft_validate_input_register(priv->sreg_proto_max); if (err < 0) return err; } else { priv->sreg_proto_max = priv->sreg_proto_min; } } if (tb[NFTA_NAT_FLAGS]) { priv->flags = ntohl(nla_get_be32(tb[NFTA_NAT_FLAGS])); if (priv->flags & ~NF_NAT_RANGE_MASK) return -EINVAL; } return 0; }