summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/datatype.c3
-rw-r--r--src/erec.c20
-rw-r--r--src/main.c8
-rw-r--r--src/netlink.c9
-rw-r--r--src/netlink_delinearize.c3
-rw-r--r--src/parser_bison.y16
-rw-r--r--src/payload.c9
-rw-r--r--src/rule.c44
8 files changed, 71 insertions, 41 deletions
diff --git a/src/datatype.c b/src/datatype.c
index f42e3dfb..f79f5d2d 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -156,13 +156,14 @@ out:
void symbolic_constant_print(const struct symbol_table *tbl,
const struct expr *expr)
{
+ unsigned int len = div_round_up(expr->len, BITS_PER_BYTE);
const struct symbolic_constant *s;
uint64_t val = 0;
/* Export the data in the correct byteorder for comparison */
assert(expr->len / BITS_PER_BYTE <= sizeof(val));
mpz_export_data(constant_data_ptr(val, expr->len), expr->value,
- expr->byteorder, expr->len / BITS_PER_BYTE);
+ expr->byteorder, len);
for (s = tbl->symbols; s->identifier != NULL; s++) {
if (val == s->value)
diff --git a/src/erec.c b/src/erec.c
index 810e9bfd..d5142307 100644
--- a/src/erec.c
+++ b/src/erec.c
@@ -12,6 +12,7 @@
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <netlink.h>
#include <gmputil.h>
@@ -82,8 +83,10 @@ void erec_print(FILE *f, const struct error_record *erec)
const struct input_descriptor *indesc = loc->indesc, *tmp;
const char *line = NULL; /* silence gcc */
char buf[1024];
+ char *pbuf = NULL;
unsigned int i, end;
int l, ret;
+ off_t orig_offset = 0;
switch (indesc->type) {
case INDESC_BUFFER:
@@ -92,11 +95,13 @@ void erec_print(FILE *f, const struct error_record *erec)
break;
case INDESC_FILE:
memset(buf, 0, sizeof(buf));
+ orig_offset = lseek(indesc->fd, 0, SEEK_CUR);
lseek(indesc->fd, loc->line_offset, SEEK_SET);
ret = read(indesc->fd, buf, sizeof(buf) - 1);
if (ret > 0)
*strchrnul(buf, '\n') = '\0';
line = buf;
+ lseek(indesc->fd, orig_offset, SEEK_SET);
break;
case INDESC_INTERNAL:
case INDESC_NETLINK:
@@ -141,17 +146,22 @@ void erec_print(FILE *f, const struct error_record *erec)
if (indesc->type != INDESC_INTERNAL)
fprintf(f, "%s\n", line);
- memset(buf, ' ', sizeof(buf));
end = 0;
for (l = erec->num_locations - 1; l >= 0; l--) {
loc = &erec->locations[l];
+ end = max(end, loc->last_column);
+ }
+ pbuf = xmalloc(end + 1);
+ memset(pbuf, ' ', end + 1);
+ for (l = erec->num_locations - 1; l >= 0; l--) {
+ loc = &erec->locations[l];
for (i = loc->first_column ? loc->first_column - 1 : 0;
i < loc->last_column; i++)
- buf[i] = l ? '~' : '^';
- end = max(end, loc->last_column);
+ pbuf[i] = l ? '~' : '^';
}
- buf[end] = '\0';
- fprintf(f, "%s", buf);
+ pbuf[end] = '\0';
+ fprintf(f, "%s", pbuf);
+ xfree(pbuf);
}
fprintf(f, "\n");
}
diff --git a/src/main.c b/src/main.c
index bfe589a0..a2c4f87d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -230,15 +230,17 @@ int nft_run(void *scanner, struct parser_state *state, struct list_head *msgs)
int ret;
ret = nft_parse(scanner, state);
- if (ret != 0 || state->nerrs > 0)
- return -1;
+ if (ret != 0 || state->nerrs > 0) {
+ ret = -1;
+ goto err1;
+ }
retry:
ret = nft_netlink(state, msgs);
if (ret < 0 && errno == EINTR) {
netlink_restart();
goto retry;
}
-
+err1:
list_for_each_entry_safe(cmd, next, &state->cmds, list) {
list_del(&cmd->list);
cmd_free(cmd);
diff --git a/src/netlink.c b/src/netlink.c
index bef33a1d..cff93446 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -694,6 +694,8 @@ static struct chain *netlink_delinearize_chain(struct netlink_ctx *ctx,
nft_chain_attr_is_set(nlc, NFT_CHAIN_ATTR_POLICY)) {
chain->hooknum =
nft_chain_attr_get_u32(nlc, NFT_CHAIN_ATTR_HOOKNUM);
+ chain->hookstr =
+ hooknum2str(chain->handle.family, chain->hooknum);
chain->priority =
nft_chain_attr_get_s32(nlc, NFT_CHAIN_ATTR_PRIO);
chain->type =
@@ -979,7 +981,7 @@ int netlink_get_table(struct netlink_ctx *ctx, const struct handle *h,
ntable = netlink_delinearize_table(ctx, nlt);
table->flags = ntable->flags;
- xfree(ntable);
+ table_free(ntable);
out:
nft_table_free(nlt);
return err;
@@ -1989,14 +1991,15 @@ static void netlink_events_cache_deltable(struct netlink_mon_handler *monh,
nlt = netlink_table_alloc(nlh);
h.family = nft_table_attr_get_u32(nlt, NFT_TABLE_ATTR_FAMILY);
h.table = nft_table_attr_get_str(nlt, NFT_TABLE_ATTR_NAME);
- nft_table_free(nlt);
t = table_lookup(&h);
if (t == NULL)
- return;
+ goto out;
list_del(&t->list);
table_free(t);
+out:
+ nft_table_free(nlt);
}
static void netlink_events_cache_addset(struct netlink_mon_handler *monh,
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 6d60be32..4226b822 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -983,6 +983,9 @@ static void meta_match_postprocess(struct rule_pp_ctx *ctx,
switch (expr->op) {
case OP_EQ:
+ if (expr->right->ops->type == EXPR_RANGE)
+ break;
+
expr->left->ops->pctx_update(&ctx->pctx, expr);
if (ctx->pbase == PROTO_BASE_INVALID &&
diff --git a/src/parser_bison.y b/src/parser_bison.y
index fab4c52e..942470f6 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -398,12 +398,12 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token XML "xml"
%token JSON "json"
-%type <string> identifier string comment_spec
-%destructor { xfree($$); } identifier string comment_spec
+%type <string> identifier type_identifier string comment_spec
+%destructor { xfree($$); } identifier type_identifier string comment_spec
%type <val> time_spec
-%type <val> type_identifier
+%type <val> type_identifier_list
%type <datatype> data_type
%type <cmd> line
@@ -1027,7 +1027,7 @@ set_policy_spec : PERFORMANCE { $$ = NFT_SET_POL_PERFORMANCE; }
| MEMORY { $$ = NFT_SET_POL_MEMORY; }
;
-data_type : type_identifier
+data_type : type_identifier_list
{
if ($1 & ~TYPE_MASK)
$$ = concat_type_alloc($1);
@@ -1036,7 +1036,7 @@ data_type : type_identifier
}
;
-type_identifier : identifier
+type_identifier_list : type_identifier
{
const struct datatype *dtype = datatype_lookup_byname($1);
if (dtype == NULL) {
@@ -1046,7 +1046,7 @@ type_identifier : identifier
}
$$ = dtype->type;
}
- | type_identifier DOT identifier
+ | type_identifier_list DOT type_identifier
{
const struct datatype *dtype = datatype_lookup_byname($3);
if (dtype == NULL) {
@@ -1058,6 +1058,10 @@ type_identifier : identifier
}
;
+type_identifier : STRING { $$ = $1; }
+ | MARK { $$ = xstrdup("mark"); }
+ ;
+
hook_spec : TYPE STRING HOOK STRING PRIORITY NUM
{
$<chain>0->type = chain_type_name_lookup($2);
diff --git a/src/payload.c b/src/payload.c
index 1a9d4917..62f1d56d 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -204,12 +204,12 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
switch (ctx->pctx.family) {
case NFPROTO_INET:
switch (expr->payload.base) {
- case PROTO_BASE_TRANSPORT_HDR:
- desc = &proto_inet_service;
- break;
case PROTO_BASE_LL_HDR:
desc = &proto_inet;
break;
+ case PROTO_BASE_TRANSPORT_HDR:
+ desc = &proto_inet_service;
+ break;
default:
break;
}
@@ -220,6 +220,9 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
case PROTO_BASE_LL_HDR:
desc = &proto_eth;
break;
+ case PROTO_BASE_TRANSPORT_HDR:
+ desc = &proto_inet_service;
+ break;
default:
break;
}
diff --git a/src/rule.c b/src/rule.c
index f930a374..8e3ef5f6 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -411,7 +411,7 @@ const char *family2str(unsigned int family)
return "unknown";
}
-static const char *hooknum2str(unsigned int family, unsigned int hooknum)
+const char *hooknum2str(unsigned int family, unsigned int hooknum)
{
switch (family) {
case NFPROTO_IPV4:
@@ -476,15 +476,16 @@ static void chain_print(const struct chain *chain)
printf("\tchain %s {\n", chain->handle.chain);
if (chain->flags & CHAIN_F_BASECHAIN) {
if (chain->dev != NULL) {
- printf("\t\ttype %s hook %s device %s priority %d;\n",
+ printf("\t\ttype %s hook %s device %s priority %d; policy %s;\n",
chain->type,
hooknum2str(chain->handle.family, chain->hooknum),
- chain->dev, chain->priority);
+ chain->dev, chain->priority,
+ chain_policy2str(chain->policy));
} else {
- printf("\t\ttype %s hook %s priority %d;\n",
+ printf("\t\ttype %s hook %s priority %d; policy %s;\n",
chain->type,
hooknum2str(chain->handle.family, chain->hooknum),
- chain->priority);
+ chain->priority, chain_policy2str(chain->policy));
}
}
list_for_each_entry(rule, &chain->rules, list) {
@@ -505,8 +506,7 @@ void chain_print_plain(const struct chain *chain)
if (chain->flags & CHAIN_F_BASECHAIN) {
printf(" { type %s hook %s priority %d; policy %s; }",
- chain->type,
- hooknum2str(chain->handle.family, chain->hooknum),
+ chain->type, chain->hookstr,
chain->priority, chain_policy2str(chain->policy));
}
@@ -919,6 +919,21 @@ static int do_list_ruleset(struct netlink_ctx *ctx, struct cmd *cmd)
return 0;
}
+static int do_list_tables(struct netlink_ctx *ctx, struct cmd *cmd)
+{
+ struct table *table;
+
+ if (netlink_list_tables(ctx, &cmd->handle, &cmd->location) < 0)
+ return -1;
+
+ list_for_each_entry(table, &ctx->list, list)
+ printf("table %s %s\n",
+ family2str(table->handle.family),
+ table->handle.table);
+
+ return 0;
+}
+
static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
{
struct table *table = NULL;
@@ -936,19 +951,8 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
switch (cmd->obj) {
case CMD_OBJ_TABLE:
- if (!cmd->handle.table) {
- /* List all existing tables */
- struct table *table;
-
- if (netlink_list_tables(ctx, &cmd->handle,
- &cmd->location) < 0)
- return -1;
-
- list_for_each_entry(table, &ctx->list, list) {
- printf("table %s\n", table->handle.table);
- }
- return 0;
- }
+ if (!cmd->handle.table)
+ return do_list_tables(ctx, cmd);
return do_list_table(ctx, cmd, table);
case CMD_OBJ_CHAIN:
return do_list_table(ctx, cmd, table);