Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nf_tables: add register parsing/dumping helpers

Add helper functions to parse and dump register values in netlink attributes.
These helpers will later be changed to take care of translation between the
old 128 bit and the new 32 bit register numbers.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Patrick McHardy and committed by
Pablo Neira Ayuso
b1c96ed3 8cd8937a

+68 -53
+3
include/net/netfilter/nf_tables.h
··· 128 128 return type == NFT_DATA_VERDICT ? NFT_REG_VERDICT : NFT_REG_1; 129 129 } 130 130 131 + unsigned int nft_parse_register(const struct nlattr *attr); 132 + int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg); 133 + 131 134 int nft_validate_register_load(enum nft_registers reg, unsigned int len); 132 135 int nft_validate_register_store(const struct nft_ctx *ctx, 133 136 enum nft_registers reg,
+1 -1
net/bridge/netfilter/nft_meta_bridge.c
··· 65 65 return nft_meta_get_init(ctx, expr, tb); 66 66 } 67 67 68 - priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); 68 + priv->dreg = nft_parse_register(tb[NFTA_META_DREG]); 69 69 return nft_validate_register_store(ctx, priv->dreg, NULL, 70 70 NFT_DATA_VALUE, len); 71 71 }
+12
net/netfilter/nf_tables_api.c
··· 4122 4122 return 0; 4123 4123 } 4124 4124 4125 + unsigned int nft_parse_register(const struct nlattr *attr) 4126 + { 4127 + return ntohl(nla_get_be32(attr)); 4128 + } 4129 + EXPORT_SYMBOL_GPL(nft_parse_register); 4130 + 4131 + int nft_dump_register(struct sk_buff *skb, unsigned int attr, unsigned int reg) 4132 + { 4133 + return nla_put_be32(skb, attr, htonl(reg)); 4134 + } 4135 + EXPORT_SYMBOL_GPL(nft_dump_register); 4136 + 4125 4137 /** 4126 4138 * nft_validate_register_load - validate a load from a register 4127 4139 *
+4 -4
net/netfilter/nft_bitwise.c
··· 62 62 return -EINVAL; 63 63 64 64 priv->len = ntohl(nla_get_be32(tb[NFTA_BITWISE_LEN])); 65 - priv->sreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_SREG])); 65 + priv->sreg = nft_parse_register(tb[NFTA_BITWISE_SREG]); 66 66 err = nft_validate_register_load(priv->sreg, priv->len); 67 67 if (err < 0) 68 68 return err; 69 69 70 - priv->dreg = ntohl(nla_get_be32(tb[NFTA_BITWISE_DREG])); 70 + priv->dreg = nft_parse_register(tb[NFTA_BITWISE_DREG]); 71 71 err = nft_validate_register_store(ctx, priv->dreg, NULL, 72 72 NFT_DATA_VALUE, priv->len); 73 73 if (err < 0) ··· 92 92 { 93 93 const struct nft_bitwise *priv = nft_expr_priv(expr); 94 94 95 - if (nla_put_be32(skb, NFTA_BITWISE_SREG, htonl(priv->sreg))) 95 + if (nft_dump_register(skb, NFTA_BITWISE_SREG, priv->sreg)) 96 96 goto nla_put_failure; 97 - if (nla_put_be32(skb, NFTA_BITWISE_DREG, htonl(priv->dreg))) 97 + if (nft_dump_register(skb, NFTA_BITWISE_DREG, priv->dreg)) 98 98 goto nla_put_failure; 99 99 if (nla_put_be32(skb, NFTA_BITWISE_LEN, htonl(priv->len))) 100 100 goto nla_put_failure;
+4 -4
net/netfilter/nft_byteorder.c
··· 106 106 return -EINVAL; 107 107 } 108 108 109 - priv->sreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SREG])); 109 + priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]); 110 110 priv->len = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN])); 111 111 err = nft_validate_register_load(priv->sreg, priv->len); 112 112 if (err < 0) 113 113 return err; 114 114 115 - priv->dreg = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_DREG])); 115 + priv->dreg = nft_parse_register(tb[NFTA_BYTEORDER_DREG]); 116 116 return nft_validate_register_store(ctx, priv->dreg, NULL, 117 117 NFT_DATA_VALUE, priv->len); 118 118 } ··· 121 121 { 122 122 const struct nft_byteorder *priv = nft_expr_priv(expr); 123 123 124 - if (nla_put_be32(skb, NFTA_BYTEORDER_SREG, htonl(priv->sreg))) 124 + if (nft_dump_register(skb, NFTA_BYTEORDER_SREG, priv->sreg)) 125 125 goto nla_put_failure; 126 - if (nla_put_be32(skb, NFTA_BYTEORDER_DREG, htonl(priv->dreg))) 126 + if (nft_dump_register(skb, NFTA_BYTEORDER_DREG, priv->dreg)) 127 127 goto nla_put_failure; 128 128 if (nla_put_be32(skb, NFTA_BYTEORDER_OP, htonl(priv->op))) 129 129 goto nla_put_failure;
+4 -4
net/netfilter/nft_cmp.c
··· 78 78 err = nft_data_init(NULL, &priv->data, &desc, tb[NFTA_CMP_DATA]); 79 79 BUG_ON(err < 0); 80 80 81 - priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG])); 81 + priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]); 82 82 err = nft_validate_register_load(priv->sreg, desc.len); 83 83 if (err < 0) 84 84 return err; ··· 92 92 { 93 93 const struct nft_cmp_expr *priv = nft_expr_priv(expr); 94 94 95 - if (nla_put_be32(skb, NFTA_CMP_SREG, htonl(priv->sreg))) 95 + if (nft_dump_register(skb, NFTA_CMP_SREG, priv->sreg)) 96 96 goto nla_put_failure; 97 97 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(priv->op))) 98 98 goto nla_put_failure; ··· 128 128 err = nft_data_init(NULL, &data, &desc, tb[NFTA_CMP_DATA]); 129 129 BUG_ON(err < 0); 130 130 131 - priv->sreg = ntohl(nla_get_be32(tb[NFTA_CMP_SREG])); 131 + priv->sreg = nft_parse_register(tb[NFTA_CMP_SREG]); 132 132 err = nft_validate_register_load(priv->sreg, desc.len); 133 133 if (err < 0) 134 134 return err; ··· 146 146 const struct nft_cmp_fast_expr *priv = nft_expr_priv(expr); 147 147 struct nft_data data; 148 148 149 - if (nla_put_be32(skb, NFTA_CMP_SREG, htonl(priv->sreg))) 149 + if (nft_dump_register(skb, NFTA_CMP_SREG, priv->sreg)) 150 150 goto nla_put_failure; 151 151 if (nla_put_be32(skb, NFTA_CMP_OP, htonl(NFT_CMP_EQ))) 152 152 goto nla_put_failure;
+4 -4
net/netfilter/nft_ct.c
··· 306 306 } 307 307 } 308 308 309 - priv->dreg = ntohl(nla_get_be32(tb[NFTA_CT_DREG])); 309 + priv->dreg = nft_parse_register(tb[NFTA_CT_DREG]); 310 310 err = nft_validate_register_store(ctx, priv->dreg, NULL, 311 311 NFT_DATA_VALUE, len); 312 312 if (err < 0) ··· 338 338 return -EOPNOTSUPP; 339 339 } 340 340 341 - priv->sreg = ntohl(nla_get_be32(tb[NFTA_CT_SREG])); 341 + priv->sreg = nft_parse_register(tb[NFTA_CT_SREG]); 342 342 err = nft_validate_register_load(priv->sreg, len); 343 343 if (err < 0) 344 344 return err; ··· 360 360 { 361 361 const struct nft_ct *priv = nft_expr_priv(expr); 362 362 363 - if (nla_put_be32(skb, NFTA_CT_DREG, htonl(priv->dreg))) 363 + if (nft_dump_register(skb, NFTA_CT_DREG, priv->dreg)) 364 364 goto nla_put_failure; 365 365 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) 366 366 goto nla_put_failure; ··· 387 387 { 388 388 const struct nft_ct *priv = nft_expr_priv(expr); 389 389 390 - if (nla_put_be32(skb, NFTA_CT_SREG, htonl(priv->sreg))) 390 + if (nft_dump_register(skb, NFTA_CT_SREG, priv->sreg)) 391 391 goto nla_put_failure; 392 392 if (nla_put_be32(skb, NFTA_CT_KEY, htonl(priv->key))) 393 393 goto nla_put_failure;
+4 -4
net/netfilter/nft_dynset.c
··· 124 124 timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT])); 125 125 } 126 126 127 - priv->sreg_key = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_KEY])); 127 + priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]); 128 128 err = nft_validate_register_load(priv->sreg_key, set->klen);; 129 129 if (err < 0) 130 130 return err; ··· 135 135 if (set->dtype == NFT_DATA_VERDICT) 136 136 return -EOPNOTSUPP; 137 137 138 - priv->sreg_data = ntohl(nla_get_be32(tb[NFTA_DYNSET_SREG_DATA])); 138 + priv->sreg_data = nft_parse_register(tb[NFTA_DYNSET_SREG_DATA]); 139 139 err = nft_validate_register_load(priv->sreg_data, set->dlen); 140 140 if (err < 0) 141 141 return err; ··· 173 173 { 174 174 const struct nft_dynset *priv = nft_expr_priv(expr); 175 175 176 - if (nla_put_be32(skb, NFTA_DYNSET_SREG_KEY, htonl(priv->sreg_key))) 176 + if (nft_dump_register(skb, NFTA_DYNSET_SREG_KEY, priv->sreg_key)) 177 177 goto nla_put_failure; 178 178 if (priv->set->flags & NFT_SET_MAP && 179 - nla_put_be32(skb, NFTA_DYNSET_SREG_DATA, htonl(priv->sreg_data))) 179 + nft_dump_register(skb, NFTA_DYNSET_SREG_DATA, priv->sreg_data)) 180 180 goto nla_put_failure; 181 181 if (nla_put_be32(skb, NFTA_DYNSET_OP, htonl(priv->op))) 182 182 goto nla_put_failure;
+2 -2
net/netfilter/nft_exthdr.c
··· 68 68 priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); 69 69 priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET])); 70 70 priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN])); 71 - priv->dreg = ntohl(nla_get_be32(tb[NFTA_EXTHDR_DREG])); 71 + priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]); 72 72 73 73 return nft_validate_register_store(ctx, priv->dreg, NULL, 74 74 NFT_DATA_VALUE, priv->len); ··· 78 78 { 79 79 const struct nft_exthdr *priv = nft_expr_priv(expr); 80 80 81 - if (nla_put_be32(skb, NFTA_EXTHDR_DREG, htonl(priv->dreg))) 81 + if (nft_dump_register(skb, NFTA_EXTHDR_DREG, priv->dreg)) 82 82 goto nla_put_failure; 83 83 if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type)) 84 84 goto nla_put_failure;
+2 -2
net/netfilter/nft_immediate.c
··· 54 54 return err; 55 55 priv->dlen = desc.len; 56 56 57 - priv->dreg = ntohl(nla_get_be32(tb[NFTA_IMMEDIATE_DREG])); 57 + priv->dreg = nft_parse_register(tb[NFTA_IMMEDIATE_DREG]); 58 58 err = nft_validate_register_store(ctx, priv->dreg, &priv->data, 59 59 desc.type, desc.len); 60 60 if (err < 0) ··· 78 78 { 79 79 const struct nft_immediate_expr *priv = nft_expr_priv(expr); 80 80 81 - if (nla_put_be32(skb, NFTA_IMMEDIATE_DREG, htonl(priv->dreg))) 81 + if (nft_dump_register(skb, NFTA_IMMEDIATE_DREG, priv->dreg)) 82 82 goto nla_put_failure; 83 83 84 84 return nft_data_dump(skb, NFTA_IMMEDIATE_DATA, &priv->data,
+4 -4
net/netfilter/nft_lookup.c
··· 71 71 return PTR_ERR(set); 72 72 } 73 73 74 - priv->sreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_SREG])); 74 + priv->sreg = nft_parse_register(tb[NFTA_LOOKUP_SREG]); 75 75 err = nft_validate_register_load(priv->sreg, set->klen); 76 76 if (err < 0) 77 77 return err; ··· 80 80 if (!(set->flags & NFT_SET_MAP)) 81 81 return -EINVAL; 82 82 83 - priv->dreg = ntohl(nla_get_be32(tb[NFTA_LOOKUP_DREG])); 83 + priv->dreg = nft_parse_register(tb[NFTA_LOOKUP_DREG]); 84 84 err = nft_validate_register_store(ctx, priv->dreg, NULL, 85 85 set->dtype, set->dlen); 86 86 if (err < 0) ··· 112 112 113 113 if (nla_put_string(skb, NFTA_LOOKUP_SET, priv->set->name)) 114 114 goto nla_put_failure; 115 - if (nla_put_be32(skb, NFTA_LOOKUP_SREG, htonl(priv->sreg))) 115 + if (nft_dump_register(skb, NFTA_LOOKUP_SREG, priv->sreg)) 116 116 goto nla_put_failure; 117 117 if (priv->set->flags & NFT_SET_MAP) 118 - if (nla_put_be32(skb, NFTA_LOOKUP_DREG, htonl(priv->dreg))) 118 + if (nft_dump_register(skb, NFTA_LOOKUP_DREG, priv->dreg)) 119 119 goto nla_put_failure; 120 120 return 0; 121 121
+4 -4
net/netfilter/nft_meta.c
··· 254 254 return -EOPNOTSUPP; 255 255 } 256 256 257 - priv->dreg = ntohl(nla_get_be32(tb[NFTA_META_DREG])); 257 + priv->dreg = nft_parse_register(tb[NFTA_META_DREG]); 258 258 return nft_validate_register_store(ctx, priv->dreg, NULL, 259 259 NFT_DATA_VALUE, len); 260 260 } ··· 281 281 return -EOPNOTSUPP; 282 282 } 283 283 284 - priv->sreg = ntohl(nla_get_be32(tb[NFTA_META_SREG])); 284 + priv->sreg = nft_parse_register(tb[NFTA_META_SREG]); 285 285 err = nft_validate_register_load(priv->sreg, len); 286 286 if (err < 0) 287 287 return err; ··· 297 297 298 298 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key))) 299 299 goto nla_put_failure; 300 - if (nla_put_be32(skb, NFTA_META_DREG, htonl(priv->dreg))) 300 + if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg)) 301 301 goto nla_put_failure; 302 302 return 0; 303 303 ··· 313 313 314 314 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key))) 315 315 goto nla_put_failure; 316 - if (nla_put_be32(skb, NFTA_META_SREG, htonl(priv->sreg))) 316 + if (nft_dump_register(skb, NFTA_META_SREG, priv->sreg)) 317 317 goto nla_put_failure; 318 318 319 319 return 0;
+12 -12
net/netfilter/nft_nat.c
··· 163 163 164 164 if (tb[NFTA_NAT_REG_ADDR_MIN]) { 165 165 priv->sreg_addr_min = 166 - ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MIN])); 166 + nft_parse_register(tb[NFTA_NAT_REG_ADDR_MIN]); 167 167 err = nft_validate_register_load(priv->sreg_addr_min, alen); 168 168 if (err < 0) 169 169 return err; 170 170 171 171 if (tb[NFTA_NAT_REG_ADDR_MAX]) { 172 172 priv->sreg_addr_max = 173 - ntohl(nla_get_be32(tb[NFTA_NAT_REG_ADDR_MAX])); 173 + nft_parse_register(tb[NFTA_NAT_REG_ADDR_MAX]); 174 174 175 175 err = nft_validate_register_load(priv->sreg_addr_max, 176 176 alen); ··· 184 184 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all); 185 185 if (tb[NFTA_NAT_REG_PROTO_MIN]) { 186 186 priv->sreg_proto_min = 187 - ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MIN])); 187 + nft_parse_register(tb[NFTA_NAT_REG_PROTO_MIN]); 188 188 189 189 err = nft_validate_register_load(priv->sreg_proto_min, plen); 190 190 if (err < 0) ··· 192 192 193 193 if (tb[NFTA_NAT_REG_PROTO_MAX]) { 194 194 priv->sreg_proto_max = 195 - ntohl(nla_get_be32(tb[NFTA_NAT_REG_PROTO_MAX])); 195 + nft_parse_register(tb[NFTA_NAT_REG_PROTO_MAX]); 196 196 197 197 err = nft_validate_register_load(priv->sreg_proto_max, 198 198 plen); ··· 231 231 goto nla_put_failure; 232 232 233 233 if (priv->sreg_addr_min) { 234 - if (nla_put_be32(skb, NFTA_NAT_REG_ADDR_MIN, 235 - htonl(priv->sreg_addr_min)) || 236 - nla_put_be32(skb, NFTA_NAT_REG_ADDR_MAX, 237 - htonl(priv->sreg_addr_max))) 234 + if (nft_dump_register(skb, NFTA_NAT_REG_ADDR_MIN, 235 + priv->sreg_addr_min) || 236 + nft_dump_register(skb, NFTA_NAT_REG_ADDR_MAX, 237 + priv->sreg_addr_max)) 238 238 goto nla_put_failure; 239 239 } 240 240 241 241 if (priv->sreg_proto_min) { 242 - if (nla_put_be32(skb, NFTA_NAT_REG_PROTO_MIN, 243 - htonl(priv->sreg_proto_min)) || 244 - nla_put_be32(skb, NFTA_NAT_REG_PROTO_MAX, 245 - htonl(priv->sreg_proto_max))) 242 + if (nft_dump_register(skb, NFTA_NAT_REG_PROTO_MIN, 243 + priv->sreg_proto_min) || 244 + nft_dump_register(skb, NFTA_NAT_REG_PROTO_MAX, 245 + priv->sreg_proto_max)) 246 246 goto nla_put_failure; 247 247 } 248 248
+2 -2
net/netfilter/nft_payload.c
··· 66 66 priv->base = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_BASE])); 67 67 priv->offset = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_OFFSET])); 68 68 priv->len = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_LEN])); 69 - priv->dreg = ntohl(nla_get_be32(tb[NFTA_PAYLOAD_DREG])); 69 + priv->dreg = nft_parse_register(tb[NFTA_PAYLOAD_DREG]); 70 70 71 71 return nft_validate_register_store(ctx, priv->dreg, NULL, 72 72 NFT_DATA_VALUE, priv->len); ··· 76 76 { 77 77 const struct nft_payload *priv = nft_expr_priv(expr); 78 78 79 - if (nla_put_be32(skb, NFTA_PAYLOAD_DREG, htonl(priv->dreg)) || 79 + if (nft_dump_register(skb, NFTA_PAYLOAD_DREG, priv->dreg) || 80 80 nla_put_be32(skb, NFTA_PAYLOAD_BASE, htonl(priv->base)) || 81 81 nla_put_be32(skb, NFTA_PAYLOAD_OFFSET, htonl(priv->offset)) || 82 82 nla_put_be32(skb, NFTA_PAYLOAD_LEN, htonl(priv->len)))
+6 -6
net/netfilter/nft_redir.c
··· 54 54 plen = FIELD_SIZEOF(struct nf_nat_range, min_addr.all); 55 55 if (tb[NFTA_REDIR_REG_PROTO_MIN]) { 56 56 priv->sreg_proto_min = 57 - ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MIN])); 57 + nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MIN]); 58 58 59 59 err = nft_validate_register_load(priv->sreg_proto_min, plen); 60 60 if (err < 0) ··· 62 62 63 63 if (tb[NFTA_REDIR_REG_PROTO_MAX]) { 64 64 priv->sreg_proto_max = 65 - ntohl(nla_get_be32(tb[NFTA_REDIR_REG_PROTO_MAX])); 65 + nft_parse_register(tb[NFTA_REDIR_REG_PROTO_MAX]); 66 66 67 67 err = nft_validate_register_load(priv->sreg_proto_max, 68 68 plen); ··· 88 88 const struct nft_redir *priv = nft_expr_priv(expr); 89 89 90 90 if (priv->sreg_proto_min) { 91 - if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MIN, 92 - htonl(priv->sreg_proto_min))) 91 + if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MIN, 92 + priv->sreg_proto_min)) 93 93 goto nla_put_failure; 94 - if (nla_put_be32(skb, NFTA_REDIR_REG_PROTO_MAX, 95 - htonl(priv->sreg_proto_max))) 94 + if (nft_dump_register(skb, NFTA_REDIR_REG_PROTO_MAX, 95 + priv->sreg_proto_max)) 96 96 goto nla_put_failure; 97 97 } 98 98