Re: [PATCH nf-next v4 00/10] netfilter: nft_bitwise: shift support

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

 



Hi Jeremy,

I've been looking into (ab)using bitwise to implement add/sub. I would
like to not add nft_arith for only this, and it seems to me much of
your code can be reused.

Do you think something like this would work?

Thanks.
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 065218a20bb7..c4078359b6e4 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -508,11 +508,15 @@ enum nft_immediate_attributes {
  *                    XOR boolean operations
  * @NFT_BITWISE_LSHIFT: left-shift operation
  * @NFT_BITWISE_RSHIFT: right-shift operation
+ * @NFT_BITWISE_ADD: add operation
+ * @NFT_BITWISE_SUB: subtract operation
  */
 enum nft_bitwise_ops {
 	NFT_BITWISE_BOOL,
 	NFT_BITWISE_LSHIFT,
 	NFT_BITWISE_RSHIFT,
+	NFT_BITWISE_ADD,
+	NFT_BITWISE_SUB,
 };
 
 /**
diff --git a/net/netfilter/nft_bitwise.c b/net/netfilter/nft_bitwise.c
index 0ed2281f03be..fd0cd2b4722a 100644
--- a/net/netfilter/nft_bitwise.c
+++ b/net/netfilter/nft_bitwise.c
@@ -60,6 +60,38 @@ static void nft_bitwise_eval_rshift(u32 *dst, const u32 *src,
 	}
 }
 
+static void nft_bitwise_eval_add(u32 *dst, const u32 *src,
+				 const struct nft_bitwise *priv)
+{
+	u32 delta = priv->data.data[0];
+	unsigned int i, words;
+	u32 tmp = 0;
+
+	words = DIV_ROUND_UP(priv->len, sizeof(u32));
+	for (i = 0; i < words; i++) {
+		tmp = src[i];
+		dst[i] = src[i] + delta;
+		if (dst[i] < tmp && i + 1 < words)
+			dst[i + 1]++;
+	}
+}
+
+static void nft_bitwise_eval_sub(u32 *dst, const u32 *src,
+				 const struct nft_bitwise *priv)
+{
+	u32 delta = priv->data.data[0];
+	unsigned int i, words;
+	u32 tmp = 0;
+
+	words = DIV_ROUND_UP(priv->len, sizeof(u32));
+	for (i = 0; i < words; i++) {
+		tmp = src[i];
+		dst[i] = src[i] - delta;
+		if (dst[i] > tmp && i + 1 < words)
+			dst[i + 1]--;
+	}
+}
+
 void nft_bitwise_eval(const struct nft_expr *expr,
 		      struct nft_regs *regs, const struct nft_pktinfo *pkt)
 {
@@ -77,6 +109,12 @@ void nft_bitwise_eval(const struct nft_expr *expr,
 	case NFT_BITWISE_RSHIFT:
 		nft_bitwise_eval_rshift(dst, src, priv);
 		break;
+	case NFT_BITWISE_ADD:
+		nft_bitwise_eval_add(dst, src, priv);
+		break;
+	case NFT_BITWISE_SUB:
+		nft_bitwise_eval_sub(dst, src, priv);
+		break;
 	}
 }
 
@@ -129,8 +167,8 @@ static int nft_bitwise_init_bool(struct nft_bitwise *priv,
 	return err;
 }
 
-static int nft_bitwise_init_shift(struct nft_bitwise *priv,
-				  const struct nlattr *const tb[])
+static int nft_bitwise_init_data(struct nft_bitwise *priv,
+				 const struct nlattr *const tb[])
 {
 	struct nft_data_desc d;
 	int err;
@@ -191,6 +229,8 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
 		case NFT_BITWISE_BOOL:
 		case NFT_BITWISE_LSHIFT:
 		case NFT_BITWISE_RSHIFT:
+		case NFT_BITWISE_ADD:
+		case NFT_BITWISE_SUB:
 			break;
 		default:
 			return -EOPNOTSUPP;
@@ -205,7 +245,9 @@ static int nft_bitwise_init(const struct nft_ctx *ctx,
 		break;
 	case NFT_BITWISE_LSHIFT:
 	case NFT_BITWISE_RSHIFT:
-		err = nft_bitwise_init_shift(priv, tb);
+	case NFT_BITWISE_ADD:
+	case NFT_BITWISE_SUB:
+		err = nft_bitwise_init_data(priv, tb);
 		break;
 	}
 
@@ -226,8 +268,8 @@ static int nft_bitwise_dump_bool(struct sk_buff *skb,
 	return 0;
 }
 
-static int nft_bitwise_dump_shift(struct sk_buff *skb,
-				  const struct nft_bitwise *priv)
+static int nft_bitwise_dump_data(struct sk_buff *skb,
+				 const struct nft_bitwise *priv)
 {
 	if (nft_data_dump(skb, NFTA_BITWISE_DATA, &priv->data,
 			  NFT_DATA_VALUE, sizeof(u32)) < 0)
@@ -255,7 +297,9 @@ static int nft_bitwise_dump(struct sk_buff *skb, const struct nft_expr *expr)
 		break;
 	case NFT_BITWISE_LSHIFT:
 	case NFT_BITWISE_RSHIFT:
-		err = nft_bitwise_dump_shift(skb, priv);
+	case NFT_BITWISE_ADD:
+	case NFT_BITWISE_SUB:
+		err = nft_bitwise_dump_data(skb, priv);
 		break;
 	}
 

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

  Powered by Linux