Blame SOURCES/0043-extensions-dccp-Fix-for-DCCP-type-INVALID.patch

7cc531
From 98794894774a39927bc975921fc9e40f00db937b Mon Sep 17 00:00:00 2001
7cc531
From: Phil Sutter <phil@nwl.cc>
7cc531
Date: Wed, 2 Dec 2020 13:37:06 +0100
7cc531
Subject: [PATCH] extensions: dccp: Fix for DCCP type 'INVALID'
7cc531
7cc531
Support for matching on invalid DCCP type field values was pretty
7cc531
broken: While RFC4340 declares any type value from 10 to 15 invalid, the
7cc531
extension's type name 'INVALID' mapped to type value 10 only. Fix this
7cc531
by introduction of INVALID_OTHER_TYPE_MASK which has the remaining
7cc531
invalid type's bits set and apply it if bit 10 is set after parsing the
7cc531
type list. When printing, stop searching type names after printing
7cc531
'INVALID' - unless numeric output was requested. The latter prints all
7cc531
actual type values. Since parsing types in numeric form is not
7cc531
supported, changing the output should not break existing scripts.
7cc531
7cc531
When translating into nftables syntax, the code returned prematurely if
7cc531
'INVALID' was among the list of types - thereby emitting invalid syntax.
7cc531
Instead print a real match for invalid types by use of a range
7cc531
expression.
7cc531
7cc531
While being at it, fix syntax of translator output: If only
7cc531
'--dccp-types' was translated, the output contained an extra 'dccp'. On
7cc531
the other hand, if '--sport' and '--dport' was present, a required
7cc531
'dccp' between the translations of both was missing.
7cc531
7cc531
Fixes: e40b11d7ef827 ("add support for new 'dccp' protocol match")
7cc531
Fixes: c94a998724143 ("extensions: libxt_dccp: Add translation to nft")
7cc531
Signed-off-by: Phil Sutter <phil@nwl.cc>
7cc531
(cherry picked from commit 4bcbc8e11a2764f4537dc405962f83cd072cccfe)
7cc531
Signed-off-by: Phil Sutter <psutter@redhat.com>
7cc531
---
7cc531
 extensions/libxt_dccp.c      | 58 ++++++++++++++++++++++--------------
7cc531
 extensions/libxt_dccp.txlate | 12 ++++++--
7cc531
 2 files changed, 45 insertions(+), 25 deletions(-)
7cc531
7cc531
diff --git a/extensions/libxt_dccp.c b/extensions/libxt_dccp.c
7cc531
index 5e67c264db2a9..aea3e20be4818 100644
7cc531
--- a/extensions/libxt_dccp.c
7cc531
+++ b/extensions/libxt_dccp.c
7cc531
@@ -76,6 +76,9 @@ static const char *const dccp_pkt_types[] = {
7cc531
 	[DCCP_PKT_INVALID]	= "INVALID",
7cc531
 };
7cc531
 
7cc531
+/* Bits for type values 11-15 */
7cc531
+#define INVALID_OTHER_TYPE_MASK		0xf800
7cc531
+
7cc531
 static uint16_t
7cc531
 parse_dccp_types(const char *typestring)
7cc531
 {
7cc531
@@ -95,6 +98,9 @@ parse_dccp_types(const char *typestring)
7cc531
 			xtables_error(PARAMETER_PROBLEM,
7cc531
 				   "Unknown DCCP type `%s'", ptr);
7cc531
 	}
7cc531
+	if (typemask & (1 << DCCP_PKT_INVALID))
7cc531
+		typemask |= INVALID_OTHER_TYPE_MASK;
7cc531
+
7cc531
 
7cc531
 	free(buffer);
7cc531
 	return typemask;
7cc531
@@ -193,9 +199,13 @@ print_types(uint16_t types, int inverted, int numeric)
7cc531
 
7cc531
 		if (numeric)
7cc531
 			printf("%u", i);
7cc531
-		else
7cc531
+		else {
7cc531
 			printf("%s", dccp_pkt_types[i]);
7cc531
 
7cc531
+			if (i == DCCP_PKT_INVALID)
7cc531
+				break;
7cc531
+		}
7cc531
+
7cc531
 		types &= ~(1 << i);
7cc531
 	}
7cc531
 }
7cc531
@@ -288,6 +298,7 @@ static const char *const dccp_pkt_types_xlate[] = {
7cc531
 	[DCCP_PKT_RESET]        = "reset",
7cc531
 	[DCCP_PKT_SYNC]         = "sync",
7cc531
 	[DCCP_PKT_SYNCACK]      = "syncack",
7cc531
+	[DCCP_PKT_INVALID]	= "10-15",
7cc531
 };
7cc531
 
