Skip to content

Commit 22c7652

Browse files
ffmanceraummakynes
authored andcommitted
netfilter: nft_osf: Add version option support
Add version option support to the nftables "osf" expression. Signed-off-by: Fernando Fernandez Mancera <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 6978cdb commit 22c7652

File tree

4 files changed

+46
-15
lines changed

4 files changed

+46
-15
lines changed

include/linux/netfilter/nfnetlink_osf.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,18 @@ struct nf_osf_finger {
2121
struct nf_osf_user_finger finger;
2222
};
2323

24+
struct nf_osf_data {
25+
const char *genre;
26+
const char *version;
27+
};
28+
2429
bool nf_osf_match(const struct sk_buff *skb, u_int8_t family,
2530
int hooknum, struct net_device *in, struct net_device *out,
2631
const struct nf_osf_info *info, struct net *net,
2732
const struct list_head *nf_osf_fingers);
2833

29-
const char *nf_osf_find(const struct sk_buff *skb,
30-
const struct list_head *nf_osf_fingers,
31-
const int ttl_check);
34+
bool nf_osf_find(const struct sk_buff *skb,
35+
const struct list_head *nf_osf_fingers,
36+
const int ttl_check, struct nf_osf_data *data);
3237

3338
#endif /* _NFOSF_H */

include/uapi/linux/netfilter/nf_tables.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,15 +1522,21 @@ enum nft_flowtable_hook_attributes {
15221522
*
15231523
* @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers)
15241524
* @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8)
1525+
* @NFTA_OSF_FLAGS: flags (NLA_U32)
15251526
*/
15261527
enum nft_osf_attributes {
15271528
NFTA_OSF_UNSPEC,
15281529
NFTA_OSF_DREG,
15291530
NFTA_OSF_TTL,
1531+
NFTA_OSF_FLAGS,
15301532
__NFTA_OSF_MAX,
15311533
};
15321534
#define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1)
15331535

1536+
enum nft_osf_flags {
1537+
NFT_OSF_F_VERSION = (1 << 0),
1538+
};
1539+
15341540
/**
15351541
* enum nft_device_attributes - nf_tables device netlink attributes
15361542
*

net/netfilter/nfnetlink_osf.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,34 +255,34 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family,
255255
}
256256
EXPORT_SYMBOL_GPL(nf_osf_match);
257257

258-
const char *nf_osf_find(const struct sk_buff *skb,
259-
const struct list_head *nf_osf_fingers,
260-
const int ttl_check)
258+
bool nf_osf_find(const struct sk_buff *skb,
259+
const struct list_head *nf_osf_fingers,
260+
const int ttl_check, struct nf_osf_data *data)
261261
{
262262
const struct iphdr *ip = ip_hdr(skb);
263263
const struct nf_osf_user_finger *f;
264264
unsigned char opts[MAX_IPOPTLEN];
265265
const struct nf_osf_finger *kf;
266266
struct nf_osf_hdr_ctx ctx;
267267
const struct tcphdr *tcp;
268-
const char *genre = NULL;
269268

270269
memset(&ctx, 0, sizeof(ctx));
271270

272271
tcp = nf_osf_hdr_ctx_init(&ctx, skb, ip, opts);
273272
if (!tcp)
274-
return NULL;
273+
return false;
275274

276275
list_for_each_entry_rcu(kf, &nf_osf_fingers[ctx.df], finger_entry) {
277276
f = &kf->finger;
278277
if (!nf_osf_match_one(skb, f, ttl_check, &ctx))
279278
continue;
280279

281-
genre = f->genre;
280+
data->genre = f->genre;
281+
data->version = f->version;
282282
break;
283283
}
284284

285-
return genre;
285+
return true;
286286
}
287287
EXPORT_SYMBOL_GPL(nf_osf_find);
288288

net/netfilter/nft_osf.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
struct nft_osf {
88
enum nft_registers dreg:8;
99
u8 ttl;
10+
u32 flags;
1011
};
1112

1213
static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = {
1314
[NFTA_OSF_DREG] = { .type = NLA_U32 },
1415
[NFTA_OSF_TTL] = { .type = NLA_U8 },
16+
[NFTA_OSF_FLAGS] = { .type = NLA_U32 },
1517
};
1618

1719
static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
@@ -20,9 +22,10 @@ static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
2022
struct nft_osf *priv = nft_expr_priv(expr);
2123
u32 *dest = &regs->data[priv->dreg];
2224
struct sk_buff *skb = pkt->skb;
25+
char os_match[NFT_OSF_MAXGENRELEN + 1];
2326
const struct tcphdr *tcp;
27+
struct nf_osf_data data;
2428
struct tcphdr _tcph;
25-
const char *os_name;
2629

2730
tcp = skb_header_pointer(skb, ip_hdrlen(skb),
2831
sizeof(struct tcphdr), &_tcph);
@@ -35,18 +38,25 @@ static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs,
3538
return;
3639
}
3740

38-
os_name = nf_osf_find(skb, nf_osf_fingers, priv->ttl);
39-
if (!os_name)
41+
if (!nf_osf_find(skb, nf_osf_fingers, priv->ttl, &data)) {
4042
strncpy((char *)dest, "unknown", NFT_OSF_MAXGENRELEN);
41-
else
42-
strncpy((char *)dest, os_name, NFT_OSF_MAXGENRELEN);
43+
} else {
44+
if (priv->flags & NFT_OSF_F_VERSION)
45+
snprintf(os_match, NFT_OSF_MAXGENRELEN, "%s:%s",
46+
data.genre, data.version);
47+
else
48+
strlcpy(os_match, data.genre, NFT_OSF_MAXGENRELEN);
49+
50+
strncpy((char *)dest, os_match, NFT_OSF_MAXGENRELEN);
51+
}
4352
}
4453

4554
static int nft_osf_init(const struct nft_ctx *ctx,
4655
const struct nft_expr *expr,
4756
const struct nlattr * const tb[])
4857
{
4958
struct nft_osf *priv = nft_expr_priv(expr);
59+
u32 flags;
5060
int err;
5161
u8 ttl;
5262

@@ -57,6 +67,13 @@ static int nft_osf_init(const struct nft_ctx *ctx,
5767
priv->ttl = ttl;
5868
}
5969

70+
if (tb[NFTA_OSF_FLAGS]) {
71+
flags = ntohl(nla_get_be32(tb[NFTA_OSF_FLAGS]));
72+
if (flags != NFT_OSF_F_VERSION)
73+
return -EINVAL;
74+
priv->flags = flags;
75+
}
76+
6077
priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]);
6178
err = nft_validate_register_store(ctx, priv->dreg, NULL,
6279
NFT_DATA_VALUE, NFT_OSF_MAXGENRELEN);
@@ -73,6 +90,9 @@ static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr)
7390
if (nla_put_u8(skb, NFTA_OSF_TTL, priv->ttl))
7491
goto nla_put_failure;
7592

93+
if (nla_put_be32(skb, NFTA_OSF_FLAGS, ntohl(priv->flags)))
94+
goto nla_put_failure;
95+
7696
if (nft_dump_register(skb, NFTA_OSF_DREG, priv->dreg))
7797
goto nla_put_failure;
7898

0 commit comments

Comments
 (0)