aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/nfnetlink_log.c177
1 files changed, 117 insertions, 60 deletions
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index b593fd1f8cab..8e7bf641e096 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -32,6 +32,7 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33#include <net/sock.h> 33#include <net/sock.h>
34#include <net/netfilter/nf_log.h> 34#include <net/netfilter/nf_log.h>
35#include <net/netns/generic.h>
35#include <net/netfilter/nfnetlink_log.h> 36#include <net/netfilter/nfnetlink_log.h>
36 37
37#include <linux/atomic.h> 38#include <linux/atomic.h>
@@ -56,6 +57,7 @@ struct nfulnl_instance {
56 unsigned int qlen; /* number of nlmsgs in skb */ 57 unsigned int qlen; /* number of nlmsgs in skb */
57 struct sk_buff *skb; /* pre-allocatd skb */ 58 struct sk_buff *skb; /* pre-allocatd skb */
58 struct timer_list timer; 59 struct timer_list timer;
60 struct net *net;
59 struct user_namespace *peer_user_ns; /* User namespace of the peer process */ 61 struct user_namespace *peer_user_ns; /* User namespace of the peer process */
60 int peer_portid; /* PORTID of the peer process */ 62 int peer_portid; /* PORTID of the peer process */
61 63
@@ -71,25 +73,34 @@ struct nfulnl_instance {
71 struct rcu_head rcu; 73 struct rcu_head rcu;
72}; 74};
73 75
74static DEFINE_SPINLOCK(instances_lock);
75static atomic_t global_seq;
76
77#define INSTANCE_BUCKETS 16 76#define INSTANCE_BUCKETS 16
78static struct hlist_head instance_table[INSTANCE_BUCKETS];
79static unsigned int hash_init; 77static unsigned int hash_init;
80 78
79static int nfnl_log_net_id __read_mostly;
80
81struct nfnl_log_net {
82 spinlock_t instances_lock;
83 struct hlist_head instance_table[INSTANCE_BUCKETS];
84 atomic_t global_seq;
85};
86
87static struct nfnl_log_net *nfnl_log_pernet(struct net *net)
88{
89 return net_generic(net, nfnl_log_net_id);
90}
91
81static inline u_int8_t instance_hashfn(u_int16_t group_num) 92static inline u_int8_t instance_hashfn(u_int16_t group_num)
82{ 93{
83 return ((group_num & 0xff) % INSTANCE_BUCKETS); 94 return ((group_num & 0xff) % INSTANCE_BUCKETS);
84} 95}
85 96
86static struct nfulnl_instance * 97static struct nfulnl_instance *
87__instance_lookup(u_int16_t group_num) 98__instance_lookup(struct nfnl_log_net *log, u_int16_t group_num)
88{ 99{
89 struct hlist_head *head; 100 struct hlist_head *head;
90 struct nfulnl_instance *inst; 101 struct nfulnl_instance *inst;
91 102
92 head = &instance_table[instance_hashfn(group_num)]; 103 head = &log->instance_table[instance_hashfn(group_num)];
93 hlist_for_each_entry_rcu(inst, head, hlist) { 104 hlist_for_each_entry_rcu(inst, head, hlist) {
94 if (inst->group_num == group_num) 105 if (inst->group_num == group_num)
95 return inst; 106 return inst;
@@ -104,12 +115,12 @@ instance_get(struct nfulnl_instance *inst)
104} 115}
105 116
106static struct nfulnl_instance * 117static struct nfulnl_instance *
107instance_lookup_get(u_int16_t group_num) 118instance_lookup_get(struct nfnl_log_net *log, u_int16_t group_num)
108{ 119{
109 struct nfulnl_instance *inst; 120 struct nfulnl_instance *inst;
110 121
111 rcu_read_lock_bh(); 122 rcu_read_lock_bh();
112 inst = __instance_lookup(group_num); 123 inst = __instance_lookup(log, group_num);
113 if (inst && !atomic_inc_not_zero(&inst->use)) 124 if (inst && !atomic_inc_not_zero(&inst->use))
114 inst = NULL; 125 inst = NULL;
115 rcu_read_unlock_bh(); 126 rcu_read_unlock_bh();
@@ -119,7 +130,11 @@ instance_lookup_get(u_int16_t group_num)
119 130
120static void nfulnl_instance_free_rcu(struct rcu_head *head) 131static void nfulnl_instance_free_rcu(struct rcu_head *head)
121{ 132{
122 kfree(container_of(head, struct nfulnl_instance, rcu)); 133 struct nfulnl_instance *inst =
134 container_of(head, struct nfulnl_instance, rcu);
135
136 put_net(inst->net);
137 kfree(inst);
123 module_put(THIS_MODULE); 138 module_put(THIS_MODULE);
124} 139}
125 140
@@ -133,13 +148,15 @@ instance_put(struct nfulnl_instance *inst)
133static void nfulnl_timer(unsigned long data); 148static void nfulnl_timer(unsigned long data);
134 149
135static struct nfulnl_instance * 150static struct nfulnl_instance *
136instance_create(u_int16_t group_num, int portid, struct user_namespace *user_ns) 151instance_create(struct net *net, u_int16_t group_num,
152 int portid, struct user_namespace *user_ns)
137{ 153{
138 struct nfulnl_instance *inst; 154 struct nfulnl_instance *inst;
155 struct nfnl_log_net *log = nfnl_log_pernet(net);
139 int err; 156 int err;
140 157
141 spin_lock_bh(&instances_lock); 158 spin_lock_bh(&log->instances_lock);
142 if (__instance_lookup(group_num)) { 159 if (__instance_lookup(log, group_num)) {
143 err = -EEXIST; 160 err = -EEXIST;
144 goto out_unlock; 161 goto out_unlock;
145 } 162 }
@@ -163,6 +180,7 @@ instance_create(u_int16_t group_num, int portid, struct user_namespace *user_ns)
163 180
164 setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst); 181 setup_timer(&inst->timer, nfulnl_timer, (unsigned long)inst);
165 182
183 inst->net = get_net(net);
166 inst->peer_user_ns = user_ns; 184 inst->peer_user_ns = user_ns;
167 inst->peer_portid = portid; 185 inst->peer_portid = portid;
168 inst->group_num = group_num; 186 inst->group_num = group_num;
@@ -174,14 +192,15 @@ instance_create(u_int16_t group_num, int portid, struct user_namespace *user_ns)
174 inst->copy_range = NFULNL_COPY_RANGE_MAX; 192 inst->copy_range = NFULNL_COPY_RANGE_MAX;
175 193
176 hlist_add_head_rcu(&inst->hlist, 194 hlist_add_head_rcu(&inst->hlist,
177 &instance_table[instance_hashfn(group_num)]); 195 &log->instance_table[instance_hashfn(group_num)]);
196
178 197
179 spin_unlock_bh(&instances_lock); 198 spin_unlock_bh(&log->instances_lock);
180 199
181 return inst; 200 return inst;
182 201
183out_unlock: 202out_unlock:
184 spin_unlock_bh(&instances_lock); 203 spin_unlock_bh(&log->instances_lock);
185 return ERR_PTR(err); 204 return ERR_PTR(err);
186} 205}
187 206
@@ -210,11 +229,12 @@ __instance_destroy(struct nfulnl_instance *inst)
210} 229}
211 230
212static inline void 231static inline void
213instance_destroy(struct nfulnl_instance *inst) 232instance_destroy(struct nfnl_log_net *log,
233 struct nfulnl_instance *inst)
214{ 234{
215 spin_lock_bh(&instances_lock); 235 spin_lock_bh(&log->instances_lock);
216 __instance_destroy(inst); 236 __instance_destroy(inst);
217 spin_unlock_bh(&instances_lock); 237 spin_unlock_bh(&log->instances_lock);
218} 238}
219 239
220static int 240static int
@@ -336,7 +356,7 @@ __nfulnl_send(struct nfulnl_instance *inst)
336 if (!nlh) 356 if (!nlh)
337 goto out; 357 goto out;
338 } 358 }
339 status = nfnetlink_unicast(inst->skb, &init_net, inst->peer_portid, 359 status = nfnetlink_unicast(inst->skb, inst->net, inst->peer_portid,
340 MSG_DONTWAIT); 360 MSG_DONTWAIT);
341 361
342 inst->qlen = 0; 362 inst->qlen = 0;
@@ -370,7 +390,8 @@ nfulnl_timer(unsigned long data)
370/* This is an inline function, we don't really care about a long 390/* This is an inline function, we don't really care about a long
371 * list of arguments */ 391 * list of arguments */
372static inline int 392static inline int
373__build_packet_message(struct nfulnl_instance *inst, 393__build_packet_message(struct nfnl_log_net *log,
394 struct nfulnl_instance *inst,
374 const struct sk_buff *skb, 395 const struct sk_buff *skb,
375 unsigned int data_len, 396 unsigned int data_len,
376 u_int8_t pf, 397 u_int8_t pf,
@@ -536,7 +557,7 @@ __build_packet_message(struct nfulnl_instance *inst,
536 /* global sequence number */ 557 /* global sequence number */
537 if ((inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) && 558 if ((inst->flags & NFULNL_CFG_F_SEQ_GLOBAL) &&
538 nla_put_be32(inst->skb, NFULA_SEQ_GLOBAL, 559 nla_put_be32(inst->skb, NFULA_SEQ_GLOBAL,
539 htonl(atomic_inc_return(&global_seq)))) 560 htonl(atomic_inc_return(&log->global_seq))))
540 goto nla_put_failure; 561 goto nla_put_failure;
541 562
542 if (data_len) { 563 if (data_len) {
@@ -592,13 +613,15 @@ nfulnl_log_packet(u_int8_t pf,
592 const struct nf_loginfo *li; 613 const struct nf_loginfo *li;
593 unsigned int qthreshold; 614 unsigned int qthreshold;
594 unsigned int plen; 615 unsigned int plen;
616 struct net *net = dev_net(in ? in : out);
617 struct nfnl_log_net *log = nfnl_log_pernet(net);
595 618
596 if (li_user && li_user->type == NF_LOG_TYPE_ULOG) 619 if (li_user && li_user->type == NF_LOG_TYPE_ULOG)
597 li = li_user; 620 li = li_user;
598 else 621 else
599 li = &default_loginfo; 622 li = &default_loginfo;
600 623
601 inst = instance_lookup_get(li->u.ulog.group); 624 inst = instance_lookup_get(log, li->u.ulog.group);
602 if (!inst) 625 if (!inst)
603 return; 626 return;
604 627
@@ -680,7 +703,7 @@ nfulnl_log_packet(u_int8_t pf,
680 703
681 inst->qlen++; 704 inst->qlen++;
682 705
683 __build_packet_message(inst, skb, data_len, pf, 706 __build_packet_message(log, inst, skb, data_len, pf,
684 hooknum, in, out, prefix, plen); 707 hooknum, in, out, prefix, plen);
685 708
686 if (inst->qlen >= qthreshold) 709 if (inst->qlen >= qthreshold)
@@ -709,24 +732,24 @@ nfulnl_rcv_nl_event(struct notifier_block *this,
709 unsigned long event, void *ptr) 732 unsigned long event, void *ptr)
710{ 733{
711 struct netlink_notify *n = ptr; 734 struct netlink_notify *n = ptr;
735 struct nfnl_log_net *log = nfnl_log_pernet(n->net);
712 736
713 if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) { 737 if (event == NETLINK_URELEASE && n->protocol == NETLINK_NETFILTER) {
714 int i; 738 int i;
715 739
716 /* destroy all instances for this portid */ 740 /* destroy all instances for this portid */
717 spin_lock_bh(&instances_lock); 741 spin_lock_bh(&log->instances_lock);
718 for (i = 0; i < INSTANCE_BUCKETS; i++) { 742 for (i = 0; i < INSTANCE_BUCKETS; i++) {
719 struct hlist_node *t2; 743 struct hlist_node *t2;
720 struct nfulnl_instance *inst; 744 struct nfulnl_instance *inst;
721 struct hlist_head *head = &instance_table[i]; 745 struct hlist_head *head = &log->instance_table[i];
722 746
723 hlist_for_each_entry_safe(inst, t2, head, hlist) { 747 hlist_for_each_entry_safe(inst, t2, head, hlist) {
724 if ((net_eq(n->net, &init_net)) && 748 if (n->portid == inst->peer_portid)
725 (n->portid == inst->peer_portid))
726 __instance_destroy(inst); 749 __instance_destroy(inst);
727 } 750 }
728 } 751 }
729 spin_unlock_bh(&instances_lock); 752 spin_unlock_bh(&log->instances_lock);
730 } 753 }
731 return NOTIFY_DONE; 754 return NOTIFY_DONE;
732} 755}
@@ -768,6 +791,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
768 struct nfulnl_instance *inst; 791 struct nfulnl_instance *inst;
769 struct nfulnl_msg_config_cmd *cmd = NULL; 792 struct nfulnl_msg_config_cmd *cmd = NULL;
770 struct net *net = sock_net(ctnl); 793 struct net *net = sock_net(ctnl);
794 struct nfnl_log_net *log = nfnl_log_pernet(net);
771 int ret = 0; 795 int ret = 0;
772 796
773 if (nfula[NFULA_CFG_CMD]) { 797 if (nfula[NFULA_CFG_CMD]) {
@@ -784,7 +808,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
784 } 808 }
785 } 809 }
786 810
787 inst = instance_lookup_get(group_num); 811 inst = instance_lookup_get(log, group_num);
788 if (inst && inst->peer_portid != NETLINK_CB(skb).portid) { 812 if (inst && inst->peer_portid != NETLINK_CB(skb).portid) {
789 ret = -EPERM; 813 ret = -EPERM;
790 goto out_put; 814 goto out_put;
@@ -798,7 +822,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
798 goto out_put; 822 goto out_put;
799 } 823 }
800 824
801 inst = instance_create(group_num, 825 inst = instance_create(net, group_num,
802 NETLINK_CB(skb).portid, 826 NETLINK_CB(skb).portid,
803 sk_user_ns(NETLINK_CB(skb).ssk)); 827 sk_user_ns(NETLINK_CB(skb).ssk));
804 if (IS_ERR(inst)) { 828 if (IS_ERR(inst)) {
@@ -812,7 +836,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
812 goto out; 836 goto out;
813 } 837 }
814 838
815 instance_destroy(inst); 839 instance_destroy(log, inst);
816 goto out_put; 840 goto out_put;
817 default: 841 default:
818 ret = -ENOTSUPP; 842 ret = -ENOTSUPP;
@@ -895,55 +919,68 @@ static const struct nfnetlink_subsystem nfulnl_subsys = {
895 919
896#ifdef CONFIG_PROC_FS 920#ifdef CONFIG_PROC_FS
897struct iter_state { 921struct iter_state {
922 struct seq_net_private p;
898 unsigned int bucket; 923 unsigned int bucket;
899}; 924};
900 925
901static struct hlist_node *get_first(struct iter_state *st) 926static struct hlist_node *get_first(struct net *net, struct iter_state *st)
902{ 927{
928 struct nfnl_log_net *log;
903 if (!st) 929 if (!st)
904 return NULL; 930 return NULL;
905 931
932 log = nfnl_log_pernet(net);
933
906 for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) { 934 for (st->bucket = 0; st->bucket < INSTANCE_BUCKETS; st->bucket++) {
907 if (!hlist_empty(&instance_table[st->bucket])) 935 struct hlist_head *head = &log->instance_table[st->bucket];
908 return rcu_dereference_bh(hlist_first_rcu(&instance_table[st->bucket])); 936
937 if (!hlist_empty(head))
938 return rcu_dereference_bh(hlist_first_rcu(head));
909 } 939 }
910 return NULL; 940 return NULL;
911} 941}
912 942
913static struct hlist_node *get_next(struct iter_state *st, struct hlist_node *h) 943static struct hlist_node *get_next(struct net *net, struct iter_state *st,
944 struct hlist_node *h)
914{ 945{
915 h = rcu_dereference_bh(hlist_next_rcu(h)); 946 h = rcu_dereference_bh(hlist_next_rcu(h));
916 while (!h) { 947 while (!h) {
948 struct nfnl_log_net *log;
949 struct hlist_head *head;
950
917 if (++st->bucket >= INSTANCE_BUCKETS) 951 if (++st->bucket >= INSTANCE_BUCKETS)
918 return NULL; 952 return NULL;
919 953
920 h = rcu_dereference_bh(hlist_first_rcu(&instance_table[st->bucket])); 954 log = nfnl_log_pernet(net);
955 head = &log->instance_table[st->bucket];
956 h = rcu_dereference_bh(hlist_first_rcu(head));
921 } 957 }
922 return h; 958 return h;
923} 959}
924 960
925static struct hlist_node *get_idx(struct iter_state *st, loff_t pos) 961static struct hlist_node *get_idx(struct net *net, struct iter_state *st,
962 loff_t pos)
926{ 963{
927 struct hlist_node *head; 964 struct hlist_node *head;
928 head = get_first(st); 965 head = get_first(net, st);
929 966
930 if (head) 967 if (head)
931 while (pos && (head = get_next(st, head))) 968 while (pos && (head = get_next(net, st, head)))
932 pos--; 969 pos--;
933 return pos ? NULL : head; 970 return pos ? NULL : head;
934} 971}
935 972
936static void *seq_start(struct seq_file *seq, loff_t *pos) 973static void *seq_start(struct seq_file *s, loff_t *pos)
937 __acquires(rcu_bh) 974 __acquires(rcu_bh)
938{ 975{
939 rcu_read_lock_bh(); 976 rcu_read_lock_bh();
940 return get_idx(seq->private, *pos); 977 return get_idx(seq_file_net(s), s->private, *pos);
941} 978}
942 979
943static void *seq_next(struct seq_file *s, void *v, loff_t *pos) 980static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
944{ 981{
945 (*pos)++; 982 (*pos)++;
946 return get_next(s->private, v); 983 return get_next(seq_file_net(s), s->private, v);
947} 984}
948 985
949static void seq_stop(struct seq_file *s, void *v) 986static void seq_stop(struct seq_file *s, void *v)
@@ -972,8 +1009,8 @@ static const struct seq_operations nful_seq_ops = {
972 1009
973static int nful_open(struct inode *inode, struct file *file) 1010static int nful_open(struct inode *inode, struct file *file)
974{ 1011{
975 return seq_open_private(file, &nful_seq_ops, 1012 return seq_open_net(inode, file, &nful_seq_ops,
976 sizeof(struct iter_state)); 1013 sizeof(struct iter_state));
977} 1014}
978 1015
979static const struct file_operations nful_file_ops = { 1016static const struct file_operations nful_file_ops = {
@@ -981,17 +1018,43 @@ static const struct file_operations nful_file_ops = {
981 .open = nful_open, 1018 .open = nful_open,
982 .read = seq_read, 1019 .read = seq_read,
983 .llseek = seq_lseek, 1020 .llseek = seq_lseek,
984 .release = seq_release_private, 1021 .release = seq_release_net,
985}; 1022};
986 1023
987#endif /* PROC_FS */ 1024#endif /* PROC_FS */
988 1025
989static int __init nfnetlink_log_init(void) 1026static int __net_init nfnl_log_net_init(struct net *net)
990{ 1027{
991 int i, status = -ENOMEM; 1028 unsigned int i;
1029 struct nfnl_log_net *log = nfnl_log_pernet(net);
992 1030
993 for (i = 0; i < INSTANCE_BUCKETS; i++) 1031 for (i = 0; i < INSTANCE_BUCKETS; i++)
994 INIT_HLIST_HEAD(&instance_table[i]); 1032 INIT_HLIST_HEAD(&log->instance_table[i]);
1033 spin_lock_init(&log->instances_lock);
1034
1035#ifdef CONFIG_PROC_FS
1036 if (!proc_create("nfnetlink_log", 0440,
1037 net->nf.proc_netfilter, &nful_file_ops))
1038 return -ENOMEM;
1039#endif
1040 return 0;
1041}
1042
1043static void __net_exit nfnl_log_net_exit(struct net *net)
1044{
1045 remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter);
1046}
1047
1048static struct pernet_operations nfnl_log_net_ops = {
1049 .init = nfnl_log_net_init,
1050 .exit = nfnl_log_net_exit,
1051 .id = &nfnl_log_net_id,
1052 .size = sizeof(struct nfnl_log_net),
1053};
1054
1055static int __init nfnetlink_log_init(void)
1056{
1057 int status = -ENOMEM;
995 1058
996 /* it's not really all that important to have a random value, so 1059 /* it's not really all that important to have a random value, so
997 * we can do this from the init function, even if there hasn't 1060 * we can do this from the init function, even if there hasn't
@@ -1001,29 +1064,25 @@ static int __init nfnetlink_log_init(void)
1001 netlink_register_notifier(&nfulnl_rtnl_notifier); 1064 netlink_register_notifier(&nfulnl_rtnl_notifier);
1002 status = nfnetlink_subsys_register(&nfulnl_subsys); 1065 status = nfnetlink_subsys_register(&nfulnl_subsys);
1003 if (status < 0) { 1066 if (status < 0) {
1004 printk(KERN_ERR "log: failed to create netlink socket\n"); 1067 pr_err("log: failed to create netlink socket\n");
1005 goto cleanup_netlink_notifier; 1068 goto cleanup_netlink_notifier;
1006 } 1069 }
1007 1070
1008 status = nf_log_register(NFPROTO_UNSPEC, &nfulnl_logger); 1071 status = nf_log_register(NFPROTO_UNSPEC, &nfulnl_logger);
1009 if (status < 0) { 1072 if (status < 0) {
1010 printk(KERN_ERR "log: failed to register logger\n"); 1073 pr_err("log: failed to register logger\n");
1011 goto cleanup_subsys; 1074 goto cleanup_subsys;
1012 } 1075 }
1013 1076
1014#ifdef CONFIG_PROC_FS 1077 status = register_pernet_subsys(&nfnl_log_net_ops);
1015 if (!proc_create("nfnetlink_log", 0440, 1078 if (status < 0) {
1016 proc_net_netfilter, &nful_file_ops)) { 1079 pr_err("log: failed to register pernet ops\n");
1017 status = -ENOMEM;
1018 goto cleanup_logger; 1080 goto cleanup_logger;
1019 } 1081 }
1020#endif
1021 return status; 1082 return status;
1022 1083
1023#ifdef CONFIG_PROC_FS
1024cleanup_logger: 1084cleanup_logger:
1025 nf_log_unregister(&nfulnl_logger); 1085 nf_log_unregister(&nfulnl_logger);
1026#endif
1027cleanup_subsys: 1086cleanup_subsys:
1028 nfnetlink_subsys_unregister(&nfulnl_subsys); 1087 nfnetlink_subsys_unregister(&nfulnl_subsys);
1029cleanup_netlink_notifier: 1088cleanup_netlink_notifier:
@@ -1033,10 +1092,8 @@ cleanup_netlink_notifier:
1033 1092
1034static void __exit nfnetlink_log_fini(void) 1093static void __exit nfnetlink_log_fini(void)
1035{ 1094{
1095 unregister_pernet_subsys(&nfnl_log_net_ops);
1036 nf_log_unregister(&nfulnl_logger); 1096 nf_log_unregister(&nfulnl_logger);
1037#ifdef CONFIG_PROC_FS
1038 remove_proc_entry("nfnetlink_log", proc_net_netfilter);
1039#endif
1040 nfnetlink_subsys_unregister(&nfulnl_subsys); 1097 nfnetlink_subsys_unregister(&nfulnl_subsys);
1041 netlink_unregister_notifier(&nfulnl_rtnl_notifier); 1098 netlink_unregister_notifier(&nfulnl_rtnl_notifier);
1042} 1099}