Example #1
0
static int connbytes_mt_check(const struct xt_mtchk_param *par)
{
    const struct xt_connbytes_info *sinfo = par->matchinfo;
    int ret;

    if (sinfo->what != XT_CONNBYTES_PKTS &&
            sinfo->what != XT_CONNBYTES_BYTES &&
            sinfo->what != XT_CONNBYTES_AVGPKT)
        return -EINVAL;

    if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL &&
            sinfo->direction != XT_CONNBYTES_DIR_REPLY &&
            sinfo->direction != XT_CONNBYTES_DIR_BOTH)
        return -EINVAL;

    ret = nf_ct_l3proto_try_module_get(par->family);
    if (ret < 0)
        pr_info("cannot load conntrack support for proto=%u\n",
                par->family);

    /*
     * This filter cannot function correctly unless connection tracking
     * accounting is enabled, so complain in the hope that someone notices.
     */
    if (!nf_ct_acct_enabled(par->net)) {
        pr_warning("Forcing CT accounting to be enabled\n");
        nf_ct_set_acct(par->net, true);
    }

    return ret;
}
Example #2
0
static bool connbytes_mt_check(const struct xt_mtchk_param *par)
{
	const struct xt_connbytes_info *sinfo = par->matchinfo;

	if (sinfo->what != XT_CONNBYTES_PKTS &&
	    sinfo->what != XT_CONNBYTES_BYTES &&
	    sinfo->what != XT_CONNBYTES_AVGPKT)
		return false;

	if (sinfo->direction != XT_CONNBYTES_DIR_ORIGINAL &&
	    sinfo->direction != XT_CONNBYTES_DIR_REPLY &&
	    sinfo->direction != XT_CONNBYTES_DIR_BOTH)
		return false;

	if (nf_ct_l3proto_try_module_get(par->family) < 0) {
		printk(KERN_WARNING "can't load conntrack support for "
				    "proto=%u\n", par->family);
		return false;
	}

	/*
	 * This filter cannot function correctly unless connection tracking
	 * accounting is enabled, so complain in the hope that someone notices.
	 */
	if (!nf_ct_acct_enabled(&init_net)) {
		pr_warning("Forcing CT accounting to be enabled\n");
		nf_ct_set_acct(&init_net, true);
	}

	return true;
}
static int nft_ct_get_init(const struct nft_ctx *ctx,
                           const struct nft_expr *expr,
                           const struct nlattr * const tb[])
{
    struct nft_ct *priv = nft_expr_priv(expr);
    unsigned int len;
    int err;

    priv->key = ntohl(nla_get_be32(tb[NFTA_CT_KEY]));
    switch (priv->key) {
    case NFT_CT_DIRECTION:
        if (tb[NFTA_CT_DIRECTION] != NULL)
            return -EINVAL;
        len = sizeof(u8);
        break;
    case NFT_CT_STATE:
    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:
        if (tb[NFTA_CT_DIRECTION] != NULL)
            return -EINVAL;
        len = sizeof(u32);
        break;
#ifdef CONFIG_NF_CONNTRACK_LABELS
    case NFT_CT_LABELS:
        if (tb[NFTA_CT_DIRECTION] != NULL)
            return -EINVAL;
        len = NF_CT_LABELS_MAX_SIZE;
        break;
#endif
    case NFT_CT_HELPER:
        if (tb[NFTA_CT_DIRECTION] != NULL)
            return -EINVAL;
        len = NF_CT_HELPER_NAME_LEN;
        break;

    case NFT_CT_L3PROTOCOL:
    case NFT_CT_PROTOCOL:
        if (tb[NFTA_CT_DIRECTION] == NULL)
            return -EINVAL;
        len = sizeof(u8);
        break;
    case NFT_CT_SRC:
    case NFT_CT_DST:
        if (tb[NFTA_CT_DIRECTION] == NULL)
            return -EINVAL;

        switch (ctx->afi->family) {
        case NFPROTO_IPV4:
            len = FIELD_SIZEOF(struct nf_conntrack_tuple,
                               src.u3.ip);
            break;
        case NFPROTO_IPV6:
        case NFPROTO_INET:
            len = FIELD_SIZEOF(struct nf_conntrack_tuple,
                               src.u3.ip6);
            break;
        default:
            return -EAFNOSUPPORT;
        }
        break;
    case NFT_CT_PROTO_SRC:
    case NFT_CT_PROTO_DST:
        if (tb[NFTA_CT_DIRECTION] == NULL)
            return -EINVAL;
        len = FIELD_SIZEOF(struct nf_conntrack_tuple, src.u.all);
        break;
    case NFT_CT_BYTES:
    case NFT_CT_PKTS:
        /* no direction? return sum of original + reply */
        if (tb[NFTA_CT_DIRECTION] == NULL)
            priv->dir = IP_CT_DIR_MAX;
        len = sizeof(u64);
        break;
    default:
        return -EOPNOTSUPP;
    }

    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;
        }
    }

    priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]);
    err = nft_validate_register_store(ctx, priv->dreg, NULL,
                                      NFT_DATA_VALUE, len);
    if (err < 0)
        return err;

    err = nft_ct_l3proto_try_module_get(ctx->afi->family);
    if (err < 0)
        return err;

    if (priv->key == NFT_CT_BYTES || priv->key == NFT_CT_PKTS)
        nf_ct_set_acct(ctx->net, true);

    return 0;
}