diff options
-rw-r--r-- | libiptc/libiptc.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c index 05985050..29f671e6 100644 --- a/libiptc/libiptc.c +++ b/libiptc/libiptc.c @@ -415,12 +415,28 @@ static inline void iptc_insert_chain(TC_HANDLE_T h, struct chain_head *c) static void __iptcc_p_add_chain(TC_HANDLE_T h, struct chain_head *c, unsigned int offset, unsigned int *num) { + struct list_head *tail = h->chains.prev; + struct chain_head *ctail; + __iptcc_p_del_policy(h, *num); c->head_offset = offset; c->index = *num; - list_add_tail(&c->list, &h->chains); /* Its already sorted */ + /* Chains from kernel are already sorted, as they are inserted + * sorted. But there exists an issue when shifting to 1.4.0 + * from an older version, as old versions allow last created + * chain to be unsorted. + */ + if (iptcc_is_builtin(c)) /* Only user defined chains are sorted*/ + list_add_tail(&c->list, &h->chains); + else { + ctail = list_entry(tail, struct chain_head, list); + if (strcmp(c->name, ctail->name) > 0) + list_add_tail(&c->list, &h->chains);/* Already sorted*/ + else + iptc_insert_chain(h, c);/* Was not sorted */ + } h->chain_iterator_cur = c; } |