]> git.ipfire.org Git - thirdparty/ipset.git/commitdiff
Sort naturally instead of textual sort (bugzilla #1369)
authorJozsef Kadlecsik <kadlec@netfilter.org>
Thu, 31 Oct 2019 13:18:48 +0000 (14:18 +0100)
committerJozsef Kadlecsik <kadlec@netfilter.org>
Thu, 31 Oct 2019 13:18:48 +0000 (14:18 +0100)
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
tests/iphash.t.restore.sorted

index c28c2d84aa41b3e6994be0a65ad583018a0a4d89..9e3eae35955d25de10f55eacee5cc0d1a3bb940a 100644 (file)
@@ -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;
 }
 
+/* "<member><elem>" */
+#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:
+               /* "<member><elem>" */
+               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
index 5bd53a20e76d01441140115f3fcb51aa545585a0..e94406165b49352f6c315273987a87d649d3ac63 100644 (file)
@@ -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