From: Stephen Hemminger Date: Thu, 29 May 2008 18:54:19 +0000 (-0700) Subject: ematch related bugfix and cleanup X-Git-Tag: v2.6.26~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6da1afc736b7ab7fcd3b4df4f4486525c1ab7d3;p=thirdparty%2Fiproute2.git ematch related bugfix and cleanup Bugfix: use strtoul rather than strtol for bstrtol to handle large key/mask. Deinline larger functions to save space. --- diff --git a/tc/m_ematch.c b/tc/m_ematch.c index da4f22b25..7065fd0bf 100644 --- a/tc/m_ematch.c +++ b/tc/m_ematch.c @@ -491,3 +491,80 @@ int print_ematch(FILE *fd, const struct rtattr *rta) 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 "); + } +} diff --git a/tc/m_ematch.h b/tc/m_ematch.h index 2b5d29386..5036e9b6b 100644 --- a/tc/m_ematch.h +++ b/tc/m_ematch.h @@ -18,23 +18,7 @@ struct bstr struct bstr *next; }; -static inline 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; -} +extern struct bstr * bstr_alloc(const char *text); 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) 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) { 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 bstr *args; @@ -123,30 +77,8 @@ static inline struct ematch * new_ematch(struct bstr *args, int inverted) return e; } -static inline void print_ematch_tree(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 "); - } -} +extern void print_ematch_tree(const struct ematch *tree); + struct ematch_util {