Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ KERNEL = /lib/modules/$(shell uname -r)/build

export KERNEL TFW_CFLAGS AVX2 BMI2 ADX TFW_GCOV

obj-m += lib/ db/core/ fw/ tls/
obj-m += lib/ db/core/ regex/ fw/ tls/

all: build

Expand Down
80 changes: 67 additions & 13 deletions fw/cfg.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@
* them. Helpers below facilitate that.
*/

unsigned short number_of_regex = 0;
unsigned short number_of_db_regex = 0;

static const char *
__alloc_and_copy_literal(const char *src, size_t len, bool keep_bs)
{
Expand Down Expand Up @@ -397,6 +400,7 @@ typedef enum {
TOKEN_SEMICOLON,
TOKEN_LITERAL,
TOKEN_ARROW,
TOKEN_REGEX,
_TOKEN_COUNT,
} token_t;

Expand Down Expand Up @@ -591,6 +595,7 @@ read_next_token(TfwCfgParserState *ps)

/* Special case to differ single equal sign from double one. */
TFSM_COND_MOVE(ps->c == '=', TS_EQSIGN);
TFSM_COND_MOVE(ps->c == '~', TS_TILDA);

/* Everything else is not a special character and therefore
* it starts a literal. */
Expand Down Expand Up @@ -619,6 +624,12 @@ read_next_token(TfwCfgParserState *ps)
TFSM_JMP_EXIT(TOKEN_EQSIGN);
}

FSM_STATE(TS_TILDA) {
TFSM_COND_JMP_EXIT(!ps->c, TOKEN_REGEX);

TFSM_JMP_EXIT(TOKEN_REGEX);
}

FSM_STATE(TS_COMMENT) {
TFSM_COND_JMP_EXIT(!ps->c, TOKEN_NA);

Expand Down Expand Up @@ -732,7 +743,17 @@ entry_set_cond(TfwCfgEntry *e, token_t cond_type, const char *src, int len)
if (!(e->name = alloc_and_copy_literal(name, name_len)))
return -ENOMEM;

rule->inv = cond_type == TOKEN_DEQSIGN ? false : true;
switch (cond_type) {
case TOKEN_REGEX:
rule->regex = true;
rule->inv = false;
break;
default:
rule->regex = false;
rule->inv = cond_type == TOKEN_DEQSIGN ? false : true;
break;
}

return 0;
}

Expand Down Expand Up @@ -806,8 +827,9 @@ parse_cfg_entry(TfwCfgParserState *ps)

FSM_STATE(PS_PLAIN_OR_RULE) {
PFSM_COND_MOVE(ps->t == TOKEN_DEQSIGN ||
ps->t == TOKEN_NEQSIGN,
PS_RULE_COND);
ps->t == TOKEN_NEQSIGN ||
ps->t == TOKEN_REGEX,
PS_RULE_COND);
PFSM_COND_MOVE(ps->t == TOKEN_LITERAL, PS_PLAIN_OR_LONG_RULE);

/* Jump to plain val/attr scheme to make remained checks
Expand All @@ -819,35 +841,39 @@ parse_cfg_entry(TfwCfgParserState *ps)

FSM_STATE(PS_PLAIN_OR_LONG_RULE) {
FSM_COND_JMP(ps->t == TOKEN_DEQSIGN ||
ps->t == TOKEN_NEQSIGN,
PS_LONG_RULE_COND);
ps->t == TOKEN_NEQSIGN ||
ps->t == TOKEN_REGEX,
PS_LONG_RULE_COND);

/* This is not rule (simple or extended), so jump to
* plain val/attr scheme. */
ps->err = entry_set_name(&ps->e);
FSM_COND_JMP(ps->err, PS_EXIT);
FSM_COND_JMP(ps->t == TOKEN_EQSIGN, PS_STORE_ATTR_PREV);
FSM_COND_JMP(ps->t == TOKEN_LITERAL ||
ps->t == TOKEN_SEMICOLON ||
ps->t == TOKEN_LBRACE,
PS_STORE_VAL_PREV);
ps->t == TOKEN_SEMICOLON ||
ps->t == TOKEN_LBRACE,
PS_STORE_VAL_PREV);

