Skip to content

Commit

Permalink
Implemented regex for locations and httptables
Browse files Browse the repository at this point in the history
Made regex configuration same way as in Nginx.
  • Loading branch information
supervisor authored and biathlon3 committed Jul 29, 2024
1 parent 09bd329 commit 09f70b3
Show file tree
Hide file tree
Showing 193 changed files with 58,582 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,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
97 changes: 84 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,9 @@ typedef enum {
TOKEN_SEMICOLON,
TOKEN_LITERAL,
TOKEN_ARROW,
TOKEN_TILDA,
TOKEN_REGEX,
TOKEN_REGEX_CI,
_TOKEN_COUNT,
} token_t;

Expand Down Expand Up @@ -588,9 +594,12 @@ read_next_token(TfwCfgParserState *ps)
TOKEN_NEQSIGN);
TFSM_COND_MOVE_EXIT(ps->c == '>' && ps->prev_c == '-',
TOKEN_ARROW);
TFSM_COND_MOVE_EXIT(ps->c == '*' && ps->prev_c == '~',
TOKEN_REGEX_CI);

/* 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 +628,14 @@ read_next_token(TfwCfgParserState *ps)
TFSM_JMP_EXIT(TOKEN_EQSIGN);
}

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

/* If this is double equal sign, eat second sign and exit. */
TFSM_COND_MOVE_EXIT(ps->c == '*', TOKEN_REGEX_CI);
TFSM_JMP_EXIT(TOKEN_REGEX);
}

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

Expand Down Expand Up @@ -732,7 +749,21 @@ 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 = TFW_REGEX_REGULAR;
rule->inv = false;
break;
case TOKEN_REGEX_CI:
rule->regex = TFW_REGEX_CI;
rule->inv = false;
break;
default:
rule->regex = TFW_REGEX_NO;
rule->inv = cond_type == TOKEN_DEQSIGN ? false : true;
break;
}

return 0;
}

Expand Down Expand Up @@ -806,8 +837,10 @@ 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->t == TOKEN_REGEX_CI,
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 +852,41 @@ 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->t == TOKEN_REGEX_CI,
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->prev_t == TOKEN_REGEX_CI,
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 +905,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 +917,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 +953,38 @@ 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"));
if (ps->prev_t == TOKEN_REGEX_CI)
ps->err = entry_add_val(&ps->e,
"regex_ci",
sizeof("regex_ci"));
}
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
10 changes: 10 additions & 0 deletions fw/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ typedef struct {
const char *act;
const char *val;
bool inv;
int regex;
} TfwCfgRule;

typedef struct {
Expand Down Expand Up @@ -336,6 +337,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 Expand Up @@ -412,6 +416,12 @@ enum {
TFW_CFG_B_KEEP, /* Keep an entry */
};

enum {
TFW_REGEX_NO = 0,
TFW_REGEX_REGULAR,
TFW_REGEX_CI,
};

#define TFW_CFG_F_ADD (1 << TFW_CFG_B_ADD)
#define TFW_CFG_F_DEL (1 << TFW_CFG_B_DEL)
#define TFW_CFG_F_MOD (1 << TFW_CFG_B_MOD)
Expand Down
Loading

0 comments on commit 09f70b3

Please sign in to comment.