Back to home page

OSCL-LXR

 
 

    


0001 /* Netfilter messages via netlink socket. Allows for user space
0002  * protocol helpers and general trouble making from userspace.
0003  *
0004  * (C) 2001 by Jay Schulist <jschlst@samba.org>,
0005  * (C) 2002-2005 by Harald Welte <laforge@gnumonks.org>
0006  * (C) 2005-2017 by Pablo Neira Ayuso <pablo@netfilter.org>
0007  *
0008  * Initial netfilter messages via netlink development funded and
0009  * generally made possible by Network Robots, Inc. (www.networkrobots.com)
0010  *
0011  * Further development of this code funded by Astaro AG (http://www.astaro.com)
0012  *
0013  * This software may be used and distributed according to the terms
0014  * of the GNU General Public License, incorporated herein by reference.
0015  */
0016 
0017 #include <linux/module.h>
0018 #include <linux/types.h>
0019 #include <linux/socket.h>
0020 #include <linux/kernel.h>
0021 #include <linux/string.h>
0022 #include <linux/sockios.h>
0023 #include <linux/net.h>
0024 #include <linux/skbuff.h>
0025 #include <linux/uaccess.h>
0026 #include <net/sock.h>
0027 #include <linux/init.h>
0028 #include <linux/sched/signal.h>
0029 
0030 #include <net/netlink.h>
0031 #include <net/netns/generic.h>
0032 #include <linux/netfilter/nfnetlink.h>
0033 
0034 MODULE_LICENSE("GPL");
0035 MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
0036 MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NETFILTER);
0037 MODULE_DESCRIPTION("Netfilter messages via netlink socket");
0038 
0039 #define nfnl_dereference_protected(id) \
0040     rcu_dereference_protected(table[(id)].subsys, \
0041                   lockdep_nfnl_is_held((id)))
0042 
0043 #define NFNL_MAX_ATTR_COUNT 32
0044 
0045 static unsigned int nfnetlink_pernet_id __read_mostly;
0046 
0047 #ifdef CONFIG_NF_CONNTRACK_EVENTS
0048 static DEFINE_SPINLOCK(nfnl_grp_active_lock);
0049 #endif
0050 
0051 struct nfnl_net {
0052     struct sock *nfnl;
0053 };
0054 
0055 static struct {
0056     struct mutex                mutex;
0057     const struct nfnetlink_subsystem __rcu  *subsys;
0058 } table[NFNL_SUBSYS_COUNT];
0059 
0060 static struct lock_class_key nfnl_lockdep_keys[NFNL_SUBSYS_COUNT];
0061 
0062 static const char *const nfnl_lockdep_names[NFNL_SUBSYS_COUNT] = {
0063     [NFNL_SUBSYS_NONE] = "nfnl_subsys_none",
0064     [NFNL_SUBSYS_CTNETLINK] = "nfnl_subsys_ctnetlink",
0065     [NFNL_SUBSYS_CTNETLINK_EXP] = "nfnl_subsys_ctnetlink_exp",
0066     [NFNL_SUBSYS_QUEUE] = "nfnl_subsys_queue",
0067     [NFNL_SUBSYS_ULOG] = "nfnl_subsys_ulog",
0068     [NFNL_SUBSYS_OSF] = "nfnl_subsys_osf",
0069     [NFNL_SUBSYS_IPSET] = "nfnl_subsys_ipset",
0070     [NFNL_SUBSYS_ACCT] = "nfnl_subsys_acct",
0071     [NFNL_SUBSYS_CTNETLINK_TIMEOUT] = "nfnl_subsys_cttimeout",
0072     [NFNL_SUBSYS_CTHELPER] = "nfnl_subsys_cthelper",
0073     [NFNL_SUBSYS_NFTABLES] = "nfnl_subsys_nftables",
0074     [NFNL_SUBSYS_NFT_COMPAT] = "nfnl_subsys_nftcompat",
0075     [NFNL_SUBSYS_HOOK] = "nfnl_subsys_hook",
0076 };
0077 
0078 static const int nfnl_group2type[NFNLGRP_MAX+1] = {
0079     [NFNLGRP_CONNTRACK_NEW]     = NFNL_SUBSYS_CTNETLINK,
0080     [NFNLGRP_CONNTRACK_UPDATE]  = NFNL_SUBSYS_CTNETLINK,
0081     [NFNLGRP_CONNTRACK_DESTROY] = NFNL_SUBSYS_CTNETLINK,
0082     [NFNLGRP_CONNTRACK_EXP_NEW] = NFNL_SUBSYS_CTNETLINK_EXP,
0083     [NFNLGRP_CONNTRACK_EXP_UPDATE]  = NFNL_SUBSYS_CTNETLINK_EXP,
0084     [NFNLGRP_CONNTRACK_EXP_DESTROY] = NFNL_SUBSYS_CTNETLINK_EXP,
0085     [NFNLGRP_NFTABLES]      = NFNL_SUBSYS_NFTABLES,
0086     [NFNLGRP_ACCT_QUOTA]        = NFNL_SUBSYS_ACCT,
0087     [NFNLGRP_NFTRACE]       = NFNL_SUBSYS_NFTABLES,
0088 };
0089 
0090 static struct nfnl_net *nfnl_pernet(struct net *net)
0091 {
0092     return net_generic(net, nfnetlink_pernet_id);
0093 }
0094 
0095 void nfnl_lock(__u8 subsys_id)
0096 {
0097     mutex_lock(&table[subsys_id].mutex);
0098 }
0099 EXPORT_SYMBOL_GPL(nfnl_lock);
0100 
0101 void nfnl_unlock(__u8 subsys_id)
0102 {
0103     mutex_unlock(&table[subsys_id].mutex);
0104 }
0105 EXPORT_SYMBOL_GPL(nfnl_unlock);
0106 
0107 #ifdef CONFIG_PROVE_LOCKING
0108 bool lockdep_nfnl_is_held(u8 subsys_id)
0109 {
0110     return lockdep_is_held(&table[subsys_id].mutex);
0111 }
0112 EXPORT_SYMBOL_GPL(lockdep_nfnl_is_held);
0113 #endif
0114 
0115 int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
0116 {
0117     u8 cb_id;
0118 
0119     /* Sanity-check attr_count size to avoid stack buffer overflow. */
0120     for (cb_id = 0; cb_id < n->cb_count; cb_id++)
0121         if (WARN_ON(n->cb[cb_id].attr_count > NFNL_MAX_ATTR_COUNT))
0122             return -EINVAL;
0123 
0124     nfnl_lock(n->subsys_id);
0125     if (table[n->subsys_id].subsys) {
0126         nfnl_unlock(n->subsys_id);
0127         return -EBUSY;
0128     }
0129     rcu_assign_pointer(table[n->subsys_id].subsys, n);
0130     nfnl_unlock(n->subsys_id);
0131 
0132     return 0;
0133 }
0134 EXPORT_SYMBOL_GPL(nfnetlink_subsys_register);
0135 
0136 int nfnetlink_subsys_unregister(const struct nfnetlink_subsystem *n)
0137 {
0138     nfnl_lock(n->subsys_id);
0139     table[n->subsys_id].subsys = NULL;
0140     nfnl_unlock(n->subsys_id);
0141     synchronize_rcu();
0142     return 0;
0143 }
0144 EXPORT_SYMBOL_GPL(nfnetlink_subsys_unregister);
0145 
0146 static inline const struct nfnetlink_subsystem *nfnetlink_get_subsys(u16 type)
0147 {
0148     u8 subsys_id = NFNL_SUBSYS_ID(type);
0149 
0150     if (subsys_id >= NFNL_SUBSYS_COUNT)
0151         return NULL;
0152 
0153     return rcu_dereference(table[subsys_id].subsys);
0154 }
0155 
0156 static inline const struct nfnl_callback *
0157 nfnetlink_find_client(u16 type, const struct nfnetlink_subsystem *ss)
0158 {
0159     u8 cb_id = NFNL_MSG_TYPE(type);
0160 
0161     if (cb_id >= ss->cb_count)
0162         return NULL;
0163 
0164     return &ss->cb[cb_id];
0165 }
0166 
0167 int nfnetlink_has_listeners(struct net *net, unsigned int group)
0168 {
0169     struct nfnl_net *nfnlnet = nfnl_pernet(net);
0170 
0171     return netlink_has_listeners(nfnlnet->nfnl, group);
0172 }
0173 EXPORT_SYMBOL_GPL(nfnetlink_has_listeners);
0174 
0175 int nfnetlink_send(struct sk_buff *skb, struct net *net, u32 portid,
0176            unsigned int group, int echo, gfp_t flags)
0177 {
0178     struct nfnl_net *nfnlnet = nfnl_pernet(net);
0179 
0180     return nlmsg_notify(nfnlnet->nfnl, skb, portid, group, echo, flags);
0181 }
0182 EXPORT_SYMBOL_GPL(nfnetlink_send);
0183 
0184 int nfnetlink_set_err(struct net *net, u32 portid, u32 group, int error)
0185 {
0186     struct nfnl_net *nfnlnet = nfnl_pernet(net);
0187 
0188     return netlink_set_err(nfnlnet->nfnl, portid, group, error);
0189 }
0190 EXPORT_SYMBOL_GPL(nfnetlink_set_err);
0191 
0192 int nfnetlink_unicast(struct sk_buff *skb, struct net *net, u32 portid)
0193 {
0194     struct nfnl_net *nfnlnet = nfnl_pernet(net);
0195     int err;
0196 
0197     err = nlmsg_unicast(nfnlnet->nfnl, skb, portid);
0198     if (err == -EAGAIN)
0199         err = -ENOBUFS;
0200 
0201     return err;
0202 }
0203 EXPORT_SYMBOL_GPL(nfnetlink_unicast);
0204 
0205 void nfnetlink_broadcast(struct net *net, struct sk_buff *skb, __u32 portid,
0206              __u32 group, gfp_t allocation)
0207 {
0208     struct nfnl_net *nfnlnet = nfnl_pernet(net);
0209 
0210     netlink_broadcast(nfnlnet->nfnl, skb, portid, group, allocation);
0211 }
0212 EXPORT_SYMBOL_GPL(nfnetlink_broadcast);
0213 
0214 /* Process one complete nfnetlink message. */
0215 static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
0216                  struct netlink_ext_ack *extack)
0217 {
0218     struct net *net = sock_net(skb->sk);
0219     const struct nfnl_callback *nc;
0220     const struct nfnetlink_subsystem *ss;
0221     int type, err;
0222 
0223     /* All the messages must at least contain nfgenmsg */
0224     if (nlmsg_len(nlh) < sizeof(struct nfgenmsg))
0225         return 0;
0226 
0227     type = nlh->nlmsg_type;
0228 replay:
0229     rcu_read_lock();
0230 
0231     ss = nfnetlink_get_subsys(type);
0232     if (!ss) {
0233 #ifdef CONFIG_MODULES
0234         rcu_read_unlock();
0235         request_module("nfnetlink-subsys-%d", NFNL_SUBSYS_ID(type));
0236         rcu_read_lock();
0237         ss = nfnetlink_get_subsys(type);
0238         if (!ss)
0239 #endif
0240         {
0241             rcu_read_unlock();
0242             return -EINVAL;
0243         }
0244     }
0245 
0246     nc = nfnetlink_find_client(type, ss);
0247     if (!nc) {
0248         rcu_read_unlock();
0249         return -EINVAL;
0250     }
0251 
0252     {
0253         int min_len = nlmsg_total_size(sizeof(struct nfgenmsg));
0254         struct nfnl_net *nfnlnet = nfnl_pernet(net);
0255         u8 cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type);
0256         struct nlattr *cda[NFNL_MAX_ATTR_COUNT + 1];
0257         struct nlattr *attr = (void *)nlh + min_len;
0258         int attrlen = nlh->nlmsg_len - min_len;
0259         __u8 subsys_id = NFNL_SUBSYS_ID(type);
0260         struct nfnl_info info = {
0261             .net    = net,
0262             .sk = nfnlnet->nfnl,
0263             .nlh    = nlh,
0264             .nfmsg  = nlmsg_data(nlh),
0265             .extack = extack,
0266         };
0267 
0268         /* Sanity-check NFNL_MAX_ATTR_COUNT */
0269         if (ss->cb[cb_id].attr_count > NFNL_MAX_ATTR_COUNT) {
0270             rcu_read_unlock();
0271             return -ENOMEM;
0272         }
0273 
0274         err = nla_parse_deprecated(cda, ss->cb[cb_id].attr_count,
0275                        attr, attrlen,
0276                        ss->cb[cb_id].policy, extack);
0277         if (err < 0) {
0278             rcu_read_unlock();
0279             return err;
0280         }
0281 
0282         if (!nc->call) {
0283             rcu_read_unlock();
0284             return -EINVAL;
0285         }
0286 
0287         switch (nc->type) {
0288         case NFNL_CB_RCU:
0289             err = nc->call(skb, &info, (const struct nlattr **)cda);
0290             rcu_read_unlock();
0291             break;
0292         case NFNL_CB_MUTEX:
0293             rcu_read_unlock();
0294             nfnl_lock(subsys_id);
0295             if (nfnl_dereference_protected(subsys_id) != ss ||
0296                 nfnetlink_find_client(type, ss) != nc) {
0297                 err = -EAGAIN;
0298                 break;
0299             }
0300             err = nc->call(skb, &info, (const struct nlattr **)cda);
0301             nfnl_unlock(subsys_id);
0302             break;
0303         default:
0304             rcu_read_unlock();
0305             err = -EINVAL;
0306             break;
0307         }
0308         if (err == -EAGAIN)
0309             goto replay;
0310         return err;
0311     }
0312 }
0313 
0314 struct nfnl_err {
0315     struct list_head    head;
0316     struct nlmsghdr     *nlh;
0317     int         err;
0318     struct netlink_ext_ack  extack;
0319 };
0320 
0321 static int nfnl_err_add(struct list_head *list, struct nlmsghdr *nlh, int err,
0322             const struct netlink_ext_ack *extack)
0323 {
0324     struct nfnl_err *nfnl_err;
0325 
0326     nfnl_err = kmalloc(sizeof(struct nfnl_err), GFP_KERNEL);
0327     if (nfnl_err == NULL)
0328         return -ENOMEM;
0329 
0330     nfnl_err->nlh = nlh;
0331     nfnl_err->err = err;
0332     nfnl_err->extack = *extack;
0333     list_add_tail(&nfnl_err->head, list);
0334 
0335     return 0;
0336 }
0337 
0338 static void nfnl_err_del(struct nfnl_err *nfnl_err)
0339 {
0340     list_del(&nfnl_err->head);
0341     kfree(nfnl_err);
0342 }
0343 
0344 static void nfnl_err_reset(struct list_head *err_list)
0345 {
0346     struct nfnl_err *nfnl_err, *next;
0347 
0348     list_for_each_entry_safe(nfnl_err, next, err_list, head)
0349         nfnl_err_del(nfnl_err);
0350 }
0351 
0352 static void nfnl_err_deliver(struct list_head *err_list, struct sk_buff *skb)
0353 {
0354     struct nfnl_err *nfnl_err, *next;
0355 
0356     list_for_each_entry_safe(nfnl_err, next, err_list, head) {
0357         netlink_ack(skb, nfnl_err->nlh, nfnl_err->err,
0358                 &nfnl_err->extack);
0359         nfnl_err_del(nfnl_err);
0360     }
0361 }
0362 
0363 enum {
0364     NFNL_BATCH_FAILURE  = (1 << 0),
0365     NFNL_BATCH_DONE     = (1 << 1),
0366     NFNL_BATCH_REPLAY   = (1 << 2),
0367 };
0368 
0369 static void nfnetlink_rcv_batch(struct sk_buff *skb, struct nlmsghdr *nlh,
0370                 u16 subsys_id, u32 genid)
0371 {
0372     struct sk_buff *oskb = skb;
0373     struct net *net = sock_net(skb->sk);
0374     const struct nfnetlink_subsystem *ss;
0375     const struct nfnl_callback *nc;
0376     struct netlink_ext_ack extack;
0377     LIST_HEAD(err_list);
0378     u32 status;
0379     int err;
0380 
0381     if (subsys_id >= NFNL_SUBSYS_COUNT)
0382         return netlink_ack(skb, nlh, -EINVAL, NULL);
0383 replay:
0384     status = 0;
0385 replay_abort:
0386     skb = netlink_skb_clone(oskb, GFP_KERNEL);
0387     if (!skb)
0388         return netlink_ack(oskb, nlh, -ENOMEM, NULL);
0389 
0390     nfnl_lock(subsys_id);
0391     ss = nfnl_dereference_protected(subsys_id);
0392     if (!ss) {
0393 #ifdef CONFIG_MODULES
0394         nfnl_unlock(subsys_id);
0395         request_module("nfnetlink-subsys-%d", subsys_id);
0396         nfnl_lock(subsys_id);
0397         ss = nfnl_dereference_protected(subsys_id);
0398         if (!ss)
0399 #endif
0400         {
0401             nfnl_unlock(subsys_id);
0402             netlink_ack(oskb, nlh, -EOPNOTSUPP, NULL);
0403             return kfree_skb(skb);
0404         }
0405     }
0406 
0407     if (!ss->valid_genid || !ss->commit || !ss->abort) {
0408         nfnl_unlock(subsys_id);
0409         netlink_ack(oskb, nlh, -EOPNOTSUPP, NULL);
0410         return kfree_skb(skb);
0411     }
0412 
0413     if (!try_module_get(ss->owner)) {
0414         nfnl_unlock(subsys_id);
0415         netlink_ack(oskb, nlh, -EOPNOTSUPP, NULL);
0416         return kfree_skb(skb);
0417     }
0418 
0419     if (!ss->valid_genid(net, genid)) {
0420         module_put(ss->owner);
0421         nfnl_unlock(subsys_id);
0422         netlink_ack(oskb, nlh, -ERESTART, NULL);
0423         return kfree_skb(skb);
0424     }
0425 
0426     nfnl_unlock(subsys_id);
0427 
0428     while (skb->len >= nlmsg_total_size(0)) {
0429         int msglen, type;
0430 
0431         if (fatal_signal_pending(current)) {
0432             nfnl_err_reset(&err_list);
0433             err = -EINTR;
0434             status = NFNL_BATCH_FAILURE;
0435             goto done;
0436         }
0437 
0438         memset(&extack, 0, sizeof(extack));
0439         nlh = nlmsg_hdr(skb);
0440         err = 0;
0441 
0442         if (nlh->nlmsg_len < NLMSG_HDRLEN ||
0443             skb->len < nlh->nlmsg_len ||
0444             nlmsg_len(nlh) < sizeof(struct nfgenmsg)) {
0445             nfnl_err_reset(&err_list);
0446             status |= NFNL_BATCH_FAILURE;
0447             goto done;
0448         }
0449 
0450         /* Only requests are handled by the kernel */
0451         if (!(nlh->nlmsg_flags & NLM_F_REQUEST)) {
0452             err = -EINVAL;
0453             goto ack;
0454         }
0455 
0456         type = nlh->nlmsg_type;
0457         if (type == NFNL_MSG_BATCH_BEGIN) {
0458             /* Malformed: Batch begin twice */
0459             nfnl_err_reset(&err_list);
0460             status |= NFNL_BATCH_FAILURE;
0461             goto done;
0462         } else if (type == NFNL_MSG_BATCH_END) {
0463             status |= NFNL_BATCH_DONE;
0464             goto done;
0465         } else if (type < NLMSG_MIN_TYPE) {
0466             err = -EINVAL;
0467             goto ack;
0468         }
0469 
0470         /* We only accept a batch with messages for the same
0471          * subsystem.
0472          */
0473         if (NFNL_SUBSYS_ID(type) != subsys_id) {
0474             err = -EINVAL;
0475             goto ack;
0476         }
0477 
0478         nc = nfnetlink_find_client(type, ss);
0479         if (!nc) {
0480             err = -EINVAL;
0481             goto ack;
0482         }
0483 
0484         if (nc->type != NFNL_CB_BATCH) {
0485             err = -EINVAL;
0486             goto ack;
0487         }
0488 
0489         {
0490             int min_len = nlmsg_total_size(sizeof(struct nfgenmsg));
0491             struct nfnl_net *nfnlnet = nfnl_pernet(net);
0492             struct nlattr *cda[NFNL_MAX_ATTR_COUNT + 1];
0493             struct nlattr *attr = (void *)nlh + min_len;
0494             u8 cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type);
0495             int attrlen = nlh->nlmsg_len - min_len;
0496             struct nfnl_info info = {
0497                 .net    = net,
0498                 .sk = nfnlnet->nfnl,
0499                 .nlh    = nlh,
0500                 .nfmsg  = nlmsg_data(nlh),
0501                 .extack = &extack,
0502             };
0503 
0504             /* Sanity-check NFTA_MAX_ATTR */
0505             if (ss->cb[cb_id].attr_count > NFNL_MAX_ATTR_COUNT) {
0506                 err = -ENOMEM;
0507                 goto ack;
0508             }
0509 
0510             err = nla_parse_deprecated(cda,
0511                            ss->cb[cb_id].attr_count,
0512                            attr, attrlen,
0513                            ss->cb[cb_id].policy, NULL);
0514             if (err < 0)
0515                 goto ack;
0516 
0517             err = nc->call(skb, &info, (const struct nlattr **)cda);
0518 
0519             /* The lock was released to autoload some module, we
0520              * have to abort and start from scratch using the
0521              * original skb.
0522              */
0523             if (err == -EAGAIN) {
0524                 status |= NFNL_BATCH_REPLAY;
0525                 goto done;
0526             }
0527         }
0528 ack:
0529         if (nlh->nlmsg_flags & NLM_F_ACK || err) {
0530             /* Errors are delivered once the full batch has been
0531              * processed, this avoids that the same error is
0532              * reported several times when replaying the batch.
0533              */
0534             if (nfnl_err_add(&err_list, nlh, err, &extack) < 0) {
0535                 /* We failed to enqueue an error, reset the
0536                  * list of errors and send OOM to userspace
0537                  * pointing to the batch header.
0538                  */
0539                 nfnl_err_reset(&err_list);
0540                 netlink_ack(oskb, nlmsg_hdr(oskb), -ENOMEM,
0541                         NULL);
0542                 status |= NFNL_BATCH_FAILURE;
0543                 goto done;
0544             }
0545             /* We don't stop processing the batch on errors, thus,
0546              * userspace gets all the errors that the batch
0547              * triggers.
0548              */
0549             if (err)
0550                 status |= NFNL_BATCH_FAILURE;
0551         }
0552 
0553         msglen = NLMSG_ALIGN(nlh->nlmsg_len);
0554         if (msglen > skb->len)
0555             msglen = skb->len;
0556         skb_pull(skb, msglen);
0557     }
0558 done:
0559     if (status & NFNL_BATCH_REPLAY) {
0560         ss->abort(net, oskb, NFNL_ABORT_AUTOLOAD);
0561         nfnl_err_reset(&err_list);
0562         kfree_skb(skb);
0563         module_put(ss->owner);
0564         goto replay;
0565     } else if (status == NFNL_BATCH_DONE) {
0566         err = ss->commit(net, oskb);
0567         if (err == -EAGAIN) {
0568             status |= NFNL_BATCH_REPLAY;
0569             goto done;
0570         } else if (err) {
0571             ss->abort(net, oskb, NFNL_ABORT_NONE);
0572             netlink_ack(oskb, nlmsg_hdr(oskb), err, NULL);
0573         }
0574     } else {
0575         enum nfnl_abort_action abort_action;
0576 
0577         if (status & NFNL_BATCH_FAILURE)
0578             abort_action = NFNL_ABORT_NONE;
0579         else
0580             abort_action = NFNL_ABORT_VALIDATE;
0581 
0582         err = ss->abort(net, oskb, abort_action);
0583         if (err == -EAGAIN) {
0584             nfnl_err_reset(&err_list);
0585             kfree_skb(skb);
0586             module_put(ss->owner);
0587             status |= NFNL_BATCH_FAILURE;
0588             goto replay_abort;
0589         }
0590     }
0591     if (ss->cleanup)
0592         ss->cleanup(net);
0593 
0594     nfnl_err_deliver(&err_list, oskb);
0595     kfree_skb(skb);
0596     module_put(ss->owner);
0597 }
0598 
0599 static const struct nla_policy nfnl_batch_policy[NFNL_BATCH_MAX + 1] = {
0600     [NFNL_BATCH_GENID]  = { .type = NLA_U32 },
0601 };
0602 
0603 static void nfnetlink_rcv_skb_batch(struct sk_buff *skb, struct nlmsghdr *nlh)
0604 {
0605     int min_len = nlmsg_total_size(sizeof(struct nfgenmsg));
0606     struct nlattr *attr = (void *)nlh + min_len;
0607     struct nlattr *cda[NFNL_BATCH_MAX + 1];
0608     int attrlen = nlh->nlmsg_len - min_len;
0609     struct nfgenmsg *nfgenmsg;
0610     int msglen, err;
0611     u32 gen_id = 0;
0612     u16 res_id;
0613 
0614     msglen = NLMSG_ALIGN(nlh->nlmsg_len);
0615     if (msglen > skb->len)
0616         msglen = skb->len;
0617 
0618     if (skb->len < NLMSG_HDRLEN + sizeof(struct nfgenmsg))
0619         return;
0620 
0621     err = nla_parse_deprecated(cda, NFNL_BATCH_MAX, attr, attrlen,
0622                    nfnl_batch_policy, NULL);
0623     if (err < 0) {
0624         netlink_ack(skb, nlh, err, NULL);
0625         return;
0626     }
0627     if (cda[NFNL_BATCH_GENID])
0628         gen_id = ntohl(nla_get_be32(cda[NFNL_BATCH_GENID]));
0629 
0630     nfgenmsg = nlmsg_data(nlh);
0631     skb_pull(skb, msglen);
0632     /* Work around old nft using host byte order */
0633     if (nfgenmsg->res_id == (__force __be16)NFNL_SUBSYS_NFTABLES)
0634         res_id = NFNL_SUBSYS_NFTABLES;
0635     else
0636         res_id = ntohs(nfgenmsg->res_id);
0637 
0638     nfnetlink_rcv_batch(skb, nlh, res_id, gen_id);
0639 }
0640 
0641 static void nfnetlink_rcv(struct sk_buff *skb)
0642 {
0643     struct nlmsghdr *nlh = nlmsg_hdr(skb);
0644 
0645     if (skb->len < NLMSG_HDRLEN ||
0646         nlh->nlmsg_len < NLMSG_HDRLEN ||
0647         skb->len < nlh->nlmsg_len)
0648         return;
0649 
0650     if (!netlink_net_capable(skb, CAP_NET_ADMIN)) {
0651         netlink_ack(skb, nlh, -EPERM, NULL);
0652         return;
0653     }
0654 
0655     if (nlh->nlmsg_type == NFNL_MSG_BATCH_BEGIN)
0656         nfnetlink_rcv_skb_batch(skb, nlh);
0657     else
0658         netlink_rcv_skb(skb, nfnetlink_rcv_msg);
0659 }
0660 
0661 static void nfnetlink_bind_event(struct net *net, unsigned int group)
0662 {
0663 #ifdef CONFIG_NF_CONNTRACK_EVENTS
0664     int type, group_bit;
0665     u8 v;
0666 
0667     /* All NFNLGRP_CONNTRACK_* group bits fit into u8.
0668      * The other groups are not relevant and can be ignored.
0669      */
0670     if (group >= 8)
0671         return;
0672 
0673     type = nfnl_group2type[group];
0674 
0675     switch (type) {
0676     case NFNL_SUBSYS_CTNETLINK:
0677         break;
0678     case NFNL_SUBSYS_CTNETLINK_EXP:
0679         break;
0680     default:
0681         return;
0682     }
0683 
0684     group_bit = (1 << group);
0685 
0686     spin_lock(&nfnl_grp_active_lock);
0687     v = READ_ONCE(net->ct.ctnetlink_has_listener);
0688     if ((v & group_bit) == 0) {
0689         v |= group_bit;
0690 
0691         /* read concurrently without nfnl_grp_active_lock held. */
0692         WRITE_ONCE(net->ct.ctnetlink_has_listener, v);
0693     }
0694 
0695     spin_unlock(&nfnl_grp_active_lock);
0696 #endif
0697 }
0698 
0699 static int nfnetlink_bind(struct net *net, int group)
0700 {
0701     const struct nfnetlink_subsystem *ss;
0702     int type;
0703 
0704     if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX)
0705         return 0;
0706 
0707     type = nfnl_group2type[group];
0708 
0709     rcu_read_lock();
0710     ss = nfnetlink_get_subsys(type << 8);
0711     rcu_read_unlock();
0712     if (!ss)
0713         request_module_nowait("nfnetlink-subsys-%d", type);
0714 
0715     nfnetlink_bind_event(net, group);
0716     return 0;
0717 }
0718 
0719 static void nfnetlink_unbind(struct net *net, int group)
0720 {
0721 #ifdef CONFIG_NF_CONNTRACK_EVENTS
0722     int type, group_bit;
0723 
0724     if (group <= NFNLGRP_NONE || group > NFNLGRP_MAX)
0725         return;
0726 
0727     type = nfnl_group2type[group];
0728 
0729     switch (type) {
0730     case NFNL_SUBSYS_CTNETLINK:
0731         break;
0732     case NFNL_SUBSYS_CTNETLINK_EXP:
0733         break;
0734     default:
0735         return;
0736     }
0737 
0738     /* ctnetlink_has_listener is u8 */
0739     if (group >= 8)
0740         return;
0741 
0742     group_bit = (1 << group);
0743 
0744     spin_lock(&nfnl_grp_active_lock);
0745     if (!nfnetlink_has_listeners(net, group)) {
0746         u8 v = READ_ONCE(net->ct.ctnetlink_has_listener);
0747 
0748         v &= ~group_bit;
0749 
0750         /* read concurrently without nfnl_grp_active_lock held. */
0751         WRITE_ONCE(net->ct.ctnetlink_has_listener, v);
0752     }
0753     spin_unlock(&nfnl_grp_active_lock);
0754 #endif
0755 }
0756 
0757 static int __net_init nfnetlink_net_init(struct net *net)
0758 {
0759     struct nfnl_net *nfnlnet = nfnl_pernet(net);
0760     struct netlink_kernel_cfg cfg = {
0761         .groups = NFNLGRP_MAX,
0762         .input  = nfnetlink_rcv,
0763         .bind   = nfnetlink_bind,
0764         .unbind = nfnetlink_unbind,
0765     };
0766 
0767     nfnlnet->nfnl = netlink_kernel_create(net, NETLINK_NETFILTER, &cfg);
0768     if (!nfnlnet->nfnl)
0769         return -ENOMEM;
0770     return 0;
0771 }
0772 
0773 static void __net_exit nfnetlink_net_exit_batch(struct list_head *net_exit_list)
0774 {
0775     struct nfnl_net *nfnlnet;
0776     struct net *net;
0777 
0778     list_for_each_entry(net, net_exit_list, exit_list) {
0779         nfnlnet = nfnl_pernet(net);
0780 
0781         netlink_kernel_release(nfnlnet->nfnl);
0782     }
0783 }
0784 
0785 static struct pernet_operations nfnetlink_net_ops = {
0786     .init       = nfnetlink_net_init,
0787     .exit_batch = nfnetlink_net_exit_batch,
0788     .id     = &nfnetlink_pernet_id,
0789     .size       = sizeof(struct nfnl_net),
0790 };
0791 
0792 static int __init nfnetlink_init(void)
0793 {
0794     int i;
0795 
0796     for (i = NFNLGRP_NONE + 1; i <= NFNLGRP_MAX; i++)
0797         BUG_ON(nfnl_group2type[i] == NFNL_SUBSYS_NONE);
0798 
0799     for (i=0; i<NFNL_SUBSYS_COUNT; i++)
0800         __mutex_init(&table[i].mutex, nfnl_lockdep_names[i], &nfnl_lockdep_keys[i]);
0801 
0802     return register_pernet_subsys(&nfnetlink_net_ops);
0803 }
0804 
0805 static void __exit nfnetlink_exit(void)
0806 {
0807     unregister_pernet_subsys(&nfnetlink_net_ops);
0808 }
0809 module_init(nfnetlink_init);
0810 module_exit(nfnetlink_exit);