ps->err = -EINVAL;
FSM_JMP(PS_EXIT);
}

FSM_STATE(PS_LONG_RULE_COND) {
ps->err = entry_add_rule_param(&ps->e.rule.fst_ext,
ps->prev_lit,
ps->prev_lit_len);
ps->prev_lit,
ps->prev_lit_len);
FSM_COND_JMP(ps->err, PS_EXIT);
PFSM_MOVE(PS_RULE_COND);
}

FSM_STATE(PS_RULE_COND) {
FSM_COND_JMP(ps->prev_t == TOKEN_REGEX,
PS_STORE_VAL_PREV_REGEX);

PFSM_COND_JMP_EXIT_ERROR(ps->t != TOKEN_LITERAL);
ps->err = entry_set_cond(&ps->e, ps->prev_t, ps->lit,
ps->lit_len);
ps->lit_len);
FSM_COND_JMP(ps->err, PS_EXIT);
PFSM_MOVE(PS_RULE_COND_END);
}
Expand All @@ -866,7 +892,7 @@ parse_cfg_entry(TfwCfgParserState *ps)
FSM_STATE(PS_RULE_ACTION) {
PFSM_COND_JMP_EXIT_ERROR(ps->t != TOKEN_LITERAL);
ps->err = entry_add_rule_param(&ps->e.rule.act, ps->lit,
ps->lit_len);
ps->lit_len);
FSM_COND_JMP(ps->err, PS_EXIT);
PFSM_MOVE(PS_RULE_ACTION_VAL);
}
Expand All @@ -878,7 +904,7 @@ parse_cfg_entry(TfwCfgParserState *ps)
PFSM_COND_JMP_EXIT_ERROR(ps->t != TOKEN_LITERAL);

ps->err = entry_add_rule_param(&ps->e.rule.val, ps->lit,
ps->lit_len);
ps->lit_len);
FSM_COND_JMP(ps->err, PS_EXIT);

read_next_token(ps);
Expand Down Expand Up @@ -914,6 +940,34 @@ parse_cfg_entry(TfwCfgParserState *ps)
FSM_JMP(PS_STORE_VAL_PREV);
}

FSM_STATE(PS_STORE_VAL_PREV_REGEX) {
/* name val1 val2;
* ^
* We are here (but still need to store val1)
* and name or condition.
*/
T_DBG3("add value: %.*s\n", ps->prev_lit_len, ps->prev_lit);

if (ps->e.ftoken && !strcmp(ps->e.ftoken, "location")) {
ps->err = entry_set_name(&ps->e);

if (!ps->err) {
if (ps->prev_t == TOKEN_REGEX)
ps->err = entry_add_val(&ps->e, "regex",
sizeof("regex"));
}
FSM_COND_JMP(ps->err, PS_EXIT);
FSM_JMP(PS_VAL_OR_ATTR);
}

/*If it is not location*/
ps->err = entry_set_cond(&ps->e, ps->prev_t,
ps->lit, ps->lit_len);
FSM_COND_JMP(ps->err, PS_EXIT);
PFSM_MOVE(PS_RULE_COND_END);

}

FSM_STATE(PS_STORE_VAL_PREV) {
/* name val1 val2;
* ^
Expand Down
6 changes: 5 additions & 1 deletion fw/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@ typedef struct {
const char *snd;
const char *act;
const char *val;
bool inv;
bool inv : 1;
bool regex : 1;
} TfwCfgRule;

typedef struct {
Expand Down Expand Up @@ -388,6 +389,9 @@ struct TfwCfgSpec {
void (*cleanup)(TfwCfgSpec *self);
};

extern unsigned short number_of_regex;
extern unsigned short number_of_db_regex;

/**
* Walks over a NULL-terminated array of TfwCfgSpec structures.
*/
Expand Down
Loading