This populates xt_nfnetlink.c with support for NFXTM_IDENTIFY. Right now that just returns a freeform string but eventually shall dump all the match and target modules' info. Signed-off-by: Jan Engelhardt <jengelh@xxxxxxx> --- include/uapi/linux/netfilter/Kbuild | 1 + include/uapi/linux/netfilter/nfnetlink.h | 3 +- include/uapi/linux/netfilter/nfnetlink_xtables.h | 27 ++++ net/netfilter/Makefile | 3 +- net/netfilter/xt_core.c | 14 +- net/netfilter/xt_nfnetlink.c | 156 ++++++++++++++++++++++ net/netfilter/xt_nfnetlink.h | 7 + 7 files changed, 208 insertions(+), 3 deletions(-) create mode 100644 include/uapi/linux/netfilter/nfnetlink_xtables.h create mode 100644 net/netfilter/xt_nfnetlink.c create mode 100644 net/netfilter/xt_nfnetlink.h diff --git a/include/uapi/linux/netfilter/Kbuild b/include/uapi/linux/netfilter/Kbuild index 08f555f..edd789c 100644 --- a/include/uapi/linux/netfilter/Kbuild +++ b/include/uapi/linux/netfilter/Kbuild @@ -14,6 +14,7 @@ header-y += nfnetlink_cthelper.h header-y += nfnetlink_cttimeout.h header-y += nfnetlink_log.h header-y += nfnetlink_queue.h +header-y += nfnetlink_xtables.h header-y += x_tables.h header-y += xt_AUDIT.h header-y += xt_CHECKSUM.h diff --git a/include/uapi/linux/netfilter/nfnetlink.h b/include/uapi/linux/netfilter/nfnetlink.h index 4a4efaf..d5c3f68 100644 --- a/include/uapi/linux/netfilter/nfnetlink.h +++ b/include/uapi/linux/netfilter/nfnetlink.h @@ -51,6 +51,7 @@ struct nfgenmsg { #define NFNL_SUBSYS_ACCT 7 #define NFNL_SUBSYS_CTNETLINK_TIMEOUT 8 #define NFNL_SUBSYS_CTHELPER 9 -#define NFNL_SUBSYS_COUNT 10 +#define NFNL_SUBSYS_XTABLES 10 +#define NFNL_SUBSYS_COUNT 11 #endif /* _UAPI_NFNETLINK_H */ diff --git a/include/uapi/linux/netfilter/nfnetlink_xtables.h b/include/uapi/linux/netfilter/nfnetlink_xtables.h new file mode 100644 index 0000000..a548394 --- /dev/null +++ b/include/uapi/linux/netfilter/nfnetlink_xtables.h @@ -0,0 +1,27 @@ +#ifndef _LINUX_NFNETLINK_XTABLES_H +#define _LINUX_NFNETLINK_XTABLES_H 1 + +/** + * %NFXTM_IDENTIFY: multifunction debug command to inquire about xt2 + * properties (e.g. match size) + */ +enum nfxt_msg_type { + NFXTM_IDENTIFY = 1, +}; + +/** + * %NFXTA_NAME: name of the object being operated on + */ +enum nfxt_attr_type { + NFXTA_UNSPEC = 0, + NFXTA_NAME, +}; + +/** + * %NFXTE_SUCCESS: the operation completed successfully + */ +enum nfxt_errno { + NFXTE_SUCCESS = 0, +}; + +#endif /* _LINUX_NFNETLINK_XTABLES_H */ diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 00eab5c..cf716f4 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -65,7 +65,8 @@ obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o # generic X tables obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o -obj-$(CONFIG_NETFILTER_XTABLES2) += xt_core.o +obj-$(CONFIG_NETFILTER_XTABLES2) += xtables2.o +xtables2-y := xt_core.o xt_nfnetlink.o # combos obj-$(CONFIG_NETFILTER_XT_MARK) += xt_mark.o diff --git a/net/netfilter/xt_core.c b/net/netfilter/xt_core.c index 89dd0a0..24c418b 100644 --- a/net/netfilter/xt_core.c +++ b/net/netfilter/xt_core.c @@ -15,6 +15,7 @@ #include <net/net_namespace.h> #include <net/netns/generic.h> #include <net/netfilter/xt_core.h> +#include "xt_nfnetlink.h" MODULE_DESCRIPTION("Netfilter Xtables2 packet filtering"); MODULE_AUTHOR("Jan Engelhardt"); @@ -72,12 +73,23 @@ static struct pernet_operations xtables2_pernet_ops = { static int __init xtables2_init(void) { + int ret; + pr_info("Xtables2, (C) 2009-2012, J.Engelhardt\n"); - return register_pernet_subsys(&xtables2_pernet_ops); + ret = register_pernet_subsys(&xtables2_pernet_ops); + if (ret < 0) + return ret; + ret = xtnetlink_init(); + if (ret < 0) { + unregister_pernet_subsys(&xtables2_pernet_ops); + return ret; + } + return 0; } static void __exit xtables2_exit(void) { + xtnetlink_exit(); unregister_pernet_subsys(&xtables2_pernet_ops); } diff --git a/net/netfilter/xt_nfnetlink.c b/net/netfilter/xt_nfnetlink.c new file mode 100644 index 0000000..8a58bb8 --- /dev/null +++ b/net/netfilter/xt_nfnetlink.c @@ -0,0 +1,156 @@ +/* + * Xtables2 nfnetlink interface + * Copyright © Jan Engelhardt, 2010-2012 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + */ +#include <linux/err.h> +#include <linux/errno.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/netlink.h> +#include <linux/skbuff.h> +#include <linux/netfilter.h> +#include <linux/netfilter/nfnetlink.h> +#include <linux/netfilter/nfnetlink_xtables.h> +#include <net/netlink.h> +#include <net/netfilter/xt_core.h> +#include "xt_nfnetlink.h" + +#define MAKE_TAGGED_TYPE(x) ((x) | (NFNL_SUBSYS_XTABLES << 8)) + +/** + * Something to keep all the pointers that NL gives us in one place. + * You need quite a lot of variables to construct and send out a packet... + */ +struct xtnetlink_pktref { + union { + struct sk_buff *skb; + const struct sk_buff *c_skb; + }; + union { + struct nlmsghdr *msg; + const struct nlmsghdr *c_msg; + }; + struct sock *sock; +}; + +/** + * @skb: outgoing skb + * @old: pointers to the original incoming skb/nl headers + * @flags: extra flags to set in nlmsg + * + * Fill an skb (for outgoing direction) with NL and NFNL headers, using data + * from the original skb for initialization. + */ +static struct nlmsghdr * +xtnetlink_fill(struct sk_buff *skb, const struct xtnetlink_pktref *old, + unsigned int flags) +{ + uint16_t type = NFNL_MSG_TYPE(old->msg->nlmsg_type); + struct nlmsghdr *nlmsg; + struct nfgenmsg *hdr; + + nlmsg = nlmsg_put(skb, NETLINK_CB(old->skb).portid, + old->msg->nlmsg_seq, MAKE_TAGGED_TYPE(type), + sizeof(*hdr), flags); + if (nlmsg == NULL) { + nlmsg_cancel(skb, nlmsg); + return ERR_PTR(-ENOBUFS); + } + + hdr = nlmsg_data(nlmsg); + hdr->nfgen_family = NFPROTO_UNSPEC; + hdr->version = NFNETLINK_V0; + hdr->res_id = 0; + return nlmsg; +} + +/** + * Ran too often into NULL derefs. Now there is a dummy function for unused + * message type 0. + */ +static int +xtnetlink_ignore(struct sock *k, struct sk_buff *s, + const struct nlmsghdr *n, const struct nlattr *const *a) +{ + return -ENXIO; +} + +/** + * Respond to a %NFXTM_IDENTIFY inquiry. Reports the Xtables2 version (for + * now), and in future the extension info. + */ +static int +xtnetlink_identify2(struct sk_buff *skb, struct netlink_callback *nl_cb) +{ + struct xtnetlink_pktref ref = {.c_skb = skb, .c_msg = nl_cb->nlh}; + struct nlmsghdr *nlmsg = NULL; + + switch (nl_cb->args[0]) { + case 0: + nlmsg = xtnetlink_fill(skb, &ref, NLM_F_MULTI); + if (IS_ERR(nlmsg)) + return 0; + if (nla_put_string(skb, NFXTA_NAME, "Xtables2-xtnl/nfnl") != 0) + goto nla_put_failure; + ++nl_cb->args[0]; + break; + } + if (nlmsg != NULL) + nlmsg_end(skb, nlmsg); + return skb->len; + nla_put_failure: + return 0; +} + +static int +xtnetlink_identify(struct sock *xtnl, struct sk_buff *iskb, + const struct nlmsghdr *imsg, const struct nlattr *const *ad) +{ + static struct netlink_dump_control ctl __read_mostly = { + .dump = xtnetlink_identify2, + .module = THIS_MODULE, + }; + return netlink_dump_start(xtnl, iskb, imsg, &ctl); +} + +static const struct nla_policy xtnetlink_policy[] = { + [NFXTA_NAME] = {.type = NLA_NUL_STRING}, +}; + +/* + * Use the same policy for all messages. I do not want to see EINVAL anytime + * soon again just because I forgot sending an attribute from userspace. + * (If such occurs, it will be dealt with %NFXTE_ATTRSET_INCOMPLETE, tbd.) + */ +#define pol \ + .policy = xtnetlink_policy, \ + .attr_count = ARRAY_SIZE(xtnetlink_policy) +static const struct nfnl_callback xtnetlink_callback[] = { + [0] = {.call = xtnetlink_ignore}, + [NFXTM_IDENTIFY] = {.call = xtnetlink_identify, pol}, +}; +#undef pol + +static const struct nfnetlink_subsystem xtnetlink_subsys = { + .name = "xtables", + .subsys_id = NFNL_SUBSYS_XTABLES, + .cb = xtnetlink_callback, + .cb_count = ARRAY_SIZE(xtnetlink_callback), +}; + +int __init xtnetlink_init(void) +{ + return nfnetlink_subsys_register(&xtnetlink_subsys); +} + +void __exit xtnetlink_exit(void) +{ + nfnetlink_subsys_unregister(&xtnetlink_subsys); +} + +MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_XTABLES); diff --git a/net/netfilter/xt_nfnetlink.h b/net/netfilter/xt_nfnetlink.h new file mode 100644 index 0000000..f8ed87f --- /dev/null +++ b/net/netfilter/xt_nfnetlink.h @@ -0,0 +1,7 @@ +#ifndef XT_NFNETLINK_H +#define XT_NFNETLINK_H 1 + +extern int xtnetlink_init(void); +extern void xtnetlink_exit(void); + +#endif /* XT_NFNETLINK_H */ -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html