]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
extensions: tcp/udp: Save/xlate inverted full ranges
authorPhil Sutter <phil@nwl.cc>
Thu, 1 Feb 2024 16:42:12 +0000 (17:42 +0100)
committerPhil Sutter <phil@nwl.cc>
Fri, 2 Feb 2024 17:26:14 +0000 (18:26 +0100)
Also translate a bare '-m tcp/udp' to 'meta l4proto' match.

Fixes: 04f569ded54a7 ("extensions: libxt_udp: add translation to nft")
Fixes: fb2593ebbf656 ("extensions: libxt_tcp: add translation to nft")
Signed-off-by: Phil Sutter <phil@nwl.cc>
extensions/libxt_tcp.c
extensions/libxt_tcp.t
extensions/libxt_tcp.txlate
extensions/libxt_udp.c
extensions/libxt_udp.t
extensions/libxt_udp.txlate

index f82572828649b0800e59dc8a065fbc081974031c..32bbd684fd5d767e74dab6f8d323e04f329c40de 100644 (file)
@@ -225,13 +225,18 @@ print_port(uint16_t port, int numeric)
                printf("%s", service);
 }
 
+static bool skip_ports_match(uint16_t min, uint16_t max, bool inv)
+{
+       return min == 0 && max == UINT16_MAX && !inv;
+}
+
 static void
 print_ports(const char *name, uint16_t min, uint16_t max,
            int invert, int numeric)
 {
        const char *inv = invert ? "!" : "";
 
-       if (min != 0 || max != 0xFFFF || invert) {
+       if (!skip_ports_match(min, max, invert)) {
                printf(" %s", name);
                if (min == max) {
                        printf(":%s", inv);
@@ -315,10 +320,11 @@ tcp_print(const void *ip, const struct xt_entry_match *match, int numeric)
 static void tcp_save(const void *ip, const struct xt_entry_match *match)
 {
        const struct xt_tcp *tcpinfo = (struct xt_tcp *)match->data;
+       bool inv_srcpt = tcpinfo->invflags & XT_TCP_INV_SRCPT;
+       bool inv_dstpt = tcpinfo->invflags & XT_TCP_INV_DSTPT;
 
-       if (tcpinfo->spts[0] != 0
-           || tcpinfo->spts[1] != 0xFFFF) {
-               if (tcpinfo->invflags & XT_TCP_INV_SRCPT)
+       if (!skip_ports_match(tcpinfo->spts[0], tcpinfo->spts[1], inv_srcpt)) {
+               if (inv_srcpt)
                        printf(" !");
                if (tcpinfo->spts[0]
                    != tcpinfo->spts[1])
@@ -330,9 +336,8 @@ static void tcp_save(const void *ip, const struct xt_entry_match *match)
                               tcpinfo->spts[0]);
        }
 
-       if (tcpinfo->dpts[0] != 0
-           || tcpinfo->dpts[1] != 0xFFFF) {
-               if (tcpinfo->invflags & XT_TCP_INV_DSTPT)
+       if (!skip_ports_match(tcpinfo->dpts[0], tcpinfo->dpts[1], inv_dstpt)) {
+               if (inv_dstpt)
                        printf(" !");
                if (tcpinfo->dpts[0]
                    != tcpinfo->dpts[1])
@@ -397,39 +402,42 @@ static int tcp_xlate(struct xt_xlate *xl,
 {
        const struct xt_tcp *tcpinfo =
                (const struct xt_tcp *)params->match->data;
+       bool inv_srcpt = tcpinfo->invflags & XT_TCP_INV_SRCPT;
+       bool inv_dstpt = tcpinfo->invflags & XT_TCP_INV_DSTPT;
+       bool xlated = false;
 
-       if (tcpinfo->spts[0] != 0 || tcpinfo->spts[1] != 0xffff) {
+       if (!skip_ports_match(tcpinfo->spts[0], tcpinfo->spts[1], inv_srcpt)) {
                if (tcpinfo->spts[0] != tcpinfo->spts[1]) {
                        xt_xlate_add(xl, "tcp sport %s%u-%u",
-                                  tcpinfo->invflags & XT_TCP_INV_SRCPT ?
-                                       "!= " : "",
+                                  inv_srcpt ? "!= " : "",
                                   tcpinfo->spts[0], tcpinfo->spts[1]);
                } else {
                        xt_xlate_add(xl, "tcp sport %s%u",
-                                  tcpinfo->invflags & XT_TCP_INV_SRCPT ?
-                                       "!= " : "",
+                                  inv_srcpt ? "!= " : "",
                                   tcpinfo->spts[0]);
                }
+               xlated = true;
        }
 
-       if (tcpinfo->dpts[0] != 0 || tcpinfo->dpts[1] != 0xffff) {
+       if (!skip_ports_match(tcpinfo->dpts[0], tcpinfo->dpts[1], inv_dstpt)) {
                if (tcpinfo->dpts[0] != tcpinfo->dpts[1]) {
                        xt_xlate_add(xl, "tcp dport %s%u-%u",
-                                  tcpinfo->invflags & XT_TCP_INV_DSTPT ?
-                                       "!= " : "",
+                                  inv_dstpt ? "!= " : "",
                                   tcpinfo->dpts[0], tcpinfo->dpts[1]);
                } else {
                        xt_xlate_add(xl, "tcp dport %s%u",
-                                  tcpinfo->invflags & XT_TCP_INV_DSTPT ?
-                                       "!= " : "",
+                                  inv_dstpt ? "!= " : "",
                                   tcpinfo->dpts[0]);
                }
+               xlated = true;
        }
 
-       if (tcpinfo->option)
+       if (tcpinfo->option) {
                xt_xlate_add(xl, "tcp option %u %s", tcpinfo->option,
                             tcpinfo->invflags & XT_TCP_INV_OPTION ?
                             "missing" : "exists");
+               xlated = true;
+       }
 
        if (tcpinfo->flg_mask || (tcpinfo->invflags & XT_TCP_INV_FLAGS)) {
                xt_xlate_add(xl, "tcp flags %s",
@@ -437,8 +445,12 @@ static int tcp_xlate(struct xt_xlate *xl,
                print_tcp_xlate(xl, tcpinfo->flg_cmp);
                xt_xlate_add(xl, " / ");
                print_tcp_xlate(xl, tcpinfo->flg_mask);
+               xlated = true;
        }
 
+       if (!xlated)
+               xt_xlate_add(xl, "meta l4proto tcp");
+
        return 1;
 }
 
index 911c51113cf2ae9737ff2d48f6a545fa6612d5eb..75d5b1ed90996cffd7b93f07cc3edfe9b1079403 100644 (file)
@@ -7,13 +7,13 @@
 -p tcp -m tcp --sport 1024:65535;=;OK
 -p tcp -m tcp --sport 1024:;-p tcp -m tcp --sport 1024:65535;OK
 -p tcp -m tcp --sport :;-p tcp -m tcp;OK
--p tcp -m tcp ! --sport :;-p tcp -m tcp;OK
+-p tcp -m tcp ! --sport :;-p tcp -m tcp ! --sport 0:65535;OK
 -p tcp -m tcp --sport :4;-p tcp -m tcp --sport 0:4;OK
 -p tcp -m tcp --sport 4:;-p tcp -m tcp --sport 4:65535;OK
 -p tcp -m tcp --sport 4:4;-p tcp -m tcp --sport 4;OK
 -p tcp -m tcp --sport 4:3;;FAIL
 -p tcp -m tcp --dport :;-p tcp -m tcp;OK
--p tcp -m tcp ! --dport :;-p tcp -m tcp;OK
+-p tcp -m tcp ! --dport :;-p tcp -m tcp ! --dport 0:65535;OK
 -p tcp -m tcp --dport :4;-p tcp -m tcp --dport 0:4;OK
 -p tcp -m tcp --dport 4:;-p tcp -m tcp --dport 4:65535;OK
 -p tcp -m tcp --dport 4:4;-p tcp -m tcp --dport 4;OK
index a7e921bff2ca0b70c58cc2e812749376f6f7468d..b3ddcc15833cf186a4df8c26a67b2ed23008f2d3 100644 (file)
@@ -32,7 +32,7 @@ iptables-translate -A INPUT -p tcp ! --tcp-option 23
 nft 'add rule ip filter INPUT tcp option 23 missing counter'
 
 iptables-translate -I OUTPUT -p tcp --sport 0:65535 -j ACCEPT
-nft 'insert rule ip filter OUTPUT counter accept'
+nft 'insert rule ip filter OUTPUT meta l4proto tcp counter accept'
 
 iptables-translate -I OUTPUT -p tcp ! --sport 0:65535 -j ACCEPT
-nft 'insert rule ip filter OUTPUT counter accept'
+nft 'insert rule ip filter OUTPUT tcp sport != 0-65535 counter accept'
index ba1c3eb768592c571088f65df13512ed7b351fea..748d418039c3a0b3cb13c16a7f2b3d7164d2075f 100644 (file)
@@ -82,13 +82,18 @@ print_port(uint16_t port, int numeric)
                printf("%s", service);
 }
 
+static bool skip_ports_match(uint16_t min, uint16_t max, bool inv)
+{
+       return min == 0 && max == UINT16_MAX && !inv;
+}
+
 static void
 print_ports(const char *name, uint16_t min, uint16_t max,
            int invert, int numeric)
 {
        const char *inv = invert ? "!" : "";
 
-       if (min != 0 || max != 0xFFFF || invert) {
+       if (!skip_ports_match(min, max, invert)) {
                printf(" %s", name);
                if (min == max) {
                        printf(":%s", inv);
@@ -122,10 +127,11 @@ udp_print(const void *ip, const struct xt_entry_match *match, int numeric)
 static void udp_save(const void *ip, const struct xt_entry_match *match)
 {
        const struct xt_udp *udpinfo = (struct xt_udp *)match->data;
+       bool inv_srcpt = udpinfo->invflags & XT_UDP_INV_SRCPT;
+       bool inv_dstpt = udpinfo->invflags & XT_UDP_INV_DSTPT;
 
-       if (udpinfo->spts[0] != 0
-           || udpinfo->spts[1] != 0xFFFF) {
-               if (udpinfo->invflags & XT_UDP_INV_SRCPT)
+       if (!skip_ports_match(udpinfo->spts[0], udpinfo->spts[1], inv_srcpt)) {
+               if (inv_srcpt)
                        printf(" !");
                if (udpinfo->spts[0]
                    != udpinfo->spts[1])
@@ -137,9 +143,8 @@ static void udp_save(const void *ip, const struct xt_entry_match *match)
                               udpinfo->spts[0]);
        }
 
-       if (udpinfo->dpts[0] != 0
-           || udpinfo->dpts[1] != 0xFFFF) {
-               if (udpinfo->invflags & XT_UDP_INV_DSTPT)
+       if (!skip_ports_match(udpinfo->dpts[0], udpinfo->dpts[1], inv_dstpt)) {
+               if (inv_dstpt)
                        printf(" !");
                if (udpinfo->dpts[0]
                    != udpinfo->dpts[1])
@@ -156,35 +161,39 @@ static int udp_xlate(struct xt_xlate *xl,
                     const struct xt_xlate_mt_params *params)
 {
        const struct xt_udp *udpinfo = (struct xt_udp *)params->match->data;
+       bool inv_srcpt = udpinfo->invflags & XT_UDP_INV_SRCPT;
+       bool inv_dstpt = udpinfo->invflags & XT_UDP_INV_DSTPT;
+       bool xlated = false;
 
-       if (udpinfo->spts[0] != 0 || udpinfo->spts[1] != 0xFFFF) {
+       if (!skip_ports_match(udpinfo->spts[0], udpinfo->spts[1], inv_srcpt)) {
                if (udpinfo->spts[0] != udpinfo->spts[1]) {
                        xt_xlate_add(xl,"udp sport %s%u-%u",
-                                  udpinfo->invflags & XT_UDP_INV_SRCPT ?
-                                        "!= ": "",
+                                  inv_srcpt ? "!= ": "",
                                   udpinfo->spts[0], udpinfo->spts[1]);
                } else {
                        xt_xlate_add(xl, "udp sport %s%u",
-                                  udpinfo->invflags & XT_UDP_INV_SRCPT ?
-                                        "!= ": "",
+                                  inv_srcpt ? "!= ": "",
                                   udpinfo->spts[0]);
                }
+               xlated = true;
        }
 
-       if (udpinfo->dpts[0] != 0 || udpinfo->dpts[1] != 0xFFFF) {
+       if (!skip_ports_match(udpinfo->dpts[0], udpinfo->dpts[1], inv_dstpt)) {
                if (udpinfo->dpts[0]  != udpinfo->dpts[1]) {
                        xt_xlate_add(xl,"udp dport %s%u-%u",
-                                  udpinfo->invflags & XT_UDP_INV_SRCPT ?
-                                        "!= ": "",
+                                  inv_dstpt ? "!= ": "",
                                   udpinfo->dpts[0], udpinfo->dpts[1]);
                } else {
                        xt_xlate_add(xl,"udp dport %s%u",
-                                  udpinfo->invflags & XT_UDP_INV_SRCPT ?
-                                        "!= ": "",
+                                  inv_dstpt ? "!= ": "",
                                   udpinfo->dpts[0]);
                }
+               xlated = true;
        }
 
+       if (!xlated)
+               xt_xlate_add(xl, "meta l4proto udp");
+
        return 1;
 }
 
index 3c85b09f871da5c1b86d2e1e8517fb66a6c068d6..6a2c9d07e357691ade755a9e0f8eb799fe10a723 100644 (file)
@@ -7,13 +7,13 @@
 -p udp -m udp --sport 1024:65535;=;OK
 -p udp -m udp --sport 1024:;-p udp -m udp --sport 1024:65535;OK
 -p udp -m udp --sport :;-p udp -m udp;OK
--p udp -m udp ! --sport :;-p udp -m udp;OK
+-p udp -m udp ! --sport :;-p udp -m udp ! --sport 0:65535;OK
 -p udp -m udp --sport :4;-p udp -m udp --sport 0:4;OK
 -p udp -m udp --sport 4:;-p udp -m udp --sport 4:65535;OK
 -p udp -m udp --sport 4:4;-p udp -m udp --sport 4;OK
 -p udp -m udp --sport 4:3;;FAIL
 -p udp -m udp --dport :;-p udp -m udp;OK
--p udp -m udp ! --dport :;-p udp -m udp;OK
+-p udp -m udp ! --dport :;-p udp -m udp ! --dport 0:65535;OK
 -p udp -m udp --dport :4;-p udp -m udp --dport 0:4;OK
 -p udp -m udp --dport 4:;-p udp -m udp --dport 4:65535;OK
 -p udp -m udp --dport 4:4;-p udp -m udp --dport 4;OK
index 3aed7cd15dbd70f616fde47c70dc8244ae2f6ffe..d6bbb96f5d7441272de1bfc9e2992ca1e6d3969a 100644 (file)
@@ -11,7 +11,7 @@ iptables-translate -I OUTPUT -p udp --dport 1020:1023 --sport 53 -j ACCEPT
 nft 'insert rule ip filter OUTPUT udp sport 53 udp dport 1020-1023 counter accept'
 
 iptables-translate -I OUTPUT -p udp --sport 0:65535 -j ACCEPT
-nft 'insert rule ip filter OUTPUT counter accept'
+nft 'insert rule ip filter OUTPUT meta l4proto udp counter accept'
 
 iptables-translate -I OUTPUT -p udp ! --sport 0:65535 -j ACCEPT
-nft 'insert rule ip filter OUTPUT counter accept'
+nft 'insert rule ip filter OUTPUT udp sport != 0-65535 counter accept'