diff options
Diffstat (limited to 'iprule.c')
-rw-r--r-- | iprule.c | 29 |
1 files changed, 27 insertions, 2 deletions
@@ -290,7 +290,7 @@ iprule_add(struct blob_attr *attr, bool v6) rule->flags |= IPRULE_GOTO; } - vlist_add(&iprules, &rule->node, &rule->flags); + vlist_add(&iprules, &rule->node, rule); return; error: @@ -320,7 +320,32 @@ iprule_update_complete(void) static int rule_cmp(const void *k1, const void *k2, void *ptr) { - return memcmp(k1, k2, sizeof(struct iprule)-offsetof(struct iprule, flags)); + const struct iprule *r1 = k1, *r2 = k2; + int ret; + + /* First compare the interface names */ + if (r1->flags & IPRULE_IN || r2->flags & IPRULE_IN) { + char *str1 = r1->flags & IPRULE_IN ? r1->in_iface : ""; + char *str2 = r2->flags & IPRULE_IN ? r2->in_iface : ""; + + ret = strcmp(str1, str2); + if (ret) + return ret; + } + + if (r1->flags & IPRULE_OUT || r2->flags & IPRULE_OUT) { + char *str1 = r1->flags & IPRULE_OUT ? r1->out_iface : ""; + char *str2 = r2->flags & IPRULE_OUT ? r2->out_iface : ""; + + ret = strcmp(str1, str2); + if (ret) + return ret; + } + + /* Next compare everything after the flags field */ + return memcmp(k1 + offsetof(struct iprule, flags), + k2 + offsetof(struct iprule, flags), + sizeof(struct iprule) - offsetof(struct iprule, flags)); } static void deregister_interfaces(struct iprule *rule) |