Commit b6da1afc authored by Stephen Hemminger's avatar Stephen Hemminger

ematch related bugfix and cleanup

Bugfix: use strtoul rather than strtol for bstrtol to handle large key/mask.
Deinline larger functions to save space.
parent 516ffb6b
...@@ -491,3 +491,80 @@ int print_ematch(FILE *fd, const struct rtattr *rta) ...@@ -491,3 +491,80 @@ int print_ematch(FILE *fd, const struct rtattr *rta)
return print_ematch_list(fd, hdr, tb[TCA_EMATCH_TREE_LIST]); return print_ematch_list(fd, hdr, tb[TCA_EMATCH_TREE_LIST]);
} }
struct bstr * bstr_alloc(const char *text)
{
struct bstr *b = calloc(1, sizeof(*b));
if (b == NULL)
return NULL;
b->data = strdup(text);
if (b->data == NULL) {
free(b);
return NULL;
}
b->len = strlen(text);
return b;
}
unsigned long bstrtoul(const struct bstr *b)
{
char *inv = NULL;
unsigned long l;
char buf[b->len+1];
memcpy(buf, b->data, b->len);
buf[b->len] = '\0';
l = strtoul(buf, &inv, 0);
if (l == ULONG_MAX || inv == buf)
return ULONG_MAX;
return l;
}
void bstr_print(FILE *fd, const struct bstr *b, int ascii)
{
int i;
char *s = b->data;
if (ascii)
for (i = 0; i < b->len; i++)
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
else {
for (i = 0; i < b->len; i++)
fprintf(fd, "%02x", s[i]);
fprintf(fd, "\"");
for (i = 0; i < b->len; i++)
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
fprintf(fd, "\"");
}
}
void print_ematch_tree(const struct ematch *tree)
{
const struct ematch *t;
for (t = tree; t; t = t->next) {
if (t->inverted)
printf("NOT ");
if (t->child) {
printf("(");
print_ematch_tree(t->child);
printf(")");
} else {
struct bstr *b;
for (b = t->args; b; b = b->next)
printf("%s%s", b->data, b->next ? " " : "");
}
if (t->relation == TCF_EM_REL_AND)
printf(" AND ");
else if (t->relation == TCF_EM_REL_OR)
printf(" OR ");
}
}
...@@ -18,23 +18,7 @@ struct bstr ...@@ -18,23 +18,7 @@ struct bstr
struct bstr *next; struct bstr *next;
}; };
static inline struct bstr * bstr_alloc(const char *text) extern struct bstr * bstr_alloc(const char *text);
{
struct bstr *b = calloc(1, sizeof(*b));
if (b == NULL)
return NULL;
b->data = strdup(text);
if (b->data == NULL) {
free(b);
return NULL;
}
b->len = strlen(text);
return b;
}
static inline struct bstr * bstr_new(char *data, unsigned int len) static inline struct bstr * bstr_new(char *data, unsigned int len)
{ {
...@@ -60,45 +44,15 @@ static inline int bstrcmp(struct bstr *b, const char *text) ...@@ -60,45 +44,15 @@ static inline int bstrcmp(struct bstr *b, const char *text)
return d; return d;
} }
static inline unsigned long bstrtoul(struct bstr *b)
{
char *inv = NULL;
unsigned long l;
char buf[b->len+1];
memcpy(buf, b->data, b->len);
buf[b->len] = '\0';
l = strtol(buf, &inv, 0);
if (l == ULONG_MAX || inv == buf)
return LONG_MAX;
return l;
}
static inline void bstr_print(FILE *fd, struct bstr *b, int ascii)
{
int i;
char *s = b->data;
if (ascii)
for (i = 0; i < b->len; i++)
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
else {
for (i = 0; i < b->len; i++)
fprintf(fd, "%02x", s[i]);
fprintf(fd, "\"");
for (i = 0; i < b->len; i++)
fprintf(fd, "%c", isprint(s[i]) ? s[i] : '.');
fprintf(fd, "\"");
}
}
static inline struct bstr *bstr_next(struct bstr *b) static inline struct bstr *bstr_next(struct bstr *b)
{ {
return b->next; return b->next;
} }
extern unsigned long bstrtoul(const struct bstr *b);
extern void bstr_print(FILE *fd, const struct bstr *b, int ascii);
struct ematch struct ematch
{ {
struct bstr *args; struct bstr *args;
...@@ -123,30 +77,8 @@ static inline struct ematch * new_ematch(struct bstr *args, int inverted) ...@@ -123,30 +77,8 @@ static inline struct ematch * new_ematch(struct bstr *args, int inverted)
return e; return e;
} }
static inline void print_ematch_tree(struct ematch *tree) extern void print_ematch_tree(const struct ematch *tree);
{
struct ematch *t;
for (t = tree; t; t = t->next) {
if (t->inverted)
printf("NOT ");
if (t->child) {
printf("(");
print_ematch_tree(t->child);
printf(")");
} else {
struct bstr *b;
for (b = t->args; b; b = b->next)
printf("%s%s", b->data, b->next ? " " : "");
}
if (t->relation == TCF_EM_REL_AND)
printf(" AND ");
else if (t->relation == TCF_EM_REL_OR)
printf(" OR ");
}
}
struct ematch_util struct ematch_util
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment