Commit b18dfa90 authored by Bart De Schuymer's avatar Bart De Schuymer Committed by David S. Miller
Browse files

[NETFILTER]: ebt_mark: add or/and/xor action support to mark target



The following patch adds or/and/xor functionality for the mark target,
while staying backwards compatible.

Signed-off-by: default avatarBart De Schuymer <bdschuym@pandora.be>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9d02002d
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
#ifndef __LINUX_BRIDGE_EBT_MARK_T_H
#define __LINUX_BRIDGE_EBT_MARK_T_H

/* The target member is reused for adding new actions, the
 * value of the real target is -1 to -NUM_STANDARD_TARGETS.
 * For backward compatibility, the 4 lsb (2 would be enough,
 * but let's play it safe) are kept to designate this target.
 * The remaining bits designate the action. By making the set
 * action 0xfffffff0, the result will look ok for older
 * versions. [September 2006] */
#define MARK_SET_VALUE (0xfffffff0)
#define MARK_OR_VALUE  (0xffffffe0)
#define MARK_AND_VALUE (0xffffffd0)
#define MARK_XOR_VALUE (0xffffffc0)

struct ebt_mark_t_info
{
	unsigned long mark;
+17 −4
Original line number Diff line number Diff line
@@ -22,24 +22,37 @@ static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr,
   const void *data, unsigned int datalen)
{
	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
	int action = info->target & -16;

	if ((*pskb)->nfmark != info->mark)
	if (action == MARK_SET_VALUE)
		(*pskb)->nfmark = info->mark;
	else if (action == MARK_OR_VALUE)
		(*pskb)->nfmark |= info->mark;
	else if (action == MARK_AND_VALUE)
		(*pskb)->nfmark &= info->mark;
	else
		(*pskb)->nfmark ^= info->mark;

	return info->target;
	return info->target | -16;
}

static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
   const struct ebt_entry *e, void *data, unsigned int datalen)
{
	struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data;
	int tmp;

	if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
		return -EINVAL;
	if (BASE_CHAIN && info->target == EBT_RETURN)
	tmp = info->target | -16;
	if (BASE_CHAIN && tmp == EBT_RETURN)
		return -EINVAL;
	CLEAR_BASE_CHAIN_BIT;
	if (INVALID_TARGET)
	if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
		return -EINVAL;
	tmp = info->target & -16;
	if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
	    tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
		return -EINVAL;
	return 0;
}