From 0b08f9f17ae95a6f8eded6543922b99e7f29cbf7 Mon Sep 17 00:00:00 2001 From: Jozsef Kadlecsik Date: Thu, 31 Oct 2019 14:18:48 +0100 Subject: Sort naturally instead of textual sort (bugzilla #1369) Sort 95.0.0.0 before 107.0.0.0 instead of the textual sorting. Also, in the case of subnets, sort reversed, ie. most specific first. --- lib/session.c | 80 ++++++++++++++- tests/iphash.t.restore.sorted | 222 +++++++++++++++++++++--------------------- 2 files changed, 189 insertions(+), 113 deletions(-) diff --git a/lib/session.c b/lib/session.c index c28c2d8..9e3eae3 100644 --- a/lib/session.c +++ b/lib/session.c @@ -64,6 +64,7 @@ struct ipset_session { ipset_print_outfn print_outfn; /* Output function to file */ void *p; /* Private data for print_outfn */ bool sort; /* Print sorted hash:* types */ + size_t save_elem_prefix; /* "add setname " */ /* Session IO */ bool normal_io, full_io; /* Default/normal/full IO */ FILE *istream, *ostream; /* Session input/output stream */ @@ -979,6 +980,7 @@ list_create(struct ipset_session *session, struct nlattr *nla[]) return MNL_CB_ERROR; family = ipset_data_family(data); + session->save_elem_prefix = strlen(ipset_data_setname(data)) + 5; switch (session->mode) { case IPSET_LIST_SAVE: safe_snprintf(session, "create %s %s", @@ -1084,15 +1086,89 @@ list_create(struct ipset_session *session, struct nlattr *nla[]) return MNL_CB_OK; } +/* "" */ +#define XML_ELEM_PREFIX_LEN 14 + +/* Core should handle sorting more directly */ static int bystrcmp(void *priv, struct list_head *a, struct list_head *b) { struct ipset_session *session = priv; struct ipset_sorted *x = list_entry(a, struct ipset_sorted, list); struct ipset_sorted *y = list_entry(b, struct ipset_sorted, list); + char *sep1, *x1 = session->outbuf + x->offset; + char *sep2, *x2 = session->outbuf + y->offset; + long int n1, n2; + int neg = 1; + + if (session->envopts & IPSET_ENV_RESOLVE) + return strcmp(x1, x2); + + /* Skip prefix */ + switch (session->mode) { + case IPSET_LIST_SAVE: + /* "add setname " */ + x1 += session->save_elem_prefix; + x2 += session->save_elem_prefix; + break; + case IPSET_LIST_XML: + /* "" */ + x1 += XML_ELEM_PREFIX_LEN; + x2 += XML_ELEM_PREFIX_LEN; + break; + default: + break; + } - return strcmp(session->outbuf + x->offset, - session->outbuf + y->offset); + while (*x1 != '\0' && *x2 != '\0') { + n1 = strtol(x1, &sep1, 16); + n2 = strtol(x2, &sep2, 16); + if (x1 == sep1 || x2 == sep2) { + /* No leading numbers: proto:port, iface, setname */ + n1 = strcspn(x1, ":,"); + n2 = strcspn(x2, ":,"); + if (n1 != 0 || n2 != 0) { + if (n1 == n2) { + n2 = strncmp(x1, x2, n1); + if (n2 == 0) { + x1 += n1 + 1; + x2 += n1 + 1; + neg = 1; + continue; + } + return n2; + } + return n1 < n2 ? -1 : 1; + } + /* Setname or iface */ + return strcmp(x1, x2); + } + /* Leading numbers found */ + if (n1 != n2) + return neg * (n1 - n2); + /* Check subnet separator */ + if (*sep1 == '/' || *sep2 == '/') { + if (*sep1 == *sep2) + neg = *sep1 == '/' ? -1 : 1; + else if (*sep1 == '/') + return 1; + else + return -1; + } + x1 = ++sep1; + x2 = ++sep2; + /* Handle IPv6 '::' case */ + if (*x1 == ':' || *x2 == ':') { + if (*x1 == *x2) { + x1++; + x2++; + } else if (*x1 == ':') + return -1; + else + return 1; + } + } + return *x1 != '\0' ? 1 : (*x2 != '\0' ? -1 : 0); } static int diff --git a/tests/iphash.t.restore.sorted b/tests/iphash.t.restore.sorted index 5bd53a2..e944061 100644 --- a/tests/iphash.t.restore.sorted +++ b/tests/iphash.t.restore.sorted @@ -1,38 +1,17 @@ create test hash:ip family inet hashsize 128 maxelem 65536 add test 10.0.0.0 add test 10.0.0.1 +add test 10.0.0.2 +add test 10.0.0.3 +add test 10.0.0.4 +add test 10.0.0.5 +add test 10.0.0.6 +add test 10.0.0.7 +add test 10.0.0.8 +add test 10.0.0.9 add test 10.0.0.10 -add test 10.0.0.100 -add test 10.0.0.101 -add test 10.0.0.102 -add test 10.0.0.103 -add test 10.0.0.104 -add test 10.0.0.105 -add test 10.0.0.106 -add test 10.0.0.107 -add test 10.0.0.108 -add test 10.0.0.109 add test 10.0.0.11 -add test 10.0.0.110 -add test 10.0.0.111 -add test 10.0.0.112 -add test 10.0.0.113 -add test 10.0.0.114 -add test 10.0.0.115 -add test 10.0.0.116 -add test 10.0.0.117 -add test 10.0.0.118 -add test 10.0.0.119 add test 10.0.0.12 -add test 10.0.0.120 -add test 10.0.0.121 -add test 10.0.0.122 -add test 10.0.0.123 -add test 10.0.0.124 -add test 10.0.0.125 -add test 10.0.0.126 -add test 10.0.0.127 -add test 10.0.0.128 add test 10.0.0.13 add test 10.0.0.14 add test 10.0.0.15 @@ -40,7 +19,6 @@ add test 10.0.0.16 add test 10.0.0.17 add test 10.0.0.18 add test 10.0.0.19 -add test 10.0.0.2 add test 10.0.0.20 add test 10.0.0.21 add test 10.0.0.22 @@ -51,7 +29,6 @@ add test 10.0.0.26 add test 10.0.0.27 add test 10.0.0.28 add test 10.0.0.29 -add test 10.0.0.3 add test 10.0.0.30 add test 10.0.0.31 add test 10.0.0.32 @@ -62,7 +39,6 @@ add test 10.0.0.36 add test 10.0.0.37 add test 10.0.0.38 add test 10.0.0.39 -add test 10.0.0.4 add test 10.0.0.40 add test 10.0.0.41 add test 10.0.0.42 @@ -73,7 +49,6 @@ add test 10.0.0.46 add test 10.0.0.47 add test 10.0.0.48 add test 10.0.0.49 -add test 10.0.0.5 add test 10.0.0.50 add test 10.0.0.51 add test 10.0.0.52 @@ -84,7 +59,6 @@ add test 10.0.0.56 add test 10.0.0.57 add test 10.0.0.58 add test 10.0.0.59 -add test 10.0.0.6 add test 10.0.0.60 add test 10.0.0.61 add test 10.0.0.62 @@ -95,7 +69,6 @@ add test 10.0.0.66 add test 10.0.0.67 add test 10.0.0.68 add test 10.0.0.69 -add test 10.0.0.7 add test 10.0.0.70 add test 10.0.0.71 add test 10.0.0.72 @@ -106,7 +79,6 @@ add test 10.0.0.76 add test 10.0.0.77 add test 10.0.0.78 add test 10.0.0.79 -add test 10.0.0.8 add test 10.0.0.80 add test 10.0.0.81 add test 10.0.0.82 @@ -117,7 +89,6 @@ add test 10.0.0.86 add test 10.0.0.87 add test 10.0.0.88 add test 10.0.0.89 -add test 10.0.0.9 add test 10.0.0.90 add test 10.0.0.91 add test 10.0.0.92 @@ -128,41 +99,49 @@ add test 10.0.0.96 add test 10.0.0.97 add test 10.0.0.98 add test 10.0.0.99 +add test 10.0.0.100 +add test 10.0.0.101 +add test 10.0.0.102 +add test 10.0.0.103 +add test 10.0.0.104 +add test 10.0.0.105 +add test 10.0.0.106 +add test 10.0.0.107 +add test 10.0.0.108 +add test 10.0.0.109 +add test 10.0.0.110 +add test 10.0.0.111 +add test 10.0.0.112 +add test 10.0.0.113 +add test 10.0.0.114 +add test 10.0.0.115 +add test 10.0.0.116 +add test 10.0.0.117 +add test 10.0.0.118 +add test 10.0.0.119 +add test 10.0.0.120 +add test 10.0.0.121 +add test 10.0.0.122 +add test 10.0.0.123 +add test 10.0.0.124 +add test 10.0.0.125 +add test 10.0.0.126 +add test 10.0.0.127 +add test 10.0.0.128 create test2 hash:ip family inet hashsize 128 maxelem 65536 add test2 20.0.0.0 add test2 20.0.0.1 +add test2 20.0.0.2 +add test2 20.0.0.3 +add test2 20.0.0.4 +add test2 20.0.0.5 +add test2 20.0.0.6 +add test2 20.0.0.7 +add test2 20.0.0.8 +add test2 20.0.0.9 add test2 20.0.0.10 -add test2 20.0.0.100 -add test2 20.0.0.101 -add test2 20.0.0.102 -add test2 20.0.0.103 -add test2 20.0.0.104 -add test2 20.0.0.105 -add test2 20.0.0.106 -add test2 20.0.0.107 -add test2 20.0.0.108 -add test2 20.0.0.109 add test2 20.0.0.11 -add test2 20.0.0.110 -add test2 20.0.0.111 -add test2 20.0.0.112 -add test2 20.0.0.113 -add test2 20.0.0.114 -add test2 20.0.0.115 -add test2 20.0.0.116 -add test2 20.0.0.117 -add test2 20.0.0.118 -add test2 20.0.0.119 add test2 20.0.0.12 -add test2 20.0.0.120 -add test2 20.0.0.121 -add test2 20.0.0.122 -add test2 20.0.0.123 -add test2 20.0.0.124 -add test2 20.0.0.125 -add test2 20.0.0.126 -add test2 20.0.0.127 -add test2 20.0.0.128 add test2 20.0.0.13 add test2 20.0.0.14 add test2 20.0.0.15 @@ -170,7 +149,6 @@ add test2 20.0.0.16 add test2 20.0.0.17 add test2 20.0.0.18 add test2 20.0.0.19 -add test2 20.0.0.2 add test2 20.0.0.20 add test2 20.0.0.21 add test2 20.0.0.22 @@ -181,7 +159,6 @@ add test2 20.0.0.26 add test2 20.0.0.27 add test2 20.0.0.28 add test2 20.0.0.29 -add test2 20.0.0.3 add test2 20.0.0.30 add test2 20.0.0.31 add test2 20.0.0.32 @@ -192,7 +169,6 @@ add test2 20.0.0.36 add test2 20.0.0.37 add test2 20.0.0.38 add test2 20.0.0.39 -add test2 20.0.0.4 add test2 20.0.0.40 add test2 20.0.0.41 add test2 20.0.0.42 @@ -203,7 +179,6 @@ add test2 20.0.0.46 add test2 20.0.0.47 add test2 20.0.0.48 add test2 20.0.0.49 -add test2 20.0.0.5 add test2 20.0.0.50 add test2 20.0.0.51 add test2 20.0.0.52 @@ -214,7 +189,6 @@ add test2 20.0.0.56 add test2 20.0.0.57 add test2 20.0.0.58 add test2 20.0.0.59 -add test2 20.0.0.6 add test2 20.0.0.60 add test2 20.0.0.61 add test2 20.0.0.62 @@ -225,7 +199,6 @@ add test2 20.0.0.66 add test2 20.0.0.67 add test2 20.0.0.68 add test2 20.0.0.69 -add test2 20.0.0.7 add test2 20.0.0.70 add test2 20.0.0.71 add test2 20.0.0.72 @@ -236,7 +209,6 @@ add test2 20.0.0.76 add test2 20.0.0.77 add test2 20.0.0.78 add test2 20.0.0.79 -add test2 20.0.0.8 add test2 20.0.0.80 add test2 20.0.0.81 add test2 20.0.0.82 @@ -247,7 +219,6 @@ add test2 20.0.0.86 add test2 20.0.0.87 add test2 20.0.0.88 add test2 20.0.0.89 -add test2 20.0.0.9 add test2 20.0.0.90 add test2 20.0.0.91 add test2 20.0.0.92 @@ -258,40 +229,48 @@ add test2 20.0.0.96 add test2 20.0.0.97 add test2 20.0.0.98 add test2 20.0.0.99 +add test2 20.0.0.100 +add test2 20.0.0.101 +add test2 20.0.0.102 +add test2 20.0.0.103 +add test2 20.0.0.104 +add test2 20.0.0.105 +add test2 20.0.0.106 +add test2 20.0.0.107 +add test2 20.0.0.108 +add test2 20.0.0.109 +add test2 20.0.0.110 +add test2 20.0.0.111 +add test2 20.0.0.112 +add test2 20.0.0.113 +add test2 20.0.0.114 +add test2 20.0.0.115 +add test2 20.0.0.116 +add test2 20.0.0.117 +add test2 20.0.0.118 +add test2 20.0.0.119 +add test2 20.0.0.120 +add test2 20.0.0.121 +add test2 20.0.0.122 +add test2 20.0.0.123 +add test2 20.0.0.124 +add test2 20.0.0.125 +add test2 20.0.0.126 +add test2 20.0.0.127 +add test2 20.0.0.128 add test2 30.0.0.0 add test2 30.0.0.1 +add test2 30.0.0.2 +add test2 30.0.0.3 +add test2 30.0.0.4 +add test2 30.0.0.5 +add test2 30.0.0.6 +add test2 30.0.0.7 +add test2 30.0.0.8 +add test2 30.0.0.9 add test2 30.0.0.10 -add test2 30.0.0.100 -add test2 30.0.0.101 -add test2 30.0.0.102 -add test2 30.0.0.103 -add test2 30.0.0.104 -add test2 30.0.0.105 -add test2 30.0.0.106 -add test2 30.0.0.107 -add test2 30.0.0.108 -add test2 30.0.0.109 add test2 30.0.0.11 -add test2 30.0.0.110 -add test2 30.0.0.111 -add test2 30.0.0.112 -add test2 30.0.0.113 -add test2 30.0.0.114 -add test2 30.0.0.115 -add test2 30.0.0.116 -add test2 30.0.0.117 -add test2 30.0.0.118 -add test2 30.0.0.119 add test2 30.0.0.12 -add test2 30.0.0.120 -add test2 30.0.0.121 -add test2 30.0.0.122 -add test2 30.0.0.123 -add test2 30.0.0.124 -add test2 30.0.0.125 -add test2 30.0.0.126 -add test2 30.0.0.127 -add test2 30.0.0.128 add test2 30.0.0.13 add test2 30.0.0.14 add test2 30.0.0.15 @@ -299,7 +278,6 @@ add test2 30.0.0.16 add test2 30.0.0.17 add test2 30.0.0.18 add test2 30.0.0.19 -add test2 30.0.0.2 add test2 30.0.0.20 add test2 30.0.0.21 add test2 30.0.0.22 @@ -310,7 +288,6 @@ add test2 30.0.0.26 add test2 30.0.0.27 add test2 30.0.0.28 add test2 30.0.0.29 -add test2 30.0.0.3 add test2 30.0.0.30 add test2 30.0.0.31 add test2 30.0.0.32 @@ -321,7 +298,6 @@ add test2 30.0.0.36 add test2 30.0.0.37 add test2 30.0.0.38 add test2 30.0.0.39 -add test2 30.0.0.4 add test2 30.0.0.40 add test2 30.0.0.41 add test2 30.0.0.42 @@ -332,7 +308,6 @@ add test2 30.0.0.46 add test2 30.0.0.47 add test2 30.0.0.48 add test2 30.0.0.49 -add test2 30.0.0.5 add test2 30.0.0.50 add test2 30.0.0.51 add test2 30.0.0.52 @@ -343,7 +318,6 @@ add test2 30.0.0.56 add test2 30.0.0.57 add test2 30.0.0.58 add test2 30.0.0.59 -add test2 30.0.0.6 add test2 30.0.0.60 add test2 30.0.0.61 add test2 30.0.0.62 @@ -354,7 +328,6 @@ add test2 30.0.0.66 add test2 30.0.0.67 add test2 30.0.0.68 add test2 30.0.0.69 -add test2 30.0.0.7 add test2 30.0.0.70 add test2 30.0.0.71 add test2 30.0.0.72 @@ -365,7 +338,6 @@ add test2 30.0.0.76 add test2 30.0.0.77 add test2 30.0.0.78 add test2 30.0.0.79 -add test2 30.0.0.8 add test2 30.0.0.80 add test2 30.0.0.81 add test2 30.0.0.82 @@ -376,7 +348,6 @@ add test2 30.0.0.86 add test2 30.0.0.87 add test2 30.0.0.88 add test2 30.0.0.89 -add test2 30.0.0.9 add test2 30.0.0.90 add test2 30.0.0.91 add test2 30.0.0.92 @@ -387,3 +358,32 @@ add test2 30.0.0.96 add test2 30.0.0.97 add test2 30.0.0.98 add test2 30.0.0.99 +add test2 30.0.0.100 +add test2 30.0.0.101 +add test2 30.0.0.102 +add test2 30.0.0.103 +add test2 30.0.0.104 +add test2 30.0.0.105 +add test2 30.0.0.106 +add test2 30.0.0.107 +add test2 30.0.0.108 +add test2 30.0.0.109 +add test2 30.0.0.110 +add test2 30.0.0.111 +add test2 30.0.0.112 +add test2 30.0.0.113 +add test2 30.0.0.114 +add test2 30.0.0.115 +add test2 30.0.0.116 +add test2 30.0.0.117 +add test2 30.0.0.118 +add test2 30.0.0.119 +add test2 30.0.0.120 +add test2 30.0.0.121 +add test2 30.0.0.122 +add test2 30.0.0.123 +add test2 30.0.0.124 +add test2 30.0.0.125 +add test2 30.0.0.126 +add test2 30.0.0.127 +add test2 30.0.0.128 -- cgit v1.2.3