History

netfilter: nft_osf: Add version option support

Add version option support to the nftables "osf" expression.

Fernando Fernandez Mancera committed 7 years ago

Commit 22c76521 parent 6978cdb4 files · +46 −15Browse files

Unified · Split

4 files
  1. include/linux/netfilter/nfnetlink_osf.h +8 −3
  2. include/uapi/linux/netfilter/nf_tables.h +6 −0
  3. net/netfilter/nfnetlink_osf.c +7 −7
  4. net/netfilter/nft_osf.c +25 −5
include/linux/netfilter/nfnetlink_osf.h+8−3
@@ -21,13 +21,18 @@ struct nf_osf_finger { · 20 unmodified lines
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+6−0
@@ -1522,15 +1522,21 @@ enum nft_flowtable_hook_attributes { · 1521 unmodified lines
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+7−7
@@ -255,9 +255,9 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family, · 254 unmodified lines
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;
@@ -265,24 +265,24 @@ const char *nf_osf_find(const struct sk_buff *skb, · 1 unmodified line
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+25−5
@@ -7,11 +7,13 @@ · 6 unmodified lines
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, · 2 unmodified lines
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,11 +38,17 @@ static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs, · 6 unmodified lines
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,
@@ -47,6 +56,7 @@ static int nft_osf_init(const struct nft_ctx *ctx, · 1 unmodified line
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, · 4 unmodified lines
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) · 10 unmodified lines
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