{.name = "ctstate", .id = O_CTSTATE, .type = XTTYPE_STRING,
.flags = XTOPT_INVERT},
{.name = "ctproto", .id = O_CTPROTO, .type = XTTYPE_PROTOCOL,
- .flags = XTOPT_INVERT},
+ .flags = XTOPT_INVERT,
+ XTOPT_POINTER(s, tuple[IP_CT_DIR_ORIGINAL].dst.protonum)},
{.name = "ctorigsrc", .id = O_CTORIGSRC, .type = XTTYPE_HOST,
.flags = XTOPT_INVERT},
{.name = "ctorigdst", .id = O_CTORIGDST, .type = XTTYPE_HOST,
};
#undef s
-#define s struct xt_conntrack_mtinfo2 /* for v1-v2 */
-/* We exploit the fact that v1-v2 share the same layout */
+#define s struct xt_conntrack_mtinfo2
+/* We exploit the fact that v1-v2 share the same xt_o_e layout */
static const struct xt_option_entry conntrack2_mt_opts[] = {
{.name = "ctstate", .id = O_CTSTATE, .type = XTTYPE_STRING,
.flags = XTOPT_INVERT},
{.name = "ctproto", .id = O_CTPROTO, .type = XTTYPE_PROTOCOL,
- .flags = XTOPT_INVERT},
+ .flags = XTOPT_INVERT, XTOPT_POINTER(s, l4proto)},
{.name = "ctorigsrc", .id = O_CTORIGSRC, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT},
{.name = "ctorigdst", .id = O_CTORIGDST, .type = XTTYPE_HOSTMASK,
{.name = "ctstate", .id = O_CTSTATE, .type = XTTYPE_STRING,
.flags = XTOPT_INVERT},
{.name = "ctproto", .id = O_CTPROTO, .type = XTTYPE_PROTOCOL,
- .flags = XTOPT_INVERT},
+ .flags = XTOPT_INVERT, XTOPT_POINTER(s, l4proto)},
{.name = "ctorigsrc", .id = O_CTORIGSRC, .type = XTTYPE_HOSTMASK,
.flags = XTOPT_INVERT},
{.name = "ctorigdst", .id = O_CTORIGDST, .type = XTTYPE_HOSTMASK,
case O_CTPROTO:
if (cb->invert)
sinfo->invflags |= XT_CONNTRACK_PROTO;
- sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum = cb->val.protocol;
-
if (sinfo->tuple[IP_CT_DIR_ORIGINAL].dst.protonum == 0
&& (sinfo->invflags & XT_INV_PROTO))
xtables_error(PARAMETER_PROBLEM,
info->invert_flags |= XT_CONNTRACK_STATE;
break;
case O_CTPROTO:
- info->l4proto = cb->val.protocol;
if (info->l4proto == 0 && (info->invert_flags & XT_INV_PROTO))
xtables_error(PARAMETER_PROBLEM, "conntrack: rule would "
"never match protocol");