7cc531
 static int dccp_type_xlate(const struct xt_dccp_info *einfo,
7cc531
@@ -296,10 +307,10 @@ static int dccp_type_xlate(const struct xt_dccp_info *einfo,
7cc531
 	bool have_type = false, set_need = false;
7cc531
 	uint16_t types = einfo->typemask;
7cc531
 
7cc531
-	if (types & (1 << DCCP_PKT_INVALID))
7cc531
-		return 0;
7cc531
-
7cc531
-	xt_xlate_add(xl, " dccp type%s ", einfo->invflags ? " !=" : "");
7cc531
+	if (types & INVALID_OTHER_TYPE_MASK) {
7cc531
+		types &= ~INVALID_OTHER_TYPE_MASK;
7cc531
+		types |= 1 << DCCP_PKT_INVALID;
7cc531
+	}
7cc531
 
7cc531
 	if ((types != 0) && !(types == (types & -types))) {
7cc531
 		xt_xlate_add(xl, "{");
7cc531
@@ -335,34 +346,37 @@ static int dccp_xlate(struct xt_xlate *xl,
7cc531
 	char *space = "";
7cc531
 	int ret = 1;
7cc531
 
7cc531
-	xt_xlate_add(xl, "dccp ");
7cc531
-
7cc531
 	if (einfo->flags & XT_DCCP_SRC_PORTS) {
7cc531
+		xt_xlate_add(xl, "dccp sport%s %u",
7cc531
+			     einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
7cc531
+			     einfo->spts[0]);
7cc531
+
7cc531
 		if (einfo->spts[0] != einfo->spts[1])
7cc531
-			xt_xlate_add(xl, "sport%s %u-%u",
7cc531
-				     einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
7cc531
-				     einfo->spts[0], einfo->spts[1]);
7cc531
-		else
7cc531
-			xt_xlate_add(xl, "sport%s %u",
7cc531
-				     einfo->invflags & XT_DCCP_SRC_PORTS ? " !=" : "",
7cc531
-				     einfo->spts[0]);
7cc531
+			xt_xlate_add(xl, "-%u", einfo->spts[1]);
7cc531
+
7cc531
 		space = " ";
7cc531
 	}
7cc531
 
7cc531
 	if (einfo->flags & XT_DCCP_DEST_PORTS) {
7cc531
+		xt_xlate_add(xl, "%sdccp dport%s %u", space,
7cc531
+			     einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
7cc531
+			     einfo->dpts[0]);
7cc531
+
7cc531
 		if (einfo->dpts[0] != einfo->dpts[1])
7cc531
-			xt_xlate_add(xl, "%sdport%s %u-%u", space,
7cc531
-				     einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
7cc531
-				     einfo->dpts[0], einfo->dpts[1]);
7cc531
-		else
7cc531
-			xt_xlate_add(xl, "%sdport%s %u", space,
7cc531
-				     einfo->invflags & XT_DCCP_DEST_PORTS ? " !=" : "",
7cc531
-				     einfo->dpts[0]);
7cc531
+			xt_xlate_add(xl, "-%u", einfo->dpts[1]);
7cc531
+
7cc531
+		space = " ";
7cc531
 	}
7cc531
 
7cc531
-	if (einfo->flags & XT_DCCP_TYPE)
7cc531
+	if (einfo->flags & XT_DCCP_TYPE && einfo->typemask) {
7cc531
+		xt_xlate_add(xl, "%sdccp type%s ", space,
7cc531
+			     einfo->invflags & XT_DCCP_TYPE ? " !=" : "");
7cc531
 		ret = dccp_type_xlate(einfo, xl);
7cc531
 
7cc531
+		space = " ";
7cc531
+	}
7cc531
+
7cc531
+	/* FIXME: no dccp option support in nftables yet */
7cc531
 	if (einfo->flags & XT_DCCP_OPTION)
7cc531
 		ret = 0;
7cc531
 
7cc531
diff --git a/extensions/libxt_dccp.txlate b/extensions/libxt_dccp.txlate
7cc531
index b47dc65f5bc4f..ea853f6acf627 100644
7cc531
--- a/extensions/libxt_dccp.txlate
7cc531
+++ b/extensions/libxt_dccp.txlate
7cc531
@@ -7,8 +7,14 @@ nft add rule ip filter INPUT dccp dport 100-200 counter
7cc531
 iptables-translate -A INPUT -p dccp -m dccp ! --dport 100
7cc531
 nft add rule ip filter INPUT dccp dport != 100 counter
7cc531
 
7cc531
-iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK
7cc531
-nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack} counter
7cc531
+iptables-translate -A INPUT -p dccp -m dccp --dccp-types CLOSE
7cc531
+nft add rule ip filter INPUT dccp type close counter
7cc531
+
7cc531
+iptables-translate -A INPUT -p dccp -m dccp --dccp-types INVALID
7cc531
+nft add rule ip filter INPUT dccp type 10-15 counter
7cc531
+
7cc531
+iptables-translate -A INPUT -p dccp -m dccp --dport 100 --dccp-types REQUEST,RESPONSE,DATA,ACK,DATAACK,CLOSEREQ,CLOSE,SYNC,SYNCACK,INVALID
7cc531
+nft add rule ip filter INPUT dccp dport 100 dccp type {request, response, data, ack, dataack, closereq, close, sync, syncack, 10-15} counter
7cc531
 
7cc531
 iptables-translate -A INPUT -p dccp -m dccp --sport 200 --dport 100
7cc531
-nft add rule ip filter INPUT dccp sport 200 dport 100 counter
7cc531
+nft add rule ip filter INPUT dccp sport 200 dccp dport 100 counter
7cc531
-- 
7cc531
2.28.0
7cc531