Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 96e32272 authored by Jan Engelhardt's avatar Jan Engelhardt Committed by David S. Miller
Browse files

[NETFILTER]: xt_connmark match, revision 1



Introduces the xt_connmark match revision 1. It uses fixed types,
eventually obsoleting revision 0 some day (uses nonfixed types).
(Unfixed types like "unsigned long" do not play well with mixed
user-/kernelspace "bitness", e.g. 32/64, as is common on SPARC64,
and need extra compat code.)

Signed-off-by: default avatarJan Engelhardt <jengelh@computergmbh.de>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e0a812ae
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -15,4 +15,9 @@ struct xt_connmark_info {
	u_int8_t invert;
};

struct xt_connmark_mtinfo1 {
	u_int32_t mark, mask;
	u_int8_t invert;
};

#endif /*_XT_CONNMARK_H*/
+71 −17
Original line number Diff line number Diff line
/* This kernel module matches connection mark values set by the
 * CONNMARK target
/*
 *	xt_connmark - Netfilter module to match connection mark values
 *
 *	Copyright (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
 *	by Henrik Nordstrom <hno@marasystems.com>
 *	Copyright © CC Computer Consultants GmbH, 2007 - 2008
 *	Jan Engelhardt <jengelh@computergmbh.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
@@ -36,6 +38,23 @@ connmark_mt(const struct sk_buff *skb, const struct net_device *in,
            const struct net_device *out, const struct xt_match *match,
            const void *matchinfo, int offset, unsigned int protoff,
            bool *hotdrop)
{
	const struct xt_connmark_mtinfo1 *info = matchinfo;
	enum ip_conntrack_info ctinfo;
	const struct nf_conn *ct;

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

	return ((ct->mark & info->mask) == info->mark) ^ info->invert;
}

static bool
connmark_mt_v0(const struct sk_buff *skb, const struct net_device *in,
               const struct net_device *out, const struct xt_match *match,
               const void *matchinfo, int offset, unsigned int protoff,
               bool *hotdrop)
{
	const struct xt_connmark_info *info = matchinfo;
	const struct nf_conn *ct;
@@ -49,7 +68,7 @@ connmark_mt(const struct sk_buff *skb, const struct net_device *in,
}

static bool
connmark_mt_check(const char *tablename, const void *ip,
connmark_mt_check_v0(const char *tablename, const void *ip,
                     const struct xt_match *match, void *matchinfo,
                     unsigned int hook_mask)
{
@@ -67,6 +86,19 @@ connmark_mt_check(const char *tablename, const void *ip,
	return true;
}

static bool
connmark_mt_check(const char *tablename, const void *ip,
                  const struct xt_match *match, void *matchinfo,
                  unsigned int hook_mask)
{
	if (nf_ct_l3proto_try_module_get(match->family) < 0) {
		printk(KERN_WARNING "cannot load conntrack support for "
		       "proto=%u\n", match->family);
		return false;
	}
	return true;
}

static void
connmark_mt_destroy(const struct xt_match *match, void *matchinfo)
{
@@ -81,7 +113,7 @@ struct compat_xt_connmark_info {
	u_int16_t	__pad2;
};

static void connmark_mt_compat_from_user(void *dst, void *src)
static void connmark_mt_compat_from_user_v0(void *dst, void *src)
{
	const struct compat_xt_connmark_info *cm = src;
	struct xt_connmark_info m = {
@@ -92,7 +124,7 @@ static void connmark_mt_compat_from_user(void *dst, void *src)
	memcpy(dst, &m, sizeof(m));
}

static int connmark_mt_compat_to_user(void __user *dst, void *src)
static int connmark_mt_compat_to_user_v0(void __user *dst, void *src)
{
	const struct xt_connmark_info *m = src;
	struct compat_xt_connmark_info cm = {
@@ -107,32 +139,54 @@ static int connmark_mt_compat_to_user(void __user *dst, void *src)
static struct xt_match connmark_mt_reg[] __read_mostly = {
	{
		.name		= "connmark",
		.revision	= 0,
		.family		= AF_INET,
		.checkentry	= connmark_mt_check,
		.match		= connmark_mt,
		.checkentry	= connmark_mt_check_v0,
		.match		= connmark_mt_v0,
		.destroy	= connmark_mt_destroy,
		.matchsize	= sizeof(struct xt_connmark_info),
#ifdef CONFIG_COMPAT
		.compatsize	= sizeof(struct compat_xt_connmark_info),
		.compat_from_user = connmark_mt_compat_from_user,
		.compat_to_user	= connmark_mt_compat_to_user,
		.compat_from_user = connmark_mt_compat_from_user_v0,
		.compat_to_user	= connmark_mt_compat_to_user_v0,
#endif
		.me		= THIS_MODULE
	},
	{
		.name		= "connmark",
		.revision	= 0,
		.family		= AF_INET6,
		.checkentry	= connmark_mt_check,
		.match		= connmark_mt,
		.checkentry	= connmark_mt_check_v0,
		.match		= connmark_mt_v0,
		.destroy	= connmark_mt_destroy,
		.matchsize	= sizeof(struct xt_connmark_info),
#ifdef CONFIG_COMPAT
		.compatsize	= sizeof(struct compat_xt_connmark_info),
		.compat_from_user = connmark_mt_compat_from_user,
		.compat_to_user	= connmark_mt_compat_to_user,
		.compat_from_user = connmark_mt_compat_from_user_v0,
		.compat_to_user	= connmark_mt_compat_to_user_v0,
#endif
		.me		= THIS_MODULE
	},
	{
		.name           = "connmark",
		.revision       = 1,
		.family         = AF_INET,
		.checkentry     = connmark_mt_check,
		.match          = connmark_mt,
		.matchsize      = sizeof(struct xt_connmark_mtinfo1),
		.destroy        = connmark_mt_destroy,
		.me             = THIS_MODULE,
	},
	{
		.name           = "connmark",
		.revision       = 1,
		.family         = AF_INET6,
		.checkentry     = connmark_mt_check,
		.match          = connmark_mt,
		.matchsize      = sizeof(struct xt_connmark_mtinfo1),
		.destroy        = connmark_mt_destroy,
		.me             = THIS_MODULE,
	},
};

static int __init connmark_mt_init(void)