Hi Patrick and Pablo, Here follows the userspace part: The patch adds support to control the conntrack event generation by adding the required options to the CONNMARK target. With it, one is able to specify exactly - for which traffic - and which events should be generated by the kernel. For example with the rules iptables -t mangle -A FORWARD -p tcp -m state NEW \ -j CONNMARK --events ASSURED,PROTOINFO,HELPER,DESTROY iptables -t mangle -A FORWARD -p udp -m state RELATED \ -j CONNMARK --events ASSURED,PROTOINFO,HELPER,DESTROY we can define that only forwarded TCP traffic and their possible related (TCP/)UDP connections generate the listed events. Signed-off-by: Jozsef Kadlecsik <kadlec@xxxxxxxxxxxxxxxxx> --- extensions/libxt_CONNMARK.c | 493 ++++++++++++++++++++++++++++++--- extensions/libxt_CONNMARK.man | 11 + include/linux/netfilter/xt_CONNMARK.h | 113 ++++++++- 3 files changed, 584 insertions(+), 33 deletions(-) diff --git a/extensions/libxt_CONNMARK.c b/extensions/libxt_CONNMARK.c index 6e42898..bf60658 100644 --- a/extensions/libxt_CONNMARK.c +++ b/extensions/libxt_CONNMARK.c @@ -29,8 +29,10 @@ #include <linux/netfilter/xt_CONNMARK.h> enum { - F_MARK = 1 << 0, - F_SR_MARK = 1 << 1, + F_MARK = 1 << 0, + F_SR_MARK = 1 << 1, + F_EVENTS = 1 << 2, + F_EXP_EVENTS = 1 << 3, }; static void CONNMARK_help(void) @@ -50,7 +52,7 @@ static const struct option CONNMARK_opts[] = { { .name = NULL } }; -static const struct option connmark_tg_opts[] = { +static const struct option connmark_tg1_opts[] = { {.name = "set-xmark", .has_arg = true, .val = '='}, {.name = "set-mark", .has_arg = true, .val = '-'}, {.name = "and-mark", .has_arg = true, .val = '&'}, @@ -64,7 +66,7 @@ static const struct option connmark_tg_opts[] = { {.name = NULL}, }; -static void connmark_tg_help(void) +static void connmark_tg1_help(void) { printf( "CONNMARK target options:\n" @@ -82,7 +84,7 @@ static void connmark_tg_help(void) ); } -static void connmark_tg_init(struct xt_entry_target *target) +static void connmark_tg1_init(struct xt_entry_target *target) { struct xt_connmark_tginfo1 *info = (void *)target->data; @@ -94,6 +96,78 @@ static void connmark_tg_init(struct xt_entry_target *target) info->nfmask = UINT32_MAX; } +static const struct option connmark_tg2_opts[] = { + {.name = "set-xmark", .has_arg = true, .val = '='}, + {.name = "set-mark", .has_arg = true, .val = '-'}, + {.name = "and-mark", .has_arg = true, .val = '&'}, + {.name = "or-mark", .has_arg = true, .val = '|'}, + {.name = "xor-mark", .has_arg = true, .val = '^'}, + {.name = "save-mark", .has_arg = false, .val = 'S'}, + {.name = "restore-mark", .has_arg = false, .val = 'R'}, + {.name = "ctmask", .has_arg = true, .val = 'c'}, + {.name = "nfmask", .has_arg = true, .val = 'n'}, + {.name = "mask", .has_arg = true, .val = 'm'}, + {.name = "events", .has_arg = true, .val = 'e'}, + {.name = "exp-events", .has_arg = true, .val = 'x'}, + {.name = NULL}, +}; + +static void connmark_tg2_help(void) +{ + int i; + + printf( +"CONNMARK target options:\n" +" --set-xmark value[/ctmask] Zero mask bits and XOR ctmark with value\n" +" --save-mark [--ctmask mask] [--nfmask mask]\n" +" Copy ctmark to nfmark using masks\n" +" --restore-mark [--ctmask mask] [--nfmask mask]\n" +" Copy nfmark to ctmark using masks\n" +" --set-mark value[/mask] Set conntrack mark value\n" +" --save-mark [--mask mask] Save the packet nfmark in the connection\n" +" --restore-mark [--mask mask] Restore saved nfmark value\n" +" --and-mark value Binary AND the ctmark with bits\n" +" --or-mark value Binary OR the ctmark with bits\n" +" --xor-mark value Binary XOR the ctmark with bits\n" +" --events value Comma separated list of conntrack events\n" +" --exp-events value Comma separated list of expecation events\n" +" Valid events:\n" +" NONE," +); + for (i = IPCT_NEW_BIT; i < IPCT_ALL_BIT; i++) { + if (events[i][0]) + printf("%s,", events[i]); + if ((i + 1)%8 == 0) + printf("\n "); + } + printf( +"ALL\n" +" Valid expectation events:\n" +" NONE," +); + for (i = IPEXP_NEW_BIT; i < IPEXP_ALL_BIT; i++) { + if (events[i][0]) + printf("%s,", events[i]); + if ((i - IPEXP_NEW_BIT + 1)%8 == 0) + printf("\n "); + } + printf("ALL\n"); +} + +static void connmark_tg2_init(struct xt_entry_target *target) +{ + struct xt_connmark_tginfo2 *info = (void *)target->data; + + /* + * Need these defaults for --save-mark/--restore-mark if no + * --ctmark or --nfmask is given. + */ + info->ctmask = UINT32_MAX; + info->nfmask = UINT32_MAX; + /* Make possible to set events alone */ + info->mode = XT_CONNMARK_EVENT_ONLY; +} + static int CONNMARK_parse(int c, char **argv, int invert, unsigned int *flags, const void *entry, struct xt_entry_target **target) @@ -147,9 +221,9 @@ CONNMARK_parse(int c, char **argv, int invert, unsigned int *flags, return 1; } -static int connmark_tg_parse(int c, char **argv, int invert, - unsigned int *flags, const void *entry, - struct xt_entry_target **target) +static int connmark_tg1_parse(int c, char **argv, int invert, + unsigned int *flags, const void *entry, + struct xt_entry_target **target) { struct xt_connmark_tginfo1 *info = (void *)(*target)->data; unsigned int value, mask = UINT32_MAX; @@ -250,7 +324,194 @@ static int connmark_tg_parse(int c, char **argv, int invert, return false; } -static void connmark_tg_check(unsigned int flags) +static void connmark_tg1_check(unsigned int flags) +{ + if (!flags) + xtables_error(PARAMETER_PROBLEM, + "CONNMARK target: No operation specified"); +} + +#define STREQ(a, b) (strncasecmp(a,b,strlen(b)) == 0) + +static void parse_events(uint16_t *eventmask) +{ + size_t offset = 0; + int i, m; + + if (STREQ(optarg, "NONE")) { + *eventmask &= ~IPCT_ALL; + return; + } else if (STREQ(optarg, "ALL")) { + *eventmask |= IPCT_ALL; + return; + } + + while (offset < strlen(optarg)) { + for (i = IPCT_NEW_BIT, m = 0; i < IPCT_ALL_BIT; i++) { + if (events[i][0] + && STREQ(optarg + offset, events[i])) { + *eventmask |= (1 << i); + offset += strlen(events[i]); + offset += !!(optarg[offset] == ','); + m++; + } + } + if (m == 0) + xtables_error(PARAMETER_PROBLEM, + "CONNMARK target: Cannot parse events '%s'", + optarg + offset); + } +} + +static void parse_exp_events(u_int16_t *eventmask) +{ + size_t offset = 0; + int i, m; + + if (STREQ(optarg, "NONE")) { + *eventmask &= ~IPEXP_ALL; + return; + } else if (STREQ(optarg, "ALL")) { + *eventmask |= IPEXP_ALL; + return; + } + + while (offset < strlen(optarg)) { + for (i = IPEXP_NEW_BIT, m = 0; i < IPEXP_ALL_BIT; i++) { + if (events[i][0] + && STREQ(optarg + offset, events[i])) { + *eventmask |= (1 << i); + offset += strlen(events[i]); + offset += !!(optarg[offset] == ','); + m++; + } + } + if (m == 0) + xtables_error(PARAMETER_PROBLEM, + "CONNMARK target: Cannot parse expectation events '%s'", + optarg + offset); + } +} + +static int connmark_tg2_parse(int c, char **argv, int invert, + unsigned int *flags, const void *entry, + struct xt_entry_target **target) +{ + struct xt_connmark_tginfo2 *info = (void *)(*target)->data; + unsigned int value, mask = UINT32_MAX; + char *end; + + switch (c) { + case '=': /* --set-xmark */ + case '-': /* --set-mark */ + xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); + if (!xtables_strtoui(optarg, &end, &value, 0, UINT32_MAX)) + xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg); + if (*end == '/') + if (!xtables_strtoui(end + 1, &end, &mask, 0, UINT32_MAX)) + xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg); + if (*end != '\0') + xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--set-xmark/--set-mark", optarg); + info->mode = XT_CONNMARK_SET; + info->ctmark = value; + info->ctmask = mask; + if (c == '-') + info->ctmask |= value; + *flags |= F_MARK; + return true; + + case '&': /* --and-mark */ + xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); + if (!xtables_strtoui(optarg, NULL, &mask, 0, UINT32_MAX)) + xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--and-mark", optarg); + info->mode = XT_CONNMARK_SET; + info->ctmark = 0; + info->ctmask = ~mask; + *flags |= F_MARK; + return true; + + case '|': /* --or-mark */ + xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); + if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) + xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--or-mark", optarg); + info->mode = XT_CONNMARK_SET; + info->ctmark = value; + info->ctmask = value; + *flags |= F_MARK; + return true; + + case '^': /* --xor-mark */ + xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); + if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) + xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--xor-mark", optarg); + info->mode = XT_CONNMARK_SET; + info->ctmark = value; + info->ctmask = 0; + *flags |= F_MARK; + return true; + + case 'S': /* --save-mark */ + xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); + info->mode = XT_CONNMARK_SAVE; + *flags |= F_MARK | F_SR_MARK; + return true; + + case 'R': /* --restore-mark */ + xtables_param_act(XTF_ONE_ACTION, "CONNMARK", *flags & F_MARK); + info->mode = XT_CONNMARK_RESTORE; + *flags |= F_MARK | F_SR_MARK; + return true; + + case 'n': /* --nfmask */ + if (!(*flags & F_SR_MARK)) + xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark " + "or --restore-mark is required for " + "--nfmask"); + if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) + xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--nfmask", optarg); + info->nfmask = value; + return true; + + case 'c': /* --ctmask */ + if (!(*flags & F_SR_MARK)) + xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark " + "or --restore-mark is required for " + "--ctmask"); + if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) + xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--ctmask", optarg); + info->ctmask = value; + return true; + + case 'm': /* --mask */ + if (!(*flags & F_SR_MARK)) + xtables_error(PARAMETER_PROBLEM, "CONNMARK: --save-mark " + "or --restore-mark is required for " + "--mask"); + if (!xtables_strtoui(optarg, NULL, &value, 0, UINT32_MAX)) + xtables_param_act(XTF_BAD_VALUE, "CONNMARK", "--mask", optarg); + info->nfmask = info->ctmask = value; + return true; + + case 'e': /* --events */ + xtables_param_act(XTF_ONE_ACTION, "CONNMARK", + *flags & F_EVENTS); + parse_events(&info->eventmask); + info->events = 1; + *flags |= F_EVENTS; + return true; + + case 'x': /* --exp-events */ + xtables_param_act(XTF_ONE_ACTION, "CONNMARK", + *flags & F_EXP_EVENTS); + parse_exp_events(&info->eventmask); + info->events = 1; + *flags |= F_EXP_EVENTS; + return true; + } + return false; +} + +static void connmark_tg2_check(unsigned int flags) { if (!flags) xtables_error(PARAMETER_PROBLEM, @@ -298,8 +559,8 @@ static void CONNMARK_print(const void *ip, } static void -connmark_tg_print(const void *ip, const struct xt_entry_target *target, - int numeric) +connmark_tg1_print(const void *ip, const struct xt_entry_target *target, + int numeric) { const struct xt_connmark_tginfo1 *info = (const void *)target->data; @@ -341,6 +602,84 @@ connmark_tg_print(const void *ip, const struct xt_entry_target *target, } } +static void +connmark_tg2_print(const void *ip, const struct xt_entry_target *target, + int numeric) +{ + const struct xt_connmark_tginfo2 *info = (const void *)target->data; + + switch (info->mode) { + case XT_CONNMARK_SET: + if (info->ctmark == 0) + printf("CONNMARK and 0x%x ", + (unsigned int)(u_int32_t)~info->ctmask); + else if (info->ctmark == info->ctmask) + printf("CONNMARK or 0x%x ", info->ctmark); + else if (info->ctmask == 0) + printf("CONNMARK xor 0x%x ", info->ctmark); + else + printf("CONNMARK xset 0x%x/0x%x ", + info->ctmark, info->ctmask); + break; + case XT_CONNMARK_SAVE: + if (info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX) + printf("CONNMARK save "); + else if (info->nfmask == info->ctmask) + printf("CONNMARK save mask 0x%x ", info->nfmask); + else + printf("CONNMARK save nfmask 0x%x ctmask ~0x%x ", + info->nfmask, info->ctmask); + break; + case XT_CONNMARK_RESTORE: + if (info->ctmask == UINT32_MAX && info->nfmask == UINT32_MAX) + printf("CONNMARK restore "); + else if (info->ctmask == info->nfmask) + printf("CONNMARK restore mask 0x%x ", info->ctmask); + else + printf("CONNMARK restore ctmask 0x%x nfmask ~0x%x ", + info->ctmask, info->nfmask); + break; + case XT_CONNMARK_EVENT_ONLY: + printf("CONNMARK "); + break; + default: + printf("ERROR: UNKNOWN CONNMARK MODE"); + break; + } + if (info->events) { + int i, comma; + if ((info->eventmask & IPCT_ALL) == IPCT_ALL) + printf("events ALL "); + else if ((info->eventmask & ~IPEXP_ALL) & IPCT_ALL) { + printf("events "); + for (i = IPCT_NEW_BIT, comma = 0; i < IPCT_ALL_BIT; i++) + if ((info->eventmask & (1 << i)) && events[i][0]) { + if (comma) + printf(","); + printf("%s", events[i]); + comma = 1; + } + printf(" "); + } else + printf("events NONE "); + + if ((info->eventmask & IPEXP_ALL) == IPEXP_ALL) + printf("exp-events ALL "); + else if ((info->eventmask & ~IPCT_ALL) & IPEXP_ALL) { + printf("exp-events "); + for (i = IPEXP_NEW_BIT, comma = 0; i < IPEXP_ALL_BIT; i++) + if ((info->eventmask & (1 << i)) && events[i][0]) { + if (comma) + printf(","); + printf("%s", events[i]); + comma = 1; + } + printf(" "); + } else + printf("exp-events NONE "); + } +} + static void CONNMARK_save(const void *ip, const struct xt_entry_target *target) { const struct xt_connmark_target_info *markinfo = @@ -376,7 +715,7 @@ static void CONNMARK_init(struct xt_entry_target *t) } static void -connmark_tg_save(const void *ip, const struct xt_entry_target *target) +connmark_tg1_save(const void *ip, const struct xt_entry_target *target) { const struct xt_connmark_tginfo1 *info = (const void *)target->data; @@ -398,6 +737,62 @@ connmark_tg_save(const void *ip, const struct xt_entry_target *target) } } +static void +connmark_tg2_save(const void *ip, const struct xt_entry_target *target) +{ + const struct xt_connmark_tginfo2 *info = (const void *)target->data; + + switch (info->mode) { + case XT_CONNMARK_SET: + printf("--set-xmark 0x%x/0x%x ", info->ctmark, info->ctmask); + break; + case XT_CONNMARK_SAVE: + printf("--save-mark --nfmask 0x%x --ctmask 0x%x ", + info->nfmask, info->ctmask); + break; + case XT_CONNMARK_RESTORE: + printf("--restore-mark --nfmask 0x%x --ctmask 0x%x ", + info->nfmask, info->ctmask); + break; + case XT_CONNMARK_EVENT_ONLY: + break; + default: + printf("ERROR: UNKNOWN CONNMARK MODE"); + break; + } + if (info->events) { + int i, comma; + if ((info->eventmask & IPCT_ALL) == IPCT_ALL) + printf("--events ALL "); + else if ((info->eventmask & ~IPEXP_ALL) & IPCT_ALL) { + printf("--events "); + for (i = IPCT_NEW_BIT, comma = 0; i < IPCT_ALL_BIT; i++) + if ((info->eventmask & (1 << i)) && events[i][0]) { + if (comma) + printf(","); + printf("%s", events[i]); + comma = 1; + } + printf(" "); + } else + printf("--events NONE "); + if ((info->eventmask & IPEXP_ALL) == IPEXP_ALL) + printf("--exp-events ALL "); + else if ((info->eventmask & ~IPCT_ALL) & IPEXP_ALL) { + printf("--exp-events "); + for (i = IPEXP_NEW_BIT, comma = 0; i < IPEXP_ALL_BIT; i++) + if ((info->eventmask & (1 << i)) && events[i][0]) { + if (comma) + printf(","); + printf("%s", events[i]); + comma = 1; + } + printf(" "); + } else + printf("--exp-events NONE "); + } +} + static struct xtables_target connmark_target = { .family = NFPROTO_IPV4, .name = "CONNMARK", @@ -408,7 +803,7 @@ static struct xtables_target connmark_target = { .help = CONNMARK_help, .init = CONNMARK_init, .parse = CONNMARK_parse, - .final_check = connmark_tg_check, + .final_check = connmark_tg1_check, .print = CONNMARK_print, .save = CONNMARK_save, .extra_opts = CONNMARK_opts, @@ -424,48 +819,82 @@ static struct xtables_target connmark_target6 = { .help = CONNMARK_help, .init = CONNMARK_init, .parse = CONNMARK_parse, - .final_check = connmark_tg_check, + .final_check = connmark_tg1_check, .print = CONNMARK_print, .save = CONNMARK_save, .extra_opts = CONNMARK_opts, }; -static struct xtables_target connmark_tg_reg = { +static struct xtables_target connmark_tg1_reg = { .version = XTABLES_VERSION, .name = "CONNMARK", .revision = 1, .family = NFPROTO_IPV4, .size = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)), .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)), - .help = connmark_tg_help, - .init = connmark_tg_init, - .parse = connmark_tg_parse, - .final_check = connmark_tg_check, - .print = connmark_tg_print, - .save = connmark_tg_save, - .extra_opts = connmark_tg_opts, + .help = connmark_tg1_help, + .init = connmark_tg1_init, + .parse = connmark_tg1_parse, + .final_check = connmark_tg1_check, + .print = connmark_tg1_print, + .save = connmark_tg1_save, + .extra_opts = connmark_tg1_opts, }; -static struct xtables_target connmark_tg6_reg = { +static struct xtables_target connmark_tg16_reg = { .version = XTABLES_VERSION, .name = "CONNMARK", .revision = 1, .family = NFPROTO_IPV6, .size = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)), .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo1)), - .help = connmark_tg_help, - .init = connmark_tg_init, - .parse = connmark_tg_parse, - .final_check = connmark_tg_check, - .print = connmark_tg_print, - .save = connmark_tg_save, - .extra_opts = connmark_tg_opts, + .help = connmark_tg1_help, + .init = connmark_tg1_init, + .parse = connmark_tg1_parse, + .final_check = connmark_tg1_check, + .print = connmark_tg1_print, + .save = connmark_tg1_save, + .extra_opts = connmark_tg1_opts, +}; + +static struct xtables_target connmark_tg2_reg = { + .version = XTABLES_VERSION, + .name = "CONNMARK", + .revision = 2, + .family = NFPROTO_IPV4, + .size = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)), + .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)), + .help = connmark_tg2_help, + .init = connmark_tg2_init, + .parse = connmark_tg2_parse, + .final_check = connmark_tg2_check, + .print = connmark_tg2_print, + .save = connmark_tg2_save, + .extra_opts = connmark_tg2_opts, +}; + +static struct xtables_target connmark_tg26_reg = { + .version = XTABLES_VERSION, + .name = "CONNMARK", + .revision = 2, + .family = NFPROTO_IPV6, + .size = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)), + .userspacesize = XT_ALIGN(sizeof(struct xt_connmark_tginfo2)), + .help = connmark_tg2_help, + .init = connmark_tg2_init, + .parse = connmark_tg2_parse, + .final_check = connmark_tg2_check, + .print = connmark_tg2_print, + .save = connmark_tg2_save, + .extra_opts = connmark_tg2_opts, }; void _init(void) { xtables_register_target(&connmark_target); xtables_register_target(&connmark_target6); - xtables_register_target(&connmark_tg_reg); - xtables_register_target(&connmark_tg6_reg); + xtables_register_target(&connmark_tg1_reg); + xtables_register_target(&connmark_tg16_reg); + xtables_register_target(&connmark_tg2_reg); + xtables_register_target(&connmark_tg26_reg); } diff --git a/extensions/libxt_CONNMARK.man b/extensions/libxt_CONNMARK.man index 571ce37..0050003 100644 --- a/extensions/libxt_CONNMARK.man +++ b/extensions/libxt_CONNMARK.man @@ -24,6 +24,17 @@ ctmark to XOR into the nfmark. \fIctmask\fR and \fInfmask\fR default to 0xFFFFFFFF. .IP \fB\-\-restore\-mark\fP is only valid in the \fBmangle\fP table. +.TP +\fB\-\-events\fP \fIevents\fP +Set for the rule-matching conntrack entry which \fIevents\fR should be handled. +The argument is a comma-separated list of the possible event identifier strings, +which can be listed by specifying the \-\-help option. +.TP +\fB\-\-exp-events\fP \fIexp-events\fP +Set for the rule-matching conntrack entry which \fIexpectation events\fR +should be handled. The argument is a comma-separated list of the possible +expectation event identifier strings which can be listed by specifying +the \-\-help option. .PP The following mnemonics are available for \fB\-\-set\-xmark\fP: .TP diff --git a/include/linux/netfilter/xt_CONNMARK.h b/include/linux/netfilter/xt_CONNMARK.h index 4e58ba4..bc4526e 100644 --- a/include/linux/netfilter/xt_CONNMARK.h +++ b/include/linux/netfilter/xt_CONNMARK.h @@ -13,7 +13,8 @@ enum { XT_CONNMARK_SET = 0, XT_CONNMARK_SAVE, - XT_CONNMARK_RESTORE + XT_CONNMARK_RESTORE, + XT_CONNMARK_EVENT_ONLY }; struct xt_connmark_target_info { @@ -27,4 +28,114 @@ struct xt_connmark_tginfo1 { u_int8_t mode; }; +struct xt_connmark_tginfo2 { + u_int32_t ctmark, ctmask, nfmask; + u_int8_t mode; + u_int8_t events; + u_int16_t eventmask; +}; + +/* Connection tracking event bits */ +enum ip_conntrack_events +{ + /* New conntrack */ + IPCT_NEW_BIT = 0, + IPCT_NEW = (1 << IPCT_NEW_BIT), + + /* Expected connection */ + IPCT_RELATED_BIT = 1, + IPCT_RELATED = (1 << IPCT_RELATED_BIT), + + /* Destroyed conntrack */ + IPCT_DESTROY_BIT = 2, + IPCT_DESTROY = (1 << IPCT_DESTROY_BIT), + + /* Timer has been refreshed */ + IPCT_REFRESH_BIT = 3, + IPCT_REFRESH = (1 << IPCT_REFRESH_BIT), + + /* Assured bit is set */ + IPCT_ASSURED_BIT = 4, + IPCT_ASSURED = (1 << IPCT_ASSURED_BIT), + + /* Backward compatibility */ + IPCT_STATUS = IPCT_ASSURED, + + /* Protocol state info */ + IPCT_PROTOINFO_BIT = 5, + IPCT_PROTOINFO = (1 << IPCT_PROTOINFO_BIT), + + /* ICMP(v6) protocol info */ + IPCT_ICMP_PROTOINFO_BIT = 6, + IPCT_ICMP_PROTOINFO = (1 << IPCT_ICMP_PROTOINFO_BIT), + + /* Backward compatibility */ + IPCT_PROTOINFO_VOLATILE = IPCT_ICMP_PROTOINFO, + + /* Helper for conntrack added/removed */ + IPCT_HELPER_BIT = 7, + IPCT_HELPER = (1 << IPCT_HELPER_BIT), + + /* Update of helper info */ + IPCT_HELPINFO_BIT = 8, + IPCT_HELPINFO = (1 << IPCT_HELPINFO_BIT), + + /* Seen reply packet */ + IPCT_SEEN_REPLY_BIT = 9, + IPCT_SEEN_REPLY = (1 << IPCT_SEEN_REPLY_BIT), + + /* Mark is set */ + IPCT_MARK_BIT = 10, + IPCT_MARK = (1 << IPCT_MARK_BIT), + + /* NAT sequence adjustment */ + IPCT_NATSEQADJ_BIT = 11, + IPCT_NATSEQADJ = (1 << IPCT_NATSEQADJ_BIT), + + /* Secmark is set */ + IPCT_SECMARK_BIT = 12, + IPCT_SECMARK = (1 << IPCT_SECMARK_BIT), + + /* All conntrack event bits */ + IPCT_ALL_BIT = 13, + IPCT_ALL = ((1 << IPCT_ALL_BIT) - 1), + + /* New expectation created */ + IPEXP_NEW_BIT = 13, + IPEXP_NEW = (1 << IPEXP_NEW_BIT), + + /* Timer has been refreshed */ + IPEXP_REFRESH_BIT = 14, + IPEXP_REFRESH = (1 << IPEXP_REFRESH_BIT), + + /* Expectation timed out */ + IPEXP_TIMEOUT_BIT = 15, + IPEXP_TIMEOUT = (1 << IPEXP_TIMEOUT_BIT), + + /* All expectation event bits */ + IPEXP_ALL_BIT = 16, + IPEXP_ALL = (((1 << IPEXP_ALL_BIT) - 1) & ~IPCT_ALL) +}; + +static const char events[IPEXP_ALL_BIT+1][16] = { + [IPCT_NEW_BIT] = "NEW", + [IPCT_RELATED_BIT] = "RELATED", + [IPCT_DESTROY_BIT] = "DESTROY", + [IPCT_REFRESH_BIT] = "REFRESH", + [IPCT_ASSURED_BIT] = "ASSURED", + [IPCT_PROTOINFO_BIT] = "PROTOINFO", + [IPCT_ICMP_PROTOINFO_BIT] = "ICMP_PROTOINFO", + [IPCT_HELPER_BIT] = "HELPER", + [IPCT_HELPINFO_BIT] = "HELPINFO", + [IPCT_SEEN_REPLY_BIT] = "SEEN_REPLY", + [IPCT_MARK_BIT] = "MARK", + [IPCT_NATSEQADJ_BIT] = "NATSEQADJ", + [IPCT_SECMARK_BIT] = "SECMARK", + [IPCT_ALL_BIT] = "ALL", + [IPEXP_NEW_BIT] = "NEW", + [IPEXP_REFRESH_BIT] = "REFRESH", + [IPEXP_TIMEOUT_BIT] = "TIMEOUT", + [IPEXP_ALL_BIT] = "ALL", +}; + #endif /*_XT_CONNMARK_H_target*/ -- 1.5.4.3 Best regards, Jozsef - E-mail : kadlec@xxxxxxxxxxxxxxxxx, kadlec@xxxxxxxxxxxx PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt Address : KFKI Research Institute for Particle and Nuclear Physics H-1525 Budapest 114, POB. 49, Hungary -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html