summaryrefslogtreecommitdiffstats
path: root/libiptc
diff options
context:
space:
mode:
Diffstat (limited to 'libiptc')
-rw-r--r--libiptc/libiptc.c18
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;
}