Message ID | 20180717172517.8776-1-ffmancera@riseup.net |
---|---|
State | Changes Requested |
Delegated to: | Pablo Neira |
Headers | show |
Series | [nf-next,v2] netfilter: nfnetlink_osf: add netlink support for osf module | expand |
It has been testing by adding the following rules: #iptables -I INPUT -p tcp -j ACCEPT -m osf --genre Linux --log 0 --ttl 2 #iptables -I INPUT -p tcp -j REJECT -m osf --genre Linux --log 0 --ttl 1 #iptables -I INPUT -p tcp -j ACCEPT -m osf --genre Linux --log 0 --ttl 0 Also $ lsmod | grep -i osf xt_osf 16384 1 nf_osf 16384 1 xt_osf x_tables 40960 3 iptable_filter,xt_osf,ip_tables Is this enough? Thanks. On 07/17/2018 07:25 PM, Fernando Fernandez Mancera wrote: > Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> > --- > include/linux/netfilter/nf_osf.h | 2 + > include/uapi/linux/netfilter/nf_osf.h | 5 + > include/uapi/linux/netfilter/xt_osf.h | 8 -- > net/netfilter/Kconfig | 10 +- > net/netfilter/Makefile | 1 + > net/netfilter/nf_osf.c | 7 ++ > net/netfilter/nfnetlink_osf.c | 134 ++++++++++++++++++++++++++ > net/netfilter/xt_osf.c | 133 ++----------------------- > 8 files changed, 164 insertions(+), 136 deletions(-) > create mode 100644 net/netfilter/nfnetlink_osf.c > > diff --git a/include/linux/netfilter/nf_osf.h b/include/linux/netfilter/nf_osf.h > index 7d0947d6ef16..3411c87152d7 100644 > --- a/include/linux/netfilter/nf_osf.h > +++ b/include/linux/netfilter/nf_osf.h > @@ -27,6 +27,8 @@ struct nf_osf_finger { > struct nf_osf_user_finger finger; > }; > > +extern struct list_head nf_osf_fingers[2]; > + > bool nf_osf_match(const struct sk_buff *skb, u_int8_t family, > int hooknum, struct net_device *in, struct net_device *out, > const struct nf_osf_info *info, struct net *net, > diff --git a/include/uapi/linux/netfilter/nf_osf.h b/include/uapi/linux/netfilter/nf_osf.h > index a89583099b2a..18516829fce1 100644 > --- a/include/uapi/linux/netfilter/nf_osf.h > +++ b/include/uapi/linux/netfilter/nf_osf.h > @@ -96,4 +96,9 @@ enum nf_osf_attr_type { > OSF_ATTR_MAX, > }; > > +enum nf_osf_msg_types { > + OSF_MSG_ADD, > + OSF_MSG_REMOVE, > + OSF_MSG_MAX, > +}; > #endif /* _NF_OSF_H */ > diff --git a/include/uapi/linux/netfilter/xt_osf.h b/include/uapi/linux/netfilter/xt_osf.h > index b189007f4f28..6fe4d75b1f11 100644 > --- a/include/uapi/linux/netfilter/xt_osf.h > +++ b/include/uapi/linux/netfilter/xt_osf.h > @@ -47,13 +47,5 @@ > #define xt_osf_nlmsg nf_osf_nlmsg > > #define xt_osf_attr_type nf_osf_attr_type > -/* > - * Add/remove fingerprint from the kernel. > - */ > -enum xt_osf_msg_types { > - OSF_MSG_ADD, > - OSF_MSG_REMOVE, > - OSF_MSG_MAX, > -}; > > #endif /* _XT_OSF_H */ > diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig > index 6c65d756e603..06abc3bc05d3 100644 > --- a/net/netfilter/Kconfig > +++ b/net/netfilter/Kconfig > @@ -46,6 +46,14 @@ config NETFILTER_NETLINK_LOG > and is also scheduled to replace the old syslog-based ipt_LOG > and ip6t_LOG modules. > > +config NETFILTER_NETLINK_OSF > + tristate "Netfilter OSF over NFNETLINK interface" > + depends on NETFILTER_ADVANCED > + select NETFILTER_NETLINK > + help > + If this option is enabled, the kernel will include support > + for passive OS fingerprint via NFNETLINK. > + > config NF_CONNTRACK > tristate "Netfilter connection tracking support" > default m if NETFILTER_ADVANCED=n > @@ -1379,8 +1387,8 @@ config NETFILTER_XT_MATCH_NFACCT > > config NETFILTER_XT_MATCH_OSF > tristate '"osf" Passive OS fingerprint match' > - depends on NETFILTER_ADVANCED && NETFILTER_NETLINK > select NF_OSF > + select NETFILTER_NETLINK_OSF > help > This option selects the Passive OS Fingerprinting match module > that allows to passively match the remote operating system by > diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile > index 0b3851e825fa..ab144e65edf1 100644 > --- a/net/netfilter/Makefile > +++ b/net/netfilter/Makefile > @@ -20,6 +20,7 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o > obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o > obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o > obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o > +obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o > > # connection tracking > obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o > diff --git a/net/netfilter/nf_osf.c b/net/netfilter/nf_osf.c > index f4c75e982902..b5c3af060d62 100644 > --- a/net/netfilter/nf_osf.c > +++ b/net/netfilter/nf_osf.c > @@ -20,6 +20,13 @@ > #include <net/netfilter/nf_log.h> > #include <linux/netfilter/nf_osf.h> > > +/* > + * Indexed by dont-fragment bit. > + * It is the only constant value in the fingerprint. > + */ > +struct list_head nf_osf_fingers[2]; > +EXPORT_SYMBOL_GPL(nf_osf_fingers); > + > static inline int nf_osf_ttl(const struct sk_buff *skb, > int ttl_check, unsigned char f_ttl) > { > diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c > new file mode 100644 > index 000000000000..ba71f04a4004 > --- /dev/null > +++ b/net/netfilter/nfnetlink_osf.c > @@ -0,0 +1,134 @@ > +#include <linux/netfilter/nfnetlink.h> > +#include <linux/netfilter/nf_osf.h> > + > +static const struct nla_policy nfnl_osf_policy[OSF_ATTR_MAX + 1] = { > + [OSF_ATTR_FINGER] = { .len = sizeof(struct nf_osf_user_finger) }, > +}; > + > +static int nfnl_osf_add_callback(struct net *net, struct sock *ctnl, > + struct sk_buff *skb, const struct nlmsghdr *nlh, > + const struct nlattr * const osf_attrs[], > + struct netlink_ext_ack *extack) > +{ > + struct nf_osf_user_finger *f; > + struct nf_osf_finger *kf = NULL, *sf; > + int err = 0; > + > + if (!capable(CAP_NET_ADMIN)) > + return -EPERM; > + > + if (!osf_attrs[OSF_ATTR_FINGER]) > + return -EINVAL; > + > + if (!(nlh->nlmsg_flags & NLM_F_CREATE)) > + return -EINVAL; > + > + f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > + > + kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL); > + if (!kf) > + return -ENOMEM; > + > + memcpy(&kf->finger, f, sizeof(struct nf_osf_user_finger)); > + > + list_for_each_entry(sf, &nf_osf_fingers[!!f->df], finger_entry) { > + if (memcmp(&sf->finger, f, sizeof(struct nf_osf_user_finger))) > + continue; > + > + kfree(kf); > + kf = NULL; > + > + if (nlh->nlmsg_flags & NLM_F_EXCL) > + err = -EEXIST; > + break; > + } > + > + /* > + * We are protected by nfnl mutex. > + */ > + if (kf) > + list_add_tail_rcu(&kf->finger_entry, &nf_osf_fingers[!!f->df]); > + > + return err; > +} > + > +static int nfnl_osf_remove_callback(struct net *net, struct sock *ctnl, > + struct sk_buff *skb, > + const struct nlmsghdr *nlh, > + const struct nlattr * const osf_attrs[], > + struct netlink_ext_ack *extack) > +{ > + struct nf_osf_user_finger *f; > + struct nf_osf_finger *sf; > + int err = -ENOENT; > + > + if (!capable(CAP_NET_ADMIN)) > + return -EPERM; > + > + if (!osf_attrs[OSF_ATTR_FINGER]) > + return -EINVAL; > + > + f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > + > + list_for_each_entry(sf, &nf_osf_fingers[!!f->df], finger_entry) { > + if (memcmp(&sf->finger, f, sizeof(struct nf_osf_user_finger))) > + continue; > + > + /* > + * We are protected by nfnl mutex. > + */ > + list_del_rcu(&sf->finger_entry); > + kfree_rcu(sf, rcu_head); > + > + err = 0; > + break; > + } > + > + return err; > +} > + > +static const struct nfnl_callback nfnl_nf_osf_callbacks[OSF_MSG_MAX] = { > + [OSF_MSG_ADD] = { > + .call = nfnl_osf_add_callback, > + .attr_count = OSF_ATTR_MAX, > + .policy = nfnl_osf_policy, > + }, > + [OSF_MSG_REMOVE] = { > + .call = nfnl_osf_remove_callback, > + .attr_count = OSF_ATTR_MAX, > + .policy = nfnl_osf_policy, > + }, > +}; > + > +static const struct nfnetlink_subsystem nfnl_osf_subsys = { > + .name = "osf", > + .subsys_id = NFNL_SUBSYS_OSF, > + .cb_count = OSF_MSG_MAX, > + .cb = nfnl_nf_osf_callbacks, > +}; > + > +static int __init nfnl_osf_init(void) > +{ > + int err = -EINVAL; > + > + err = nfnetlink_subsys_register(&nfnl_osf_subsys); > + if (err < 0) { > + pr_err("Failed to register OSF nsfnetlink helper (%d)\n", err); > + goto err_out_exit; > + } > + > + return 0; > + > +err_out_exit: > + return err; > +} > + > +static void __exit nfnl_osf_fini(void) > +{ > + nfnetlink_subsys_unregister(&nfnl_osf_subsys); > +} > + > +MODULE_LICENSE("GPL"); > +MODULE_AUTHOR("Fernando Fernandez <ffmancera@riseup.net>"); > +module_init(nfnl_osf_init); > +module_exit(nfnl_osf_fini); > diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c > index 9cfef73b4107..a7dcfb9835c4 100644 > --- a/net/netfilter/xt_osf.c > +++ b/net/netfilter/xt_osf.c > @@ -37,118 +37,6 @@ > #include <net/netfilter/nf_log.h> > #include <linux/netfilter/xt_osf.h> > > -/* > - * Indexed by dont-fragment bit. > - * It is the only constant value in the fingerprint. > - */ > -static struct list_head xt_osf_fingers[2]; > - > -static const struct nla_policy xt_osf_policy[OSF_ATTR_MAX + 1] = { > - [OSF_ATTR_FINGER] = { .len = sizeof(struct xt_osf_user_finger) }, > -}; > - > -static int xt_osf_add_callback(struct net *net, struct sock *ctnl, > - struct sk_buff *skb, const struct nlmsghdr *nlh, > - const struct nlattr * const osf_attrs[], > - struct netlink_ext_ack *extack) > -{ > - struct xt_osf_user_finger *f; > - struct xt_osf_finger *kf = NULL, *sf; > - int err = 0; > - > - if (!capable(CAP_NET_ADMIN)) > - return -EPERM; > - > - if (!osf_attrs[OSF_ATTR_FINGER]) > - return -EINVAL; > - > - if (!(nlh->nlmsg_flags & NLM_F_CREATE)) > - return -EINVAL; > - > - f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > - > - kf = kmalloc(sizeof(struct xt_osf_finger), GFP_KERNEL); > - if (!kf) > - return -ENOMEM; > - > - memcpy(&kf->finger, f, sizeof(struct xt_osf_user_finger)); > - > - list_for_each_entry(sf, &xt_osf_fingers[!!f->df], finger_entry) { > - if (memcmp(&sf->finger, f, sizeof(struct xt_osf_user_finger))) > - continue; > - > - kfree(kf); > - kf = NULL; > - > - if (nlh->nlmsg_flags & NLM_F_EXCL) > - err = -EEXIST; > - break; > - } > - > - /* > - * We are protected by nfnl mutex. > - */ > - if (kf) > - list_add_tail_rcu(&kf->finger_entry, &xt_osf_fingers[!!f->df]); > - > - return err; > -} > - > -static int xt_osf_remove_callback(struct net *net, struct sock *ctnl, > - struct sk_buff *skb, > - const struct nlmsghdr *nlh, > - const struct nlattr * const osf_attrs[], > - struct netlink_ext_ack *extack) > -{ > - struct xt_osf_user_finger *f; > - struct xt_osf_finger *sf; > - int err = -ENOENT; > - > - if (!capable(CAP_NET_ADMIN)) > - return -EPERM; > - > - if (!osf_attrs[OSF_ATTR_FINGER]) > - return -EINVAL; > - > - f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > - > - list_for_each_entry(sf, &xt_osf_fingers[!!f->df], finger_entry) { > - if (memcmp(&sf->finger, f, sizeof(struct xt_osf_user_finger))) > - continue; > - > - /* > - * We are protected by nfnl mutex. > - */ > - list_del_rcu(&sf->finger_entry); > - kfree_rcu(sf, rcu_head); > - > - err = 0; > - break; > - } > - > - return err; > -} > - > -static const struct nfnl_callback xt_osf_nfnetlink_callbacks[OSF_MSG_MAX] = { > - [OSF_MSG_ADD] = { > - .call = xt_osf_add_callback, > - .attr_count = OSF_ATTR_MAX, > - .policy = xt_osf_policy, > - }, > - [OSF_MSG_REMOVE] = { > - .call = xt_osf_remove_callback, > - .attr_count = OSF_ATTR_MAX, > - .policy = xt_osf_policy, > - }, > -}; > - > -static const struct nfnetlink_subsystem xt_osf_nfnetlink = { > - .name = "osf", > - .subsys_id = NFNL_SUBSYS_OSF, > - .cb_count = OSF_MSG_MAX, > - .cb = xt_osf_nfnetlink_callbacks, > -}; > - > static bool > xt_osf_match_packet(const struct sk_buff *skb, struct xt_action_param *p) > { > @@ -159,7 +47,7 @@ xt_osf_match_packet(const struct sk_buff *skb, struct xt_action_param *p) > return false; > > return nf_osf_match(skb, xt_family(p), xt_hooknum(p), xt_in(p), > - xt_out(p), info, net, xt_osf_fingers); > + xt_out(p), info, net, nf_osf_fingers); > } > > static struct xt_match xt_osf_match = { > @@ -180,26 +68,18 @@ static int __init xt_osf_init(void) > int err = -EINVAL; > int i; > > - for (i=0; i<ARRAY_SIZE(xt_osf_fingers); ++i) > - INIT_LIST_HEAD(&xt_osf_fingers[i]); > - > - err = nfnetlink_subsys_register(&xt_osf_nfnetlink); > - if (err < 0) { > - pr_err("Failed to register OSF nsfnetlink helper (%d)\n", err); > - goto err_out_exit; > - } > + for (i = 0; i < ARRAY_SIZE(nf_osf_fingers); ++i) > + INIT_LIST_HEAD(&nf_osf_fingers[i]); > > err = xt_register_match(&xt_osf_match); > if (err) { > pr_err("Failed to register OS fingerprint " > "matching module (%d)\n", err); > - goto err_out_remove; > + goto err_out_exit; > } > > return 0; > > -err_out_remove: > - nfnetlink_subsys_unregister(&xt_osf_nfnetlink); > err_out_exit: > return err; > } > @@ -209,13 +89,12 @@ static void __exit xt_osf_fini(void) > struct xt_osf_finger *f; > int i; > > - nfnetlink_subsys_unregister(&xt_osf_nfnetlink); > xt_unregister_match(&xt_osf_match); > > rcu_read_lock(); > - for (i=0; i<ARRAY_SIZE(xt_osf_fingers); ++i) { > + for (i = 0; i < ARRAY_SIZE(nf_osf_fingers); ++i) { > > - list_for_each_entry_rcu(f, &xt_osf_fingers[i], finger_entry) { > + list_for_each_entry_rcu(f, &nf_osf_fingers[i], finger_entry) { > list_del_rcu(&f->finger_entry); > kfree_rcu(f, rcu_head); > } > -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Please, add description to your patch, something like: Move nfnetlink osf subsystem to standalone module so we can reuse it from the new nft_ost extension. More comments below. On Tue, Jul 17, 2018 at 07:25:17PM +0200, Fernando Fernandez Mancera wrote: > Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> > --- > include/linux/netfilter/nf_osf.h | 2 + > include/uapi/linux/netfilter/nf_osf.h | 5 + > include/uapi/linux/netfilter/xt_osf.h | 8 -- > net/netfilter/Kconfig | 10 +- > net/netfilter/Makefile | 1 + > net/netfilter/nf_osf.c | 7 ++ > net/netfilter/nfnetlink_osf.c | 134 ++++++++++++++++++++++++++ > net/netfilter/xt_osf.c | 133 ++----------------------- > 8 files changed, 164 insertions(+), 136 deletions(-) > create mode 100644 net/netfilter/nfnetlink_osf.c > > diff --git a/include/linux/netfilter/nf_osf.h b/include/linux/netfilter/nf_osf.h > index 7d0947d6ef16..3411c87152d7 100644 > --- a/include/linux/netfilter/nf_osf.h > +++ b/include/linux/netfilter/nf_osf.h > @@ -27,6 +27,8 @@ struct nf_osf_finger { > struct nf_osf_user_finger finger; > }; > > +extern struct list_head nf_osf_fingers[2]; > + > bool nf_osf_match(const struct sk_buff *skb, u_int8_t family, > int hooknum, struct net_device *in, struct net_device *out, > const struct nf_osf_info *info, struct net *net, > diff --git a/include/uapi/linux/netfilter/nf_osf.h b/include/uapi/linux/netfilter/nf_osf.h > index a89583099b2a..18516829fce1 100644 > --- a/include/uapi/linux/netfilter/nf_osf.h > +++ b/include/uapi/linux/netfilter/nf_osf.h > @@ -96,4 +96,9 @@ enum nf_osf_attr_type { > OSF_ATTR_MAX, > }; > > +enum nf_osf_msg_types { > + OSF_MSG_ADD, > + OSF_MSG_REMOVE, > + OSF_MSG_MAX, > +}; > #endif /* _NF_OSF_H */ > diff --git a/include/uapi/linux/netfilter/xt_osf.h b/include/uapi/linux/netfilter/xt_osf.h > index b189007f4f28..6fe4d75b1f11 100644 > --- a/include/uapi/linux/netfilter/xt_osf.h > +++ b/include/uapi/linux/netfilter/xt_osf.h > @@ -47,13 +47,5 @@ > #define xt_osf_nlmsg nf_osf_nlmsg > > #define xt_osf_attr_type nf_osf_attr_type > -/* > - * Add/remove fingerprint from the kernel. > - */ > -enum xt_osf_msg_types { > - OSF_MSG_ADD, > - OSF_MSG_REMOVE, > - OSF_MSG_MAX, > -}; I think you're missing something like: #define xt_osf_attr_type nf_osf_attr_type here. > #endif /* _XT_OSF_H */ > diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig > index 6c65d756e603..06abc3bc05d3 100644 > --- a/net/netfilter/Kconfig > +++ b/net/netfilter/Kconfig > @@ -46,6 +46,14 @@ config NETFILTER_NETLINK_LOG > and is also scheduled to replace the old syslog-based ipt_LOG > and ip6t_LOG modules. > > +config NETFILTER_NETLINK_OSF > + tristate "Netfilter OSF over NFNETLINK interface" > + depends on NETFILTER_ADVANCED > + select NETFILTER_NETLINK > + help > + If this option is enabled, the kernel will include support > + for passive OS fingerprint via NFNETLINK. > + > config NF_CONNTRACK > tristate "Netfilter connection tracking support" > default m if NETFILTER_ADVANCED=n > @@ -1379,8 +1387,8 @@ config NETFILTER_XT_MATCH_NFACCT > > config NETFILTER_XT_MATCH_OSF > tristate '"osf" Passive OS fingerprint match' > - depends on NETFILTER_ADVANCED && NETFILTER_NETLINK > select NF_OSF > + select NETFILTER_NETLINK_OSF > help > This option selects the Passive OS Fingerprinting match module > that allows to passively match the remote operating system by > diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile > index 0b3851e825fa..ab144e65edf1 100644 > --- a/net/netfilter/Makefile > +++ b/net/netfilter/Makefile > @@ -20,6 +20,7 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o > obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o > obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o > obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o > +obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o > > # connection tracking > obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o > diff --git a/net/netfilter/nf_osf.c b/net/netfilter/nf_osf.c > index f4c75e982902..b5c3af060d62 100644 > --- a/net/netfilter/nf_osf.c > +++ b/net/netfilter/nf_osf.c > @@ -20,6 +20,13 @@ > #include <net/netfilter/nf_log.h> > #include <linux/netfilter/nf_osf.h> > > +/* > + * Indexed by dont-fragment bit. > + * It is the only constant value in the fingerprint. > + */ > +struct list_head nf_osf_fingers[2]; > +EXPORT_SYMBOL_GPL(nf_osf_fingers); > + > static inline int nf_osf_ttl(const struct sk_buff *skb, > int ttl_check, unsigned char f_ttl) > { > diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c > new file mode 100644 > index 000000000000..ba71f04a4004 > --- /dev/null > +++ b/net/netfilter/nfnetlink_osf.c > @@ -0,0 +1,134 @@ > +#include <linux/netfilter/nfnetlink.h> > +#include <linux/netfilter/nf_osf.h> > + > +static const struct nla_policy nfnl_osf_policy[OSF_ATTR_MAX + 1] = { > + [OSF_ATTR_FINGER] = { .len = sizeof(struct nf_osf_user_finger) }, > +}; > + > +static int nfnl_osf_add_callback(struct net *net, struct sock *ctnl, > + struct sk_buff *skb, const struct nlmsghdr *nlh, > + const struct nlattr * const osf_attrs[], > + struct netlink_ext_ack *extack) > +{ > + struct nf_osf_user_finger *f; > + struct nf_osf_finger *kf = NULL, *sf; > + int err = 0; > + > + if (!capable(CAP_NET_ADMIN)) > + return -EPERM; > + > + if (!osf_attrs[OSF_ATTR_FINGER]) > + return -EINVAL; > + > + if (!(nlh->nlmsg_flags & NLM_F_CREATE)) > + return -EINVAL; > + > + f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > + > + kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL); > + if (!kf) > + return -ENOMEM; > + > + memcpy(&kf->finger, f, sizeof(struct nf_osf_user_finger)); > + > + list_for_each_entry(sf, &nf_osf_fingers[!!f->df], finger_entry) { > + if (memcmp(&sf->finger, f, sizeof(struct nf_osf_user_finger))) > + continue; > + > + kfree(kf); > + kf = NULL; > + > + if (nlh->nlmsg_flags & NLM_F_EXCL) > + err = -EEXIST; > + break; > + } > + > + /* > + * We are protected by nfnl mutex. > + */ > + if (kf) > + list_add_tail_rcu(&kf->finger_entry, &nf_osf_fingers[!!f->df]); > + > + return err; > +} > + > +static int nfnl_osf_remove_callback(struct net *net, struct sock *ctnl, > + struct sk_buff *skb, > + const struct nlmsghdr *nlh, > + const struct nlattr * const osf_attrs[], > + struct netlink_ext_ack *extack) > +{ > + struct nf_osf_user_finger *f; > + struct nf_osf_finger *sf; > + int err = -ENOENT; > + > + if (!capable(CAP_NET_ADMIN)) > + return -EPERM; > + > + if (!osf_attrs[OSF_ATTR_FINGER]) > + return -EINVAL; > + > + f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > + > + list_for_each_entry(sf, &nf_osf_fingers[!!f->df], finger_entry) { > + if (memcmp(&sf->finger, f, sizeof(struct nf_osf_user_finger))) > + continue; > + > + /* > + * We are protected by nfnl mutex. > + */ > + list_del_rcu(&sf->finger_entry); > + kfree_rcu(sf, rcu_head); > + > + err = 0; > + break; > + } > + > + return err; > +} > + > +static const struct nfnl_callback nfnl_nf_osf_callbacks[OSF_MSG_MAX] = { > + [OSF_MSG_ADD] = { > + .call = nfnl_osf_add_callback, > + .attr_count = OSF_ATTR_MAX, > + .policy = nfnl_osf_policy, > + }, > + [OSF_MSG_REMOVE] = { > + .call = nfnl_osf_remove_callback, > + .attr_count = OSF_ATTR_MAX, > + .policy = nfnl_osf_policy, > + }, > +}; > + > +static const struct nfnetlink_subsystem nfnl_osf_subsys = { > + .name = "osf", > + .subsys_id = NFNL_SUBSYS_OSF, > + .cb_count = OSF_MSG_MAX, > + .cb = nfnl_nf_osf_callbacks, > +}; > + > +static int __init nfnl_osf_init(void) > +{ > + int err = -EINVAL; > + > + err = nfnetlink_subsys_register(&nfnl_osf_subsys); > + if (err < 0) { > + pr_err("Failed to register OSF nsfnetlink helper (%d)\n", err); > + goto err_out_exit; > + } > + > + return 0; > + > +err_out_exit: > + return err; > +} > + > +static void __exit nfnl_osf_fini(void) > +{ > + nfnetlink_subsys_unregister(&nfnl_osf_subsys); > +} > + > +MODULE_LICENSE("GPL"); > +MODULE_AUTHOR("Fernando Fernandez <ffmancera@riseup.net>"); > +module_init(nfnl_osf_init); > +module_exit(nfnl_osf_fini); > diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c > index 9cfef73b4107..a7dcfb9835c4 100644 > --- a/net/netfilter/xt_osf.c > +++ b/net/netfilter/xt_osf.c > @@ -37,118 +37,6 @@ > #include <net/netfilter/nf_log.h> > #include <linux/netfilter/xt_osf.h> > > -/* > - * Indexed by dont-fragment bit. > - * It is the only constant value in the fingerprint. > - */ > -static struct list_head xt_osf_fingers[2]; > - > -static const struct nla_policy xt_osf_policy[OSF_ATTR_MAX + 1] = { > - [OSF_ATTR_FINGER] = { .len = sizeof(struct xt_osf_user_finger) }, > -}; > - > -static int xt_osf_add_callback(struct net *net, struct sock *ctnl, > - struct sk_buff *skb, const struct nlmsghdr *nlh, > - const struct nlattr * const osf_attrs[], > - struct netlink_ext_ack *extack) > -{ > - struct xt_osf_user_finger *f; > - struct xt_osf_finger *kf = NULL, *sf; > - int err = 0; > - > - if (!capable(CAP_NET_ADMIN)) > - return -EPERM; > - > - if (!osf_attrs[OSF_ATTR_FINGER]) > - return -EINVAL; > - > - if (!(nlh->nlmsg_flags & NLM_F_CREATE)) > - return -EINVAL; > - > - f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > - > - kf = kmalloc(sizeof(struct xt_osf_finger), GFP_KERNEL); > - if (!kf) > - return -ENOMEM; > - > - memcpy(&kf->finger, f, sizeof(struct xt_osf_user_finger)); > - > - list_for_each_entry(sf, &xt_osf_fingers[!!f->df], finger_entry) { > - if (memcmp(&sf->finger, f, sizeof(struct xt_osf_user_finger))) > - continue; > - > - kfree(kf); > - kf = NULL; > - > - if (nlh->nlmsg_flags & NLM_F_EXCL) > - err = -EEXIST; > - break; > - } > - > - /* > - * We are protected by nfnl mutex. > - */ > - if (kf) > - list_add_tail_rcu(&kf->finger_entry, &xt_osf_fingers[!!f->df]); > - > - return err; > -} > - > -static int xt_osf_remove_callback(struct net *net, struct sock *ctnl, > - struct sk_buff *skb, > - const struct nlmsghdr *nlh, > - const struct nlattr * const osf_attrs[], > - struct netlink_ext_ack *extack) > -{ > - struct xt_osf_user_finger *f; > - struct xt_osf_finger *sf; > - int err = -ENOENT; > - > - if (!capable(CAP_NET_ADMIN)) > - return -EPERM; > - > - if (!osf_attrs[OSF_ATTR_FINGER]) > - return -EINVAL; > - > - f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > - > - list_for_each_entry(sf, &xt_osf_fingers[!!f->df], finger_entry) { > - if (memcmp(&sf->finger, f, sizeof(struct xt_osf_user_finger))) > - continue; > - > - /* > - * We are protected by nfnl mutex. > - */ > - list_del_rcu(&sf->finger_entry); > - kfree_rcu(sf, rcu_head); > - > - err = 0; > - break; > - } > - > - return err; > -} > - > -static const struct nfnl_callback xt_osf_nfnetlink_callbacks[OSF_MSG_MAX] = { > - [OSF_MSG_ADD] = { > - .call = xt_osf_add_callback, > - .attr_count = OSF_ATTR_MAX, > - .policy = xt_osf_policy, > - }, > - [OSF_MSG_REMOVE] = { > - .call = xt_osf_remove_callback, > - .attr_count = OSF_ATTR_MAX, > - .policy = xt_osf_policy, > - }, > -}; > - > -static const struct nfnetlink_subsystem xt_osf_nfnetlink = { > - .name = "osf", > - .subsys_id = NFNL_SUBSYS_OSF, > - .cb_count = OSF_MSG_MAX, > - .cb = xt_osf_nfnetlink_callbacks, > -}; > - > static bool > xt_osf_match_packet(const struct sk_buff *skb, struct xt_action_param *p) > { > @@ -159,7 +47,7 @@ xt_osf_match_packet(const struct sk_buff *skb, struct xt_action_param *p) > return false; > > return nf_osf_match(skb, xt_family(p), xt_hooknum(p), xt_in(p), > - xt_out(p), info, net, xt_osf_fingers); > + xt_out(p), info, net, nf_osf_fingers); > } > > static struct xt_match xt_osf_match = { > @@ -180,26 +68,18 @@ static int __init xt_osf_init(void) > int err = -EINVAL; > int i; > > - for (i=0; i<ARRAY_SIZE(xt_osf_fingers); ++i) > - INIT_LIST_HEAD(&xt_osf_fingers[i]); > - > - err = nfnetlink_subsys_register(&xt_osf_nfnetlink); > - if (err < 0) { > - pr_err("Failed to register OSF nsfnetlink helper (%d)\n", err); > - goto err_out_exit; > - } > + for (i = 0; i < ARRAY_SIZE(nf_osf_fingers); ++i) > + INIT_LIST_HEAD(&nf_osf_fingers[i]); Please, do this initialization from nfnetlink_osf. > err = xt_register_match(&xt_osf_match); > if (err) { > pr_err("Failed to register OS fingerprint " > "matching module (%d)\n", err); > - goto err_out_remove; > + goto err_out_exit; > } > > return 0; > > -err_out_remove: > - nfnetlink_subsys_unregister(&xt_osf_nfnetlink); > err_out_exit: > return err; > } > @@ -209,13 +89,12 @@ static void __exit xt_osf_fini(void) > struct xt_osf_finger *f; > int i; > > - nfnetlink_subsys_unregister(&xt_osf_nfnetlink); > xt_unregister_match(&xt_osf_match); > > rcu_read_lock(); > - for (i=0; i<ARRAY_SIZE(xt_osf_fingers); ++i) { > + for (i = 0; i < ARRAY_SIZE(nf_osf_fingers); ++i) { > > - list_for_each_entry_rcu(f, &xt_osf_fingers[i], finger_entry) { > + list_for_each_entry_rcu(f, &nf_osf_fingers[i], finger_entry) { > list_del_rcu(&f->finger_entry); > kfree_rcu(f, rcu_head); > } This for loop should go to nfnetlink too. Thanks. -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Tue, Jul 17, 2018 at 07:25:17PM +0200, Fernando Fernandez Mancera wrote: > Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> > --- > include/linux/netfilter/nf_osf.h | 2 + > include/uapi/linux/netfilter/nf_osf.h | 5 + > include/uapi/linux/netfilter/xt_osf.h | 8 -- > net/netfilter/Kconfig | 10 +- > net/netfilter/Makefile | 1 + > net/netfilter/nf_osf.c | 7 ++ > net/netfilter/nfnetlink_osf.c | 134 ++++++++++++++++++++++++++ BTW, could you make an initial patch to rename nf_osf.c to nfnetlink_osf.c and then add this new code to it. I don't think we need two separated modules nf_osf and nfnetlink_osf, with one single module should be good. So patchset should look like: 1) Rename net/netfilter/nf_osf.c to net/netfilter/nfnetlink_osf.c, same with header file and don't forget about the Kconfig and Makefile bits. 2) Extract nfnetlink_subsystem code from xt_osf.c to nfnetlink_osf.c 3) Add nft_osf.c :-) OK? -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/include/linux/netfilter/nf_osf.h b/include/linux/netfilter/nf_osf.h index 7d0947d6ef16..3411c87152d7 100644 --- a/include/linux/netfilter/nf_osf.h +++ b/include/linux/netfilter/nf_osf.h @@ -27,6 +27,8 @@ struct nf_osf_finger { struct nf_osf_user_finger finger; }; +extern struct list_head nf_osf_fingers[2]; + bool nf_osf_match(const struct sk_buff *skb, u_int8_t family, int hooknum, struct net_device *in, struct net_device *out, const struct nf_osf_info *info, struct net *net, diff --git a/include/uapi/linux/netfilter/nf_osf.h b/include/uapi/linux/netfilter/nf_osf.h index a89583099b2a..18516829fce1 100644 --- a/include/uapi/linux/netfilter/nf_osf.h +++ b/include/uapi/linux/netfilter/nf_osf.h @@ -96,4 +96,9 @@ enum nf_osf_attr_type { OSF_ATTR_MAX, }; +enum nf_osf_msg_types { + OSF_MSG_ADD, + OSF_MSG_REMOVE, + OSF_MSG_MAX, +}; #endif /* _NF_OSF_H */ diff --git a/include/uapi/linux/netfilter/xt_osf.h b/include/uapi/linux/netfilter/xt_osf.h index b189007f4f28..6fe4d75b1f11 100644 --- a/include/uapi/linux/netfilter/xt_osf.h +++ b/include/uapi/linux/netfilter/xt_osf.h @@ -47,13 +47,5 @@ #define xt_osf_nlmsg nf_osf_nlmsg #define xt_osf_attr_type nf_osf_attr_type -/* - * Add/remove fingerprint from the kernel. - */ -enum xt_osf_msg_types { - OSF_MSG_ADD, - OSF_MSG_REMOVE, - OSF_MSG_MAX, -}; #endif /* _XT_OSF_H */ diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 6c65d756e603..06abc3bc05d3 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -46,6 +46,14 @@ config NETFILTER_NETLINK_LOG and is also scheduled to replace the old syslog-based ipt_LOG and ip6t_LOG modules. +config NETFILTER_NETLINK_OSF + tristate "Netfilter OSF over NFNETLINK interface" + depends on NETFILTER_ADVANCED + select NETFILTER_NETLINK + help + If this option is enabled, the kernel will include support + for passive OS fingerprint via NFNETLINK. + config NF_CONNTRACK tristate "Netfilter connection tracking support" default m if NETFILTER_ADVANCED=n @@ -1379,8 +1387,8 @@ config NETFILTER_XT_MATCH_NFACCT config NETFILTER_XT_MATCH_OSF tristate '"osf" Passive OS fingerprint match' - depends on NETFILTER_ADVANCED && NETFILTER_NETLINK select NF_OSF + select NETFILTER_NETLINK_OSF help This option selects the Passive OS Fingerprinting match module that allows to passively match the remote operating system by diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 0b3851e825fa..ab144e65edf1 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o obj-$(CONFIG_NETFILTER_NETLINK_ACCT) += nfnetlink_acct.o obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o +obj-$(CONFIG_NETFILTER_NETLINK_OSF) += nfnetlink_osf.o # connection tracking obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o diff --git a/net/netfilter/nf_osf.c b/net/netfilter/nf_osf.c index f4c75e982902..b5c3af060d62 100644 --- a/net/netfilter/nf_osf.c +++ b/net/netfilter/nf_osf.c @@ -20,6 +20,13 @@ #include <net/netfilter/nf_log.h> #include <linux/netfilter/nf_osf.h> +/* + * Indexed by dont-fragment bit. + * It is the only constant value in the fingerprint. + */ +struct list_head nf_osf_fingers[2]; +EXPORT_SYMBOL_GPL(nf_osf_fingers); + static inline int nf_osf_ttl(const struct sk_buff *skb, int ttl_check, unsigned char f_ttl) { diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c new file mode 100644 index 000000000000..ba71f04a4004 --- /dev/null +++ b/net/netfilter/nfnetlink_osf.c @@ -0,0 +1,134 @@ +#include <linux/netfilter/nfnetlink.h> +#include <linux/netfilter/nf_osf.h> + +static const struct nla_policy nfnl_osf_policy[OSF_ATTR_MAX + 1] = { + [OSF_ATTR_FINGER] = { .len = sizeof(struct nf_osf_user_finger) }, +}; + +static int nfnl_osf_add_callback(struct net *net, struct sock *ctnl, + struct sk_buff *skb, const struct nlmsghdr *nlh, + const struct nlattr * const osf_attrs[], + struct netlink_ext_ack *extack) +{ + struct nf_osf_user_finger *f; + struct nf_osf_finger *kf = NULL, *sf; + int err = 0; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (!osf_attrs[OSF_ATTR_FINGER]) + return -EINVAL; + + if (!(nlh->nlmsg_flags & NLM_F_CREATE)) + return -EINVAL; + + f = nla_data(osf_attrs[OSF_ATTR_FINGER]); + + kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL); + if (!kf) + return -ENOMEM; + + memcpy(&kf->finger, f, sizeof(struct nf_osf_user_finger)); + + list_for_each_entry(sf, &nf_osf_fingers[!!f->df], finger_entry) { + if (memcmp(&sf->finger, f, sizeof(struct nf_osf_user_finger))) + continue; + + kfree(kf); + kf = NULL; + + if (nlh->nlmsg_flags & NLM_F_EXCL) + err = -EEXIST; + break; + } + + /* + * We are protected by nfnl mutex. + */ + if (kf) + list_add_tail_rcu(&kf->finger_entry, &nf_osf_fingers[!!f->df]); + + return err; +} + +static int nfnl_osf_remove_callback(struct net *net, struct sock *ctnl, + struct sk_buff *skb, + const struct nlmsghdr *nlh, + const struct nlattr * const osf_attrs[], + struct netlink_ext_ack *extack) +{ + struct nf_osf_user_finger *f; + struct nf_osf_finger *sf; + int err = -ENOENT; + + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + + if (!osf_attrs[OSF_ATTR_FINGER]) + return -EINVAL; + + f = nla_data(osf_attrs[OSF_ATTR_FINGER]); + + list_for_each_entry(sf, &nf_osf_fingers[!!f->df], finger_entry) { + if (memcmp(&sf->finger, f, sizeof(struct nf_osf_user_finger))) + continue; + + /* + * We are protected by nfnl mutex. + */ + list_del_rcu(&sf->finger_entry); + kfree_rcu(sf, rcu_head); + + err = 0; + break; + } + + return err; +} + +static const struct nfnl_callback nfnl_nf_osf_callbacks[OSF_MSG_MAX] = { + [OSF_MSG_ADD] = { + .call = nfnl_osf_add_callback, + .attr_count = OSF_ATTR_MAX, + .policy = nfnl_osf_policy, + }, + [OSF_MSG_REMOVE] = { + .call = nfnl_osf_remove_callback, + .attr_count = OSF_ATTR_MAX, + .policy = nfnl_osf_policy, + }, +}; + +static const struct nfnetlink_subsystem nfnl_osf_subsys = { + .name = "osf", + .subsys_id = NFNL_SUBSYS_OSF, + .cb_count = OSF_MSG_MAX, + .cb = nfnl_nf_osf_callbacks, +}; + +static int __init nfnl_osf_init(void) +{ + int err = -EINVAL; + + err = nfnetlink_subsys_register(&nfnl_osf_subsys); + if (err < 0) { + pr_err("Failed to register OSF nsfnetlink helper (%d)\n", err); + goto err_out_exit; + } + + return 0; + +err_out_exit: + return err; +} + +static void __exit nfnl_osf_fini(void) +{ + nfnetlink_subsys_unregister(&nfnl_osf_subsys); +} + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Fernando Fernandez <ffmancera@riseup.net>"); +module_init(nfnl_osf_init); +module_exit(nfnl_osf_fini); diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c index 9cfef73b4107..a7dcfb9835c4 100644 --- a/net/netfilter/xt_osf.c +++ b/net/netfilter/xt_osf.c @@ -37,118 +37,6 @@ #include <net/netfilter/nf_log.h> #include <linux/netfilter/xt_osf.h> -/* - * Indexed by dont-fragment bit. - * It is the only constant value in the fingerprint. - */ -static struct list_head xt_osf_fingers[2]; - -static const struct nla_policy xt_osf_policy[OSF_ATTR_MAX + 1] = { - [OSF_ATTR_FINGER] = { .len = sizeof(struct xt_osf_user_finger) }, -}; - -static int xt_osf_add_callback(struct net *net, struct sock *ctnl, - struct sk_buff *skb, const struct nlmsghdr *nlh, - const struct nlattr * const osf_attrs[], - struct netlink_ext_ack *extack) -{ - struct xt_osf_user_finger *f; - struct xt_osf_finger *kf = NULL, *sf; - int err = 0; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - if (!osf_attrs[OSF_ATTR_FINGER]) - return -EINVAL; - - if (!(nlh->nlmsg_flags & NLM_F_CREATE)) - return -EINVAL; - - f = nla_data(osf_attrs[OSF_ATTR_FINGER]); - - kf = kmalloc(sizeof(struct xt_osf_finger), GFP_KERNEL); - if (!kf) - return -ENOMEM; - - memcpy(&kf->finger, f, sizeof(struct xt_osf_user_finger)); - - list_for_each_entry(sf, &xt_osf_fingers[!!f->df], finger_entry) { - if (memcmp(&sf->finger, f, sizeof(struct xt_osf_user_finger))) - continue; - - kfree(kf); - kf = NULL; - - if (nlh->nlmsg_flags & NLM_F_EXCL) - err = -EEXIST; - break; - } - - /* - * We are protected by nfnl mutex. - */ - if (kf) - list_add_tail_rcu(&kf->finger_entry, &xt_osf_fingers[!!f->df]); - - return err; -} - -static int xt_osf_remove_callback(struct net *net, struct sock *ctnl, - struct sk_buff *skb, - const struct nlmsghdr *nlh, - const struct nlattr * const osf_attrs[], - struct netlink_ext_ack *extack) -{ - struct xt_osf_user_finger *f; - struct xt_osf_finger *sf; - int err = -ENOENT; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - if (!osf_attrs[OSF_ATTR_FINGER]) - return -EINVAL; - - f = nla_data(osf_attrs[OSF_ATTR_FINGER]); - - list_for_each_entry(sf, &xt_osf_fingers[!!f->df], finger_entry) { - if (memcmp(&sf->finger, f, sizeof(struct xt_osf_user_finger))) - continue; - - /* - * We are protected by nfnl mutex. - */ - list_del_rcu(&sf->finger_entry); - kfree_rcu(sf, rcu_head); - - err = 0; - break; - } - - return err; -} - -static const struct nfnl_callback xt_osf_nfnetlink_callbacks[OSF_MSG_MAX] = { - [OSF_MSG_ADD] = { - .call = xt_osf_add_callback, - .attr_count = OSF_ATTR_MAX, - .policy = xt_osf_policy, - }, - [OSF_MSG_REMOVE] = { - .call = xt_osf_remove_callback, - .attr_count = OSF_ATTR_MAX, - .policy = xt_osf_policy, - }, -}; - -static const struct nfnetlink_subsystem xt_osf_nfnetlink = { - .name = "osf", - .subsys_id = NFNL_SUBSYS_OSF, - .cb_count = OSF_MSG_MAX, - .cb = xt_osf_nfnetlink_callbacks, -}; - static bool xt_osf_match_packet(const struct sk_buff *skb, struct xt_action_param *p) { @@ -159,7 +47,7 @@ xt_osf_match_packet(const struct sk_buff *skb, struct xt_action_param *p) return false; return nf_osf_match(skb, xt_family(p), xt_hooknum(p), xt_in(p), - xt_out(p), info, net, xt_osf_fingers); + xt_out(p), info, net, nf_osf_fingers); } static struct xt_match xt_osf_match = { @@ -180,26 +68,18 @@ static int __init xt_osf_init(void) int err = -EINVAL; int i; - for (i=0; i<ARRAY_SIZE(xt_osf_fingers); ++i) - INIT_LIST_HEAD(&xt_osf_fingers[i]); - - err = nfnetlink_subsys_register(&xt_osf_nfnetlink); - if (err < 0) { - pr_err("Failed to register OSF nsfnetlink helper (%d)\n", err); - goto err_out_exit; - } + for (i = 0; i < ARRAY_SIZE(nf_osf_fingers); ++i) + INIT_LIST_HEAD(&nf_osf_fingers[i]); err = xt_register_match(&xt_osf_match); if (err) { pr_err("Failed to register OS fingerprint " "matching module (%d)\n", err); - goto err_out_remove; + goto err_out_exit; } return 0; -err_out_remove: - nfnetlink_subsys_unregister(&xt_osf_nfnetlink); err_out_exit: return err; } @@ -209,13 +89,12 @@ static void __exit xt_osf_fini(void) struct xt_osf_finger *f; int i; - nfnetlink_subsys_unregister(&xt_osf_nfnetlink); xt_unregister_match(&xt_osf_match); rcu_read_lock(); - for (i=0; i<ARRAY_SIZE(xt_osf_fingers); ++i) { + for (i = 0; i < ARRAY_SIZE(nf_osf_fingers); ++i) { - list_for_each_entry_rcu(f, &xt_osf_fingers[i], finger_entry) { + list_for_each_entry_rcu(f, &nf_osf_fingers[i], finger_entry) { list_del_rcu(&f->finger_entry); kfree_rcu(f, rcu_head); }
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> --- include/linux/netfilter/nf_osf.h | 2 + include/uapi/linux/netfilter/nf_osf.h | 5 + include/uapi/linux/netfilter/xt_osf.h | 8 -- net/netfilter/Kconfig | 10 +- net/netfilter/Makefile | 1 + net/netfilter/nf_osf.c | 7 ++ net/netfilter/nfnetlink_osf.c | 134 ++++++++++++++++++++++++++ net/netfilter/xt_osf.c | 133 ++----------------------- 8 files changed, 164 insertions(+), 136 deletions(-) create mode 100644 net/netfilter/nfnetlink_osf.c