1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
5 * Development of this code funded by Astaro AG (http://www.astaro.com/)
8 #include <asm/unaligned.h>
9 #include <linux/kernel.h>
10 #include <linux/init.h>
11 #include <linux/module.h>
12 #include <linux/netlink.h>
13 #include <linux/netfilter.h>
14 #include <linux/netfilter/nf_tables.h>
15 #include <net/netfilter/nf_tables_core.h>
16 #include <net/netfilter/nf_tables.h>
18 struct nft_byteorder
{
21 enum nft_byteorder_ops op
:8;
26 void nft_byteorder_eval(const struct nft_expr
*expr
,
27 struct nft_regs
*regs
,
28 const struct nft_pktinfo
*pkt
)
30 const struct nft_byteorder
*priv
= nft_expr_priv(expr
);
31 u32
*src
= ®s
->data
[priv
->sreg
];
32 u32
*dst
= ®s
->data
[priv
->dreg
];
44 case NFT_BYTEORDER_NTOH
:
45 for (i
= 0; i
< priv
->len
/ 8; i
++) {
46 src64
= nft_reg_load64(&src
[i
]);
47 nft_reg_store64(&dst
[i
],
48 be64_to_cpu((__force __be64
)src64
));
51 case NFT_BYTEORDER_HTON
:
52 for (i
= 0; i
< priv
->len
/ 8; i
++) {
53 src64
= (__force __u64
)
54 cpu_to_be64(nft_reg_load64(&src
[i
]));
55 nft_reg_store64(&dst
[i
], src64
);
63 case NFT_BYTEORDER_NTOH
:
64 for (i
= 0; i
< priv
->len
/ 4; i
++)
65 dst
[i
] = ntohl((__force __be32
)src
[i
]);
67 case NFT_BYTEORDER_HTON
:
68 for (i
= 0; i
< priv
->len
/ 4; i
++)
69 dst
[i
] = (__force __u32
)htonl(src
[i
]);
75 case NFT_BYTEORDER_NTOH
:
76 for (i
= 0; i
< priv
->len
/ 2; i
++)
77 d16
[i
] = ntohs((__force __be16
)s16
[i
]);
79 case NFT_BYTEORDER_HTON
:
80 for (i
= 0; i
< priv
->len
/ 2; i
++)
81 d16
[i
] = (__force __u16
)htons(s16
[i
]);
88 static const struct nla_policy nft_byteorder_policy
[NFTA_BYTEORDER_MAX
+ 1] = {
89 [NFTA_BYTEORDER_SREG
] = { .type
= NLA_U32
},
90 [NFTA_BYTEORDER_DREG
] = { .type
= NLA_U32
},
91 [NFTA_BYTEORDER_OP
] = NLA_POLICY_MAX(NLA_BE32
, 255),
92 [NFTA_BYTEORDER_LEN
] = NLA_POLICY_MAX(NLA_BE32
, 255),
93 [NFTA_BYTEORDER_SIZE
] = NLA_POLICY_MAX(NLA_BE32
, 255),
96 static int nft_byteorder_init(const struct nft_ctx
*ctx
,
97 const struct nft_expr
*expr
,
98 const struct nlattr
* const tb
[])
100 struct nft_byteorder
*priv
= nft_expr_priv(expr
);
104 if (tb
[NFTA_BYTEORDER_SREG
] == NULL
||
105 tb
[NFTA_BYTEORDER_DREG
] == NULL
||
106 tb
[NFTA_BYTEORDER_LEN
] == NULL
||
107 tb
[NFTA_BYTEORDER_SIZE
] == NULL
||
108 tb
[NFTA_BYTEORDER_OP
] == NULL
)
111 priv
->op
= ntohl(nla_get_be32(tb
[NFTA_BYTEORDER_OP
]));
113 case NFT_BYTEORDER_NTOH
:
114 case NFT_BYTEORDER_HTON
:
120 err
= nft_parse_u32_check(tb
[NFTA_BYTEORDER_SIZE
], U8_MAX
, &size
);
126 switch (priv
->size
) {
135 err
= nft_parse_u32_check(tb
[NFTA_BYTEORDER_LEN
], U8_MAX
, &len
);
141 err
= nft_parse_register_load(tb
[NFTA_BYTEORDER_SREG
], &priv
->sreg
,
146 return nft_parse_register_store(ctx
, tb
[NFTA_BYTEORDER_DREG
],
147 &priv
->dreg
, NULL
, NFT_DATA_VALUE
,
151 static int nft_byteorder_dump(struct sk_buff
*skb
,
152 const struct nft_expr
*expr
, bool reset
)
154 const struct nft_byteorder
*priv
= nft_expr_priv(expr
);
156 if (nft_dump_register(skb
, NFTA_BYTEORDER_SREG
, priv
->sreg
))
157 goto nla_put_failure
;
158 if (nft_dump_register(skb
, NFTA_BYTEORDER_DREG
, priv
->dreg
))
159 goto nla_put_failure
;
160 if (nla_put_be32(skb
, NFTA_BYTEORDER_OP
, htonl(priv
->op
)))
161 goto nla_put_failure
;
162 if (nla_put_be32(skb
, NFTA_BYTEORDER_LEN
, htonl(priv
->len
)))
163 goto nla_put_failure
;
164 if (nla_put_be32(skb
, NFTA_BYTEORDER_SIZE
, htonl(priv
->size
)))
165 goto nla_put_failure
;
172 static bool nft_byteorder_reduce(struct nft_regs_track
*track
,
173 const struct nft_expr
*expr
)
175 struct nft_byteorder
*priv
= nft_expr_priv(expr
);
177 nft_reg_track_cancel(track
, priv
->dreg
, priv
->len
);
182 static const struct nft_expr_ops nft_byteorder_ops
= {
183 .type
= &nft_byteorder_type
,
184 .size
= NFT_EXPR_SIZE(sizeof(struct nft_byteorder
)),
185 .eval
= nft_byteorder_eval
,
186 .init
= nft_byteorder_init
,
187 .dump
= nft_byteorder_dump
,
188 .reduce
= nft_byteorder_reduce
,
191 struct nft_expr_type nft_byteorder_type __read_mostly
= {
193 .ops
= &nft_byteorder_ops
,
194 .policy
= nft_byteorder_policy
,
195 .maxattr
= NFTA_BYTEORDER_MAX
,
196 .owner
= THIS_MODULE
,