diff options
Diffstat (limited to 'cooker/parse.c')
-rw-r--r-- | cooker/parse.c | 273 |
1 files changed, 48 insertions, 225 deletions
diff --git a/cooker/parse.c b/cooker/parse.c index 0a87088..09b1e46 100644 --- a/cooker/parse.c +++ b/cooker/parse.c @@ -12,260 +12,80 @@ #include "calls.h" #include "cooker.h" #include "gluten.h" +#include "match.h" #include "emit.h" #include "util.h" #include "calls/net.h" -struct rule_parser { - const char *type; - int (*fn)(struct gluten_ctx *g, JSON_Value *value); -}; - -static int parse_match_load(struct gluten_ctx *g, struct arg *a) -{ - if (!a->size || g->match_dst[a->pos].len) - return 0; - - g->match_dst[a->pos].offset = gluten_alloc(g, a->size); - g->match_dst[a->pos].len = a->size; - - emit_load(g, g->match_dst[a->pos].offset, a->pos, a->size); - - return 0; -} - -static long long parse_match_expr_num(struct num *desc, JSON_Value *value) +static void handle_call(struct gluten_ctx *g, JSON_Value *value) { - const char *s = NULL; - long long n; - - if (desc) { - s = json_value_get_string(value); - for (; desc->name && s && strcmp(s, desc->name); desc++); - if (s && !desc->name) - die(" Invalid value %s", s); - - n = desc->value; - } - - if (!s) { - if (json_value_get_type(value) != JSONNumber) - die(" Invalid value type"); - - n = json_value_get_number(value); - } - - return n; -} - -static void parse_match_expr_value(union desc desc, enum type type, - JSON_Value *value, union value *out) -{ - if (TYPE_IS_NUM(type)) - out->v_num = parse_match_expr_num(desc.d_num, value); -} - -/** - * parse_match_select() - Get description and type for selected value - * @s: Possible selection choices - * @v: Selector value - * @type: Type of selected value, set on return - * @desc: Description of selected value, set on return - */ -static void parse_match_select(struct select *s, union value v, - enum type *type, union desc *desc) -{ - if (TYPE_IS_NUM(s->field->type)) { - struct select_num *d_num; - - for (d_num = s->desc.d_num; d_num->type; d_num++) { - if (d_num->value == v.v_num) { - *type = d_num->type; - *desc = d_num->desc; - return; - } - } - - if (!d_num->type) - die(" No match for numeric selector %i", v.v_num); - } - - die(" not supported yet"); -} - -/* - * parse_match_arg() - * load argument - * parse_match_key() - * compound types? demux, parse_match_expr - * parse_match_expr - * in/all/not/false-true array: demux, parse_match_expr_{num,string} - * parse_match_expr_{num,string} - * - * at terminal values - * store ref *pointers*! no copies - * emit additional bpf statement if syscall arg is also terminal -*/ -static int parse_match_key(struct gluten_ctx *g, int index, enum type type, - union desc desc, JSON_Value *value) -{ - JSON_Object *tmp; - const char *ref; - - if (type == SELECT) { - struct gluten_offset base_offset, const_offset; - struct select *select = desc.d_select; - struct field *field = select->field; - JSON_Value *selector; - union value v; - - if (!(tmp = json_value_get_object(value))) - die(" no object for compound value"); - - if (!(selector = json_object_get_value(tmp, field->name))) - die(" missing selector for '%s'", field->name); - - parse_match_expr_value(field->desc, field->type, selector, &v); - - base_offset = g->match_dst[index].offset; - const_offset = emit_data(g, field->type, &v); - emit_cmp_field(g, CMP_NE, field, base_offset, const_offset, - NEXT_BLOCK); - - parse_match_select(select, v, &type, &desc); - } - - if (json_value_get_type(value) == JSONObject && - (tmp = json_value_get_object(value)) && - (ref = json_object_get_string(tmp, "ref"))) { - if (TYPE_IS_COMPOUND(type)) - die("Reference '%s' to compound value"); - - debug(" setting reference '%s'", ref); - value = json_object_get_value(tmp, "value"); - - emit_load(g, gluten_alloc_type(g, type), index, type); - } - - /* Nothing to match on: just store as reference */ - if (!value) - return 0; - - switch (type) { - case INTFLAGS: - case LONGFLAGS: - case U32FLAGS: - /* fetch/combine expr algebra loop */ - case INTMASK: - /* calculate mask first */ - case INT: - case LONG: - case U32: - parse_match_expr_num(desc.d_num, value); - //emit_cmp(...); - default: - ; - } - - return 0; + (void)g; + (void)value; } -static int parse_match_arg(struct gluten_ctx *g, const char *name, - JSON_Value *value, struct arg *a) +static void handle_inject(struct gluten_ctx *g, JSON_Value *value) { - debug(" Parsing match argument %s", name); - - parse_match_load(g, a); - parse_match_key(g, a->pos, a->type, a->desc, value); - - return 0; + (void)g; + (void)value; } -static int parse_match(struct gluten_ctx *g, JSON_Object *obj, struct arg *args) +static void handle_limit(struct gluten_ctx *g, JSON_Value *value) { - unsigned count = 0; - struct arg *a; - - for (a = args; a->name; a++) { - JSON_Value *value; - - if ((value = json_object_get_value(obj, a->name))) { - count++; - parse_match_arg(g, a->name, value, a); - } - } - - if (count != json_object_get_count(obj)) - die(" Stray elements in match"); - - return 0; + (void)g; + (void)value; } -static int parse_matches(struct gluten_ctx *g, JSON_Value *value) +static void handle_return(struct gluten_ctx *g, JSON_Value *value) { - JSON_Array *matches = json_value_get_array(value); - unsigned i; - - for (i = 0; i < json_array_get_count(matches); i++) { - JSON_Object *match, *args; - struct call **set, *call; - const char *name; - - g->lr = g->ip; - - match = json_array_get_object(matches, i); - name = json_object_get_name(match, 0); - args = json_object_get_object(match, name); - debug(" Parsing match %i: %s", i, name); - - for (set = call_sets, call = set[0]; *set; call++) { - if (!call->name) { - set++; - continue; - } - - if (!strcmp(name, call->name)) { - debug(" Found handler for %s", name); - emit_nr(g, call->number); - - parse_match(g, args, call->args); - break; - } - } - - if (!*set) - die(" Unknown system call: %s", name); - } - - return 0; + (void)g; + (void)value; } -static int parse_call(struct gluten_ctx *g, JSON_Value *value) +static void handle_block(struct gluten_ctx *g, JSON_Value *value) { (void)g; (void)value; - return 0; } -static int parse_inject(struct gluten_ctx *g, JSON_Value *value) +static void handle_context(struct gluten_ctx *g, JSON_Value *value) { (void)g; (void)value; - return 0; } -struct rule_parser parsers[] = { - { "match", parse_matches }, - { "call", parse_call }, - { "inject", parse_inject }, +/** + * struct rule_parser - Parsing handler for JSON rule type + * @type: JSON key name + * @fn: Parsing function + */ +struct rule_parser { + const char *type; + void (*fn)(struct gluten_ctx *g, JSON_Value *value); +} parsers[] = { + { "match", handle_matches }, + { "call", handle_call }, + { "inject", handle_inject }, + { "limit", handle_limit }, + { "return", handle_return }, + { "block", handle_block }, + { "context", handle_context }, { NULL, NULL }, }; -static int parse_block(struct gluten_ctx *g, JSON_Object *block) +/** + * parse_block() - Parse a transformation block with rules + * @g: gluten context + * @block: Array of rules in block + */ +static void parse_block(struct gluten_ctx *g, JSON_Object *block) { unsigned i; + memset(g->selected_arg, 0, sizeof(g->selected_arg)); + memset(g->tags, 0, sizeof(g->tags)); + g->lr = g->ip; + for (i = 0; i < json_object_get_count(block); i++) { struct rule_parser *parser; JSON_Value *rule; @@ -285,10 +105,15 @@ static int parse_block(struct gluten_ctx *g, JSON_Object *block) die(" Invalid rule type: \"%s\"", type); } - return 0; + link_block(g); } -int parse_file(struct gluten_ctx *g, const char *path) +/** + * parse_file() - Entry point for parsing of a JSON input file + * @g: gluten context + * @path: Input file path + */ +void parse_file(struct gluten_ctx *g, const char *path) { JSON_Array *blocks; JSON_Value *root; @@ -306,6 +131,4 @@ int parse_file(struct gluten_ctx *g, const char *path) debug("Parsing block %i", i); parse_block(g, obj); } - - return 0; } |