@@ -316,10 +316,40 @@ int cil_post_genfscon_compare(const void *a, const void *b)
int cil_post_netifcon_compare(const void *a, const void *b)
{
- struct cil_netifcon *anetifcon = *(struct cil_netifcon**)a;
- struct cil_netifcon *bnetifcon = *(struct cil_netifcon**)b;
+ /* keep in sync with kernel_to_common.c:netif_data_cmp() */
+ const struct cil_netifcon *anetifcon = *(struct cil_netifcon**)a;
+ const struct cil_netifcon *bnetifcon = *(struct cil_netifcon**)b;
+ const char *a_name = anetifcon->interface_str;
+ const char *b_name = bnetifcon->interface_str;
+ size_t a_stem = strcspn(a_name, "*?");
+ size_t b_stem = strcspn(b_name, "*?");
+ size_t a_len = strlen(a_name);
+ size_t b_len = strlen(b_name);
+ int a_iswildcard = a_stem != a_len;
+ int b_iswildcard = b_stem != b_len;
+ int rc;
+
+ /* order non-wildcards first */
+ rc = spaceship_cmp(a_iswildcard, b_iswildcard);
+ if (rc)
+ return rc;
+
+ /* order non-wildcards alphabetically */
+ if (!a_iswildcard)
+ return strcmp(a_name, b_name);
+
+ /* order by decreasing stem length */
+ rc = spaceship_cmp(a_stem, b_stem);
+ if (rc)
+ return -rc;
+
+ /* order '?' (0x3f) before '*' (0x2A) */
+ rc = spaceship_cmp(a_name[a_stem], b_name[b_stem]);
+ if (rc)
+ return -rc;
- return strcmp(anetifcon->interface_str, bnetifcon->interface_str);
+ /* order alphabetically */
+ return strcmp(a_name, b_name);
}
int cil_post_ibendportcon_compare(const void *a, const void *b)
@@ -441,10 +441,40 @@ static int portcon_data_cmp(const void *a, const void *b)
static int netif_data_cmp(const void *a, const void *b)
{
- struct ocontext *const *aa = a;
- struct ocontext *const *bb = b;
+ /* keep in sync with cil_post.c:cil_post_netifcon_compare() */
+ const struct ocontext *const *aa = a;
+ const struct ocontext *const *bb = b;
+ const char *a_name = (*aa)->u.name;
+ const char *b_name = (*bb)->u.name;
+ size_t a_stem = strcspn(a_name, "*?");
+ size_t b_stem = strcspn(b_name, "*?");
+ size_t a_len = strlen(a_name);
+ size_t b_len = strlen(b_name);
+ int a_iswildcard = a_stem != a_len;
+ int b_iswildcard = b_stem != b_len;
+ int rc;
- return strcmp((*aa)->u.name, (*bb)->u.name);
+ /* order non-wildcards first */
+ rc = spaceship_cmp(a_iswildcard, b_iswildcard);
+ if (rc)
+ return rc;
+
+ /* order non-wildcards alphabetically */
+ if (!a_iswildcard)
+ return strcmp(a_name, b_name);
+
+ /* order by decreasing stem length */
+ rc = spaceship_cmp(a_stem, b_stem);
+ if (rc)
+ return -rc;
+
+ /* order '?' (0x3f) before '*' (0x2A) */
+ rc = spaceship_cmp(a_name[a_stem], b_name[b_stem]);
+ if (rc)
+ return -rc;
+
+ /* order alphabetically */
+ return strcmp(a_name, b_name);
}
static int node_data_cmp(const void *a, const void *b)