[PATCH nft,v3 08/12] netlink_delinerize: incorrect byteorder in mark statement listing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When using ip dscp in combination with bitwise operation:

 # nft --debug=netlink add rule ip x y 'ct mark set ip dscp | 0x4'
 ip x y
   [ payload load 1b @ network header + 1 => reg 1 ]
   [ bitwise reg 1 = ( reg 1 & 0x000000fc ) ^ 0x00000000 ]
   [ bitwise reg 1 = ( reg 1 >> 0x00000002 ) ]
   [ bitwise reg 1 = ( reg 1 & 0xfffffffb ) ^ 0x00000004 ]
   [ ct set mark with reg 1 ]

the listing is showing in the incorrect byteorder:

 # nft list ruleset
 table ip x {
        chain y {
		ct mark set ip dscp | 0x4000000
	}
 }

handle and and or operations in host byteorder.

The following command:

 # nft --debug=netlink add rule ip6 x y 'ct mark set ip6 dscp | 0x4'
 ip6 x y
   [ payload load 2b @ network header + 0 => reg 1 ]
   [ bitwise reg 1 = ( reg 1 & 0x0000c00f ) ^ 0x00000000 ]
   [ bitwise reg 1 = ( reg 1 >> 0x00000006 ) ]
   [ byteorder reg 1 = ntoh(reg 1, 2, 1) ]
   [ bitwise reg 1 = ( reg 1 & 0xfffffffb ) ^ 0x00000004 ]
   [ ct set mark with reg 1 ]

works fine (without requiring this patch) because there is an explicit
byteorder expression.

However, ip dscp takes only 1-byte, so it does not require the byteorder
expression. Use host byteorder if the rhs of bitwise AND OR is larger
than lhs payload expression and such expression is equal or less than
1-byte.

Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
 src/netlink_delinearize.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 4dc28ed8e651..7da8e68726cd 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -2784,8 +2784,13 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
 				      BYTEORDER_HOST_ENDIAN);
 			break;
 		case OP_AND:
-			expr_set_type(expr->right, expr->left->dtype,
-				      expr->left->byteorder);
+			if (expr->right->len > expr->left->len) {
+				expr_set_type(expr->right, expr->left->dtype,
+					      BYTEORDER_HOST_ENDIAN);
+			} else {
+				expr_set_type(expr->right, expr->left->dtype,
+					      expr->left->byteorder);
+			}
 
 			/* Do not process OP_AND in ordinary rule context.
 			 *
@@ -2805,8 +2810,13 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
 			}
 			break;
 		default:
-			expr_set_type(expr->right, expr->left->dtype,
-				      expr->left->byteorder);
+			if (expr->right->len > expr->left->len) {
+				expr_set_type(expr->right, expr->left->dtype,
+					      BYTEORDER_HOST_ENDIAN);
+			} else {
+				expr_set_type(expr->right, expr->left->dtype,
+					      expr->left->byteorder);
+			}
 		}
 		expr_postprocess(ctx, &expr->right);
 
-- 
2.30.2




[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux