Blame extensions/libxt_CONNMARK.c

Packit 7b22a4
/* Shared library add-on to iptables to add CONNMARK target support.
Packit 7b22a4
 *
Packit 7b22a4
 * (C) 2002,2004 MARA Systems AB <http://www.marasystems.com>
Packit 7b22a4
 * by Henrik Nordstrom <hno@marasystems.com>
Packit 7b22a4
 *
Packit 7b22a4
 * Version 1.1
Packit 7b22a4
 *
Packit 7b22a4
 * This program is free software; you can redistribute it and/or modify
Packit 7b22a4
 * it under the terms of the GNU General Public License as published by
Packit 7b22a4
 * the Free Software Foundation; either version 2 of the License, or
Packit 7b22a4
 * (at your option) any later version.
Packit 7b22a4
 *
Packit 7b22a4
 * This program is distributed in the hope that it will be useful,
Packit 7b22a4
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 7b22a4
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 7b22a4
 * GNU General Public License for more details.
Packit 7b22a4
 *
Packit 7b22a4
 * You should have received a copy of the GNU General Public License
Packit 7b22a4
 * along with this program; if not, write to the Free Software
Packit 7b22a4
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
Packit 7b22a4
 */
Packit 7b22a4
#include <stdbool.h>
Packit 7b22a4
#include <stdint.h>
Packit 7b22a4
#include <stdio.h>
Packit 7b22a4
#include <xtables.h>
Packit 7b22a4
#include <linux/netfilter/xt_CONNMARK.h>
Packit 7b22a4
Packit 7b22a4
struct xt_connmark_target_info {
Packit 7b22a4
	unsigned long mark;
Packit 7b22a4
	unsigned long mask;
Packit 7b22a4
	uint8_t mode;
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
enum {
Packit 7b22a4
	D_SHIFT_LEFT = 0,
Packit 7b22a4
	D_SHIFT_RIGHT,
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
enum {
Packit 7b22a4
	O_SET_MARK = 0,
Packit 7b22a4
	O_SAVE_MARK,
Packit 7b22a4
	O_RESTORE_MARK,
Packit 7b22a4
	O_AND_MARK,
Packit 7b22a4
	O_OR_MARK,
Packit 7b22a4
	O_XOR_MARK,
Packit 7b22a4
	O_LEFT_SHIFT_MARK,
Packit 7b22a4
	O_RIGHT_SHIFT_MARK,
Packit 7b22a4
	O_SET_XMARK,
Packit 7b22a4
	O_CTMASK,
Packit 7b22a4
	O_NFMASK,
Packit 7b22a4
	O_MASK,
Packit 7b22a4
	F_SET_MARK         = 1 << O_SET_MARK,
Packit 7b22a4
	F_SAVE_MARK        = 1 << O_SAVE_MARK,
Packit 7b22a4
	F_RESTORE_MARK     = 1 << O_RESTORE_MARK,
Packit 7b22a4
	F_AND_MARK         = 1 << O_AND_MARK,
Packit 7b22a4
	F_OR_MARK          = 1 << O_OR_MARK,
Packit 7b22a4
	F_XOR_MARK         = 1 << O_XOR_MARK,
Packit 7b22a4
	F_LEFT_SHIFT_MARK  = 1 << O_LEFT_SHIFT_MARK,
Packit 7b22a4
	F_RIGHT_SHIFT_MARK = 1 << O_RIGHT_SHIFT_MARK,
Packit 7b22a4
	F_SET_XMARK        = 1 << O_SET_XMARK,
Packit 7b22a4
	F_CTMASK           = 1 << O_CTMASK,
Packit 7b22a4
	F_NFMASK           = 1 << O_NFMASK,
Packit 7b22a4
	F_MASK             = 1 << O_MASK,
Packit 7b22a4
	F_OP_ANY           = F_SET_MARK | F_SAVE_MARK | F_RESTORE_MARK |
Packit 7b22a4
	                     F_AND_MARK | F_OR_MARK | F_XOR_MARK | F_SET_XMARK,
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
static const char *const xt_connmark_shift_ops[] = {
Packit 7b22a4
	"left-shift-mark",
Packit 7b22a4
	"right-shift-mark"
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
static void CONNMARK_help(void)
Packit 7b22a4
{
Packit 7b22a4
	printf(
Packit 7b22a4
"CONNMARK target options:\n"
Packit 7b22a4
"  --set-mark value[/mask]       Set conntrack mark value\n"
Packit 7b22a4
"  --save-mark [--mask mask]     Save the packet nfmark in the connection\n"
Packit 7b22a4
"  --restore-mark [--mask mask]  Restore saved nfmark value\n");
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
#define s struct xt_connmark_target_info
Packit 7b22a4
static const struct xt_option_entry CONNMARK_opts[] = {
Packit 7b22a4
	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32},
Packit 7b22a4
	XTOPT_TABLEEND,
Packit 7b22a4
};
Packit 7b22a4
#undef s
Packit 7b22a4
Packit 7b22a4
#define s struct xt_connmark_tginfo1
Packit 7b22a4
static const struct xt_option_entry connmark_tg_opts[] = {
Packit 7b22a4
	{.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "ctmask", .id = O_CTMASK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, ctmask)},
Packit 7b22a4
	{.name = "nfmask", .id = O_NFMASK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, nfmask)},
Packit 7b22a4
	{.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_CTMASK | F_NFMASK},
Packit 7b22a4
	XTOPT_TABLEEND,
Packit 7b22a4
};
Packit 7b22a4
#undef s
Packit 7b22a4
Packit 7b22a4
#define s struct xt_connmark_tginfo2
Packit 7b22a4
static const struct xt_option_entry connmark_tg_opts_v2[] = {
Packit 7b22a4
	{.name = "set-xmark", .id = O_SET_XMARK, .type = XTTYPE_MARKMASK32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "set-mark", .id = O_SET_MARK, .type = XTTYPE_MARKMASK32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "and-mark", .id = O_AND_MARK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "or-mark", .id = O_OR_MARK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "xor-mark", .id = O_XOR_MARK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "save-mark", .id = O_SAVE_MARK, .type = XTTYPE_NONE,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
Packit 7b22a4
	 .excl = F_OP_ANY},
Packit 7b22a4
	{.name = "left-shift-mark", .id = O_LEFT_SHIFT_MARK, .type = XTTYPE_UINT8,
Packit 7b22a4
	 .min = 0, .max = 32},
Packit 7b22a4
	{.name = "right-shift-mark", .id = O_RIGHT_SHIFT_MARK, .type = XTTYPE_UINT8,
Packit 7b22a4
	 .min = 0, .max = 32},
Packit 7b22a4
	{.name = "ctmask", .id = O_CTMASK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, ctmask)},
Packit 7b22a4
	{.name = "nfmask", .id = O_NFMASK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, nfmask)},
Packit 7b22a4
	{.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32,
Packit 7b22a4
	 .excl = F_CTMASK | F_NFMASK},
Packit 7b22a4
	XTOPT_TABLEEND,
Packit 7b22a4
};
Packit 7b22a4
#undef s
Packit 7b22a4
Packit 7b22a4
static void connmark_tg_help(void)
Packit 7b22a4
{
Packit 7b22a4
	printf(
Packit 7b22a4
"CONNMARK target options:\n"
Packit 7b22a4
"  --set-xmark value[/ctmask]    Zero mask bits and XOR ctmark with value\n"
Packit 7b22a4
"  --save-mark [--ctmask mask] [--nfmask mask]\n"
Packit 7b22a4
"                                Copy ctmark to nfmark using masks\n"
Packit 7b22a4
"  --restore-mark [--ctmask mask] [--nfmask mask]\n"
Packit 7b22a4
"                                Copy nfmark to ctmark using masks\n"
Packit 7b22a4
"  --set-mark value[/mask]       Set conntrack mark value\n"
Packit 7b22a4
"  --save-mark [--mask mask]     Save the packet nfmark in the connection\n"
Packit 7b22a4
"  --restore-mark [--mask mask]  Restore saved nfmark value\n"
Packit 7b22a4
"  --and-mark value              Binary AND the ctmark with bits\n"
Packit 7b22a4
"  --or-mark value               Binary OR  the ctmark with bits\n"
Packit 7b22a4
"  --xor-mark value              Binary XOR the ctmark with bits\n"
Packit 7b22a4
);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void connmark_tg_help_v2(void)
Packit 7b22a4
{
Packit 7b22a4
	connmark_tg_help();
Packit 7b22a4
	printf(
Packit 7b22a4
"  --left-shift-mark value       Left shift the ctmark with bits\n"
Packit 7b22a4
"  --right-shift-mark value      Right shift the ctmark with bits\n"
Packit 7b22a4
);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void connmark_tg_init(struct xt_entry_target *target)
Packit 7b22a4
{
Packit 7b22a4
	struct xt_connmark_tginfo1 *info = (void *)target->data;
Packit 7b22a4
Packit 7b22a4
	/*
Packit 7b22a4
	 * Need these defaults for --save-mark/--restore-mark if no
Packit 7b22a4
	 * --ctmark or --nfmask is given.
Packit 7b22a4
	 */
Packit 7b22a4
	info->ctmask = UINT32_MAX;
Packit 7b22a4
	info->nfmask = UINT32_MAX;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void connmark_tg_init_v2(struct xt_entry_target *target)
Packit 7b22a4
{
Packit 7b22a4
	struct xt_connmark_tginfo2 *info;
Packit 7b22a4
Packit 7b22a4
	connmark_tg_init(target);
Packit 7b22a4
	info = (void *)target->data;
Packit 7b22a4
Packit 7b22a4
	/* Left shift by zero bit by default. */
Packit 7b22a4
	info->shift_dir = D_SHIFT_LEFT;
Packit 7b22a4
	info->shift_bits = 0;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void CONNMARK_parse(struct xt_option_call *cb)
Packit 7b22a4
{
Packit 7b22a4
	struct xt_connmark_target_info *markinfo = cb->data;
Packit 7b22a4
Packit 7b22a4
	xtables_option_parse(cb);
Packit 7b22a4
	switch (cb->entry->id) {
Packit 7b22a4
	case O_SET_MARK:
Packit 7b22a4
		markinfo->mode = XT_CONNMARK_SET;
Packit 7b22a4
		markinfo->mark = cb->val.mark;
Packit 7b22a4
		markinfo->mask = cb->val.mask;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_SAVE_MARK:
Packit 7b22a4
		markinfo->mode = XT_CONNMARK_SAVE;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_RESTORE_MARK:
Packit 7b22a4
		markinfo->mode = XT_CONNMARK_RESTORE;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_MASK:
Packit 7b22a4
		markinfo->mask = cb->val.u32;
Packit 7b22a4
		break;
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void connmark_tg_parse(struct xt_option_call *cb)
Packit 7b22a4
{
Packit 7b22a4
	struct xt_connmark_tginfo1 *info = cb->data;
Packit 7b22a4
Packit 7b22a4
	xtables_option_parse(cb);
Packit 7b22a4
	switch (cb->entry->id) {
Packit 7b22a4
	case O_SET_XMARK:
Packit 7b22a4
		info->mode   = XT_CONNMARK_SET;
Packit 7b22a4
		info->ctmark = cb->val.mark;
Packit 7b22a4
		info->ctmask = cb->val.mask;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_SET_MARK:
Packit 7b22a4
		info->mode   = XT_CONNMARK_SET;
Packit 7b22a4
		info->ctmark = cb->val.mark;
Packit 7b22a4
		info->ctmask = cb->val.mark | cb->val.mask;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_AND_MARK:
Packit 7b22a4
		info->mode   = XT_CONNMARK_SET;
Packit 7b22a4
		info->ctmark = 0;
Packit 7b22a4
		info->ctmask = ~cb->val.u32;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_OR_MARK:
Packit 7b22a4
		info->mode   = XT_CONNMARK_SET;
Packit 7b22a4
		info->ctmark = cb->val.u32;
Packit 7b22a4
		info->ctmask = cb->val.u32;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_XOR_MARK:
Packit 7b22a4
		info->mode   = XT_CONNMARK_SET;
Packit 7b22a4
		info->ctmark = cb->val.u32;
Packit 7b22a4
		info->ctmask = 0;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_SAVE_MARK:
Packit 7b22a4
		info->mode = XT_CONNMARK_SAVE;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_RESTORE_MARK:
Packit 7b22a4
		info->mode = XT_CONNMARK_RESTORE;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_MASK:
Packit 7b22a4
		info->nfmask = info->ctmask = cb->val.u32;
Packit 7b22a4
		break;
Packit 7b22a4
	default:
Packit 7b22a4
		break;
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void connmark_tg_parse_v2(struct xt_option_call *cb)
Packit 7b22a4
{
Packit 7b22a4
	struct xt_connmark_tginfo2 *info = cb->data;
Packit 7b22a4
Packit 7b22a4
	xtables_option_parse(cb);
Packit 7b22a4
	switch (cb->entry->id) {
Packit 7b22a4
	case O_SET_XMARK:
Packit 7b22a4
		info->mode   = XT_CONNMARK_SET;
Packit 7b22a4
		info->ctmark = cb->val.mark;
Packit 7b22a4
		info->ctmask = cb->val.mask;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_SET_MARK:
Packit 7b22a4
		info->mode   = XT_CONNMARK_SET;
Packit 7b22a4
		info->ctmark = cb->val.mark;
Packit 7b22a4
		info->ctmask = cb->val.mark | cb->val.mask;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_AND_MARK:
Packit 7b22a4
		info->mode   = XT_CONNMARK_SET;
Packit 7b22a4
		info->ctmark = 0;
Packit 7b22a4
		info->ctmask = ~cb->val.u32;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_OR_MARK:
Packit 7b22a4
		info->mode   = XT_CONNMARK_SET;
Packit 7b22a4
		info->ctmark = cb->val.u32;
Packit 7b22a4
		info->ctmask = cb->val.u32;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_XOR_MARK:
Packit 7b22a4
		info->mode   = XT_CONNMARK_SET;
Packit 7b22a4
		info->ctmark = cb->val.u32;
Packit 7b22a4
		info->ctmask = 0;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_SAVE_MARK:
Packit 7b22a4
		info->mode = XT_CONNMARK_SAVE;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_RESTORE_MARK:
Packit 7b22a4
		info->mode = XT_CONNMARK_RESTORE;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_MASK:
Packit 7b22a4
		info->nfmask = info->ctmask = cb->val.u32;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_LEFT_SHIFT_MARK:
Packit 7b22a4
		info->shift_dir = D_SHIFT_LEFT;
Packit 7b22a4
		info->shift_bits = cb->val.u8;
Packit 7b22a4
		break;
Packit 7b22a4
	case O_RIGHT_SHIFT_MARK:
Packit 7b22a4
		info->shift_dir = D_SHIFT_RIGHT;
Packit 7b22a4
		info->shift_bits = cb->val.u8;
Packit 7b22a4
		break;
Packit 7b22a4
	default:
Packit 7b22a4
		break;
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void connmark_tg_check(struct xt_fcheck_call *cb)
Packit 7b22a4
{
Packit 7b22a4
	if (!(cb->xflags & F_OP_ANY))
Packit 7b22a4
		xtables_error(PARAMETER_PROBLEM,
Packit 7b22a4
		           "CONNMARK target: No operation specified");
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void
Packit 7b22a4
print_mark(unsigned long mark)
Packit 7b22a4
{
Packit 7b22a4
	printf("0x%lx", mark);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void
Packit 7b22a4
print_mask(const char *text, unsigned long mask)
Packit 7b22a4
{
Packit 7b22a4
	if (mask != 0xffffffffUL)
Packit 7b22a4
		printf("%s0x%lx", text, mask);
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void CONNMARK_print(const void *ip,
Packit 7b22a4
                           const struct xt_entry_target *target, int numeric)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connmark_target_info *markinfo =
Packit 7b22a4
		(const struct xt_connmark_target_info *)target->data;
Packit 7b22a4
	switch (markinfo->mode) {
Packit 7b22a4
	case XT_CONNMARK_SET:
Packit 7b22a4
	    printf(" CONNMARK set ");
Packit 7b22a4
	    print_mark(markinfo->mark);
Packit 7b22a4
	    print_mask("/", markinfo->mask);
Packit 7b22a4
	    break;
Packit 7b22a4
	case XT_CONNMARK_SAVE:
Packit 7b22a4
	    printf(" CONNMARK save ");
Packit 7b22a4
	    print_mask("mask ", markinfo->mask);
Packit 7b22a4
	    break;
Packit 7b22a4
	case XT_CONNMARK_RESTORE:
Packit 7b22a4
	    printf(" CONNMARK restore ");
Packit 7b22a4
	    print_mask("mask ", markinfo->mask);
Packit 7b22a4
	    break;
Packit 7b22a4
	default:
Packit 7b22a4
	    printf(" ERROR: UNKNOWN CONNMARK MODE");
Packit 7b22a4
	    break;
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void
Packit 7b22a4
connmark_tg_print(const void *ip, const struct xt_entry_target *target,
Packit 7b22a4
                  int numeric)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connmark_tginfo1 *info = (const void *)target->data;
Packit 7b22a4
Packit 7b22a4
	switch (info->mode) {
Packit 7b22a4
	case XT_CONNMARK_SET:
Packit 7b22a4
		if (info->ctmark == 0)
Packit 7b22a4
			printf(" CONNMARK and 0x%x",
Packit 7b22a4
			       (unsigned int)(uint32_t)~info->ctmask);
Packit 7b22a4
		else if (info->ctmark == info->ctmask)
Packit 7b22a4
			printf(" CONNMARK or 0x%x", info->ctmark);
Packit 7b22a4
		else if (info->ctmask == 0)
Packit 7b22a4
			printf(" CONNMARK xor 0x%x", info->ctmark);
Packit 7b22a4
		else if (info->ctmask == 0xFFFFFFFFU)
Packit 7b22a4
			printf(" CONNMARK set 0x%x", info->ctmark);
Packit 7b22a4
		else
Packit 7b22a4
			printf(" CONNMARK xset 0x%x/0x%x",
Packit 7b22a4
			       info->ctmark, info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_SAVE:
Packit 7b22a4
		if (info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX)
Packit 7b22a4
			printf(" CONNMARK save");
Packit 7b22a4
		else if (info->nfmask == info->ctmask)
Packit 7b22a4
			printf(" CONNMARK save mask 0x%x", info->nfmask);
Packit 7b22a4
		else
Packit 7b22a4
			printf(" CONNMARK save nfmask 0x%x ctmask ~0x%x",
Packit 7b22a4
			       info->nfmask, info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_RESTORE:
Packit 7b22a4
		if (info->ctmask == UINT32_MAX && info->nfmask == UINT32_MAX)
Packit 7b22a4
			printf(" CONNMARK restore");
Packit 7b22a4
		else if (info->ctmask == info->nfmask)
Packit 7b22a4
			printf(" CONNMARK restore mask 0x%x", info->ctmask);
Packit 7b22a4
		else
Packit 7b22a4
			printf(" CONNMARK restore ctmask 0x%x nfmask ~0x%x",
Packit 7b22a4
			       info->ctmask, info->nfmask);
Packit 7b22a4
		break;
Packit 7b22a4
Packit 7b22a4
	default:
Packit 7b22a4
		printf(" ERROR: UNKNOWN CONNMARK MODE");
Packit 7b22a4
		break;
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void
Packit 7b22a4
connmark_tg_print_v2(const void *ip, const struct xt_entry_target *target,
Packit 7b22a4
                  int numeric)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connmark_tginfo2 *info = (const void *)target->data;
Packit 7b22a4
	const char *shift_op = xt_connmark_shift_ops[info->shift_dir];
Packit 7b22a4
Packit 7b22a4
	switch (info->mode) {
Packit 7b22a4
	case XT_CONNMARK_SET:
Packit 7b22a4
		if (info->ctmark == 0)
Packit 7b22a4
			printf(" CONNMARK and 0x%x",
Packit 7b22a4
			       (unsigned int)(uint32_t)~info->ctmask);
Packit 7b22a4
		else if (info->ctmark == info->ctmask)
Packit 7b22a4
			printf(" CONNMARK or 0x%x", info->ctmark);
Packit 7b22a4
		else if (info->ctmask == 0)
Packit 7b22a4
			printf(" CONNMARK xor 0x%x", info->ctmark);
Packit 7b22a4
		else if (info->ctmask == 0xFFFFFFFFU)
Packit 7b22a4
			printf(" CONNMARK set 0x%x", info->ctmark);
Packit 7b22a4
		else
Packit 7b22a4
			printf(" CONNMARK xset 0x%x/0x%x",
Packit 7b22a4
			       info->ctmark, info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_SAVE:
Packit 7b22a4
		if (info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX)
Packit 7b22a4
			printf(" CONNMARK save");
Packit 7b22a4
		else if (info->nfmask == info->ctmask)
Packit 7b22a4
			printf(" CONNMARK save mask 0x%x", info->nfmask);
Packit 7b22a4
		else
Packit 7b22a4
			printf(" CONNMARK save nfmask 0x%x ctmask ~0x%x",
Packit 7b22a4
			       info->nfmask, info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_RESTORE:
Packit 7b22a4
		if (info->ctmask == UINT32_MAX && info->nfmask == UINT32_MAX)
Packit 7b22a4
			printf(" CONNMARK restore");
Packit 7b22a4
		else if (info->ctmask == info->nfmask)
Packit 7b22a4
			printf(" CONNMARK restore mask 0x%x", info->ctmask);
Packit 7b22a4
		else
Packit 7b22a4
			printf(" CONNMARK restore ctmask 0x%x nfmask ~0x%x",
Packit 7b22a4
			       info->ctmask, info->nfmask);
Packit 7b22a4
		break;
Packit 7b22a4
Packit 7b22a4
	default:
Packit 7b22a4
		printf(" ERROR: UNKNOWN CONNMARK MODE");
Packit 7b22a4
		break;
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	if (info->mode <= XT_CONNMARK_RESTORE &&
Packit 7b22a4
	    info->shift_bits != 0) {
Packit 7b22a4
		printf(" %s %u", shift_op, info->shift_bits);
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void CONNMARK_save(const void *ip, const struct xt_entry_target *target)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connmark_target_info *markinfo =
Packit 7b22a4
		(const struct xt_connmark_target_info *)target->data;
Packit 7b22a4
Packit 7b22a4
	switch (markinfo->mode) {
Packit 7b22a4
	case XT_CONNMARK_SET:
Packit 7b22a4
	    printf(" --set-mark ");
Packit 7b22a4
	    print_mark(markinfo->mark);
Packit 7b22a4
	    print_mask("/", markinfo->mask);
Packit 7b22a4
	    break;
Packit 7b22a4
	case XT_CONNMARK_SAVE:
Packit 7b22a4
	    printf(" --save-mark ");
Packit 7b22a4
	    print_mask("--mask ", markinfo->mask);
Packit 7b22a4
	    break;
Packit 7b22a4
	case XT_CONNMARK_RESTORE:
Packit 7b22a4
	    printf(" --restore-mark ");
Packit 7b22a4
	    print_mask("--mask ", markinfo->mask);
Packit 7b22a4
	    break;
Packit 7b22a4
	default:
Packit 7b22a4
	    printf(" ERROR: UNKNOWN CONNMARK MODE");
Packit 7b22a4
	    break;
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void CONNMARK_init(struct xt_entry_target *t)
Packit 7b22a4
{
Packit 7b22a4
	struct xt_connmark_target_info *markinfo
Packit 7b22a4
		= (struct xt_connmark_target_info *)t->data;
Packit 7b22a4
Packit 7b22a4
	markinfo->mask = 0xffffffffUL;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void
Packit 7b22a4
connmark_tg_save(const void *ip, const struct xt_entry_target *target)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connmark_tginfo1 *info = (const void *)target->data;
Packit 7b22a4
Packit 7b22a4
	switch (info->mode) {
Packit 7b22a4
	case XT_CONNMARK_SET:
Packit 7b22a4
		printf(" --set-xmark 0x%x/0x%x", info->ctmark, info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_SAVE:
Packit 7b22a4
		printf(" --save-mark --nfmask 0x%x --ctmask 0x%x",
Packit 7b22a4
		       info->nfmask, info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_RESTORE:
Packit 7b22a4
		printf(" --restore-mark --nfmask 0x%x --ctmask 0x%x",
Packit 7b22a4
		       info->nfmask, info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	default:
Packit 7b22a4
		printf(" ERROR: UNKNOWN CONNMARK MODE");
Packit 7b22a4
		break;
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static void
Packit 7b22a4
connmark_tg_save_v2(const void *ip, const struct xt_entry_target *target)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connmark_tginfo2 *info = (const void *)target->data;
Packit 7b22a4
	const char *shift_op = xt_connmark_shift_ops[info->shift_dir];
Packit 7b22a4
Packit 7b22a4
	switch (info->mode) {
Packit 7b22a4
	case XT_CONNMARK_SET:
Packit 7b22a4
		printf(" --set-xmark 0x%x/0x%x", info->ctmark, info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_SAVE:
Packit 7b22a4
		printf(" --save-mark --nfmask 0x%x --ctmask 0x%x",
Packit 7b22a4
		       info->nfmask, info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_RESTORE:
Packit 7b22a4
		printf(" --restore-mark --nfmask 0x%x --ctmask 0x%x",
Packit 7b22a4
		       info->nfmask, info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	default:
Packit 7b22a4
		printf(" ERROR: UNKNOWN CONNMARK MODE");
Packit 7b22a4
		break;
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	if (info->mode <= XT_CONNMARK_RESTORE &&
Packit 7b22a4
	    info->shift_bits != 0) {
Packit 7b22a4
		printf(" --%s %u", shift_op, info->shift_bits);
Packit 7b22a4
	}
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int connmark_tg_xlate(struct xt_xlate *xl,
Packit 7b22a4
			     const struct xt_xlate_tg_params *params)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connmark_tginfo1 *info =
Packit 7b22a4
		(const void *)params->target->data;
Packit 7b22a4
Packit 7b22a4
	switch (info->mode) {
Packit 7b22a4
	case XT_CONNMARK_SET:
Packit 7b22a4
		xt_xlate_add(xl, "ct mark set ");
Packit 7b22a4
		if (info->ctmask == 0xFFFFFFFFU)
Packit 7b22a4
			xt_xlate_add(xl, "0x%x ", info->ctmark);
Packit 7b22a4
		else if (info->ctmark == 0)
Packit 7b22a4
			xt_xlate_add(xl, "ct mark and 0x%x", ~info->ctmask);
Packit 7b22a4
		else if (info->ctmark == info->ctmask)
Packit 7b22a4
			xt_xlate_add(xl, "ct mark or 0x%x",
Packit 7b22a4
				     info->ctmark);
Packit 7b22a4
		else if (info->ctmask == 0)
Packit 7b22a4
			xt_xlate_add(xl, "ct mark xor 0x%x",
Packit 7b22a4
				     info->ctmark);
Packit 7b22a4
		else
Packit 7b22a4
			xt_xlate_add(xl, "ct mark xor 0x%x and 0x%x",
Packit 7b22a4
				     info->ctmark, ~info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_SAVE:
Packit 7b22a4
		if (info->nfmask == info->ctmask &&
Packit 7b22a4
		    info->nfmask == UINT32_MAX)
Packit 7b22a4
			xt_xlate_add(xl, "ct mark set mark");
Packit 7b22a4
		else
Packit 7b22a4
			return 0;
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_RESTORE:
Packit 7b22a4
		if (info->nfmask == info->ctmask &&
Packit 7b22a4
		    info->nfmask == UINT32_MAX)
Packit 7b22a4
			xt_xlate_add(xl, "meta mark set ct mark");
Packit 7b22a4
		else
Packit 7b22a4
			return 0;
Packit 7b22a4
		break;
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	return 1;
Packit 7b22a4
}
Packit 7b22a4
Packit 7b22a4
static int connmark_tg_xlate_v2(struct xt_xlate *xl,
Packit 7b22a4
			     const struct xt_xlate_tg_params *params)
Packit 7b22a4
{
Packit 7b22a4
	const struct xt_connmark_tginfo2 *info =
Packit 7b22a4
		(const void *)params->target->data;
Packit 7b22a4
	const char *shift_op = xt_connmark_shift_ops[info->shift_dir];
Packit 7b22a4
Packit 7b22a4
	switch (info->mode) {
Packit 7b22a4
	case XT_CONNMARK_SET:
Packit 7b22a4
		xt_xlate_add(xl, "ct mark set ");
Packit 7b22a4
		if (info->ctmask == 0xFFFFFFFFU)
Packit 7b22a4
			xt_xlate_add(xl, "0x%x ", info->ctmark);
Packit 7b22a4
		else if (info->ctmark == 0)
Packit 7b22a4
			xt_xlate_add(xl, "ct mark and 0x%x", ~info->ctmask);
Packit 7b22a4
		else if (info->ctmark == info->ctmask)
Packit 7b22a4
			xt_xlate_add(xl, "ct mark or 0x%x",
Packit 7b22a4
				     info->ctmark);
Packit 7b22a4
		else if (info->ctmask == 0)
Packit 7b22a4
			xt_xlate_add(xl, "ct mark xor 0x%x",
Packit 7b22a4
				     info->ctmark);
Packit 7b22a4
		else
Packit 7b22a4
			xt_xlate_add(xl, "ct mark xor 0x%x and 0x%x",
Packit 7b22a4
				     info->ctmark, ~info->ctmask);
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_SAVE:
Packit 7b22a4
		xt_xlate_add(xl, "ct mark set mark");
Packit 7b22a4
		if (!(info->nfmask == UINT32_MAX &&
Packit 7b22a4
		    info->ctmask == UINT32_MAX)) {
Packit 7b22a4
			if (info->nfmask == info->ctmask)
Packit 7b22a4
				xt_xlate_add(xl, " and 0x%x", info->nfmask);
Packit 7b22a4
		}
Packit 7b22a4
		break;
Packit 7b22a4
	case XT_CONNMARK_RESTORE:
Packit 7b22a4
		xt_xlate_add(xl, "meta mark set ct mark");
Packit 7b22a4
		if (!(info->nfmask == UINT32_MAX &&
Packit 7b22a4
		    info->ctmask == UINT32_MAX)) {
Packit 7b22a4
			if (info->nfmask == info->ctmask)
Packit 7b22a4
				xt_xlate_add(xl, " and 0x%x", info->nfmask);
Packit 7b22a4
		}
Packit 7b22a4
		break;
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	if (info->mode <= XT_CONNMARK_RESTORE &&
Packit 7b22a4
	    info->shift_bits != 0) {
Packit 7b22a4
		xt_xlate_add(xl, " %s %u", shift_op, info->shift_bits);
Packit 7b22a4
	}
Packit 7b22a4
Packit 7b22a4
	return 1;
Packit 7b22a4
}
Packit 7b22a4
static struct xtables_target connmark_tg_reg[] = {
Packit 7b22a4
	{
Packit 7b22a4
		.family        = NFPROTO_UNSPEC,
Packit 7b22a4
		.name          = "CONNMARK",
Packit 7b22a4
		.revision      = 0,
Packit 7b22a4
		.version       = XTABLES_VERSION,
Packit 7b22a4
		.size          = XT_ALIGN(sizeof(struct xt_connmark_target_info)),
Packit 7b22a4
		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_target_info)),
Packit 7b22a4
		.help          = CONNMARK_help,
Packit 7b22a4
		.init          = CONNMARK_init,
Packit 7b22a4
		.print         = CONNMARK_print,
Packit 7b22a4
		.save          = CONNMARK_save,
Packit 7b22a4
		.x6_parse      = CONNMARK_parse,
Packit 7b22a4
		.x6_fcheck     = connmark_tg_check,
Packit 7b22a4
		.x6_options    = CONNMARK_opts,
Packit 7b22a4
	},
Packit 7b22a4
	{
Packit 7b22a4
		.version       = XTABLES_VERSION,
Packit 7b22a4
		.name          = "CONNMARK",
Packit 7b22a4
		.revision      = 1,
Packit 7b22a4
		.family        = NFPROTO_UNSPEC,
Packit 7b22a4
		.size          = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
Packit 7b22a4
		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)),
Packit 7b22a4
		.help          = connmark_tg_help,
Packit 7b22a4
		.init          = connmark_tg_init,
Packit 7b22a4
		.print         = connmark_tg_print,
Packit 7b22a4
		.save          = connmark_tg_save,
Packit 7b22a4
		.x6_parse      = connmark_tg_parse,
Packit 7b22a4
		.x6_fcheck     = connmark_tg_check,
Packit 7b22a4
		.x6_options    = connmark_tg_opts,
Packit 7b22a4
		.xlate         = connmark_tg_xlate,
Packit 7b22a4
	},
Packit 7b22a4
	{
Packit 7b22a4
		.version       = XTABLES_VERSION,
Packit 7b22a4
		.name          = "CONNMARK",
Packit 7b22a4
		.revision      = 2,
Packit 7b22a4
		.family        = NFPROTO_UNSPEC,
Packit 7b22a4
		.size          = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)),
Packit 7b22a4
		.userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)),
Packit 7b22a4
		.help          = connmark_tg_help_v2,
Packit 7b22a4
		.init          = connmark_tg_init_v2,
Packit 7b22a4
		.print         = connmark_tg_print_v2,
Packit 7b22a4
		.save          = connmark_tg_save_v2,
Packit 7b22a4
		.x6_parse      = connmark_tg_parse_v2,
Packit 7b22a4
		.x6_fcheck     = connmark_tg_check,
Packit 7b22a4
		.x6_options    = connmark_tg_opts_v2,
Packit 7b22a4
		.xlate         = connmark_tg_xlate_v2,
Packit 7b22a4
	},
Packit 7b22a4
};
Packit 7b22a4
Packit 7b22a4
void _init(void)
Packit 7b22a4
{
Packit 7b22a4
	xtables_register_targets(connmark_tg_reg, ARRAY_SIZE(connmark_tg_reg));
Packit 7b22a4
}