* Tue May 30 2023 Phil Sutter <psutter@redhat.com> [1.0.4-1.el8] - Synchronize patch level with nftables-1.0.4-10.el9 (Phil Sutter) [2211076] - Rebase onto version 1.0.4 (Phil Sutter) [2211076] Resolves: rhbz#2211076
		
			
				
	
	
		
			160 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			160 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 120ec5410b0c9f8f84f2bfdf092228cc61899785 Mon Sep 17 00:00:00 2001
 | |
| From: Phil Sutter <psutter@redhat.com>
 | |
| Date: Thu, 9 Feb 2023 10:27:57 +0100
 | |
| Subject: [PATCH] netlink_delinearize: postprocess binary ands in
 | |
|  concatenations
 | |
| 
 | |
| Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2211076
 | |
| Upstream Status: nftables commit 89688c947efc3
 | |
| 
 | |
| commit 89688c947efc36d25c58c85650414fa3a491732e
 | |
| Author: Florian Westphal <fw@strlen.de>
 | |
| Date:   Tue Jun 14 21:56:48 2022 +0200
 | |
| 
 | |
|     netlink_delinearize: postprocess binary ands in concatenations
 | |
| 
 | |
|     Input:
 | |
|     update ether saddr . vlan id timeout 5s @macset
 | |
|     ether saddr . vlan id @macset
 | |
| 
 | |
|     Before this patch, gets rendered as:
 | |
|     update @macset { @ll,48,48 . @ll,112,16 & 0xfff timeout 5s }
 | |
|     @ll,48,48 . @ll,112,16 & 0xfff @macset
 | |
| 
 | |
|     After this, listing will show:
 | |
|     update @macset { @ll,48,48 . vlan id timeout 5s }
 | |
|     @ll,48,48 . vlan id @macset
 | |
| 
 | |
|     The @ll, ... is due to vlan description replacing the ethernet one,
 | |
|     so payload decode fails to take the concatenation apart (the ethernet
 | |
|     header payload info is matched vs. vlan template).
 | |
| 
 | |
|     This will be adjusted by a followup patch.
 | |
| 
 | |
|     Signed-off-by: Florian Westphal <fw@strlen.de>
 | |
| 
 | |
| Signed-off-by: Phil Sutter <psutter@redhat.com>
 | |
| ---
 | |
|  include/netlink.h         |  6 ++++++
 | |
|  src/netlink_delinearize.c | 45 ++++++++++++++++++++++++++++++++++-----
 | |
|  2 files changed, 46 insertions(+), 5 deletions(-)
 | |
| 
 | |
| diff --git a/include/netlink.h b/include/netlink.h
 | |
| index e8e0f68..71c888f 100644
 | |
| --- a/include/netlink.h
 | |
| +++ b/include/netlink.h
 | |
| @@ -42,10 +42,16 @@ struct netlink_parse_ctx {
 | |
|  	struct netlink_ctx	*nlctx;
 | |
|  };
 | |
|  
 | |
| +
 | |
| +#define RULE_PP_IN_CONCATENATION	(1 << 0)
 | |
| +
 | |
| +#define RULE_PP_REMOVE_OP_AND		(RULE_PP_IN_CONCATENATION)
 | |
| +
 | |
|  struct rule_pp_ctx {
 | |
|  	struct proto_ctx	pctx;
 | |
|  	struct payload_dep_ctx	pdctx;
 | |
|  	struct stmt		*stmt;
 | |
| +	unsigned int		flags;
 | |
|  };
 | |
|  
 | |
|  extern const struct input_descriptor indesc_netlink;
 | |
| diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
 | |
| index 2f13990..cba419d 100644
 | |
| --- a/src/netlink_delinearize.c
 | |
| +++ b/src/netlink_delinearize.c
 | |
| @@ -2259,12 +2259,13 @@ static void binop_adjust(const struct expr *binop, struct expr *right,
 | |
|  	}
 | |
|  }
 | |
|  
 | |
| -static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr,
 | |
| -			      struct expr **expr_binop)
 | |
