static struct ematch_util *get_ematch_kind_num(__u16 kind) { char name[32]; if (lookup_map(kind, name, sizeof(name), EMATCH_MAP) < 0) return NULL; return get_ematch_kind(name); }
static int parse_tree(struct nlmsghdr *n, struct ematch *tree) { int index = 1; struct ematch *t; for (t = tree; t; t = t->next) { struct rtattr *tail = NLMSG_TAIL(n); struct tcf_ematch_hdr hdr = { .flags = t->relation }; if (t->inverted) hdr.flags |= TCF_EM_INVERT; addattr_l(n, MAX_MSG, index++, NULL, 0); if (t->child) { __u32 r = t->child_ref; addraw_l(n, MAX_MSG, &hdr, sizeof(hdr)); addraw_l(n, MAX_MSG, &r, sizeof(r)); } else { int num = 0, err; char buf[64]; struct ematch_util *e; if (t->args == NULL) return -1; strncpy(buf, (char*) t->args->data, sizeof(buf)-1); e = get_ematch_kind(buf); if (e == NULL) { fprintf(stderr, "Unknown ematch \"%s\"\n", buf); return -1; } err = lookup_map_id(buf, &num, EMATCH_MAP); if (err < 0) { if (err == -ENOENT) map_warning(e->kind_num, buf); return err; } hdr.kind = num; if (e->parse_eopt(n, &hdr, t->args->next) < 0) return -1; } tail->rta_len = (void*) NLMSG_TAIL(n) - (void*) tail; } return 0; } static int flatten_tree(struct ematch *head, struct ematch *tree) { int i, count = 0; struct ematch *t; for (;;) { count++; if (tree->child) { for (t = head; t->next; t = t->next); t->next = tree->child; count += flatten_tree(head, tree->child); } if (tree->relation == 0) break; tree = tree->next; } for (i = 0, t = head; t; t = t->next, i++) t->index = i; for (t = head; t; t = t->next) if (t->child) t->child_ref = t->child->index; return count; }