Loading include/linux/netfilter/nfnetlink_osf.h +2 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ bool nf_osf_match(const struct sk_buff *skb, u_int8_t family, const struct list_head *nf_osf_fingers); const char *nf_osf_find(const struct sk_buff *skb, const struct list_head *nf_osf_fingers); const struct list_head *nf_osf_fingers, const int ttl_check); #endif /* _NFOSF_H */ include/uapi/linux/netfilter/nf_tables.h +7 −0 Original line number Diff line number Diff line Loading @@ -1511,9 +1511,16 @@ enum nft_flowtable_hook_attributes { }; #define NFTA_FLOWTABLE_HOOK_MAX (__NFTA_FLOWTABLE_HOOK_MAX - 1) /** * enum nft_osf_attributes - nftables osf expression netlink attributes * * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers) * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8) */ enum nft_osf_attributes { NFTA_OSF_UNSPEC, NFTA_OSF_DREG, NFTA_OSF_TTL, __NFTA_OSF_MAX, }; #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1) Loading net/netfilter/nfnetlink_osf.c +21 −25 Original line number Diff line number Diff line Loading @@ -30,18 +30,16 @@ EXPORT_SYMBOL_GPL(nf_osf_fingers); static inline int nf_osf_ttl(const struct sk_buff *skb, int ttl_check, unsigned char f_ttl) { struct in_device *in_dev = __in_dev_get_rcu(skb->dev); const struct iphdr *ip = ip_hdr(skb); int ret = 0; if (ttl_check != -1) { if (ttl_check == NF_OSF_TTL_TRUE) return ip->ttl == f_ttl; if (ttl_check == NF_OSF_TTL_NOCHECK) return 1; else if (ip->ttl <= f_ttl) return 1; else { struct in_device *in_dev = __in_dev_get_rcu(skb->dev); int ret = 0; for_ifa(in_dev) { if (inet_ifa_match(ip->saddr, ifa)) { Loading @@ -49,14 +47,11 @@ static inline int nf_osf_ttl(const struct sk_buff *skb, break; } } endfor_ifa(in_dev); return ret; } } return ip->ttl == f_ttl; } struct nf_osf_hdr_ctx { bool df; Loading Loading @@ -213,7 +208,7 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family, if (!tcp) return false; ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : -1; ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : 0; list_for_each_entry_rcu(kf, &nf_osf_fingers[ctx.df], finger_entry) { Loading Loading @@ -257,7 +252,8 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family, EXPORT_SYMBOL_GPL(nf_osf_match); const char *nf_osf_find(const struct sk_buff *skb, const struct list_head *nf_osf_fingers) const struct list_head *nf_osf_fingers, const int ttl_check) { const struct iphdr *ip = ip_hdr(skb); const struct nf_osf_user_finger *f; Loading @@ -275,7 +271,7 @@ const char *nf_osf_find(const struct sk_buff *skb, list_for_each_entry_rcu(kf, &nf_osf_fingers[ctx.df], finger_entry) { f = &kf->finger; if (!nf_osf_match_one(skb, f, -1, &ctx)) if (!nf_osf_match_one(skb, f, ttl_check, &ctx)) continue; genre = f->genre; Loading net/netfilter/nft_osf.c +14 −1 Original line number Diff line number Diff line Loading @@ -6,10 +6,12 @@ struct nft_osf { enum nft_registers dreg:8; u8 ttl; }; static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = { [NFTA_OSF_DREG] = { .type = NLA_U32 }, [NFTA_OSF_TTL] = { .type = NLA_U8 }, }; static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs, Loading @@ -33,7 +35,7 @@ static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs, return; } os_name = nf_osf_find(skb, nf_osf_fingers); os_name = nf_osf_find(skb, nf_osf_fingers, priv->ttl); if (!os_name) strncpy((char *)dest, "unknown", NFT_OSF_MAXGENRELEN); else Loading @@ -46,6 +48,14 @@ static int nft_osf_init(const struct nft_ctx *ctx, { struct nft_osf *priv = nft_expr_priv(expr); int err; u8 ttl; if (nla_get_u8(tb[NFTA_OSF_TTL])) { ttl = nla_get_u8(tb[NFTA_OSF_TTL]); if (ttl > 2) return -EINVAL; priv->ttl = ttl; } priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]); err = nft_validate_register_store(ctx, priv->dreg, NULL, Loading @@ -60,6 +70,9 @@ static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr) { const struct nft_osf *priv = nft_expr_priv(expr); if (nla_put_u8(skb, NFTA_OSF_TTL, priv->ttl)) goto nla_put_failure; if (nft_dump_register(skb, NFTA_OSF_DREG, priv->dreg)) goto nla_put_failure; Loading Loading
include/linux/netfilter/nfnetlink_osf.h +2 −1 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ bool nf_osf_match(const struct sk_buff *skb, u_int8_t family, const struct list_head *nf_osf_fingers); const char *nf_osf_find(const struct sk_buff *skb, const struct list_head *nf_osf_fingers); const struct list_head *nf_osf_fingers, const int ttl_check); #endif /* _NFOSF_H */
include/uapi/linux/netfilter/nf_tables.h +7 −0 Original line number Diff line number Diff line Loading @@ -1511,9 +1511,16 @@ enum nft_flowtable_hook_attributes { }; #define NFTA_FLOWTABLE_HOOK_MAX (__NFTA_FLOWTABLE_HOOK_MAX - 1) /** * enum nft_osf_attributes - nftables osf expression netlink attributes * * @NFTA_OSF_DREG: destination register (NLA_U32: nft_registers) * @NFTA_OSF_TTL: Value of the TTL osf option (NLA_U8) */ enum nft_osf_attributes { NFTA_OSF_UNSPEC, NFTA_OSF_DREG, NFTA_OSF_TTL, __NFTA_OSF_MAX, }; #define NFTA_OSF_MAX (__NFTA_OSF_MAX - 1) Loading
net/netfilter/nfnetlink_osf.c +21 −25 Original line number Diff line number Diff line Loading @@ -30,18 +30,16 @@ EXPORT_SYMBOL_GPL(nf_osf_fingers); static inline int nf_osf_ttl(const struct sk_buff *skb, int ttl_check, unsigned char f_ttl) { struct in_device *in_dev = __in_dev_get_rcu(skb->dev); const struct iphdr *ip = ip_hdr(skb); int ret = 0; if (ttl_check != -1) { if (ttl_check == NF_OSF_TTL_TRUE) return ip->ttl == f_ttl; if (ttl_check == NF_OSF_TTL_NOCHECK) return 1; else if (ip->ttl <= f_ttl) return 1; else { struct in_device *in_dev = __in_dev_get_rcu(skb->dev); int ret = 0; for_ifa(in_dev) { if (inet_ifa_match(ip->saddr, ifa)) { Loading @@ -49,14 +47,11 @@ static inline int nf_osf_ttl(const struct sk_buff *skb, break; } } endfor_ifa(in_dev); return ret; } } return ip->ttl == f_ttl; } struct nf_osf_hdr_ctx { bool df; Loading Loading @@ -213,7 +208,7 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family, if (!tcp) return false; ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : -1; ttl_check = (info->flags & NF_OSF_TTL) ? info->ttl : 0; list_for_each_entry_rcu(kf, &nf_osf_fingers[ctx.df], finger_entry) { Loading Loading @@ -257,7 +252,8 @@ nf_osf_match(const struct sk_buff *skb, u_int8_t family, EXPORT_SYMBOL_GPL(nf_osf_match); const char *nf_osf_find(const struct sk_buff *skb, const struct list_head *nf_osf_fingers) const struct list_head *nf_osf_fingers, const int ttl_check) { const struct iphdr *ip = ip_hdr(skb); const struct nf_osf_user_finger *f; Loading @@ -275,7 +271,7 @@ const char *nf_osf_find(const struct sk_buff *skb, list_for_each_entry_rcu(kf, &nf_osf_fingers[ctx.df], finger_entry) { f = &kf->finger; if (!nf_osf_match_one(skb, f, -1, &ctx)) if (!nf_osf_match_one(skb, f, ttl_check, &ctx)) continue; genre = f->genre; Loading
net/netfilter/nft_osf.c +14 −1 Original line number Diff line number Diff line Loading @@ -6,10 +6,12 @@ struct nft_osf { enum nft_registers dreg:8; u8 ttl; }; static const struct nla_policy nft_osf_policy[NFTA_OSF_MAX + 1] = { [NFTA_OSF_DREG] = { .type = NLA_U32 }, [NFTA_OSF_TTL] = { .type = NLA_U8 }, }; static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs, Loading @@ -33,7 +35,7 @@ static void nft_osf_eval(const struct nft_expr *expr, struct nft_regs *regs, return; } os_name = nf_osf_find(skb, nf_osf_fingers); os_name = nf_osf_find(skb, nf_osf_fingers, priv->ttl); if (!os_name) strncpy((char *)dest, "unknown", NFT_OSF_MAXGENRELEN); else Loading @@ -46,6 +48,14 @@ static int nft_osf_init(const struct nft_ctx *ctx, { struct nft_osf *priv = nft_expr_priv(expr); int err; u8 ttl; if (nla_get_u8(tb[NFTA_OSF_TTL])) { ttl = nla_get_u8(tb[NFTA_OSF_TTL]); if (ttl > 2) return -EINVAL; priv->ttl = ttl; } priv->dreg = nft_parse_register(tb[NFTA_OSF_DREG]); err = nft_validate_register_store(ctx, priv->dreg, NULL, Loading @@ -60,6 +70,9 @@ static int nft_osf_dump(struct sk_buff *skb, const struct nft_expr *expr) { const struct nft_osf *priv = nft_expr_priv(expr); if (nla_put_u8(skb, NFTA_OSF_TTL, priv->ttl)) goto nla_put_failure; if (nft_dump_register(skb, NFTA_OSF_DREG, priv->dreg)) goto nla_put_failure; Loading