| +static void __binop_postprocess(struct rule_pp_ctx *ctx,
 | |
| +				struct expr *expr,
 | |
| +				struct expr *left,
 | |
| +				struct expr *mask,
 | |
| +				struct expr **expr_binop)
 | |
|  {
 | |
|  	struct expr *binop = *expr_binop;
 | |
| -	struct expr *left = binop->left;
 | |
| -	struct expr *mask = binop->right;
 | |
|  	unsigned int shift;
 | |
|  
 | |
|  	assert(binop->etype == EXPR_BINOP);
 | |
| @@ -2300,15 +2301,26 @@ static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr,
 | |
|  
 | |
|  		assert(binop->left == left);
 | |
|  		*expr_binop = expr_get(left);
 | |
| -		expr_free(binop);
 | |
|  
 | |
|  		if (left->etype == EXPR_PAYLOAD)
 | |
|  			payload_match_postprocess(ctx, expr, left);
 | |
|  		else if (left->etype == EXPR_EXTHDR && right)
 | |
|  			expr_set_type(right, left->dtype, left->byteorder);
 | |
| +
 | |
| +		expr_free(binop);
 | |
|  	}
 | |
|  }
 | |
|  
 | |
| +static void binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr,
 | |
| +			      struct expr **expr_binop)
 | |
| +{
 | |
| +	struct expr *binop = *expr_binop;
 | |
| +	struct expr *left = binop->left;
 | |
| +	struct expr *mask = binop->right;
 | |
| +
 | |
| +	__binop_postprocess(ctx, expr, left, mask, expr_binop);
 | |
| +}
 | |
| +
 | |
|  static void map_binop_postprocess(struct rule_pp_ctx *ctx, struct expr *expr)
 | |
|  {
 | |
|  	struct expr *binop = expr->map;
 | |
| @@ -2541,6 +2553,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
 | |
|  		LIST_HEAD(tmp);
 | |
|  		struct expr *n;
 | |
|  
 | |
| +		ctx->flags |= RULE_PP_IN_CONCATENATION;
 | |
|  		list_for_each_entry_safe(i, n, &expr->expressions, list) {
 | |
|  			if (type) {
 | |
|  				dtype = concat_subtype_lookup(type, --off);
 | |
| @@ -2552,6 +2565,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
 | |
|  
 | |
|  			ntype = concat_subtype_add(ntype, i->dtype->type);
 | |
|  		}
 | |
| +		ctx->flags &= ~RULE_PP_IN_CONCATENATION;
 | |
|  		list_splice(&tmp, &expr->expressions);
 | |
|  		datatype_set(expr, concat_type_alloc(ntype));
 | |
|  		break;
 | |
| @@ -2568,6 +2582,27 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
 | |
|  			expr_set_type(expr->right, &integer_type,
 | |
|  				      BYTEORDER_HOST_ENDIAN);
 | |
|  			break;
 | |
| +		case OP_AND:
 | |
| +			expr_set_type(expr->right, expr->left->dtype,
 | |
| +				      expr->left->byteorder);
 | |
| +
 | |
| +			/* Do not process OP_AND in ordinary rule context.
 | |
| +			 *
 | |
| +			 * Removal needs to be performed as part of the relational
 | |
| +			 * operation because the RHS constant might need to be adjusted
 | |
| +			 * (shifted).
 | |
| +			 *
 | |
| +			 * This is different in set element context or concatenations:
 | |
| +			 * There is no relational operation (eq, neq and so on), thus
 | |
| +			 * it needs to be processed right away.
 | |
| +			 */
 | |
| +			if ((ctx->flags & RULE_PP_REMOVE_OP_AND) &&
 | |
| +			    expr->left->etype == EXPR_PAYLOAD &&
 | |
| +			    expr->right->etype == EXPR_VALUE) {
 | |
| +				__binop_postprocess(ctx, expr, expr->left, expr->right, exprp);
 | |
| +				return;
 | |
| +			}
 | |
| +			break;
 | |
|  		default:
 | |
|  			expr_set_type(expr->right, expr->left->dtype,
 | |
|  				      expr->left->byteorder);
 | |
| -- 
 | |
| 2.41.0.rc1
 | |
| 
 |