aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-07-21 00:01:43 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-21 00:01:43 -0400
commita8138f42d494bcd41a6f7ff301e12fa8d4f330f1 (patch)
tree3ef25c22129c7f72aa0d6667143227b3a62a7708
parent6fe82a39e583a50f28f03b294df79c9de9ec0de4 (diff)
parent16ea4c6b9dde2ff44b2bd8bb459daa283cf3a46e (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next
Pablo Neira Ayuso says: ==================== Netfilter updates for net-next The following patchset contains updates for your net-next tree, they are: 1) Use kvfree() helper function from x_tables, from Eric Dumazet. 2) Remove extra timer from the conntrack ecache extension, use a workqueue instead to redeliver lost events to userspace instead, from Florian Westphal. 3) Removal of the ulog targets for ebtables and iptables. The nflog infrastructure superseded this almost 9 years ago, time to get rid of this code. 4) Replace the list of loggers by an array now that we can only have two possible non-overlapping logger flavours, ie. kernel ring buffer and netlink logging. 5) Move Eric Dumazet's log buffer code to nf_log to reuse it from all of the supported per-family loggers. 6) Consolidate nf_log_packet() as an unified interface for packet logging. After this patch, if the struct nf_loginfo is available, it explicitly selects the logger that is used. 7) Move ip and ip6 logging code from xt_LOG to the corresponding per-family loggers. Thus, x_tables and nf_tables share the same code for packet logging. 8) Add generic ARP packet logger, which is used by nf_tables. The format aims to be consistent with the output of xt_LOG. 9) Add generic bridge packet logger. Again, this is used by nf_tables and it routes the packets to the real family loggers. As a result, we get consistent logging format for the bridge family. The ebt_log logging code has been intentionally left in place not to break backward compatibility since the logging output differs from xt_LOG. 10) Update nft_log to explicitly request the required family logger when needed. 11) Finish nft_log so it supports arp, ip, ip6, bridge and inet families. Allowing selection between netlink and kernel buffer ring logging. 12) Several fixes coming after the netfilter core logging changes spotted by robots. 13) Use IS_ENABLED() macros whenever possible in the netfilter tree, from Duan Jiong. 14) Removal of a couple of unnecessary branch before kfree, from Fabian Frederick. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/netfilter/nf_conntrack_ecache.h26
-rw-r--r--include/net/netfilter/nf_log.h42
-rw-r--r--include/net/netfilter/xt_log.h54
-rw-r--r--include/net/netns/conntrack.h6
-rw-r--r--include/uapi/linux/netfilter/nf_tables.h4
-rw-r--r--include/uapi/linux/netfilter_bridge/Kbuild1
-rw-r--r--include/uapi/linux/netfilter_bridge/ebt_ulog.h38
-rw-r--r--include/uapi/linux/netfilter_ipv4/Kbuild1
-rw-r--r--include/uapi/linux/netfilter_ipv4/ipt_ULOG.h49
-rw-r--r--net/bridge/netfilter/Kconfig19
-rw-r--r--net/bridge/netfilter/Makefile3
-rw-r--r--net/bridge/netfilter/ebt_log.c47
-rw-r--r--net/bridge/netfilter/ebt_ulog.c393
-rw-r--r--net/bridge/netfilter/nf_log_bridge.c96
-rw-r--r--net/ipv4/netfilter/Kconfig29
-rw-r--r--net/ipv4/netfilter/Makefile4
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c498
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c4
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c4
-rw-r--r--net/ipv4/netfilter/nf_defrag_ipv4.c8
-rw-r--r--net/ipv4/netfilter/nf_log_arp.c149
-rw-r--r--net/ipv4/netfilter/nf_log_ipv4.c385
-rw-r--r--net/ipv4/netfilter/nf_nat_l3proto_ipv4.c4
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_gre.c2
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_icmp.c2
-rw-r--r--net/ipv6/netfilter/Kconfig5
-rw-r--r--net/ipv6/netfilter/Makefile3
-rw-r--r--net/ipv6/netfilter/nf_log_ipv6.c417
-rw-r--r--net/ipv6/netfilter/nf_nat_l3proto_ipv6.c4
-rw-r--r--net/netfilter/Kconfig4
-rw-r--r--net/netfilter/Makefile3
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c86
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c3
-rw-r--r--net/netfilter/nf_conntrack_core.c68
-rw-r--r--net/netfilter/nf_conntrack_ecache.c96
-rw-r--r--net/netfilter/nf_conntrack_netlink.c3
-rw-r--r--net/netfilter/nf_log.c155
-rw-r--r--net/netfilter/nf_log_common.c187
-rw-r--r--net/netfilter/nf_nat_core.c2
-rw-r--r--net/netfilter/nf_nat_proto_common.c2
-rw-r--r--net/netfilter/nf_nat_proto_dccp.c2
-rw-r--r--net/netfilter/nf_nat_proto_sctp.c2
-rw-r--r--net/netfilter/nf_nat_proto_tcp.c2
-rw-r--r--net/netfilter/nf_nat_proto_udp.c2
-rw-r--r--net/netfilter/nf_nat_proto_udplite.c2
-rw-r--r--net/netfilter/nfnetlink_log.c4
-rw-r--r--net/netfilter/nft_log.c98
-rw-r--r--net/netfilter/x_tables.c23
-rw-r--r--net/netfilter/xt_LOG.c884
49 files changed, 1694 insertions, 2231 deletions
diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h
index 0e3d08e4b1d3..57c880378443 100644
--- a/include/net/netfilter/nf_conntrack_ecache.h
+++ b/include/net/netfilter/nf_conntrack_ecache.h
@@ -18,7 +18,6 @@ struct nf_conntrack_ecache {
18 u16 ctmask; /* bitmask of ct events to be delivered */ 18 u16 ctmask; /* bitmask of ct events to be delivered */
19 u16 expmask; /* bitmask of expect events to be delivered */ 19 u16 expmask; /* bitmask of expect events to be delivered */
20 u32 portid; /* netlink portid of destroyer */ 20 u32 portid; /* netlink portid of destroyer */
21 struct timer_list timeout;
22}; 21};
23 22
24static inline struct nf_conntrack_ecache * 23static inline struct nf_conntrack_ecache *
@@ -216,8 +215,23 @@ void nf_conntrack_ecache_pernet_fini(struct net *net);
216 215
217int nf_conntrack_ecache_init(void); 216int nf_conntrack_ecache_init(void);
218void nf_conntrack_ecache_fini(void); 217void nf_conntrack_ecache_fini(void);
219#else /* CONFIG_NF_CONNTRACK_EVENTS */
220 218
219static inline void nf_conntrack_ecache_delayed_work(struct net *net)
220{
221 if (!delayed_work_pending(&net->ct.ecache_dwork)) {
222 schedule_delayed_work(&net->ct.ecache_dwork, HZ);
223 net->ct.ecache_dwork_pending = true;
224 }
225}
226
227static inline void nf_conntrack_ecache_work(struct net *net)
228{
229 if (net->ct.ecache_dwork_pending) {
230 net->ct.ecache_dwork_pending = false;
231 mod_delayed_work(system_wq, &net->ct.ecache_dwork, 0);
232 }
233}
234#else /* CONFIG_NF_CONNTRACK_EVENTS */
221static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, 235static inline void nf_conntrack_event_cache(enum ip_conntrack_events event,
222 struct nf_conn *ct) {} 236 struct nf_conn *ct) {}
223static inline int nf_conntrack_eventmask_report(unsigned int eventmask, 237static inline int nf_conntrack_eventmask_report(unsigned int eventmask,
@@ -255,6 +269,14 @@ static inline int nf_conntrack_ecache_init(void)
255static inline void nf_conntrack_ecache_fini(void) 269static inline void nf_conntrack_ecache_fini(void)
256{ 270{
257} 271}
272
273static inline void nf_conntrack_ecache_delayed_work(struct net *net)
274{
275}
276
277static inline void nf_conntrack_ecache_work(struct net *net)
278{
279}
258#endif /* CONFIG_NF_CONNTRACK_EVENTS */ 280#endif /* CONFIG_NF_CONNTRACK_EVENTS */
259 281
260#endif /*_NF_CONNTRACK_ECACHE_H*/ 282#endif /*_NF_CONNTRACK_ECACHE_H*/
diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
index 99eac12d040b..534e1f2ac4fc 100644
--- a/include/net/netfilter/nf_log.h
+++ b/include/net/netfilter/nf_log.h
@@ -12,8 +12,11 @@
12#define NF_LOG_UID 0x08 /* Log UID owning local socket */ 12#define NF_LOG_UID 0x08 /* Log UID owning local socket */
13#define NF_LOG_MASK 0x0f 13#define NF_LOG_MASK 0x0f
14 14
15#define NF_LOG_TYPE_LOG 0x01 15enum nf_log_type {
16#define NF_LOG_TYPE_ULOG 0x02 16 NF_LOG_TYPE_LOG = 0,
17 NF_LOG_TYPE_ULOG,
18 NF_LOG_TYPE_MAX
19};
17 20
18struct nf_loginfo { 21struct nf_loginfo {
19 u_int8_t type; 22 u_int8_t type;
@@ -40,10 +43,10 @@ typedef void nf_logfn(struct net *net,
40 const char *prefix); 43 const char *prefix);
41 44
42struct nf_logger { 45struct nf_logger {
43 struct module *me; 46 char *name;
44 nf_logfn *logfn; 47 enum nf_log_type type;
45 char *name; 48 nf_logfn *logfn;
46 struct list_head list[NFPROTO_NUMPROTO]; 49 struct module *me;
47}; 50};
48 51
49/* Function to register/unregister log function. */ 52/* Function to register/unregister log function. */
@@ -58,6 +61,13 @@ int nf_log_bind_pf(struct net *net, u_int8_t pf,
58 const struct nf_logger *logger); 61 const struct nf_logger *logger);
59void nf_log_unbind_pf(struct net *net, u_int8_t pf); 62void nf_log_unbind_pf(struct net *net, u_int8_t pf);
60 63
64int nf_logger_find_get(int pf, enum nf_log_type type);
65void nf_logger_put(int pf, enum nf_log_type type);
66void nf_logger_request_module(int pf, enum nf_log_type type);
67
68#define MODULE_ALIAS_NF_LOGGER(family, type) \
69 MODULE_ALIAS("nf-logger-" __stringify(family) "-" __stringify(type))
70
61/* Calls the registered backend logging function */ 71/* Calls the registered backend logging function */
62__printf(8, 9) 72__printf(8, 9)
63void nf_log_packet(struct net *net, 73void nf_log_packet(struct net *net,
@@ -69,4 +79,24 @@ void nf_log_packet(struct net *net,
69 const struct nf_loginfo *li, 79 const struct nf_loginfo *li,
70 const char *fmt, ...); 80 const char *fmt, ...);
71 81
82struct nf_log_buf;
83
84struct nf_log_buf *nf_log_buf_open(void);
85__printf(2, 3) int nf_log_buf_add(struct nf_log_buf *m, const char *f, ...);
86void nf_log_buf_close(struct nf_log_buf *m);
87
88/* common logging functions */
89int nf_log_dump_udp_header(struct nf_log_buf *m, const struct sk_buff *skb,
90 u8 proto, int fragment, unsigned int offset);
91int nf_log_dump_tcp_header(struct nf_log_buf *m, const struct sk_buff *skb,
92 u8 proto, int fragment, unsigned int offset,
93 unsigned int logflags);
94void nf_log_dump_sk_uid_gid(struct nf_log_buf *m, struct sock *sk);
95void nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf,
96 unsigned int hooknum, const struct sk_buff *skb,
97 const struct net_device *in,
98 const struct net_device *out,
99 const struct nf_loginfo *loginfo,
100 const char *prefix);
101
72#endif /* _NF_LOG_H */ 102#endif /* _NF_LOG_H */
diff --git a/include/net/netfilter/xt_log.h b/include/net/netfilter/xt_log.h
deleted file mode 100644
index 9d9756cca013..000000000000
--- a/include/net/netfilter/xt_log.h
+++ /dev/null
@@ -1,54 +0,0 @@
1#define S_SIZE (1024 - (sizeof(unsigned int) + 1))
2
3struct sbuff {
4 unsigned int count;
5 char buf[S_SIZE + 1];
6};
7static struct sbuff emergency, *emergency_ptr = &emergency;
8
9static __printf(2, 3) int sb_add(struct sbuff *m, const char *f, ...)
10{
11 va_list args;
12 int len;
13
14 if (likely(m->count < S_SIZE)) {
15 va_start(args, f);
16 len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args);
17 va_end(args);
18 if (likely(m->count + len < S_SIZE)) {
19 m->count += len;
20 return 0;
21 }
22 }
23 m->count = S_SIZE;
24 printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n");
25 return -1;
26}
27
28static struct sbuff *sb_open(void)
29{
30 struct sbuff *m = kmalloc(sizeof(*m), GFP_ATOMIC);
31
32 if (unlikely(!m)) {
33 local_bh_disable();
34 do {
35 m = xchg(&emergency_ptr, NULL);
36 } while (!m);
37 }
38 m->count = 0;
39 return m;
40}
41
42static void sb_close(struct sbuff *m)
43{
44 m->buf[m->count] = 0;
45 printk("%s\n", m->buf);
46
47 if (likely(m != &emergency))
48 kfree(m);
49 else {
50 emergency_ptr = m;
51 local_bh_enable();
52 }
53}
54
diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
index 773cce308bc6..29d6a94db54d 100644
--- a/include/net/netns/conntrack.h
+++ b/include/net/netns/conntrack.h
@@ -4,6 +4,7 @@
4#include <linux/list.h> 4#include <linux/list.h>
5#include <linux/list_nulls.h> 5#include <linux/list_nulls.h>
6#include <linux/atomic.h> 6#include <linux/atomic.h>
7#include <linux/workqueue.h>
7#include <linux/netfilter/nf_conntrack_tcp.h> 8#include <linux/netfilter/nf_conntrack_tcp.h>
8#include <linux/seqlock.h> 9#include <linux/seqlock.h>
9 10
@@ -73,6 +74,10 @@ struct ct_pcpu {
73struct netns_ct { 74struct netns_ct {
74 atomic_t count; 75 atomic_t count;
75 unsigned int expect_count; 76 unsigned int expect_count;
77#ifdef CONFIG_NF_CONNTRACK_EVENTS
78 struct delayed_work ecache_dwork;
79 bool ecache_dwork_pending;
80#endif
76#ifdef CONFIG_SYSCTL 81#ifdef CONFIG_SYSCTL
77 struct ctl_table_header *sysctl_header; 82 struct ctl_table_header *sysctl_header;
78 struct ctl_table_header *acct_sysctl_header; 83 struct ctl_table_header *acct_sysctl_header;
@@ -82,7 +87,6 @@ struct netns_ct {
82#endif 87#endif
83 char *slabname; 88 char *slabname;
84 unsigned int sysctl_log_invalid; /* Log invalid packets */ 89 unsigned int sysctl_log_invalid; /* Log invalid packets */
85 unsigned int sysctl_events_retry_timeout;
86 int sysctl_events; 90 int sysctl_events;
87 int sysctl_acct; 91 int sysctl_acct;
88 int sysctl_auto_assign_helper; 92 int sysctl_auto_assign_helper;
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 2a88f645a5d8..801bdd1e56e3 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -697,6 +697,8 @@ enum nft_counter_attributes {
697 * @NFTA_LOG_PREFIX: prefix to prepend to log messages (NLA_STRING) 697 * @NFTA_LOG_PREFIX: prefix to prepend to log messages (NLA_STRING)
698 * @NFTA_LOG_SNAPLEN: length of payload to include in netlink message (NLA_U32) 698 * @NFTA_LOG_SNAPLEN: length of payload to include in netlink message (NLA_U32)
699 * @NFTA_LOG_QTHRESHOLD: queue threshold (NLA_U32) 699 * @NFTA_LOG_QTHRESHOLD: queue threshold (NLA_U32)
700 * @NFTA_LOG_LEVEL: log level (NLA_U32)
701 * @NFTA_LOG_FLAGS: logging flags (NLA_U32)
700 */ 702 */
701enum nft_log_attributes { 703enum nft_log_attributes {
702 NFTA_LOG_UNSPEC, 704 NFTA_LOG_UNSPEC,
@@ -704,6 +706,8 @@ enum nft_log_attributes {
704 NFTA_LOG_PREFIX, 706 NFTA_LOG_PREFIX,
705 NFTA_LOG_SNAPLEN, 707 NFTA_LOG_SNAPLEN,
706 NFTA_LOG_QTHRESHOLD, 708 NFTA_LOG_QTHRESHOLD,
709 NFTA_LOG_LEVEL,
710 NFTA_LOG_FLAGS,
707 __NFTA_LOG_MAX 711 __NFTA_LOG_MAX
708}; 712};
709#define NFTA_LOG_MAX (__NFTA_LOG_MAX - 1) 713#define NFTA_LOG_MAX (__NFTA_LOG_MAX - 1)
diff --git a/include/uapi/linux/netfilter_bridge/Kbuild b/include/uapi/linux/netfilter_bridge/Kbuild
index 348717c3a22f..0fbad8ef96de 100644
--- a/include/uapi/linux/netfilter_bridge/Kbuild
+++ b/include/uapi/linux/netfilter_bridge/Kbuild
@@ -14,6 +14,5 @@ header-y += ebt_nflog.h
14header-y += ebt_pkttype.h 14header-y += ebt_pkttype.h
15header-y += ebt_redirect.h 15header-y += ebt_redirect.h
16header-y += ebt_stp.h 16header-y += ebt_stp.h
17header-y += ebt_ulog.h
18header-y += ebt_vlan.h 17header-y += ebt_vlan.h
19header-y += ebtables.h 18header-y += ebtables.h
diff --git a/include/uapi/linux/netfilter_bridge/ebt_ulog.h b/include/uapi/linux/netfilter_bridge/ebt_ulog.h
deleted file mode 100644
index 89a6becb5269..000000000000
--- a/include/uapi/linux/netfilter_bridge/ebt_ulog.h
+++ /dev/null
@@ -1,38 +0,0 @@
1#ifndef _EBT_ULOG_H
2#define _EBT_ULOG_H
3
4#include <linux/types.h>
5
6#define EBT_ULOG_DEFAULT_NLGROUP 0
7#define EBT_ULOG_DEFAULT_QTHRESHOLD 1
8#define EBT_ULOG_MAXNLGROUPS 32 /* hardcoded netlink max */
9#define EBT_ULOG_PREFIX_LEN 32
10#define EBT_ULOG_MAX_QLEN 50
11#define EBT_ULOG_WATCHER "ulog"
12#define EBT_ULOG_VERSION 1
13
14struct ebt_ulog_info {
15 __u32 nlgroup;
16 unsigned int cprange;
17 unsigned int qthreshold;
18 char prefix[EBT_ULOG_PREFIX_LEN];
19};
20
21typedef struct ebt_ulog_packet_msg {
22 int version;
23 char indev[IFNAMSIZ];
24 char outdev[IFNAMSIZ];
25 char physindev[IFNAMSIZ];
26 char physoutdev[IFNAMSIZ];
27 char prefix[EBT_ULOG_PREFIX_LEN];
28 struct timeval stamp;
29 unsigned long mark;
30 unsigned int hook;
31 size_t data_len;
32 /* The complete packet, including Ethernet header and perhaps
33 * the VLAN header is appended */
34 unsigned char data[0] __attribute__
35 ((aligned (__alignof__(struct ebt_ulog_info))));
36} ebt_ulog_packet_msg_t;
37
38#endif /* _EBT_ULOG_H */
diff --git a/include/uapi/linux/netfilter_ipv4/Kbuild b/include/uapi/linux/netfilter_ipv4/Kbuild
index fb008437dde1..ecb291df390e 100644
--- a/include/uapi/linux/netfilter_ipv4/Kbuild
+++ b/include/uapi/linux/netfilter_ipv4/Kbuild
@@ -5,7 +5,6 @@ header-y += ipt_ECN.h
5header-y += ipt_LOG.h 5header-y += ipt_LOG.h
6header-y += ipt_REJECT.h 6header-y += ipt_REJECT.h
7header-y += ipt_TTL.h 7header-y += ipt_TTL.h
8header-y += ipt_ULOG.h
9header-y += ipt_ah.h 8header-y += ipt_ah.h
10header-y += ipt_ecn.h 9header-y += ipt_ecn.h
11header-y += ipt_ttl.h 10header-y += ipt_ttl.h
diff --git a/include/uapi/linux/netfilter_ipv4/ipt_ULOG.h b/include/uapi/linux/netfilter_ipv4/ipt_ULOG.h
deleted file mode 100644
index 417aad280bcc..000000000000
--- a/include/uapi/linux/netfilter_ipv4/ipt_ULOG.h
+++ /dev/null
@@ -1,49 +0,0 @@
1/* Header file for IP tables userspace logging, Version 1.8
2 *
3 * (C) 2000-2002 by Harald Welte <laforge@gnumonks.org>
4 *
5 * Distributed under the terms of GNU GPL */
6
7#ifndef _IPT_ULOG_H
8#define _IPT_ULOG_H
9
10#ifndef NETLINK_NFLOG
11#define NETLINK_NFLOG 5
12#endif
13
14#define ULOG_DEFAULT_NLGROUP 1
15#define ULOG_DEFAULT_QTHRESHOLD 1
16
17#define ULOG_MAC_LEN 80
18#define ULOG_PREFIX_LEN 32
19
20#define ULOG_MAX_QLEN 50
21/* Why 50? Well... there is a limit imposed by the slab cache 131000
22 * bytes. So the multipart netlink-message has to be < 131000 bytes.
23 * Assuming a standard ethernet-mtu of 1500, we could define this up
24 * to 80... but even 50 seems to be big enough. */
25
26/* private data structure for each rule with a ULOG target */
27struct ipt_ulog_info {
28 unsigned int nl_group;
29 size_t copy_range;
30 size_t qthreshold;
31 char prefix[ULOG_PREFIX_LEN];
32};
33
34/* Format of the ULOG packets passed through netlink */
35typedef struct ulog_packet_msg {
36 unsigned long mark;
37 long timestamp_sec;
38 long timestamp_usec;
39 unsigned int hook;
40 char indev_name[IFNAMSIZ];
41 char outdev_name[IFNAMSIZ];
42 size_t data_len;
43 char prefix[ULOG_PREFIX_LEN];
44 unsigned char mac_len;
45 unsigned char mac[ULOG_MAC_LEN];
46 unsigned char payload[0];
47} ulog_packet_msg_t;
48
49#endif /*_IPT_ULOG_H*/
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index 629dc77874a9..4ce0b313f72c 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -14,6 +14,9 @@ config NFT_BRIDGE_META
14 help 14 help
15 Add support for bridge dedicated meta key. 15 Add support for bridge dedicated meta key.
16 16
17config NF_LOG_BRIDGE
18 tristate "Bridge packet logging"
19
17endif # NF_TABLES_BRIDGE 20endif # NF_TABLES_BRIDGE
18 21
19menuconfig BRIDGE_NF_EBTABLES 22menuconfig BRIDGE_NF_EBTABLES
@@ -202,22 +205,6 @@ config BRIDGE_EBT_LOG
202 205
203 To compile it as a module, choose M here. If unsure, say N. 206 To compile it as a module, choose M here. If unsure, say N.
204 207
205config BRIDGE_EBT_ULOG
206 tristate "ebt: ulog support (OBSOLETE)"
207 help
208 This option enables the old bridge-specific "ebt_ulog" implementation
209 which has been obsoleted by the new "nfnetlink_log" code (see
210 CONFIG_NETFILTER_NETLINK_LOG).
211
212 This option adds the ulog watcher, that you can use in any rule
213 in any ebtables table. The packet is passed to a userspace
214 logging daemon using netlink multicast sockets. This differs
215 from the log watcher in the sense that the complete packet is
216 sent to userspace instead of a descriptive text and that
217 netlink multicast sockets are used instead of the syslog.
218
219 To compile it as a module, choose M here. If unsure, say N.
220
221config BRIDGE_EBT_NFLOG 208config BRIDGE_EBT_NFLOG
222 tristate "ebt: nflog support" 209 tristate "ebt: nflog support"
223 help 210 help
diff --git a/net/bridge/netfilter/Makefile b/net/bridge/netfilter/Makefile
index 6f2f3943d66f..1f78ea0d90e4 100644
--- a/net/bridge/netfilter/Makefile
+++ b/net/bridge/netfilter/Makefile
@@ -5,6 +5,9 @@
5obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o 5obj-$(CONFIG_NF_TABLES_BRIDGE) += nf_tables_bridge.o
6obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o 6obj-$(CONFIG_NFT_BRIDGE_META) += nft_meta_bridge.o
7 7
8# packet logging
9obj-$(CONFIG_NF_LOG_BRIDGE) += nf_log_bridge.o
10
8obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o 11obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o
9 12
10# tables 13# tables
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 5322a36867a3..17f2e4bc2a29 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -186,6 +186,10 @@ ebt_log_tg(struct sk_buff *skb, const struct xt_action_param *par)
186 li.u.log.level = info->loglevel; 186 li.u.log.level = info->loglevel;
187 li.u.log.logflags = info->bitmask; 187 li.u.log.logflags = info->bitmask;
188 188
189 /* Remember that we have to use ebt_log_packet() not to break backward
190 * compatibility. We cannot use the default bridge packet logger via
191 * nf_log_packet() with NFT_LOG_TYPE_LOG here. --Pablo
192 */
189 if (info->bitmask & EBT_LOG_NFLOG) 193 if (info->bitmask & EBT_LOG_NFLOG)
190 nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb, 194 nf_log_packet(net, NFPROTO_BRIDGE, par->hooknum, skb,
191 par->in, par->out, &li, "%s", info->prefix); 195 par->in, par->out, &li, "%s", info->prefix);
@@ -205,54 +209,13 @@ static struct xt_target ebt_log_tg_reg __read_mostly = {
205 .me = THIS_MODULE, 209 .me = THIS_MODULE,
206}; 210};
207 211
208static struct nf_logger ebt_log_logger __read_mostly = {
209 .name = "ebt_log",
210 .logfn = &ebt_log_packet,
211 .me = THIS_MODULE,
212};
213
214static int __net_init ebt_log_net_init(struct net *net)
215{
216 nf_log_set(net, NFPROTO_BRIDGE, &ebt_log_logger);
217 return 0;
218}
219
220static void __net_exit ebt_log_net_fini(struct net *net)
221{
222 nf_log_unset(net, &ebt_log_logger);
223}
224
225static struct pernet_operations ebt_log_net_ops = {
226 .init = ebt_log_net_init,
227 .exit = ebt_log_net_fini,
228};
229
230static int __init ebt_log_init(void) 212static int __init ebt_log_init(void)
231{ 213{
232 int ret; 214 return xt_register_target(&ebt_log_tg_reg);
233
234 ret = register_pernet_subsys(&ebt_log_net_ops);
235 if (ret < 0)
236 goto err_pernet;
237
238 ret = xt_register_target(&ebt_log_tg_reg);
239 if (ret < 0)
240 goto err_target;
241
242 nf_log_register(NFPROTO_BRIDGE, &ebt_log_logger);
243
244 return ret;
245
246err_target:
247 unregister_pernet_subsys(&ebt_log_net_ops);
248err_pernet:
249 return ret;
250} 215}
251 216
252static void __exit ebt_log_fini(void) 217static void __exit ebt_log_fini(void)
253{ 218{
254 unregister_pernet_subsys(&ebt_log_net_ops);
255 nf_log_unregister(&ebt_log_logger);
256 xt_unregister_target(&ebt_log_tg_reg); 219 xt_unregister_target(&ebt_log_tg_reg);
257} 220}
258 221
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
deleted file mode 100644
index 7c470c371e14..000000000000
--- a/net/bridge/netfilter/ebt_ulog.c
+++ /dev/null
@@ -1,393 +0,0 @@
1/*
2 * netfilter module for userspace bridged Ethernet frames logging daemons
3 *
4 * Authors:
5 * Bart De Schuymer <bdschuym@pandora.be>
6 * Harald Welte <laforge@netfilter.org>
7 *
8 * November, 2004
9 *
10 * Based on ipt_ULOG.c, which is
11 * (C) 2000-2002 by Harald Welte <laforge@netfilter.org>
12 *
13 * This module accepts two parameters:
14 *
15 * nlbufsiz:
16 * The parameter specifies how big the buffer for each netlink multicast
17 * group is. e.g. If you say nlbufsiz=8192, up to eight kb of packets will
18 * get accumulated in the kernel until they are sent to userspace. It is
19 * NOT possible to allocate more than 128kB, and it is strongly discouraged,
20 * because atomically allocating 128kB inside the network rx softirq is not
21 * reliable. Please also keep in mind that this buffer size is allocated for
22 * each nlgroup you are using, so the total kernel memory usage increases
23 * by that factor.
24 *
25 * flushtimeout:
26 * Specify, after how many hundredths of a second the queue should be
27 * flushed even if it is not full yet.
28 *
29 */
30#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31#include <linux/module.h>
32#include <linux/slab.h>
33#include <linux/spinlock.h>
34#include <linux/socket.h>
35#include <linux/skbuff.h>
36#include <linux/kernel.h>
37#include <linux/timer.h>
38#include <net/netlink.h>
39#include <linux/netdevice.h>
40#include <linux/netfilter/x_tables.h>
41#include <linux/netfilter_bridge/ebtables.h>
42#include <linux/netfilter_bridge/ebt_ulog.h>
43#include <net/netfilter/nf_log.h>
44#include <net/netns/generic.h>
45#include <net/sock.h>
46#include "../br_private.h"
47
48static unsigned int nlbufsiz = NLMSG_GOODSIZE;
49module_param(nlbufsiz, uint, 0600);
50MODULE_PARM_DESC(nlbufsiz, "netlink buffer size (number of bytes) "
51 "(defaults to 4096)");
52
53static unsigned int flushtimeout = 10;
54module_param(flushtimeout, uint, 0600);
55MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths ofa second) "
56 "(defaults to 10)");
57
58typedef struct {
59 unsigned int qlen; /* number of nlmsgs' in the skb */
60 struct nlmsghdr *lastnlh; /* netlink header of last msg in skb */
61 struct sk_buff *skb; /* the pre-allocated skb */
62 struct timer_list timer; /* the timer function */
63 spinlock_t lock; /* the per-queue lock */
64} ebt_ulog_buff_t;
65
66static int ebt_ulog_net_id __read_mostly;
67struct ebt_ulog_net {
68 unsigned int nlgroup[EBT_ULOG_MAXNLGROUPS];
69 ebt_ulog_buff_t ulog_buffers[EBT_ULOG_MAXNLGROUPS];
70 struct sock *ebtulognl;
71};
72
73static struct ebt_ulog_net *ebt_ulog_pernet(struct net *net)
74{
75 return net_generic(net, ebt_ulog_net_id);
76}
77
78/* send one ulog_buff_t to userspace */
79static void ulog_send(struct ebt_ulog_net *ebt, unsigned int nlgroup)
80{
81 ebt_ulog_buff_t *ub = &ebt->ulog_buffers[nlgroup];
82
83 del_timer(&ub->timer);
84
85 if (!ub->skb)
86 return;
87
88 /* last nlmsg needs NLMSG_DONE */
89 if (ub->qlen > 1)
90 ub->lastnlh->nlmsg_type = NLMSG_DONE;
91
92 NETLINK_CB(ub->skb).dst_group = nlgroup + 1;
93 netlink_broadcast(ebt->ebtulognl, ub->skb, 0, nlgroup + 1, GFP_ATOMIC);
94
95 ub->qlen = 0;
96 ub->skb = NULL;
97}
98
99/* timer function to flush queue in flushtimeout time */
100static void ulog_timer(unsigned long data)
101{
102 struct ebt_ulog_net *ebt = container_of((void *)data,
103 struct ebt_ulog_net,
104 nlgroup[*(unsigned int *)data]);
105
106 ebt_ulog_buff_t *ub = &ebt->ulog_buffers[*(unsigned int *)data];
107 spin_lock_bh(&ub->lock);
108 if (ub->skb)
109 ulog_send(ebt, *(unsigned int *)data);
110 spin_unlock_bh(&ub->lock);
111}
112
113static struct sk_buff *ulog_alloc_skb(unsigned int size)
114{
115 struct sk_buff *skb;
116 unsigned int n;
117
118 n = max(size, nlbufsiz);
119 skb = alloc_skb(n, GFP_ATOMIC | __GFP_NOWARN);
120 if (!skb) {
121 if (n > size) {
122 /* try to allocate only as much as we need for
123 * current packet */
124 skb = alloc_skb(size, GFP_ATOMIC);
125 if (!skb)
126 pr_debug("cannot even allocate buffer of size %ub\n",
127 size);
128 }
129 }
130
131 return skb;
132}
133
134static void ebt_ulog_packet(struct net *net, unsigned int hooknr,
135 const struct sk_buff *skb,
136 const struct net_device *in,
137 const struct net_device *out,
138 const struct ebt_ulog_info *uloginfo,
139 const char *prefix)
140{
141 ebt_ulog_packet_msg_t *pm;
142 size_t size, copy_len;
143 struct nlmsghdr *nlh;
144 struct ebt_ulog_net *ebt = ebt_ulog_pernet(net);
145 unsigned int group = uloginfo->nlgroup;
146 ebt_ulog_buff_t *ub = &ebt->ulog_buffers[group];
147 spinlock_t *lock = &ub->lock;
148 ktime_t kt;
149
150 if ((uloginfo->cprange == 0) ||
151 (uloginfo->cprange > skb->len + ETH_HLEN))
152 copy_len = skb->len + ETH_HLEN;
153 else
154 copy_len = uloginfo->cprange;
155
156 size = nlmsg_total_size(sizeof(*pm) + copy_len);
157 if (size > nlbufsiz) {
158 pr_debug("Size %Zd needed, but nlbufsiz=%d\n", size, nlbufsiz);
159 return;
160 }
161
162 spin_lock_bh(lock);
163
164 if (!ub->skb) {
165 if (!(ub->skb = ulog_alloc_skb(size)))
166 goto unlock;
167 } else if (size > skb_tailroom(ub->skb)) {
168 ulog_send(ebt, group);
169
170 if (!(ub->skb = ulog_alloc_skb(size)))
171 goto unlock;
172 }
173
174 nlh = nlmsg_put(ub->skb, 0, ub->qlen, 0,
175 size - NLMSG_ALIGN(sizeof(*nlh)), 0);
176 if (!nlh) {
177 kfree_skb(ub->skb);
178 ub->skb = NULL;
179 goto unlock;
180 }
181 ub->qlen++;
182
183 pm = nlmsg_data(nlh);
184 memset(pm, 0, sizeof(*pm));
185
186 /* Fill in the ulog data */
187 pm->version = EBT_ULOG_VERSION;
188 kt = ktime_get_real();
189 pm->stamp = ktime_to_timeval(kt);
190 if (ub->qlen == 1)
191 ub->skb->tstamp = kt;
192 pm->data_len = copy_len;
193 pm->mark = skb->mark;
194 pm->hook = hooknr;
195 if (uloginfo->prefix != NULL)
196 strcpy(pm->prefix, uloginfo->prefix);
197
198 if (in) {
199 strcpy(pm->physindev, in->name);
200 /* If in isn't a bridge, then physindev==indev */
201 if (br_port_exists(in))
202 /* rcu_read_lock()ed by nf_hook_slow */
203 strcpy(pm->indev, br_port_get_rcu(in)->br->dev->name);
204 else
205 strcpy(pm->indev, in->name);
206 }
207
208 if (out) {
209 /* If out exists, then out is a bridge port */
210 strcpy(pm->physoutdev, out->name);
211 /* rcu_read_lock()ed by nf_hook_slow */
212 strcpy(pm->outdev, br_port_get_rcu(out)->br->dev->name);
213 }
214
215 if (skb_copy_bits(skb, -ETH_HLEN, pm->data, copy_len) < 0)
216 BUG();
217
218 if (ub->qlen > 1)
219 ub->lastnlh->nlmsg_flags |= NLM_F_MULTI;
220
221 ub->lastnlh = nlh;
222
223 if (ub->qlen >= uloginfo->qthreshold)
224 ulog_send(ebt, group);
225 else if (!timer_pending(&ub->timer)) {
226 ub->timer.expires = jiffies + flushtimeout * HZ / 100;
227 add_timer(&ub->timer);
228 }
229
230unlock:
231 spin_unlock_bh(lock);
232}
233
234/* this function is registered with the netfilter core */
235static void ebt_log_packet(struct net *net, u_int8_t pf, unsigned int hooknum,
236 const struct sk_buff *skb, const struct net_device *in,
237 const struct net_device *out, const struct nf_loginfo *li,
238 const char *prefix)
239{
240 struct ebt_ulog_info loginfo;
241
242 if (!li || li->type != NF_LOG_TYPE_ULOG) {
243 loginfo.nlgroup = EBT_ULOG_DEFAULT_NLGROUP;
244 loginfo.cprange = 0;
245 loginfo.qthreshold = EBT_ULOG_DEFAULT_QTHRESHOLD;
246 loginfo.prefix[0] = '\0';
247 } else {
248 loginfo.nlgroup = li->u.ulog.group;
249 loginfo.cprange = li->u.ulog.copy_len;
250 loginfo.qthreshold = li->u.ulog.qthreshold;
251 strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
252 }
253
254 ebt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix);
255}
256
257static unsigned int
258ebt_ulog_tg(struct sk_buff *skb, const struct xt_action_param *par)
259{
260 struct net *net = dev_net(par->in ? par->in : par->out);
261
262 ebt_ulog_packet(net, par->hooknum, skb, par->in, par->out,
263 par->targinfo, NULL);
264 return EBT_CONTINUE;
265}
266
267static int ebt_ulog_tg_check(const struct xt_tgchk_param *par)
268{
269 struct ebt_ulog_info *uloginfo = par->targinfo;
270
271 if (!par->net->xt.ebt_ulog_warn_deprecated) {
272 pr_info("ebt_ulog is deprecated and it will be removed soon, "
273 "use ebt_nflog instead\n");
274 par->net->xt.ebt_ulog_warn_deprecated = true;
275 }
276
277 if (uloginfo->nlgroup > 31)
278 return -EINVAL;
279
280 uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
281
282 if (uloginfo->qthreshold > EBT_ULOG_MAX_QLEN)
283 uloginfo->qthreshold = EBT_ULOG_MAX_QLEN;
284
285 return 0;
286}
287
288static struct xt_target ebt_ulog_tg_reg __read_mostly = {
289 .name = "ulog",
290 .revision = 0,
291 .family = NFPROTO_BRIDGE,
292 .target = ebt_ulog_tg,
293 .checkentry = ebt_ulog_tg_check,
294 .targetsize = sizeof(struct ebt_ulog_info),
295 .me = THIS_MODULE,
296};
297
298static struct nf_logger ebt_ulog_logger __read_mostly = {
299 .name = "ebt_ulog",
300 .logfn = &ebt_log_packet,
301 .me = THIS_MODULE,
302};
303
304static int __net_init ebt_ulog_net_init(struct net *net)
305{
306 int i;
307 struct ebt_ulog_net *ebt = ebt_ulog_pernet(net);
308
309 struct netlink_kernel_cfg cfg = {
310 .groups = EBT_ULOG_MAXNLGROUPS,
311 };
312
313 /* initialize ulog_buffers */
314 for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
315 ebt->nlgroup[i] = i;
316 setup_timer(&ebt->ulog_buffers[i].timer, ulog_timer,
317 (unsigned long)&ebt->nlgroup[i]);
318 spin_lock_init(&ebt->ulog_buffers[i].lock);
319 }
320
321 ebt->ebtulognl = netlink_kernel_create(net, NETLINK_NFLOG, &cfg);
322 if (!ebt->ebtulognl)
323 return -ENOMEM;
324
325 nf_log_set(net, NFPROTO_BRIDGE, &ebt_ulog_logger);
326 return 0;
327}
328
329static void __net_exit ebt_ulog_net_fini(struct net *net)
330{
331 int i;
332 struct ebt_ulog_net *ebt = ebt_ulog_pernet(net);
333
334 nf_log_unset(net, &ebt_ulog_logger);
335 for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
336 ebt_ulog_buff_t *ub = &ebt->ulog_buffers[i];
337 del_timer(&ub->timer);
338
339 if (ub->skb) {
340 kfree_skb(ub->skb);
341 ub->skb = NULL;
342 }
343 }
344 netlink_kernel_release(ebt->ebtulognl);
345}
346
347static struct pernet_operations ebt_ulog_net_ops = {
348 .init = ebt_ulog_net_init,
349 .exit = ebt_ulog_net_fini,
350 .id = &ebt_ulog_net_id,
351 .size = sizeof(struct ebt_ulog_net),
352};
353
354static int __init ebt_ulog_init(void)
355{
356 int ret;
357
358 if (nlbufsiz >= 128*1024) {
359 pr_warn("Netlink buffer has to be <= 128kB,"
360 "please try a smaller nlbufsiz parameter.\n");
361 return -EINVAL;
362 }
363
364 ret = register_pernet_subsys(&ebt_ulog_net_ops);
365 if (ret)
366 goto out_pernet;
367
368 ret = xt_register_target(&ebt_ulog_tg_reg);
369 if (ret)
370 goto out_target;
371
372 nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger);
373
374 return 0;
375
376out_target:
377 unregister_pernet_subsys(&ebt_ulog_net_ops);
378out_pernet:
379 return ret;
380}
381
382static void __exit ebt_ulog_fini(void)
383{
384 nf_log_unregister(&ebt_ulog_logger);
385 xt_unregister_target(&ebt_ulog_tg_reg);
386 unregister_pernet_subsys(&ebt_ulog_net_ops);
387}
388
389module_init(ebt_ulog_init);
390module_exit(ebt_ulog_fini);
391MODULE_LICENSE("GPL");
392MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
393MODULE_DESCRIPTION("Ebtables: Packet logging to netlink using ULOG");
diff --git a/net/bridge/netfilter/nf_log_bridge.c b/net/bridge/netfilter/nf_log_bridge.c
new file mode 100644
index 000000000000..5d9953a90929
--- /dev/null
+++ b/net/bridge/netfilter/nf_log_bridge.c
@@ -0,0 +1,96 @@
1/*
2 * (C) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/spinlock.h>
11#include <linux/skbuff.h>
12#include <linux/if_bridge.h>
13#include <linux/ip.h>
14#include <net/route.h>
15
16#include <linux/netfilter.h>
17#include <net/netfilter/nf_log.h>
18
19static void nf_log_bridge_packet(struct net *net, u_int8_t pf,
20 unsigned int hooknum,
21 const struct sk_buff *skb,
22 const struct net_device *in,
23 const struct net_device *out,
24 const struct nf_loginfo *loginfo,
25 const char *prefix)
26{
27 switch (eth_hdr(skb)->h_proto) {
28 case htons(ETH_P_IP):
29 nf_log_packet(net, NFPROTO_IPV4, hooknum, skb, in, out,
30 loginfo, "%s", prefix);
31 break;
32 case htons(ETH_P_IPV6):
33 nf_log_packet(net, NFPROTO_IPV6, hooknum, skb, in, out,
34 loginfo, "%s", prefix);
35 break;
36 case htons(ETH_P_ARP):
37 case htons(ETH_P_RARP):
38 nf_log_packet(net, NFPROTO_ARP, hooknum, skb, in, out,
39 loginfo, "%s", prefix);
40 break;
41 }
42}
43
44static struct nf_logger nf_bridge_logger __read_mostly = {
45 .name = "nf_log_bridge",
46 .type = NF_LOG_TYPE_LOG,
47 .logfn = nf_log_bridge_packet,
48 .me = THIS_MODULE,
49};
50
51static int __net_init nf_log_bridge_net_init(struct net *net)
52{
53 nf_log_set(net, NFPROTO_BRIDGE, &nf_bridge_logger);
54 return 0;
55}
56
57static void __net_exit nf_log_bridge_net_exit(struct net *net)
58{
59 nf_log_unset(net, &nf_bridge_logger);
60}
61
62static struct pernet_operations nf_log_bridge_net_ops = {
63 .init = nf_log_bridge_net_init,
64 .exit = nf_log_bridge_net_exit,
65};
66
67static int __init nf_log_bridge_init(void)
68{
69 int ret;
70
71 /* Request to load the real packet loggers. */
72 nf_logger_request_module(NFPROTO_IPV4, NF_LOG_TYPE_LOG);
73 nf_logger_request_module(NFPROTO_IPV6, NF_LOG_TYPE_LOG);
74 nf_logger_request_module(NFPROTO_ARP, NF_LOG_TYPE_LOG);
75
76 ret = register_pernet_subsys(&nf_log_bridge_net_ops);
77 if (ret < 0)
78 return ret;
79
80 nf_log_register(NFPROTO_BRIDGE, &nf_bridge_logger);
81 return 0;
82}
83
84static void __exit nf_log_bridge_exit(void)
85{
86 unregister_pernet_subsys(&nf_log_bridge_net_ops);
87 nf_log_unregister(&nf_bridge_logger);
88}
89
90module_init(nf_log_bridge_init);
91module_exit(nf_log_bridge_exit);
92
93MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
94MODULE_DESCRIPTION("Netfilter bridge packet logging");
95MODULE_LICENSE("GPL");
96MODULE_ALIAS_NF_LOGGER(AF_BRIDGE, 0);
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index a26ce035e3fa..fb173126f03d 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -36,6 +36,16 @@ config NF_CONNTRACK_PROC_COMPAT
36 36
37 If unsure, say Y. 37 If unsure, say Y.
38 38
39config NF_LOG_ARP
40 tristate "ARP packet logging"
41 default m if NETFILTER_ADVANCED=n
42 select NF_LOG_COMMON
43
44config NF_LOG_IPV4
45 tristate "IPv4 packet logging"
46 default m if NETFILTER_ADVANCED=n
47 select NF_LOG_COMMON
48
39config NF_TABLES_IPV4 49config NF_TABLES_IPV4
40 depends on NF_TABLES 50 depends on NF_TABLES
41 tristate "IPv4 nf_tables support" 51 tristate "IPv4 nf_tables support"
@@ -159,25 +169,6 @@ config IP_NF_TARGET_SYNPROXY
159 169
160 To compile it as a module, choose M here. If unsure, say N. 170 To compile it as a module, choose M here. If unsure, say N.
161 171
162config IP_NF_TARGET_ULOG
163 tristate "ULOG target support (obsolete)"
164 default m if NETFILTER_ADVANCED=n
165 ---help---
166
167 This option enables the old IPv4-only "ipt_ULOG" implementation
168 which has been obsoleted by the new "nfnetlink_log" code (see
169 CONFIG_NETFILTER_NETLINK_LOG).
170
171 This option adds a `ULOG' target, which allows you to create rules in
172 any iptables table. The packet is passed to a userspace logging
173 daemon using netlink multicast sockets; unlike the LOG target
174 which can only be viewed through syslog.
175
176 The appropriate userspace logging daemon (ulogd) may be obtained from
177 <http://www.netfilter.org/projects/ulogd/index.html>
178
179 To compile it as a module, choose M here. If unsure, say N.
180
181# NAT + specific targets: nf_conntrack 172# NAT + specific targets: nf_conntrack
182config NF_NAT_IPV4 173config NF_NAT_IPV4
183 tristate "IPv4 NAT" 174 tristate "IPv4 NAT"
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 90b82405331e..245db9df3337 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -19,6 +19,10 @@ obj-$(CONFIG_NF_NAT_IPV4) += nf_nat_ipv4.o
19# defrag 19# defrag
20obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o 20obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
21 21
22# logging
23obj-$(CONFIG_NF_LOG_ARP) += nf_log_arp.o
24obj-$(CONFIG_NF_LOG_IPV4) += nf_log_ipv4.o
25
22# NAT helpers (nf_conntrack) 26# NAT helpers (nf_conntrack)
23obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o 27obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
24obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o 28obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
deleted file mode 100644
index 9cb993cd224b..000000000000
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ /dev/null
@@ -1,498 +0,0 @@
1/*
2 * netfilter module for userspace packet logging daemons
3 *
4 * (C) 2000-2004 by Harald Welte <laforge@netfilter.org>
5 * (C) 1999-2001 Paul `Rusty' Russell
6 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
7 * (C) 2005-2007 Patrick McHardy <kaber@trash.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This module accepts two parameters:
14 *
15 * nlbufsiz:
16 * The parameter specifies how big the buffer for each netlink multicast
17 * group is. e.g. If you say nlbufsiz=8192, up to eight kb of packets will
18 * get accumulated in the kernel until they are sent to userspace. It is
19 * NOT possible to allocate more than 128kB, and it is strongly discouraged,
20 * because atomically allocating 128kB inside the network rx softirq is not
21 * reliable. Please also keep in mind that this buffer size is allocated for
22 * each nlgroup you are using, so the total kernel memory usage increases
23 * by that factor.
24 *
25 * Actually you should use nlbufsiz a bit smaller than PAGE_SIZE, since
26 * nlbufsiz is used with alloc_skb, which adds another
27 * sizeof(struct skb_shared_info). Use NLMSG_GOODSIZE instead.
28 *
29 * flushtimeout:
30 * Specify, after how many hundredths of a second the queue should be
31 * flushed even if it is not full yet.
32 */
33#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
34#include <linux/module.h>
35#include <linux/spinlock.h>
36#include <linux/socket.h>
37#include <linux/slab.h>
38#include <linux/skbuff.h>
39#include <linux/kernel.h>
40#include <linux/timer.h>
41#include <net/netlink.h>
42#include <linux/netdevice.h>
43#include <linux/mm.h>
44#include <linux/moduleparam.h>
45#include <linux/netfilter.h>
46#include <linux/netfilter/x_tables.h>
47#include <linux/netfilter_ipv4/ipt_ULOG.h>
48#include <net/netfilter/nf_log.h>
49#include <net/netns/generic.h>
50#include <net/sock.h>
51#include <linux/bitops.h>
52#include <asm/unaligned.h>
53
54MODULE_LICENSE("GPL");
55MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
56MODULE_DESCRIPTION("Xtables: packet logging to netlink using ULOG");
57MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_NFLOG);
58
59#define ULOG_NL_EVENT 111 /* Harald's favorite number */
60#define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */
61
62static unsigned int nlbufsiz = NLMSG_GOODSIZE;
63module_param(nlbufsiz, uint, 0400);
64MODULE_PARM_DESC(nlbufsiz, "netlink buffer size");
65
66static unsigned int flushtimeout = 10;
67module_param(flushtimeout, uint, 0600);
68MODULE_PARM_DESC(flushtimeout, "buffer flush timeout (hundredths of a second)");
69
70static bool nflog = true;
71module_param(nflog, bool, 0400);
72MODULE_PARM_DESC(nflog, "register as internal netfilter logging module");
73
74/* global data structures */
75
76typedef struct {
77 unsigned int qlen; /* number of nlmsgs' in the skb */
78 struct nlmsghdr *lastnlh; /* netlink header of last msg in skb */
79 struct sk_buff *skb; /* the pre-allocated skb */
80 struct timer_list timer; /* the timer function */
81} ulog_buff_t;
82
83static int ulog_net_id __read_mostly;
84struct ulog_net {
85 unsigned int nlgroup[ULOG_MAXNLGROUPS];
86 ulog_buff_t ulog_buffers[ULOG_MAXNLGROUPS];
87 struct sock *nflognl;
88 spinlock_t lock;
89};
90
91static struct ulog_net *ulog_pernet(struct net *net)
92{
93 return net_generic(net, ulog_net_id);
94}
95
96/* send one ulog_buff_t to userspace */
97static void ulog_send(struct ulog_net *ulog, unsigned int nlgroupnum)
98{
99 ulog_buff_t *ub = &ulog->ulog_buffers[nlgroupnum];
100
101 pr_debug("ulog_send: timer is deleting\n");
102 del_timer(&ub->timer);
103
104 if (!ub->skb) {
105 pr_debug("ulog_send: nothing to send\n");
106 return;
107 }
108
109 /* last nlmsg needs NLMSG_DONE */
110 if (ub->qlen > 1)
111 ub->lastnlh->nlmsg_type = NLMSG_DONE;
112
113 NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1;
114 pr_debug("throwing %d packets to netlink group %u\n",
115 ub->qlen, nlgroupnum + 1);
116 netlink_broadcast(ulog->nflognl, ub->skb, 0, nlgroupnum + 1,
117 GFP_ATOMIC);
118
119 ub->qlen = 0;
120 ub->skb = NULL;
121 ub->lastnlh = NULL;
122}
123
124
125/* timer function to flush queue in flushtimeout time */
126static void ulog_timer(unsigned long data)
127{
128 unsigned int groupnum = *((unsigned int *)data);
129 struct ulog_net *ulog = container_of((void *)data,
130 struct ulog_net,
131 nlgroup[groupnum]);
132 pr_debug("timer function called, calling ulog_send\n");
133
134 /* lock to protect against somebody modifying our structure
135 * from ipt_ulog_target at the same time */
136 spin_lock_bh(&ulog->lock);
137 ulog_send(ulog, groupnum);
138 spin_unlock_bh(&ulog->lock);
139}
140
141static struct sk_buff *ulog_alloc_skb(unsigned int size)
142{
143 struct sk_buff *skb;
144 unsigned int n;
145
146 /* alloc skb which should be big enough for a whole
147 * multipart message. WARNING: has to be <= 131000
148 * due to slab allocator restrictions */
149
150 n = max(size, nlbufsiz);
151 skb = alloc_skb(n, GFP_ATOMIC | __GFP_NOWARN);
152 if (!skb) {
153 if (n > size) {
154 /* try to allocate only as much as we need for
155 * current packet */
156
157 skb = alloc_skb(size, GFP_ATOMIC);
158 if (!skb)
159 pr_debug("cannot even allocate %ub\n", size);
160 }
161 }
162
163 return skb;
164}
165
166static void ipt_ulog_packet(struct net *net,
167 unsigned int hooknum,
168 const struct sk_buff *skb,
169 const struct net_device *in,
170 const struct net_device *out,
171 const struct ipt_ulog_info *loginfo,
172 const char *prefix)
173{
174 ulog_buff_t *ub;
175 ulog_packet_msg_t *pm;
176 size_t size, copy_len;
177 struct nlmsghdr *nlh;
178 struct timeval tv;
179 struct ulog_net *ulog = ulog_pernet(net);
180
181 /* ffs == find first bit set, necessary because userspace
182 * is already shifting groupnumber, but we need unshifted.
183 * ffs() returns [1..32], we need [0..31] */
184 unsigned int groupnum = ffs(loginfo->nl_group) - 1;
185
186 /* calculate the size of the skb needed */
187 if (loginfo->copy_range == 0 || loginfo->copy_range > skb->len)
188 copy_len = skb->len;
189 else
190 copy_len = loginfo->copy_range;
191
192 size = nlmsg_total_size(sizeof(*pm) + copy_len);
193
194 ub = &ulog->ulog_buffers[groupnum];
195
196 spin_lock_bh(&ulog->lock);
197
198 if (!ub->skb) {
199 if (!(ub->skb = ulog_alloc_skb(size)))
200 goto alloc_failure;
201 } else if (ub->qlen >= loginfo->qthreshold ||
202 size > skb_tailroom(ub->skb)) {
203 /* either the queue len is too high or we don't have
204 * enough room in nlskb left. send it to userspace. */
205
206 ulog_send(ulog, groupnum);
207
208 if (!(ub->skb = ulog_alloc_skb(size)))
209 goto alloc_failure;
210 }
211
212 pr_debug("qlen %d, qthreshold %Zu\n", ub->qlen, loginfo->qthreshold);
213
214 nlh = nlmsg_put(ub->skb, 0, ub->qlen, ULOG_NL_EVENT,
215 sizeof(*pm)+copy_len, 0);
216 if (!nlh) {
217 pr_debug("error during nlmsg_put\n");
218 goto out_unlock;
219 }
220 ub->qlen++;
221
222 pm = nlmsg_data(nlh);
223 memset(pm, 0, sizeof(*pm));
224
225 /* We might not have a timestamp, get one */
226 if (skb->tstamp.tv64 == 0)
227 __net_timestamp((struct sk_buff *)skb);
228
229 /* copy hook, prefix, timestamp, payload, etc. */
230 pm->data_len = copy_len;
231 tv = ktime_to_timeval(skb->tstamp);
232 put_unaligned(tv.tv_sec, &pm->timestamp_sec);
233 put_unaligned(tv.tv_usec, &pm->timestamp_usec);
234 put_unaligned(skb->mark, &pm->mark);
235 pm->hook = hooknum;
236 if (prefix != NULL) {
237 strncpy(pm->prefix, prefix, sizeof(pm->prefix) - 1);
238 pm->prefix[sizeof(pm->prefix) - 1] = '\0';
239 }
240 else if (loginfo->prefix[0] != '\0')
241 strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix));
242
243 if (in && in->hard_header_len > 0 &&
244 skb->mac_header != skb->network_header &&
245 in->hard_header_len <= ULOG_MAC_LEN) {
246 memcpy(pm->mac, skb_mac_header(skb), in->hard_header_len);
247 pm->mac_len = in->hard_header_len;
248 } else
249 pm->mac_len = 0;
250
251 if (in)
252 strncpy(pm->indev_name, in->name, sizeof(pm->indev_name));
253
254 if (out)
255 strncpy(pm->outdev_name, out->name, sizeof(pm->outdev_name));
256
257 /* copy_len <= skb->len, so can't fail. */
258 if (skb_copy_bits(skb, 0, pm->payload, copy_len) < 0)
259 BUG();
260
261 /* check if we are building multi-part messages */
262 if (ub->qlen > 1)
263 ub->lastnlh->nlmsg_flags |= NLM_F_MULTI;
264
265 ub->lastnlh = nlh;
266
267 /* if timer isn't already running, start it */
268 if (!timer_pending(&ub->timer)) {
269 ub->timer.expires = jiffies + flushtimeout * HZ / 100;
270 add_timer(&ub->timer);
271 }
272
273 /* if threshold is reached, send message to userspace */
274 if (ub->qlen >= loginfo->qthreshold) {
275 if (loginfo->qthreshold > 1)
276 nlh->nlmsg_type = NLMSG_DONE;
277 ulog_send(ulog, groupnum);
278 }
279out_unlock:
280 spin_unlock_bh(&ulog->lock);
281
282 return;
283
284alloc_failure:
285 pr_debug("Error building netlink message\n");
286 spin_unlock_bh(&ulog->lock);
287}
288
289static unsigned int
290ulog_tg(struct sk_buff *skb, const struct xt_action_param *par)
291{
292 struct net *net = dev_net(par->in ? par->in : par->out);
293
294 ipt_ulog_packet(net, par->hooknum, skb, par->in, par->out,
295 par->targinfo, NULL);
296 return XT_CONTINUE;
297}
298
299static void ipt_logfn(struct net *net,
300 u_int8_t pf,
301 unsigned int hooknum,
302 const struct sk_buff *skb,
303 const struct net_device *in,
304 const struct net_device *out,
305 const struct nf_loginfo *li,
306 const char *prefix)
307{
308 struct ipt_ulog_info loginfo;
309
310 if (!li || li->type != NF_LOG_TYPE_ULOG) {
311 loginfo.nl_group = ULOG_DEFAULT_NLGROUP;
312 loginfo.copy_range = 0;
313 loginfo.qthreshold = ULOG_DEFAULT_QTHRESHOLD;
314 loginfo.prefix[0] = '\0';
315 } else {
316 loginfo.nl_group = li->u.ulog.group;
317 loginfo.copy_range = li->u.ulog.copy_len;
318 loginfo.qthreshold = li->u.ulog.qthreshold;
319 strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
320 }
321
322 ipt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix);
323}
324
325static int ulog_tg_check(const struct xt_tgchk_param *par)
326{
327 const struct ipt_ulog_info *loginfo = par->targinfo;
328
329 if (!par->net->xt.ulog_warn_deprecated) {
330 pr_info("ULOG is deprecated and it will be removed soon, "
331 "use NFLOG instead\n");
332 par->net->xt.ulog_warn_deprecated = true;
333 }
334
335 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
336 pr_debug("prefix not null-terminated\n");
337 return -EINVAL;
338 }
339 if (loginfo->qthreshold > ULOG_MAX_QLEN) {
340 pr_debug("queue threshold %Zu > MAX_QLEN\n",
341 loginfo->qthreshold);
342 return -EINVAL;
343 }
344 return 0;
345}
346
347#ifdef CONFIG_COMPAT
348struct compat_ipt_ulog_info {
349 compat_uint_t nl_group;
350 compat_size_t copy_range;
351 compat_size_t qthreshold;
352 char prefix[ULOG_PREFIX_LEN];
353};
354
355static void ulog_tg_compat_from_user(void *dst, const void *src)
356{
357 const struct compat_ipt_ulog_info *cl = src;
358 struct ipt_ulog_info l = {
359 .nl_group = cl->nl_group,
360 .copy_range = cl->copy_range,
361 .qthreshold = cl->qthreshold,
362 };
363
364 memcpy(l.prefix, cl->prefix, sizeof(l.prefix));
365 memcpy(dst, &l, sizeof(l));
366}
367
368static int ulog_tg_compat_to_user(void __user *dst, const void *src)
369{
370 const struct ipt_ulog_info *l = src;
371 struct compat_ipt_ulog_info cl = {
372 .nl_group = l->nl_group,
373 .copy_range = l->copy_range,
374 .qthreshold = l->qthreshold,
375 };
376
377 memcpy(cl.prefix, l->prefix, sizeof(cl.prefix));
378 return copy_to_user(dst, &cl, sizeof(cl)) ? -EFAULT : 0;
379}
380#endif /* CONFIG_COMPAT */
381
382static struct xt_target ulog_tg_reg __read_mostly = {
383 .name = "ULOG",
384 .family = NFPROTO_IPV4,
385 .target = ulog_tg,
386 .targetsize = sizeof(struct ipt_ulog_info),
387 .checkentry = ulog_tg_check,
388#ifdef CONFIG_COMPAT
389 .compatsize = sizeof(struct compat_ipt_ulog_info),
390 .compat_from_user = ulog_tg_compat_from_user,
391 .compat_to_user = ulog_tg_compat_to_user,
392#endif
393 .me = THIS_MODULE,
394};
395
396static struct nf_logger ipt_ulog_logger __read_mostly = {
397 .name = "ipt_ULOG",
398 .logfn = ipt_logfn,
399 .me = THIS_MODULE,
400};
401
402static int __net_init ulog_tg_net_init(struct net *net)
403{
404 int i;
405 struct ulog_net *ulog = ulog_pernet(net);
406 struct netlink_kernel_cfg cfg = {
407 .groups = ULOG_MAXNLGROUPS,
408 };
409
410 spin_lock_init(&ulog->lock);
411 /* initialize ulog_buffers */
412 for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
413 ulog->nlgroup[i] = i;
414 setup_timer(&ulog->ulog_buffers[i].timer, ulog_timer,
415 (unsigned long)&ulog->nlgroup[i]);
416 }
417
418 ulog->nflognl = netlink_kernel_create(net, NETLINK_NFLOG, &cfg);
419 if (!ulog->nflognl)
420 return -ENOMEM;
421
422 if (nflog)
423 nf_log_set(net, NFPROTO_IPV4, &ipt_ulog_logger);
424
425 return 0;
426}
427
428static void __net_exit ulog_tg_net_exit(struct net *net)
429{
430 ulog_buff_t *ub;
431 int i;
432 struct ulog_net *ulog = ulog_pernet(net);
433
434 if (nflog)
435 nf_log_unset(net, &ipt_ulog_logger);
436
437 netlink_kernel_release(ulog->nflognl);
438
439 /* remove pending timers and free allocated skb's */
440 for (i = 0; i < ULOG_MAXNLGROUPS; i++) {
441 ub = &ulog->ulog_buffers[i];
442 pr_debug("timer is deleting\n");
443 del_timer(&ub->timer);
444
445 if (ub->skb) {
446 kfree_skb(ub->skb);
447 ub->skb = NULL;
448 }
449 }
450}
451
452static struct pernet_operations ulog_tg_net_ops = {
453 .init = ulog_tg_net_init,
454 .exit = ulog_tg_net_exit,
455 .id = &ulog_net_id,
456 .size = sizeof(struct ulog_net),
457};
458
459static int __init ulog_tg_init(void)
460{
461 int ret;
462 pr_debug("init module\n");
463
464 if (nlbufsiz > 128*1024) {
465 pr_warn("Netlink buffer has to be <= 128kB\n");
466 return -EINVAL;
467 }
468
469 ret = register_pernet_subsys(&ulog_tg_net_ops);
470 if (ret)
471 goto out_pernet;
472
473 ret = xt_register_target(&ulog_tg_reg);
474 if (ret < 0)
475 goto out_target;
476
477 if (nflog)
478 nf_log_register(NFPROTO_IPV4, &ipt_ulog_logger);
479
480 return 0;
481
482out_target:
483 unregister_pernet_subsys(&ulog_tg_net_ops);
484out_pernet:
485 return ret;
486}
487
488static void __exit ulog_tg_exit(void)
489{
490 pr_debug("cleanup_module\n");
491 if (nflog)
492 nf_log_unregister(&ipt_ulog_logger);
493 xt_unregister_target(&ulog_tg_reg);
494 unregister_pernet_subsys(&ulog_tg_net_ops);
495}
496
497module_init(ulog_tg_init);
498module_exit(ulog_tg_exit);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 8127dc802865..4ce44c4bc57b 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -314,7 +314,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
314 return -ENOENT; 314 return -ENOENT;
315} 315}
316 316
317#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 317#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
318 318
319#include <linux/netfilter/nfnetlink.h> 319#include <linux/netfilter/nfnetlink.h>
320#include <linux/netfilter/nfnetlink_conntrack.h> 320#include <linux/netfilter/nfnetlink_conntrack.h>
@@ -388,7 +388,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
388 .invert_tuple = ipv4_invert_tuple, 388 .invert_tuple = ipv4_invert_tuple,
389 .print_tuple = ipv4_print_tuple, 389 .print_tuple = ipv4_print_tuple,
390 .get_l4proto = ipv4_get_l4proto, 390 .get_l4proto = ipv4_get_l4proto,
391#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 391#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
392 .tuple_to_nlattr = ipv4_tuple_to_nlattr, 392 .tuple_to_nlattr = ipv4_tuple_to_nlattr,
393 .nlattr_tuple_size = ipv4_nlattr_tuple_size, 393 .nlattr_tuple_size = ipv4_nlattr_tuple_size,
394 .nlattr_to_tuple = ipv4_nlattr_to_tuple, 394 .nlattr_to_tuple = ipv4_nlattr_to_tuple,
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index a338dad41b7d..b91b2641adda 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -226,7 +226,7 @@ icmp_error(struct net *net, struct nf_conn *tmpl,
226 return icmp_error_message(net, tmpl, skb, ctinfo, hooknum); 226 return icmp_error_message(net, tmpl, skb, ctinfo, hooknum);
227} 227}
228 228
229#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 229#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
230 230
231#include <linux/netfilter/nfnetlink.h> 231#include <linux/netfilter/nfnetlink.h>
232#include <linux/netfilter/nfnetlink_conntrack.h> 232#include <linux/netfilter/nfnetlink_conntrack.h>
@@ -408,7 +408,7 @@ struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp __read_mostly =
408 .error = icmp_error, 408 .error = icmp_error,
409 .destroy = NULL, 409 .destroy = NULL,
410 .me = NULL, 410 .me = NULL,
411#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 411#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
412 .tuple_to_nlattr = icmp_tuple_to_nlattr, 412 .tuple_to_nlattr = icmp_tuple_to_nlattr,
413 .nlattr_tuple_size = icmp_nlattr_tuple_size, 413 .nlattr_tuple_size = icmp_nlattr_tuple_size,
414 .nlattr_to_tuple = icmp_nlattr_to_tuple, 414 .nlattr_to_tuple = icmp_nlattr_to_tuple,
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
index b8f6381c7d0b..76bd1aef257f 100644
--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -17,7 +17,7 @@
17#include <linux/netfilter_bridge.h> 17#include <linux/netfilter_bridge.h>
18#include <linux/netfilter_ipv4.h> 18#include <linux/netfilter_ipv4.h>
19#include <net/netfilter/ipv4/nf_defrag_ipv4.h> 19#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
20#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 20#if IS_ENABLED(CONFIG_NF_CONNTRACK)
21#include <net/netfilter/nf_conntrack.h> 21#include <net/netfilter/nf_conntrack.h>
22#endif 22#endif
23#include <net/netfilter/nf_conntrack_zones.h> 23#include <net/netfilter/nf_conntrack_zones.h>
@@ -45,7 +45,7 @@ static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum,
45{ 45{
46 u16 zone = NF_CT_DEFAULT_ZONE; 46 u16 zone = NF_CT_DEFAULT_ZONE;
47 47
48#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 48#if IS_ENABLED(CONFIG_NF_CONNTRACK)
49 if (skb->nfct) 49 if (skb->nfct)
50 zone = nf_ct_zone((struct nf_conn *)skb->nfct); 50 zone = nf_ct_zone((struct nf_conn *)skb->nfct);
51#endif 51#endif
@@ -74,8 +74,8 @@ static unsigned int ipv4_conntrack_defrag(const struct nf_hook_ops *ops,
74 inet->nodefrag) 74 inet->nodefrag)
75 return NF_ACCEPT; 75 return NF_ACCEPT;
76 76
77#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 77#if IS_ENABLED(CONFIG_NF_CONNTRACK)
78#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE) 78#if !IS_ENABLED(CONFIG_NF_NAT)
79 /* Previously seen (loopback)? Ignore. Do this before 79 /* Previously seen (loopback)? Ignore. Do this before
80 fragment check. */ 80 fragment check. */
81 if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct)) 81 if (skb->nfct && !nf_ct_is_template((struct nf_conn *)skb->nfct))
diff --git a/net/ipv4/netfilter/nf_log_arp.c b/net/ipv4/netfilter/nf_log_arp.c
new file mode 100644
index 000000000000..ccfc78db12ee
--- /dev/null
+++ b/net/ipv4/netfilter/nf_log_arp.c
@@ -0,0 +1,149 @@
1/*
2 * (C) 2014 by Pablo Neira Ayuso <pablo@netfilter.org>
3 *
4 * Based on code from ebt_log from:
5 *
6 * Bart De Schuymer <bdschuym@pandora.be>
7 * Harald Welte <laforge@netfilter.org>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/module.h>
15#include <linux/spinlock.h>
16#include <linux/skbuff.h>
17#include <linux/if_arp.h>
18#include <linux/ip.h>
19#include <net/route.h>
20
21#include <linux/netfilter.h>
22#include <linux/netfilter/xt_LOG.h>
23#include <net/netfilter/nf_log.h>
24
25static struct nf_loginfo default_loginfo = {
26 .type = NF_LOG_TYPE_LOG,
27 .u = {
28 .log = {
29 .level = 5,
30 .logflags = NF_LOG_MASK,
31 },
32 },
33};
34
35struct arppayload {
36 unsigned char mac_src[ETH_ALEN];
37 unsigned char ip_src[4];
38 unsigned char mac_dst[ETH_ALEN];
39 unsigned char ip_dst[4];
40};
41
42static void dump_arp_packet(struct nf_log_buf *m,
43 const struct nf_loginfo *info,
44 const struct sk_buff *skb, unsigned int nhoff)
45{
46 const struct arphdr *ah;
47 struct arphdr _arph;
48 const struct arppayload *ap;
49 struct arppayload _arpp;
50
51 ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
52 if (ah == NULL) {
53 nf_log_buf_add(m, "TRUNCATED");
54 return;
55 }
56 nf_log_buf_add(m, "ARP HTYPE=%d PTYPE=0x%04x OPCODE=%d",
57 ntohs(ah->ar_hrd), ntohs(ah->ar_pro), ntohs(ah->ar_op));
58
59 /* If it's for Ethernet and the lengths are OK, then log the ARP
60 * payload.
61 */
62 if (ah->ar_hrd != htons(1) ||
63 ah->ar_hln != ETH_ALEN ||
64 ah->ar_pln != sizeof(__be32))
65 return;
66
67 ap = skb_header_pointer(skb, sizeof(_arph), sizeof(_arpp), &_arpp);
68 if (ap == NULL) {
69 nf_log_buf_add(m, " INCOMPLETE [%Zu bytes]",
70 skb->len - sizeof(_arph));
71 return;
72 }
73 nf_log_buf_add(m, " MACSRC=%pM IPSRC=%pI4 MACDST=%pM IPDST=%pI4",
74 ap->mac_src, ap->ip_src, ap->mac_dst, ap->ip_dst);
75}
76
77void nf_log_arp_packet(struct net *net, u_int8_t pf,
78 unsigned int hooknum, const struct sk_buff *skb,
79 const struct net_device *in,
80 const struct net_device *out,
81 const struct nf_loginfo *loginfo,
82 const char *prefix)
83{
84 struct nf_log_buf *m;
85
86 /* FIXME: Disabled from containers until syslog ns is supported */
87 if (!net_eq(net, &init_net))
88 return;
89
90 m = nf_log_buf_open();
91
92 if (!loginfo)
93 loginfo = &default_loginfo;
94
95 nf_log_dump_packet_common(m, pf, hooknum, skb, in, out, loginfo,
96 prefix);
97 dump_arp_packet(m, loginfo, skb, 0);
98
99 nf_log_buf_close(m);
100}
101
102static struct nf_logger nf_arp_logger __read_mostly = {
103 .name = "nf_log_arp",
104 .type = NF_LOG_TYPE_LOG,
105 .logfn = nf_log_arp_packet,
106 .me = THIS_MODULE,
107};
108
109static int __net_init nf_log_arp_net_init(struct net *net)
110{
111 nf_log_set(net, NFPROTO_ARP, &nf_arp_logger);
112 return 0;
113}
114
115static void __net_exit nf_log_arp_net_exit(struct net *net)
116{
117 nf_log_unset(net, &nf_arp_logger);
118}
119
120static struct pernet_operations nf_log_arp_net_ops = {
121 .init = nf_log_arp_net_init,
122 .exit = nf_log_arp_net_exit,
123};
124
125static int __init nf_log_arp_init(void)
126{
127 int ret;
128
129 ret = register_pernet_subsys(&nf_log_arp_net_ops);
130 if (ret < 0)
131 return ret;
132
133 nf_log_register(NFPROTO_ARP, &nf_arp_logger);
134 return 0;
135}
136
137static void __exit nf_log_arp_exit(void)
138{
139 unregister_pernet_subsys(&nf_log_arp_net_ops);
140 nf_log_unregister(&nf_arp_logger);
141}
142
143module_init(nf_log_arp_init);
144module_exit(nf_log_arp_exit);
145
146MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
147MODULE_DESCRIPTION("Netfilter ARP packet logging");
148MODULE_LICENSE("GPL");
149MODULE_ALIAS_NF_LOGGER(3, 0);
diff --git a/net/ipv4/netfilter/nf_log_ipv4.c b/net/ipv4/netfilter/nf_log_ipv4.c
new file mode 100644
index 000000000000..078bdca1b607
--- /dev/null
+++ b/net/ipv4/netfilter/nf_log_ipv4.c
@@ -0,0 +1,385 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/spinlock.h>
11#include <linux/skbuff.h>
12#include <linux/if_arp.h>
13#include <linux/ip.h>
14#include <net/ipv6.h>
15#include <net/icmp.h>
16#include <net/udp.h>
17#include <net/tcp.h>
18#include <net/route.h>
19
20#include <linux/netfilter.h>
21#include <linux/netfilter/xt_LOG.h>
22#include <net/netfilter/nf_log.h>
23
24static struct nf_loginfo default_loginfo = {
25 .type = NF_LOG_TYPE_LOG,
26 .u = {
27 .log = {
28 .level = 5,
29 .logflags = NF_LOG_MASK,
30 },
31 },
32};
33
34/* One level of recursion won't kill us */
35static void dump_ipv4_packet(struct nf_log_buf *m,
36 const struct nf_loginfo *info,
37 const struct sk_buff *skb, unsigned int iphoff)
38{
39 struct iphdr _iph;
40 const struct iphdr *ih;
41 unsigned int logflags;
42
43 if (info->type == NF_LOG_TYPE_LOG)
44 logflags = info->u.log.logflags;
45 else
46 logflags = NF_LOG_MASK;
47
48 ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
49 if (ih == NULL) {
50 nf_log_buf_add(m, "TRUNCATED");
51 return;
52 }
53
54 /* Important fields:
55 * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
56 /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
57 nf_log_buf_add(m, "SRC=%pI4 DST=%pI4 ", &ih->saddr, &ih->daddr);
58
59 /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
60 nf_log_buf_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
61 ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK,
62 ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id));
63
64 /* Max length: 6 "CE DF MF " */
65 if (ntohs(ih->frag_off) & IP_CE)
66 nf_log_buf_add(m, "CE ");
67 if (ntohs(ih->frag_off) & IP_DF)
68 nf_log_buf_add(m, "DF ");
69 if (ntohs(ih->frag_off) & IP_MF)
70 nf_log_buf_add(m, "MF ");
71
72 /* Max length: 11 "FRAG:65535 " */
73 if (ntohs(ih->frag_off) & IP_OFFSET)
74 nf_log_buf_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
75
76 if ((logflags & XT_LOG_IPOPT) &&
77 ih->ihl * 4 > sizeof(struct iphdr)) {
78 const unsigned char *op;
79 unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
80 unsigned int i, optsize;
81
82 optsize = ih->ihl * 4 - sizeof(struct iphdr);
83 op = skb_header_pointer(skb, iphoff+sizeof(_iph),
84 optsize, _opt);
85 if (op == NULL) {
86 nf_log_buf_add(m, "TRUNCATED");
87 return;
88 }
89
90 /* Max length: 127 "OPT (" 15*4*2chars ") " */
91 nf_log_buf_add(m, "OPT (");
92 for (i = 0; i < optsize; i++)
93 nf_log_buf_add(m, "%02X", op[i]);
94 nf_log_buf_add(m, ") ");
95 }
96
97 switch (ih->protocol) {
98 case IPPROTO_TCP:
99 if (nf_log_dump_tcp_header(m, skb, ih->protocol,
100 ntohs(ih->frag_off) & IP_OFFSET,
101 iphoff+ih->ihl*4, logflags))
102 return;
103 break;
104 case IPPROTO_UDP:
105 case IPPROTO_UDPLITE:
106 if (nf_log_dump_udp_header(m, skb, ih->protocol,
107 ntohs(ih->frag_off) & IP_OFFSET,
108 iphoff+ih->ihl*4))
109 return;
110 break;
111 case IPPROTO_ICMP: {
112 struct icmphdr _icmph;
113 const struct icmphdr *ich;
114 static const size_t required_len[NR_ICMP_TYPES+1]
115 = { [ICMP_ECHOREPLY] = 4,
116 [ICMP_DEST_UNREACH]
117 = 8 + sizeof(struct iphdr),
118 [ICMP_SOURCE_QUENCH]
119 = 8 + sizeof(struct iphdr),
120 [ICMP_REDIRECT]
121 = 8 + sizeof(struct iphdr),
122 [ICMP_ECHO] = 4,
123 [ICMP_TIME_EXCEEDED]
124 = 8 + sizeof(struct iphdr),
125 [ICMP_PARAMETERPROB]
126 = 8 + sizeof(struct iphdr),
127 [ICMP_TIMESTAMP] = 20,
128 [ICMP_TIMESTAMPREPLY] = 20,
129 [ICMP_ADDRESS] = 12,
130 [ICMP_ADDRESSREPLY] = 12 };
131
132 /* Max length: 11 "PROTO=ICMP " */
133 nf_log_buf_add(m, "PROTO=ICMP ");
134
135 if (ntohs(ih->frag_off) & IP_OFFSET)
136 break;
137
138 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
139 ich = skb_header_pointer(skb, iphoff + ih->ihl * 4,
140 sizeof(_icmph), &_icmph);
141 if (ich == NULL) {
142 nf_log_buf_add(m, "INCOMPLETE [%u bytes] ",
143 skb->len - iphoff - ih->ihl*4);
144 break;
145 }
146
147 /* Max length: 18 "TYPE=255 CODE=255 " */
148 nf_log_buf_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code);
149
150 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
151 if (ich->type <= NR_ICMP_TYPES &&
152 required_len[ich->type] &&
153 skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
154 nf_log_buf_add(m, "INCOMPLETE [%u bytes] ",
155 skb->len - iphoff - ih->ihl*4);
156 break;
157 }
158
159 switch (ich->type) {
160 case ICMP_ECHOREPLY:
161 case ICMP_ECHO:
162 /* Max length: 19 "ID=65535 SEQ=65535 " */
163 nf_log_buf_add(m, "ID=%u SEQ=%u ",
164 ntohs(ich->un.echo.id),
165 ntohs(ich->un.echo.sequence));
166 break;
167
168 case ICMP_PARAMETERPROB:
169 /* Max length: 14 "PARAMETER=255 " */
170 nf_log_buf_add(m, "PARAMETER=%u ",
171 ntohl(ich->un.gateway) >> 24);
172 break;
173 case ICMP_REDIRECT:
174 /* Max length: 24 "GATEWAY=255.255.255.255 " */
175 nf_log_buf_add(m, "GATEWAY=%pI4 ", &ich->un.gateway);
176 /* Fall through */
177 case ICMP_DEST_UNREACH:
178 case ICMP_SOURCE_QUENCH:
179 case ICMP_TIME_EXCEEDED:
180 /* Max length: 3+maxlen */
181 if (!iphoff) { /* Only recurse once. */
182 nf_log_buf_add(m, "[");
183 dump_ipv4_packet(m, info, skb,
184 iphoff + ih->ihl*4+sizeof(_icmph));
185 nf_log_buf_add(m, "] ");
186 }
187
188 /* Max length: 10 "MTU=65535 " */
189 if (ich->type == ICMP_DEST_UNREACH &&
190 ich->code == ICMP_FRAG_NEEDED) {
191 nf_log_buf_add(m, "MTU=%u ",
192 ntohs(ich->un.frag.mtu));
193 }
194 }
195 break;
196 }
197 /* Max Length */
198 case IPPROTO_AH: {
199 struct ip_auth_hdr _ahdr;
200 const struct ip_auth_hdr *ah;
201
202 if (ntohs(ih->frag_off) & IP_OFFSET)
203 break;
204
205 /* Max length: 9 "PROTO=AH " */
206 nf_log_buf_add(m, "PROTO=AH ");
207
208 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
209 ah = skb_header_pointer(skb, iphoff+ih->ihl*4,
210 sizeof(_ahdr), &_ahdr);
211 if (ah == NULL) {
212 nf_log_buf_add(m, "INCOMPLETE [%u bytes] ",
213 skb->len - iphoff - ih->ihl*4);
214 break;
215 }
216
217 /* Length: 15 "SPI=0xF1234567 " */
218 nf_log_buf_add(m, "SPI=0x%x ", ntohl(ah->spi));
219 break;
220 }
221 case IPPROTO_ESP: {
222 struct ip_esp_hdr _esph;
223 const struct ip_esp_hdr *eh;
224
225 /* Max length: 10 "PROTO=ESP " */
226 nf_log_buf_add(m, "PROTO=ESP ");
227
228 if (ntohs(ih->frag_off) & IP_OFFSET)
229 break;
230
231 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
232 eh = skb_header_pointer(skb, iphoff+ih->ihl*4,
233 sizeof(_esph), &_esph);
234 if (eh == NULL) {
235 nf_log_buf_add(m, "INCOMPLETE [%u bytes] ",
236 skb->len - iphoff - ih->ihl*4);
237 break;
238 }
239
240 /* Length: 15 "SPI=0xF1234567 " */
241 nf_log_buf_add(m, "SPI=0x%x ", ntohl(eh->spi));
242 break;
243 }
244 /* Max length: 10 "PROTO 255 " */
245 default:
246 nf_log_buf_add(m, "PROTO=%u ", ih->protocol);
247 }
248
249 /* Max length: 15 "UID=4294967295 " */
250 if ((logflags & XT_LOG_UID) && !iphoff)
251 nf_log_dump_sk_uid_gid(m, skb->sk);
252
253 /* Max length: 16 "MARK=0xFFFFFFFF " */
254 if (!iphoff && skb->mark)
255 nf_log_buf_add(m, "MARK=0x%x ", skb->mark);
256
257 /* Proto Max log string length */
258 /* IP: 40+46+6+11+127 = 230 */
259 /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */
260 /* UDP: 10+max(25,20) = 35 */
261 /* UDPLITE: 14+max(25,20) = 39 */
262 /* ICMP: 11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
263 /* ESP: 10+max(25)+15 = 50 */
264 /* AH: 9+max(25)+15 = 49 */
265 /* unknown: 10 */
266
267 /* (ICMP allows recursion one level deep) */
268 /* maxlen = IP + ICMP + IP + max(TCP,UDP,ICMP,unknown) */
269 /* maxlen = 230+ 91 + 230 + 252 = 803 */
270}
271
272static void dump_ipv4_mac_header(struct nf_log_buf *m,
273 const struct nf_loginfo *info,
274 const struct sk_buff *skb)
275{
276 struct net_device *dev = skb->dev;
277 unsigned int logflags = 0;
278
279 if (info->type == NF_LOG_TYPE_LOG)
280 logflags = info->u.log.logflags;
281
282 if (!(logflags & XT_LOG_MACDECODE))
283 goto fallback;
284
285 switch (dev->type) {
286 case ARPHRD_ETHER:
287 nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
288 eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
289 ntohs(eth_hdr(skb)->h_proto));
290 return;
291 default:
292 break;
293 }
294
295fallback:
296 nf_log_buf_add(m, "MAC=");
297 if (dev->hard_header_len &&
298 skb->mac_header != skb->network_header) {
299 const unsigned char *p = skb_mac_header(skb);
300 unsigned int i;
301
302 nf_log_buf_add(m, "%02x", *p++);
303 for (i = 1; i < dev->hard_header_len; i++, p++)
304 nf_log_buf_add(m, ":%02x", *p);
305 }
306 nf_log_buf_add(m, " ");
307}
308
309static void nf_log_ip_packet(struct net *net, u_int8_t pf,
310 unsigned int hooknum, const struct sk_buff *skb,
311 const struct net_device *in,
312 const struct net_device *out,
313 const struct nf_loginfo *loginfo,
314 const char *prefix)
315{
316 struct nf_log_buf *m;
317
318 /* FIXME: Disabled from containers until syslog ns is supported */
319 if (!net_eq(net, &init_net))
320 return;
321
322 m = nf_log_buf_open();
323
324 if (!loginfo)
325 loginfo = &default_loginfo;
326
327 nf_log_dump_packet_common(m, pf, hooknum, skb, in,
328 out, loginfo, prefix);
329
330 if (in != NULL)
331 dump_ipv4_mac_header(m, loginfo, skb);
332
333 dump_ipv4_packet(m, loginfo, skb, 0);
334
335 nf_log_buf_close(m);
336}
337
338static struct nf_logger nf_ip_logger __read_mostly = {
339 .name = "nf_log_ipv4",
340 .type = NF_LOG_TYPE_LOG,
341 .logfn = nf_log_ip_packet,
342 .me = THIS_MODULE,
343};
344
345static int __net_init nf_log_ipv4_net_init(struct net *net)
346{
347 nf_log_set(net, NFPROTO_IPV4, &nf_ip_logger);
348 return 0;
349}
350
351static void __net_exit nf_log_ipv4_net_exit(struct net *net)
352{
353 nf_log_unset(net, &nf_ip_logger);
354}
355
356static struct pernet_operations nf_log_ipv4_net_ops = {
357 .init = nf_log_ipv4_net_init,
358 .exit = nf_log_ipv4_net_exit,
359};
360
361static int __init nf_log_ipv4_init(void)
362{
363 int ret;
364
365 ret = register_pernet_subsys(&nf_log_ipv4_net_ops);
366 if (ret < 0)
367 return ret;
368
369 nf_log_register(NFPROTO_IPV4, &nf_ip_logger);
370 return 0;
371}
372
373static void __exit nf_log_ipv4_exit(void)
374{
375 unregister_pernet_subsys(&nf_log_ipv4_net_ops);
376 nf_log_unregister(&nf_ip_logger);
377}
378
379module_init(nf_log_ipv4_init);
380module_exit(nf_log_ipv4_exit);
381
382MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
383MODULE_DESCRIPTION("Netfilter IPv4 packet logging");
384MODULE_LICENSE("GPL");
385MODULE_ALIAS_NF_LOGGER(AF_INET, 0);
diff --git a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
index d8b2e14efddc..14f5ccd06337 100644
--- a/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_nat_l3proto_ipv4.c
@@ -154,6 +154,7 @@ static void nf_nat_ipv4_csum_recalc(struct sk_buff *skb,
154 htons(oldlen), htons(datalen), 1); 154 htons(oldlen), htons(datalen), 1);
155} 155}
156 156
157#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
157static int nf_nat_ipv4_nlattr_to_range(struct nlattr *tb[], 158static int nf_nat_ipv4_nlattr_to_range(struct nlattr *tb[],
158 struct nf_nat_range *range) 159 struct nf_nat_range *range)
159{ 160{
@@ -169,6 +170,7 @@ static int nf_nat_ipv4_nlattr_to_range(struct nlattr *tb[],
169 170
170 return 0; 171 return 0;
171} 172}
173#endif
172 174
173static const struct nf_nat_l3proto nf_nat_l3proto_ipv4 = { 175static const struct nf_nat_l3proto nf_nat_l3proto_ipv4 = {
174 .l3proto = NFPROTO_IPV4, 176 .l3proto = NFPROTO_IPV4,
@@ -177,7 +179,9 @@ static const struct nf_nat_l3proto nf_nat_l3proto_ipv4 = {
177 .manip_pkt = nf_nat_ipv4_manip_pkt, 179 .manip_pkt = nf_nat_ipv4_manip_pkt,
178 .csum_update = nf_nat_ipv4_csum_update, 180 .csum_update = nf_nat_ipv4_csum_update,
179 .csum_recalc = nf_nat_ipv4_csum_recalc, 181 .csum_recalc = nf_nat_ipv4_csum_recalc,
182#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
180 .nlattr_to_range = nf_nat_ipv4_nlattr_to_range, 183 .nlattr_to_range = nf_nat_ipv4_nlattr_to_range,
184#endif
181#ifdef CONFIG_XFRM 185#ifdef CONFIG_XFRM
182 .decode_session = nf_nat_ipv4_decode_session, 186 .decode_session = nf_nat_ipv4_decode_session,
183#endif 187#endif
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c
index 690d890111bb..9414923f1e15 100644
--- a/net/ipv4/netfilter/nf_nat_proto_gre.c
+++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
@@ -124,7 +124,7 @@ static const struct nf_nat_l4proto gre = {
124 .manip_pkt = gre_manip_pkt, 124 .manip_pkt = gre_manip_pkt,
125 .in_range = nf_nat_l4proto_in_range, 125 .in_range = nf_nat_l4proto_in_range,
126 .unique_tuple = gre_unique_tuple, 126 .unique_tuple = gre_unique_tuple,
127#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 127#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
128 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, 128 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
129#endif 129#endif
130}; 130};
diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c b/net/ipv4/netfilter/nf_nat_proto_icmp.c
index eb303471bcf6..4557b4ab8342 100644
--- a/net/ipv4/netfilter/nf_nat_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c
@@ -77,7 +77,7 @@ const struct nf_nat_l4proto nf_nat_l4proto_icmp = {
77 .manip_pkt = icmp_manip_pkt, 77 .manip_pkt = icmp_manip_pkt,
78 .in_range = icmp_in_range, 78 .in_range = icmp_in_range,
79 .unique_tuple = icmp_unique_tuple, 79 .unique_tuple = icmp_unique_tuple,
80#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 80#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
81 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, 81 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
82#endif 82#endif
83}; 83};
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 4bff1f297e39..ac93df16f5af 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -55,6 +55,11 @@ config NFT_REJECT_IPV6
55 default NFT_REJECT 55 default NFT_REJECT
56 tristate 56 tristate
57 57
58config NF_LOG_IPV6
59 tristate "IPv6 packet logging"
60 depends on NETFILTER_ADVANCED
61 select NF_LOG_COMMON
62
58config IP6_NF_IPTABLES 63config IP6_NF_IPTABLES
59 tristate "IP6 tables support (required for filtering)" 64 tristate "IP6 tables support (required for filtering)"
60 depends on INET && IPV6 65 depends on INET && IPV6
diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile
index 70d3dd66f2cd..c0b263104ed2 100644
--- a/net/ipv6/netfilter/Makefile
+++ b/net/ipv6/netfilter/Makefile
@@ -23,6 +23,9 @@ obj-$(CONFIG_NF_NAT_IPV6) += nf_nat_ipv6.o
23nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o 23nf_defrag_ipv6-y := nf_defrag_ipv6_hooks.o nf_conntrack_reasm.o
24obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o 24obj-$(CONFIG_NF_DEFRAG_IPV6) += nf_defrag_ipv6.o
25 25
26# logging
27obj-$(CONFIG_NF_LOG_IPV6) += nf_log_ipv6.o
28
26# nf_tables 29# nf_tables
27obj-$(CONFIG_NF_TABLES_IPV6) += nf_tables_ipv6.o 30obj-$(CONFIG_NF_TABLES_IPV6) += nf_tables_ipv6.o
28obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o 31obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o
diff --git a/net/ipv6/netfilter/nf_log_ipv6.c b/net/ipv6/netfilter/nf_log_ipv6.c
new file mode 100644
index 000000000000..7b17a0be93e7
--- /dev/null
+++ b/net/ipv6/netfilter/nf_log_ipv6.c
@@ -0,0 +1,417 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/spinlock.h>
11#include <linux/skbuff.h>
12#include <linux/if_arp.h>
13#include <linux/ip.h>
14#include <net/ipv6.h>
15#include <net/icmp.h>
16#include <net/udp.h>
17#include <net/tcp.h>
18#include <net/route.h>
19
20#include <linux/netfilter.h>
21#include <linux/netfilter_ipv6/ip6_tables.h>
22#include <linux/netfilter/xt_LOG.h>
23#include <net/netfilter/nf_log.h>
24
25static struct nf_loginfo default_loginfo = {
26 .type = NF_LOG_TYPE_LOG,
27 .u = {
28 .log = {
29 .level = 5,
30 .logflags = NF_LOG_MASK,
31 },
32 },
33};
34
35/* One level of recursion won't kill us */
36static void dump_ipv6_packet(struct nf_log_buf *m,
37 const struct nf_loginfo *info,
38 const struct sk_buff *skb, unsigned int ip6hoff,
39 int recurse)
40{
41 u_int8_t currenthdr;
42 int fragment;
43 struct ipv6hdr _ip6h;
44 const struct ipv6hdr *ih;
45 unsigned int ptr;
46 unsigned int hdrlen = 0;
47 unsigned int logflags;
48
49 if (info->type == NF_LOG_TYPE_LOG)
50 logflags = info->u.log.logflags;
51 else
52 logflags = NF_LOG_MASK;
53
54 ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
55 if (ih == NULL) {
56 nf_log_buf_add(m, "TRUNCATED");
57 return;
58 }
59
60 /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
61 nf_log_buf_add(m, "SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);
62
63 /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
64 nf_log_buf_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
65 ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
66 (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
67 ih->hop_limit,
68 (ntohl(*(__be32 *)ih) & 0x000fffff));
69
70 fragment = 0;
71 ptr = ip6hoff + sizeof(struct ipv6hdr);
72 currenthdr = ih->nexthdr;
73 while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
74 struct ipv6_opt_hdr _hdr;
75 const struct ipv6_opt_hdr *hp;
76
77 hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
78 if (hp == NULL) {
79 nf_log_buf_add(m, "TRUNCATED");
80 return;
81 }
82
83 /* Max length: 48 "OPT (...) " */
84 if (logflags & XT_LOG_IPOPT)
85 nf_log_buf_add(m, "OPT ( ");
86
87 switch (currenthdr) {
88 case IPPROTO_FRAGMENT: {
89 struct frag_hdr _fhdr;
90 const struct frag_hdr *fh;
91
92 nf_log_buf_add(m, "FRAG:");
93 fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
94 &_fhdr);
95 if (fh == NULL) {
96 nf_log_buf_add(m, "TRUNCATED ");
97 return;
98 }
99
100 /* Max length: 6 "65535 " */
101 nf_log_buf_add(m, "%u ", ntohs(fh->frag_off) & 0xFFF8);
102
103 /* Max length: 11 "INCOMPLETE " */
104 if (fh->frag_off & htons(0x0001))
105 nf_log_buf_add(m, "INCOMPLETE ");
106
107 nf_log_buf_add(m, "ID:%08x ",
108 ntohl(fh->identification));
109
110 if (ntohs(fh->frag_off) & 0xFFF8)
111 fragment = 1;
112
113 hdrlen = 8;
114
115 break;
116 }
117 case IPPROTO_DSTOPTS:
118 case IPPROTO_ROUTING:
119 case IPPROTO_HOPOPTS:
120 if (fragment) {
121 if (logflags & XT_LOG_IPOPT)
122 nf_log_buf_add(m, ")");
123 return;
124 }
125 hdrlen = ipv6_optlen(hp);
126 break;
127 /* Max Length */
128 case IPPROTO_AH:
129 if (logflags & XT_LOG_IPOPT) {
130 struct ip_auth_hdr _ahdr;
131 const struct ip_auth_hdr *ah;
132
133 /* Max length: 3 "AH " */
134 nf_log_buf_add(m, "AH ");
135
136 if (fragment) {
137 nf_log_buf_add(m, ")");
138 return;
139 }
140
141 ah = skb_header_pointer(skb, ptr, sizeof(_ahdr),
142 &_ahdr);
143 if (ah == NULL) {
144 /*
145 * Max length: 26 "INCOMPLETE [65535
146 * bytes] )"
147 */
148 nf_log_buf_add(m, "INCOMPLETE [%u bytes] )",
149 skb->len - ptr);
150 return;
151 }
152
153 /* Length: 15 "SPI=0xF1234567 */
154 nf_log_buf_add(m, "SPI=0x%x ", ntohl(ah->spi));
155
156 }
157
158 hdrlen = (hp->hdrlen+2)<<2;
159 break;
160 case IPPROTO_ESP:
161 if (logflags & XT_LOG_IPOPT) {
162 struct ip_esp_hdr _esph;
163 const struct ip_esp_hdr *eh;
164
165 /* Max length: 4 "ESP " */
166 nf_log_buf_add(m, "ESP ");
167
168 if (fragment) {
169 nf_log_buf_add(m, ")");
170 return;
171 }
172
173 /*
174 * Max length: 26 "INCOMPLETE [65535 bytes] )"
175 */
176 eh = skb_header_pointer(skb, ptr, sizeof(_esph),
177 &_esph);
178 if (eh == NULL) {
179 nf_log_buf_add(m, "INCOMPLETE [%u bytes] )",
180 skb->len - ptr);
181 return;
182 }
183
184 /* Length: 16 "SPI=0xF1234567 )" */
185 nf_log_buf_add(m, "SPI=0x%x )",
186 ntohl(eh->spi));
187 }
188 return;
189 default:
190 /* Max length: 20 "Unknown Ext Hdr 255" */
191 nf_log_buf_add(m, "Unknown Ext Hdr %u", currenthdr);
192 return;
193 }
194 if (logflags & XT_LOG_IPOPT)
195 nf_log_buf_add(m, ") ");
196
197 currenthdr = hp->nexthdr;
198 ptr += hdrlen;
199 }
200
201 switch (currenthdr) {
202 case IPPROTO_TCP:
203 if (nf_log_dump_tcp_header(m, skb, currenthdr, fragment,
204 ptr, logflags))
205 return;
206 break;
207 case IPPROTO_UDP:
208 case IPPROTO_UDPLITE:
209 if (nf_log_dump_udp_header(m, skb, currenthdr, fragment, ptr))
210 return;
211 break;
212 case IPPROTO_ICMPV6: {
213 struct icmp6hdr _icmp6h;
214 const struct icmp6hdr *ic;
215
216 /* Max length: 13 "PROTO=ICMPv6 " */
217 nf_log_buf_add(m, "PROTO=ICMPv6 ");
218
219 if (fragment)
220 break;
221
222 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
223 ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h);
224 if (ic == NULL) {
225 nf_log_buf_add(m, "INCOMPLETE [%u bytes] ",
226 skb->len - ptr);
227 return;
228 }
229
230 /* Max length: 18 "TYPE=255 CODE=255 " */
231 nf_log_buf_add(m, "TYPE=%u CODE=%u ",
232 ic->icmp6_type, ic->icmp6_code);
233
234 switch (ic->icmp6_type) {
235 case ICMPV6_ECHO_REQUEST:
236 case ICMPV6_ECHO_REPLY:
237 /* Max length: 19 "ID=65535 SEQ=65535 " */
238 nf_log_buf_add(m, "ID=%u SEQ=%u ",
239 ntohs(ic->icmp6_identifier),
240 ntohs(ic->icmp6_sequence));
241 break;
242 case ICMPV6_MGM_QUERY:
243 case ICMPV6_MGM_REPORT:
244 case ICMPV6_MGM_REDUCTION:
245 break;
246
247 case ICMPV6_PARAMPROB:
248 /* Max length: 17 "POINTER=ffffffff " */
249 nf_log_buf_add(m, "POINTER=%08x ",
250 ntohl(ic->icmp6_pointer));
251 /* Fall through */
252 case ICMPV6_DEST_UNREACH:
253 case ICMPV6_PKT_TOOBIG:
254 case ICMPV6_TIME_EXCEED:
255 /* Max length: 3+maxlen */
256 if (recurse) {
257 nf_log_buf_add(m, "[");
258 dump_ipv6_packet(m, info, skb,
259 ptr + sizeof(_icmp6h), 0);
260 nf_log_buf_add(m, "] ");
261 }
262
263 /* Max length: 10 "MTU=65535 " */
264 if (ic->icmp6_type == ICMPV6_PKT_TOOBIG) {
265 nf_log_buf_add(m, "MTU=%u ",
266 ntohl(ic->icmp6_mtu));
267 }
268 }
269 break;
270 }
271 /* Max length: 10 "PROTO=255 " */
272 default:
273 nf_log_buf_add(m, "PROTO=%u ", currenthdr);
274 }
275
276 /* Max length: 15 "UID=4294967295 " */
277 if ((logflags & XT_LOG_UID) && recurse)
278 nf_log_dump_sk_uid_gid(m, skb->sk);
279
280 /* Max length: 16 "MARK=0xFFFFFFFF " */
281 if (recurse && skb->mark)
282 nf_log_buf_add(m, "MARK=0x%x ", skb->mark);
283}
284
285static void dump_ipv6_mac_header(struct nf_log_buf *m,
286 const struct nf_loginfo *info,
287 const struct sk_buff *skb)
288{
289 struct net_device *dev = skb->dev;
290 unsigned int logflags = 0;
291
292 if (info->type == NF_LOG_TYPE_LOG)
293 logflags = info->u.log.logflags;
294
295 if (!(logflags & XT_LOG_MACDECODE))
296 goto fallback;
297
298 switch (dev->type) {
299 case ARPHRD_ETHER:
300 nf_log_buf_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
301 eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
302 ntohs(eth_hdr(skb)->h_proto));
303 return;
304 default:
305 break;
306 }
307
308fallback:
309 nf_log_buf_add(m, "MAC=");
310 if (dev->hard_header_len &&
311 skb->mac_header != skb->network_header) {
312 const unsigned char *p = skb_mac_header(skb);
313 unsigned int len = dev->hard_header_len;
314 unsigned int i;
315
316 if (dev->type == ARPHRD_SIT) {
317 p -= ETH_HLEN;
318
319 if (p < skb->head)
320 p = NULL;
321 }
322
323 if (p != NULL) {
324 nf_log_buf_add(m, "%02x", *p++);
325 for (i = 1; i < len; i++)
326 nf_log_buf_add(m, ":%02x", *p++);
327 }
328 nf_log_buf_add(m, " ");
329
330 if (dev->type == ARPHRD_SIT) {
331 const struct iphdr *iph =
332 (struct iphdr *)skb_mac_header(skb);
333 nf_log_buf_add(m, "TUNNEL=%pI4->%pI4 ", &iph->saddr,
334 &iph->daddr);
335 }
336 } else {
337 nf_log_buf_add(m, " ");
338 }
339}
340
341static void nf_log_ip6_packet(struct net *net, u_int8_t pf,
342 unsigned int hooknum, const struct sk_buff *skb,
343 const struct net_device *in,
344 const struct net_device *out,
345 const struct nf_loginfo *loginfo,
346 const char *prefix)
347{
348 struct nf_log_buf *m;
349
350 /* FIXME: Disabled from containers until syslog ns is supported */
351 if (!net_eq(net, &init_net))
352 return;
353
354 m = nf_log_buf_open();
355
356 if (!loginfo)
357 loginfo = &default_loginfo;
358
359 nf_log_dump_packet_common(m, pf, hooknum, skb, in, out,
360 loginfo, prefix);
361
362 if (in != NULL)
363 dump_ipv6_mac_header(m, loginfo, skb);
364
365 dump_ipv6_packet(m, loginfo, skb, skb_network_offset(skb), 1);
366
367 nf_log_buf_close(m);
368}
369
370static struct nf_logger nf_ip6_logger __read_mostly = {
371 .name = "nf_log_ipv6",
372 .type = NF_LOG_TYPE_LOG,
373 .logfn = nf_log_ip6_packet,
374 .me = THIS_MODULE,
375};
376
377static int __net_init nf_log_ipv6_net_init(struct net *net)
378{
379 nf_log_set(net, NFPROTO_IPV6, &nf_ip6_logger);
380 return 0;
381}
382
383static void __net_exit nf_log_ipv6_net_exit(struct net *net)
384{
385 nf_log_unset(net, &nf_ip6_logger);
386}
387
388static struct pernet_operations nf_log_ipv6_net_ops = {
389 .init = nf_log_ipv6_net_init,
390 .exit = nf_log_ipv6_net_exit,
391};
392
393static int __init nf_log_ipv6_init(void)
394{
395 int ret;
396
397 ret = register_pernet_subsys(&nf_log_ipv6_net_ops);
398 if (ret < 0)
399 return ret;
400
401 nf_log_register(NFPROTO_IPV6, &nf_ip6_logger);
402 return 0;
403}
404
405static void __exit nf_log_ipv6_exit(void)
406{
407 unregister_pernet_subsys(&nf_log_ipv6_net_ops);
408 nf_log_unregister(&nf_ip6_logger);
409}
410
411module_init(nf_log_ipv6_init);
412module_exit(nf_log_ipv6_exit);
413
414MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
415MODULE_DESCRIPTION("Netfilter IPv4 packet logging");
416MODULE_LICENSE("GPL");
417MODULE_ALIAS_NF_LOGGER(AF_INET6, 0);
diff --git a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
index abfe75a2e316..fc8e49b2ff3e 100644
--- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
@@ -158,6 +158,7 @@ static void nf_nat_ipv6_csum_recalc(struct sk_buff *skb,
158 htons(oldlen), htons(datalen), 1); 158 htons(oldlen), htons(datalen), 1);
159} 159}
160 160
161#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
161static int nf_nat_ipv6_nlattr_to_range(struct nlattr *tb[], 162static int nf_nat_ipv6_nlattr_to_range(struct nlattr *tb[],
162 struct nf_nat_range *range) 163 struct nf_nat_range *range)
163{ 164{
@@ -175,6 +176,7 @@ static int nf_nat_ipv6_nlattr_to_range(struct nlattr *tb[],
175 176
176 return 0; 177 return 0;
177} 178}
179#endif
178 180
179static const struct nf_nat_l3proto nf_nat_l3proto_ipv6 = { 181static const struct nf_nat_l3proto nf_nat_l3proto_ipv6 = {
180 .l3proto = NFPROTO_IPV6, 182 .l3proto = NFPROTO_IPV6,
@@ -183,7 +185,9 @@ static const struct nf_nat_l3proto nf_nat_l3proto_ipv6 = {
183 .manip_pkt = nf_nat_ipv6_manip_pkt, 185 .manip_pkt = nf_nat_ipv6_manip_pkt,
184 .csum_update = nf_nat_ipv6_csum_update, 186 .csum_update = nf_nat_ipv6_csum_update,
185 .csum_recalc = nf_nat_ipv6_csum_recalc, 187 .csum_recalc = nf_nat_ipv6_csum_recalc,
188#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
186 .nlattr_to_range = nf_nat_ipv6_nlattr_to_range, 189 .nlattr_to_range = nf_nat_ipv6_nlattr_to_range,
190#endif
187#ifdef CONFIG_XFRM 191#ifdef CONFIG_XFRM
188 .decode_session = nf_nat_ipv6_decode_session, 192 .decode_session = nf_nat_ipv6_decode_session,
189#endif 193#endif
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index e9410d17619d..ad751fe2e82b 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -46,6 +46,9 @@ config NF_CONNTRACK
46 46
47 To compile it as a module, choose M here. If unsure, say N. 47 To compile it as a module, choose M here. If unsure, say N.
48 48
49config NF_LOG_COMMON
50 tristate
51
49if NF_CONNTRACK 52if NF_CONNTRACK
50 53
51config NF_CONNTRACK_MARK 54config NF_CONNTRACK_MARK
@@ -744,6 +747,7 @@ config NETFILTER_XT_TARGET_LED
744 747
745config NETFILTER_XT_TARGET_LOG 748config NETFILTER_XT_TARGET_LOG
746 tristate "LOG target support" 749 tristate "LOG target support"
750 depends on NF_LOG_IPV4 && NF_LOG_IPV6
747 default m if NETFILTER_ADVANCED=n 751 default m if NETFILTER_ADVANCED=n
748 help 752 help
749 This option adds a `LOG' target, which allows you to create rules in 753 This option adds a `LOG' target, which allows you to create rules in
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index bffdad774da7..8308624a406a 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -47,6 +47,9 @@ obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
47nf_nat-y := nf_nat_core.o nf_nat_proto_unknown.o nf_nat_proto_common.o \ 47nf_nat-y := nf_nat_core.o nf_nat_proto_unknown.o nf_nat_proto_common.o \
48 nf_nat_proto_udp.o nf_nat_proto_tcp.o nf_nat_helper.o 48 nf_nat_proto_udp.o nf_nat_proto_tcp.o nf_nat_helper.o
49 49
50# generic transport layer logging
51obj-$(CONFIG_NF_LOG_COMMON) += nf_log_common.o
52
50obj-$(CONFIG_NF_NAT) += nf_nat.o 53obj-$(CONFIG_NF_NAT) += nf_nat.o
51 54
52# NAT protocols (nf_nat) 55# NAT protocols (nf_nat)
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 581a6584ed0c..8416307fdd1d 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1807,92 +1807,6 @@ static struct ctl_table vs_vars[] = {
1807 .proc_handler = proc_dointvec, 1807 .proc_handler = proc_dointvec,
1808 }, 1808 },
1809#endif 1809#endif
1810#if 0
1811 {
1812 .procname = "timeout_established",
1813 .data = &vs_timeout_table_dos.timeout[IP_VS_S_ESTABLISHED],
1814 .maxlen = sizeof(int),
1815 .mode = 0644,
1816 .proc_handler = proc_dointvec_jiffies,
1817 },
1818 {
1819 .procname = "timeout_synsent",
1820 .data = &vs_timeout_table_dos.timeout[IP_VS_S_SYN_SENT],
1821 .maxlen = sizeof(int),
1822 .mode = 0644,
1823 .proc_handler = proc_dointvec_jiffies,
1824 },
1825 {
1826 .procname = "timeout_synrecv",
1827 .data = &vs_timeout_table_dos.timeout[IP_VS_S_SYN_RECV],
1828 .maxlen = sizeof(int),
1829 .mode = 0644,
1830 .proc_handler = proc_dointvec_jiffies,
1831 },
1832 {
1833 .procname = "timeout_finwait",
1834 .data = &vs_timeout_table_dos.timeout[IP_VS_S_FIN_WAIT],
1835 .maxlen = sizeof(int),
1836 .mode = 0644,
1837 .proc_handler = proc_dointvec_jiffies,
1838 },
1839 {
1840 .procname = "timeout_timewait",
1841 .data = &vs_timeout_table_dos.timeout[IP_VS_S_TIME_WAIT],
1842 .maxlen = sizeof(int),
1843 .mode = 0644,
1844 .proc_handler = proc_dointvec_jiffies,
1845 },
1846 {
1847 .procname = "timeout_close",
1848 .data = &vs_timeout_table_dos.timeout[IP_VS_S_CLOSE],
1849 .maxlen = sizeof(int),
1850 .mode = 0644,
1851 .proc_handler = proc_dointvec_jiffies,
1852 },
1853 {
1854 .procname = "timeout_closewait",
1855 .data = &vs_timeout_table_dos.timeout[IP_VS_S_CLOSE_WAIT],
1856 .maxlen = sizeof(int),
1857 .mode = 0644,
1858 .proc_handler = proc_dointvec_jiffies,
1859 },
1860 {
1861 .procname = "timeout_lastack",
1862 .data = &vs_timeout_table_dos.timeout[IP_VS_S_LAST_ACK],
1863 .maxlen = sizeof(int),
1864 .mode = 0644,
1865 .proc_handler = proc_dointvec_jiffies,
1866 },
1867 {
1868 .procname = "timeout_listen",
1869 .data = &vs_timeout_table_dos.timeout[IP_VS_S_LISTEN],
1870 .maxlen = sizeof(int),
1871 .mode = 0644,
1872 .proc_handler = proc_dointvec_jiffies,
1873 },
1874 {
1875 .procname = "timeout_synack",
1876 .data = &vs_timeout_table_dos.timeout[IP_VS_S_SYNACK],
1877 .maxlen = sizeof(int),
1878 .mode = 0644,
1879 .proc_handler = proc_dointvec_jiffies,
1880 },
1881 {
1882 .procname = "timeout_udp",
1883 .data = &vs_timeout_table_dos.timeout[IP_VS_S_UDP],
1884 .maxlen = sizeof(int),
1885 .mode = 0644,
1886 .proc_handler = proc_dointvec_jiffies,
1887 },
1888 {
1889 .procname = "timeout_icmp",
1890 .data = &vs_timeout_table_dos.timeout[IP_VS_S_ICMP],
1891 .maxlen = sizeof(int),
1892 .mode = 0644,
1893 .proc_handler = proc_dointvec_jiffies,
1894 },
1895#endif
1896 { } 1810 { }
1897}; 1811};
1898 1812
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index db801263ee9f..eadffb29dec0 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -886,8 +886,7 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param,
886 cp = ip_vs_conn_new(param, daddr, dport, flags, dest, fwmark); 886 cp = ip_vs_conn_new(param, daddr, dport, flags, dest, fwmark);
887 rcu_read_unlock(); 887 rcu_read_unlock();
888 if (!cp) { 888 if (!cp) {
889 if (param->pe_data) 889 kfree(param->pe_data);
890 kfree(param->pe_data);
891 IP_VS_DBG(2, "BACKUP, add new conn. failed\n"); 890 IP_VS_DBG(2, "BACKUP, add new conn. failed\n");
892 return; 891 return;
893 } 892 }
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 1f4f954c4b47..de88c4ab5146 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -352,40 +352,6 @@ static void nf_ct_delete_from_lists(struct nf_conn *ct)
352 local_bh_enable(); 352 local_bh_enable();
353} 353}
354 354
355static void death_by_event(unsigned long ul_conntrack)
356{
357 struct nf_conn *ct = (void *)ul_conntrack;
358 struct net *net = nf_ct_net(ct);
359 struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct);
360
361 BUG_ON(ecache == NULL);
362
363 if (nf_conntrack_event(IPCT_DESTROY, ct) < 0) {
364 /* bad luck, let's retry again */
365 ecache->timeout.expires = jiffies +
366 (prandom_u32() % net->ct.sysctl_events_retry_timeout);
367 add_timer(&ecache->timeout);
368 return;
369 }
370 /* we've got the event delivered, now it's dying */
371 set_bit(IPS_DYING_BIT, &ct->status);
372 nf_ct_put(ct);
373}
374
375static void nf_ct_dying_timeout(struct nf_conn *ct)
376{
377 struct net *net = nf_ct_net(ct);
378 struct nf_conntrack_ecache *ecache = nf_ct_ecache_find(ct);
379
380 BUG_ON(ecache == NULL);
381
382 /* set a new timer to retry event delivery */
383 setup_timer(&ecache->timeout, death_by_event, (unsigned long)ct);
384 ecache->timeout.expires = jiffies +
385 (prandom_u32() % net->ct.sysctl_events_retry_timeout);
386 add_timer(&ecache->timeout);
387}
388
389bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report) 355bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report)
390{ 356{
391 struct nf_conn_tstamp *tstamp; 357 struct nf_conn_tstamp *tstamp;
@@ -394,15 +360,20 @@ bool nf_ct_delete(struct nf_conn *ct, u32 portid, int report)
394 if (tstamp && tstamp->stop == 0) 360 if (tstamp && tstamp->stop == 0)
395 tstamp->stop = ktime_to_ns(ktime_get_real()); 361 tstamp->stop = ktime_to_ns(ktime_get_real());
396 362
397 if (!nf_ct_is_dying(ct) && 363 if (nf_ct_is_dying(ct))
398 unlikely(nf_conntrack_event_report(IPCT_DESTROY, ct, 364 goto delete;
399 portid, report) < 0)) { 365
366 if (nf_conntrack_event_report(IPCT_DESTROY, ct,
367 portid, report) < 0) {
400 /* destroy event was not delivered */ 368 /* destroy event was not delivered */
401 nf_ct_delete_from_lists(ct); 369 nf_ct_delete_from_lists(ct);
402 nf_ct_dying_timeout(ct); 370 nf_conntrack_ecache_delayed_work(nf_ct_net(ct));
403 return false; 371 return false;
404 } 372 }
373
374 nf_conntrack_ecache_work(nf_ct_net(ct));
405 set_bit(IPS_DYING_BIT, &ct->status); 375 set_bit(IPS_DYING_BIT, &ct->status);
376 delete:
406 nf_ct_delete_from_lists(ct); 377 nf_ct_delete_from_lists(ct);
407 nf_ct_put(ct); 378 nf_ct_put(ct);
408 return true; 379 return true;
@@ -1464,26 +1435,6 @@ void nf_conntrack_flush_report(struct net *net, u32 portid, int report)
1464} 1435}
1465EXPORT_SYMBOL_GPL(nf_conntrack_flush_report); 1436EXPORT_SYMBOL_GPL(nf_conntrack_flush_report);
1466 1437
1467static void nf_ct_release_dying_list(struct net *net)
1468{
1469 struct nf_conntrack_tuple_hash *h;
1470 struct nf_conn *ct;
1471 struct hlist_nulls_node *n;
1472 int cpu;
1473
1474 for_each_possible_cpu(cpu) {
1475 struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
1476
1477 spin_lock_bh(&pcpu->lock);
1478 hlist_nulls_for_each_entry(h, n, &pcpu->dying, hnnode) {
1479 ct = nf_ct_tuplehash_to_ctrack(h);
1480 /* never fails to remove them, no listeners at this point */
1481 nf_ct_kill(ct);
1482 }
1483 spin_unlock_bh(&pcpu->lock);
1484 }
1485}
1486
1487static int untrack_refs(void) 1438static int untrack_refs(void)
1488{ 1439{
1489 int cnt = 0, cpu; 1440 int cnt = 0, cpu;
@@ -1548,7 +1499,6 @@ i_see_dead_people:
1548 busy = 0; 1499 busy = 0;
1549 list_for_each_entry(net, net_exit_list, exit_list) { 1500 list_for_each_entry(net, net_exit_list, exit_list) {
1550 nf_ct_iterate_cleanup(net, kill_all, NULL, 0, 0); 1501 nf_ct_iterate_cleanup(net, kill_all, NULL, 0, 0);
1551 nf_ct_release_dying_list(net);
1552 if (atomic_read(&net->ct.count) != 0) 1502 if (atomic_read(&net->ct.count) != 0)
1553 busy = 1; 1503 busy = 1;
1554 } 1504 }
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index 1df176146567..4e78c57b818f 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -29,6 +29,90 @@
29 29
30static DEFINE_MUTEX(nf_ct_ecache_mutex); 30static DEFINE_MUTEX(nf_ct_ecache_mutex);
31 31
32#define ECACHE_RETRY_WAIT (HZ/10)
33
34enum retry_state {
35 STATE_CONGESTED,
36 STATE_RESTART,
37 STATE_DONE,
38};
39
40static enum retry_state ecache_work_evict_list(struct ct_pcpu *pcpu)
41{
42 struct nf_conn *refs[16];
43 struct nf_conntrack_tuple_hash *h;
44 struct hlist_nulls_node *n;
45 unsigned int evicted = 0;
46 enum retry_state ret = STATE_DONE;
47
48 spin_lock(&pcpu->lock);
49
50 hlist_nulls_for_each_entry(h, n, &pcpu->dying, hnnode) {
51 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
52
53 if (nf_ct_is_dying(ct))
54 continue;
55
56 if (nf_conntrack_event(IPCT_DESTROY, ct)) {
57 ret = STATE_CONGESTED;
58 break;
59 }
60
61 /* we've got the event delivered, now it's dying */
62 set_bit(IPS_DYING_BIT, &ct->status);
63 refs[evicted] = ct;
64
65 if (++evicted >= ARRAY_SIZE(refs)) {
66 ret = STATE_RESTART;
67 break;
68 }
69 }
70
71 spin_unlock(&pcpu->lock);
72
73 /* can't _put while holding lock */
74 while (evicted)
75 nf_ct_put(refs[--evicted]);
76
77 return ret;
78}
79
80static void ecache_work(struct work_struct *work)
81{
82 struct netns_ct *ctnet =
83 container_of(work, struct netns_ct, ecache_dwork.work);
84 int cpu, delay = -1;
85 struct ct_pcpu *pcpu;
86
87 local_bh_disable();
88
89 for_each_possible_cpu(cpu) {
90 enum retry_state ret;
91
92 pcpu = per_cpu_ptr(ctnet->pcpu_lists, cpu);
93
94 ret = ecache_work_evict_list(pcpu);
95
96 switch (ret) {
97 case STATE_CONGESTED:
98 delay = ECACHE_RETRY_WAIT;
99 goto out;
100 case STATE_RESTART:
101 delay = 0;
102 break;
103 case STATE_DONE:
104 break;
105 }
106 }
107
108 out:
109 local_bh_enable();
110
111 ctnet->ecache_dwork_pending = delay > 0;
112 if (delay >= 0)
113 schedule_delayed_work(&ctnet->ecache_dwork, delay);
114}
115
32/* deliver cached events and clear cache entry - must be called with locally 116/* deliver cached events and clear cache entry - must be called with locally
33 * disabled softirqs */ 117 * disabled softirqs */
34void nf_ct_deliver_cached_events(struct nf_conn *ct) 118void nf_ct_deliver_cached_events(struct nf_conn *ct)
@@ -157,7 +241,6 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
157 241
158#define NF_CT_EVENTS_DEFAULT 1 242#define NF_CT_EVENTS_DEFAULT 1
159static int nf_ct_events __read_mostly = NF_CT_EVENTS_DEFAULT; 243static int nf_ct_events __read_mostly = NF_CT_EVENTS_DEFAULT;
160static int nf_ct_events_retry_timeout __read_mostly = 15*HZ;
161 244
162#ifdef CONFIG_SYSCTL 245#ifdef CONFIG_SYSCTL
163static struct ctl_table event_sysctl_table[] = { 246static struct ctl_table event_sysctl_table[] = {
@@ -168,13 +251,6 @@ static struct ctl_table event_sysctl_table[] = {
168 .mode = 0644, 251 .mode = 0644,
169 .proc_handler = proc_dointvec, 252 .proc_handler = proc_dointvec,
170 }, 253 },
171 {
172 .procname = "nf_conntrack_events_retry_timeout",
173 .data = &init_net.ct.sysctl_events_retry_timeout,
174 .maxlen = sizeof(unsigned int),
175 .mode = 0644,
176 .proc_handler = proc_dointvec_jiffies,
177 },
178 {} 254 {}
179}; 255};
180#endif /* CONFIG_SYSCTL */ 256#endif /* CONFIG_SYSCTL */
@@ -196,7 +272,6 @@ static int nf_conntrack_event_init_sysctl(struct net *net)
196 goto out; 272 goto out;
197 273
198 table[0].data = &net->ct.sysctl_events; 274 table[0].data = &net->ct.sysctl_events;
199 table[1].data = &net->ct.sysctl_events_retry_timeout;
200 275
201 /* Don't export sysctls to unprivileged users */ 276 /* Don't export sysctls to unprivileged users */
202 if (net->user_ns != &init_user_ns) 277 if (net->user_ns != &init_user_ns)
@@ -238,12 +313,13 @@ static void nf_conntrack_event_fini_sysctl(struct net *net)
238int nf_conntrack_ecache_pernet_init(struct net *net) 313int nf_conntrack_ecache_pernet_init(struct net *net)
239{ 314{
240 net->ct.sysctl_events = nf_ct_events; 315 net->ct.sysctl_events = nf_ct_events;
241 net->ct.sysctl_events_retry_timeout = nf_ct_events_retry_timeout; 316 INIT_DELAYED_WORK(&net->ct.ecache_dwork, ecache_work);
242 return nf_conntrack_event_init_sysctl(net); 317 return nf_conntrack_event_init_sysctl(net);
243} 318}
244 319
245void nf_conntrack_ecache_pernet_fini(struct net *net) 320void nf_conntrack_ecache_pernet_fini(struct net *net)
246{ 321{
322 cancel_delayed_work_sync(&net->ct.ecache_dwork);
247 nf_conntrack_event_fini_sysctl(net); 323 nf_conntrack_event_fini_sysctl(net);
248} 324}
249 325
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 300ed1eec729..355a5c4ef763 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -745,8 +745,7 @@ static int ctnetlink_done(struct netlink_callback *cb)
745{ 745{
746 if (cb->args[1]) 746 if (cb->args[1])
747 nf_ct_put((struct nf_conn *)cb->args[1]); 747 nf_ct_put((struct nf_conn *)cb->args[1]);
748 if (cb->data) 748 kfree(cb->data);
749 kfree(cb->data);
750 return 0; 749 return 0;
751} 750}
752 751
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 85296d4eac0e..daad6022c689 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -16,16 +16,22 @@
16#define NF_LOG_PREFIXLEN 128 16#define NF_LOG_PREFIXLEN 128
17#define NFLOGGER_NAME_LEN 64 17#define NFLOGGER_NAME_LEN 64
18 18
19static struct list_head nf_loggers_l[NFPROTO_NUMPROTO] __read_mostly; 19static struct nf_logger __rcu *loggers[NFPROTO_NUMPROTO][NF_LOG_TYPE_MAX] __read_mostly;
20static DEFINE_MUTEX(nf_log_mutex); 20static DEFINE_MUTEX(nf_log_mutex);
21 21
22static struct nf_logger *__find_logger(int pf, const char *str_logger) 22static struct nf_logger *__find_logger(int pf, const char *str_logger)
23{ 23{
24 struct nf_logger *t; 24 struct nf_logger *log;
25 int i;
26
27 for (i = 0; i < NF_LOG_TYPE_MAX; i++) {
28 if (loggers[pf][i] == NULL)
29 continue;
25 30
26 list_for_each_entry(t, &nf_loggers_l[pf], list[pf]) { 31 log = rcu_dereference_protected(loggers[pf][i],
27 if (!strnicmp(str_logger, t->name, strlen(t->name))) 32 lockdep_is_held(&nf_log_mutex));
28 return t; 33 if (!strnicmp(str_logger, log->name, strlen(log->name)))
34 return log;
29 } 35 }
30 36
31 return NULL; 37 return NULL;
@@ -73,17 +79,14 @@ int nf_log_register(u_int8_t pf, struct nf_logger *logger)
73 if (pf >= ARRAY_SIZE(init_net.nf.nf_loggers)) 79 if (pf >= ARRAY_SIZE(init_net.nf.nf_loggers))
74 return -EINVAL; 80 return -EINVAL;
75 81
76 for (i = 0; i < ARRAY_SIZE(logger->list); i++)
77 INIT_LIST_HEAD(&logger->list[i]);
78
79 mutex_lock(&nf_log_mutex); 82 mutex_lock(&nf_log_mutex);
80 83
81 if (pf == NFPROTO_UNSPEC) { 84 if (pf == NFPROTO_UNSPEC) {
82 for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++) 85 for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
83 list_add_tail(&(logger->list[i]), &(nf_loggers_l[i])); 86 rcu_assign_pointer(loggers[i][logger->type], logger);
84 } else { 87 } else {
85 /* register at end of list to honor first register win */ 88 /* register at end of list to honor first register win */
86 list_add_tail(&logger->list[pf], &nf_loggers_l[pf]); 89 rcu_assign_pointer(loggers[pf][logger->type], logger);
87 } 90 }
88 91
89 mutex_unlock(&nf_log_mutex); 92 mutex_unlock(&nf_log_mutex);
@@ -98,7 +101,7 @@ void nf_log_unregister(struct nf_logger *logger)
98 101
99 mutex_lock(&nf_log_mutex); 102 mutex_lock(&nf_log_mutex);
100 for (i = 0; i < NFPROTO_NUMPROTO; i++) 103 for (i = 0; i < NFPROTO_NUMPROTO; i++)
101 list_del(&logger->list[i]); 104 RCU_INIT_POINTER(loggers[i][logger->type], NULL);
102 mutex_unlock(&nf_log_mutex); 105 mutex_unlock(&nf_log_mutex);
103} 106}
104EXPORT_SYMBOL(nf_log_unregister); 107EXPORT_SYMBOL(nf_log_unregister);
@@ -129,6 +132,48 @@ void nf_log_unbind_pf(struct net *net, u_int8_t pf)
129} 132}
130EXPORT_SYMBOL(nf_log_unbind_pf); 133EXPORT_SYMBOL(nf_log_unbind_pf);
131 134
135void nf_logger_request_module(int pf, enum nf_log_type type)
136{
137 if (loggers[pf][type] == NULL)
138 request_module("nf-logger-%u-%u", pf, type);
139}
140EXPORT_SYMBOL_GPL(nf_logger_request_module);
141
142int nf_logger_find_get(int pf, enum nf_log_type type)
143{
144 struct nf_logger *logger;
145 int ret = -ENOENT;
146
147 logger = loggers[pf][type];
148 if (logger == NULL)
149 request_module("nf-logger-%u-%u", pf, type);
150
151 rcu_read_lock();
152 logger = rcu_dereference(loggers[pf][type]);
153 if (logger == NULL)
154 goto out;
155
156 if (logger && try_module_get(logger->me))
157 ret = 0;
158out:
159 rcu_read_unlock();
160 return ret;
161}
162EXPORT_SYMBOL_GPL(nf_logger_find_get);
163
164void nf_logger_put(int pf, enum nf_log_type type)
165{
166 struct nf_logger *logger;
167
168 BUG_ON(loggers[pf][type] == NULL);
169
170 rcu_read_lock();
171 logger = rcu_dereference(loggers[pf][type]);
172 module_put(logger->me);
173 rcu_read_unlock();
174}
175EXPORT_SYMBOL_GPL(nf_logger_put);
176
132void nf_log_packet(struct net *net, 177void nf_log_packet(struct net *net,
133 u_int8_t pf, 178 u_int8_t pf,
134 unsigned int hooknum, 179 unsigned int hooknum,
@@ -143,7 +188,11 @@ void nf_log_packet(struct net *net,
143 const struct nf_logger *logger; 188 const struct nf_logger *logger;
144 189
145 rcu_read_lock(); 190 rcu_read_lock();
146 logger = rcu_dereference(net->nf.nf_loggers[pf]); 191 if (loginfo != NULL)
192 logger = rcu_dereference(loggers[pf][loginfo->type]);
193 else
194 logger = rcu_dereference(net->nf.nf_loggers[pf]);
195
147 if (logger) { 196 if (logger) {
148 va_start(args, fmt); 197 va_start(args, fmt);
149 vsnprintf(prefix, sizeof(prefix), fmt, args); 198 vsnprintf(prefix, sizeof(prefix), fmt, args);
@@ -154,6 +203,63 @@ void nf_log_packet(struct net *net,
154} 203}
155EXPORT_SYMBOL(nf_log_packet); 204EXPORT_SYMBOL(nf_log_packet);
156 205
206#define S_SIZE (1024 - (sizeof(unsigned int) + 1))
207
208struct nf_log_buf {
209 unsigned int count;
210 char buf[S_SIZE + 1];
211};
212static struct nf_log_buf emergency, *emergency_ptr = &emergency;
213
214__printf(2, 3) int nf_log_buf_add(struct nf_log_buf *m, const char *f, ...)
215{
216 va_list args;
217 int len;
218
219 if (likely(m->count < S_SIZE)) {
220 va_start(args, f);
221 len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args);
222 va_end(args);
223 if (likely(m->count + len < S_SIZE)) {
224 m->count += len;
225 return 0;
226 }
227 }
228 m->count = S_SIZE;
229 printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n");
230 return -1;
231}
232EXPORT_SYMBOL_GPL(nf_log_buf_add);
233
234struct nf_log_buf *nf_log_buf_open(void)
235{
236 struct nf_log_buf *m = kmalloc(sizeof(*m), GFP_ATOMIC);
237
238 if (unlikely(!m)) {
239 local_bh_disable();
240 do {
241 m = xchg(&emergency_ptr, NULL);
242 } while (!m);
243 }
244 m->count = 0;
245 return m;
246}
247EXPORT_SYMBOL_GPL(nf_log_buf_open);
248
249void nf_log_buf_close(struct nf_log_buf *m)
250{
251 m->buf[m->count] = 0;
252 printk("%s\n", m->buf);
253
254 if (likely(m != &emergency))
255 kfree(m);
256 else {
257 emergency_ptr = m;
258 local_bh_enable();
259 }
260}
261EXPORT_SYMBOL_GPL(nf_log_buf_close);
262
157#ifdef CONFIG_PROC_FS 263#ifdef CONFIG_PROC_FS
158static void *seq_start(struct seq_file *seq, loff_t *pos) 264static void *seq_start(struct seq_file *seq, loff_t *pos)
159{ 265{
@@ -188,8 +294,7 @@ static int seq_show(struct seq_file *s, void *v)
188{ 294{
189 loff_t *pos = v; 295 loff_t *pos = v;
190 const struct nf_logger *logger; 296 const struct nf_logger *logger;
191 struct nf_logger *t; 297 int i, ret;
192 int ret;
193 struct net *net = seq_file_net(s); 298 struct net *net = seq_file_net(s);
194 299
195 logger = rcu_dereference_protected(net->nf.nf_loggers[*pos], 300 logger = rcu_dereference_protected(net->nf.nf_loggers[*pos],
@@ -203,11 +308,16 @@ static int seq_show(struct seq_file *s, void *v)
203 if (ret < 0) 308 if (ret < 0)
204 return ret; 309 return ret;
205 310
206 list_for_each_entry(t, &nf_loggers_l[*pos], list[*pos]) { 311 for (i = 0; i < NF_LOG_TYPE_MAX; i++) {
207 ret = seq_printf(s, "%s", t->name); 312 if (loggers[*pos][i] == NULL)
313 continue;
314
315 logger = rcu_dereference_protected(loggers[*pos][i],
316 lockdep_is_held(&nf_log_mutex));
317 ret = seq_printf(s, "%s", logger->name);
208 if (ret < 0) 318 if (ret < 0)
209 return ret; 319 return ret;
210 if (&t->list[*pos] != nf_loggers_l[*pos].prev) { 320 if (i == 0 && loggers[*pos][i + 1] != NULL) {
211 ret = seq_printf(s, ","); 321 ret = seq_printf(s, ",");
212 if (ret < 0) 322 if (ret < 0)
213 return ret; 323 return ret;
@@ -389,14 +499,5 @@ static struct pernet_operations nf_log_net_ops = {
389 499
390int __init netfilter_log_init(void) 500int __init netfilter_log_init(void)
391{ 501{
392 int i, ret; 502 return register_pernet_subsys(&nf_log_net_ops);
393
394 ret = register_pernet_subsys(&nf_log_net_ops);
395 if (ret < 0)
396 return ret;
397
398 for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
399 INIT_LIST_HEAD(&(nf_loggers_l[i]));
400
401 return 0;
402} 503}
diff --git a/net/netfilter/nf_log_common.c b/net/netfilter/nf_log_common.c
new file mode 100644
index 000000000000..eeb8ef4ff1a3
--- /dev/null
+++ b/net/netfilter/nf_log_common.c
@@ -0,0 +1,187 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/module.h>
10#include <linux/spinlock.h>
11#include <linux/skbuff.h>
12#include <linux/if_arp.h>
13#include <linux/ip.h>
14#include <net/icmp.h>
15#include <net/udp.h>
16#include <net/tcp.h>
17#include <net/route.h>
18
19#include <linux/netfilter.h>
20#include <linux/netfilter/xt_LOG.h>
21#include <net/netfilter/nf_log.h>
22
23int nf_log_dump_udp_header(struct nf_log_buf *m, const struct sk_buff *skb,
24 u8 proto, int fragment, unsigned int offset)
25{
26 struct udphdr _udph;
27 const struct udphdr *uh;
28
29 if (proto == IPPROTO_UDP)
30 /* Max length: 10 "PROTO=UDP " */
31 nf_log_buf_add(m, "PROTO=UDP ");
32 else /* Max length: 14 "PROTO=UDPLITE " */
33 nf_log_buf_add(m, "PROTO=UDPLITE ");
34
35 if (fragment)
36 goto out;
37
38 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
39 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
40 if (uh == NULL) {
41 nf_log_buf_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
42
43 return 1;
44 }
45
46 /* Max length: 20 "SPT=65535 DPT=65535 " */
47 nf_log_buf_add(m, "SPT=%u DPT=%u LEN=%u ",
48 ntohs(uh->source), ntohs(uh->dest), ntohs(uh->len));
49
50out:
51 return 0;
52}
53EXPORT_SYMBOL_GPL(nf_log_dump_udp_header);
54
55int nf_log_dump_tcp_header(struct nf_log_buf *m, const struct sk_buff *skb,
56 u8 proto, int fragment, unsigned int offset,
57 unsigned int logflags)
58{
59 struct tcphdr _tcph;
60 const struct tcphdr *th;
61
62 /* Max length: 10 "PROTO=TCP " */
63 nf_log_buf_add(m, "PROTO=TCP ");
64
65 if (fragment)
66 return 0;
67
68 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
69 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
70 if (th == NULL) {
71 nf_log_buf_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
72 return 1;
73 }
74
75 /* Max length: 20 "SPT=65535 DPT=65535 " */
76 nf_log_buf_add(m, "SPT=%u DPT=%u ",
77 ntohs(th->source), ntohs(th->dest));
78 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
79 if (logflags & XT_LOG_TCPSEQ) {
80 nf_log_buf_add(m, "SEQ=%u ACK=%u ",
81 ntohl(th->seq), ntohl(th->ack_seq));
82 }
83
84 /* Max length: 13 "WINDOW=65535 " */
85 nf_log_buf_add(m, "WINDOW=%u ", ntohs(th->window));
86 /* Max length: 9 "RES=0x3C " */
87 nf_log_buf_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) &
88 TCP_RESERVED_BITS) >> 22));
89 /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
90 if (th->cwr)
91 nf_log_buf_add(m, "CWR ");
92 if (th->ece)
93 nf_log_buf_add(m, "ECE ");
94 if (th->urg)
95 nf_log_buf_add(m, "URG ");
96 if (th->ack)
97 nf_log_buf_add(m, "ACK ");
98 if (th->psh)
99 nf_log_buf_add(m, "PSH ");
100 if (th->rst)
101 nf_log_buf_add(m, "RST ");
102 if (th->syn)
103 nf_log_buf_add(m, "SYN ");
104 if (th->fin)
105 nf_log_buf_add(m, "FIN ");
106 /* Max length: 11 "URGP=65535 " */
107 nf_log_buf_add(m, "URGP=%u ", ntohs(th->urg_ptr));
108
109 if ((logflags & XT_LOG_TCPOPT) && th->doff*4 > sizeof(struct tcphdr)) {
110 u_int8_t _opt[60 - sizeof(struct tcphdr)];
111 const u_int8_t *op;
112 unsigned int i;
113 unsigned int optsize = th->doff*4 - sizeof(struct tcphdr);
114
115 op = skb_header_pointer(skb, offset + sizeof(struct tcphdr),
116 optsize, _opt);
117 if (op == NULL) {
118 nf_log_buf_add(m, "OPT (TRUNCATED)");
119 return 1;
120 }
121
122 /* Max length: 127 "OPT (" 15*4*2chars ") " */
123 nf_log_buf_add(m, "OPT (");
124 for (i = 0; i < optsize; i++)
125 nf_log_buf_add(m, "%02X", op[i]);
126
127 nf_log_buf_add(m, ") ");
128 }
129
130 return 0;
131}
132EXPORT_SYMBOL_GPL(nf_log_dump_tcp_header);
133
134void nf_log_dump_sk_uid_gid(struct nf_log_buf *m, struct sock *sk)
135{
136 if (!sk || sk->sk_state == TCP_TIME_WAIT)
137 return;
138
139 read_lock_bh(&sk->sk_callback_lock);
140 if (sk->sk_socket && sk->sk_socket->file) {
141 const struct cred *cred = sk->sk_socket->file->f_cred;
142 nf_log_buf_add(m, "UID=%u GID=%u ",
143 from_kuid_munged(&init_user_ns, cred->fsuid),
144 from_kgid_munged(&init_user_ns, cred->fsgid));
145 }
146 read_unlock_bh(&sk->sk_callback_lock);
147}
148EXPORT_SYMBOL_GPL(nf_log_dump_sk_uid_gid);
149
150void
151nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf,
152 unsigned int hooknum, const struct sk_buff *skb,
153 const struct net_device *in,
154 const struct net_device *out,
155 const struct nf_loginfo *loginfo, const char *prefix)
156{
157 nf_log_buf_add(m, KERN_SOH "%c%sIN=%s OUT=%s ",
158 '0' + loginfo->u.log.level, prefix,
159 in ? in->name : "",
160 out ? out->name : "");
161#ifdef CONFIG_BRIDGE_NETFILTER
162 if (skb->nf_bridge) {
163 const struct net_device *physindev;
164 const struct net_device *physoutdev;
165
166 physindev = skb->nf_bridge->physindev;
167 if (physindev && in != physindev)
168 nf_log_buf_add(m, "PHYSIN=%s ", physindev->name);
169 physoutdev = skb->nf_bridge->physoutdev;
170 if (physoutdev && out != physoutdev)
171 nf_log_buf_add(m, "PHYSOUT=%s ", physoutdev->name);
172 }
173#endif
174}
175EXPORT_SYMBOL_GPL(nf_log_dump_packet_common);
176
177static int __init nf_log_common_init(void)
178{
179 return 0;
180}
181
182static void __exit nf_log_common_exit(void) {}
183
184module_init(nf_log_common_init);
185module_exit(nf_log_common_exit);
186
187MODULE_LICENSE("GPL");
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
index a49907b1dabc..552f97cd9fde 100644
--- a/net/netfilter/nf_nat_core.c
+++ b/net/netfilter/nf_nat_core.c
@@ -710,7 +710,7 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
710 .flags = NF_CT_EXT_F_PREALLOC, 710 .flags = NF_CT_EXT_F_PREALLOC,
711}; 711};
712 712
713#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 713#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
714 714
715#include <linux/netfilter/nfnetlink.h> 715#include <linux/netfilter/nfnetlink.h>
716#include <linux/netfilter/nfnetlink_conntrack.h> 716#include <linux/netfilter/nfnetlink_conntrack.h>
diff --git a/net/netfilter/nf_nat_proto_common.c b/net/netfilter/nf_nat_proto_common.c
index 83a72a235cae..fbce552a796e 100644
--- a/net/netfilter/nf_nat_proto_common.c
+++ b/net/netfilter/nf_nat_proto_common.c
@@ -95,7 +95,7 @@ void nf_nat_l4proto_unique_tuple(const struct nf_nat_l3proto *l3proto,
95} 95}
96EXPORT_SYMBOL_GPL(nf_nat_l4proto_unique_tuple); 96EXPORT_SYMBOL_GPL(nf_nat_l4proto_unique_tuple);
97 97
98#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 98#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
99int nf_nat_l4proto_nlattr_to_range(struct nlattr *tb[], 99int nf_nat_l4proto_nlattr_to_range(struct nlattr *tb[],
100 struct nf_nat_range *range) 100 struct nf_nat_range *range)
101{ 101{
diff --git a/net/netfilter/nf_nat_proto_dccp.c b/net/netfilter/nf_nat_proto_dccp.c
index c8be2cdac0bf..b8067b53ff3a 100644
--- a/net/netfilter/nf_nat_proto_dccp.c
+++ b/net/netfilter/nf_nat_proto_dccp.c
@@ -78,7 +78,7 @@ static const struct nf_nat_l4proto nf_nat_l4proto_dccp = {
78 .manip_pkt = dccp_manip_pkt, 78 .manip_pkt = dccp_manip_pkt,
79 .in_range = nf_nat_l4proto_in_range, 79 .in_range = nf_nat_l4proto_in_range,
80 .unique_tuple = dccp_unique_tuple, 80 .unique_tuple = dccp_unique_tuple,
81#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 81#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
82 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, 82 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
83#endif 83#endif
84}; 84};
diff --git a/net/netfilter/nf_nat_proto_sctp.c b/net/netfilter/nf_nat_proto_sctp.c
index 754536f2c674..cbc7ade1487b 100644
--- a/net/netfilter/nf_nat_proto_sctp.c
+++ b/net/netfilter/nf_nat_proto_sctp.c
@@ -59,7 +59,7 @@ static const struct nf_nat_l4proto nf_nat_l4proto_sctp = {
59 .manip_pkt = sctp_manip_pkt, 59 .manip_pkt = sctp_manip_pkt,
60 .in_range = nf_nat_l4proto_in_range, 60 .in_range = nf_nat_l4proto_in_range,
61 .unique_tuple = sctp_unique_tuple, 61 .unique_tuple = sctp_unique_tuple,
62#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 62#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
63 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, 63 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
64#endif 64#endif
65}; 65};
diff --git a/net/netfilter/nf_nat_proto_tcp.c b/net/netfilter/nf_nat_proto_tcp.c
index 83ec8a6e4c36..37f5505f4529 100644
--- a/net/netfilter/nf_nat_proto_tcp.c
+++ b/net/netfilter/nf_nat_proto_tcp.c
@@ -79,7 +79,7 @@ const struct nf_nat_l4proto nf_nat_l4proto_tcp = {
79 .manip_pkt = tcp_manip_pkt, 79 .manip_pkt = tcp_manip_pkt,
80 .in_range = nf_nat_l4proto_in_range, 80 .in_range = nf_nat_l4proto_in_range,
81 .unique_tuple = tcp_unique_tuple, 81 .unique_tuple = tcp_unique_tuple,
82#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 82#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
83 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, 83 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
84#endif 84#endif
85}; 85};
diff --git a/net/netfilter/nf_nat_proto_udp.c b/net/netfilter/nf_nat_proto_udp.c
index 7df613fb34a2..b0ede2f0d8bc 100644
--- a/net/netfilter/nf_nat_proto_udp.c
+++ b/net/netfilter/nf_nat_proto_udp.c
@@ -70,7 +70,7 @@ const struct nf_nat_l4proto nf_nat_l4proto_udp = {
70 .manip_pkt = udp_manip_pkt, 70 .manip_pkt = udp_manip_pkt,
71 .in_range = nf_nat_l4proto_in_range, 71 .in_range = nf_nat_l4proto_in_range,
72 .unique_tuple = udp_unique_tuple, 72 .unique_tuple = udp_unique_tuple,
73#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 73#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
74 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, 74 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
75#endif 75#endif
76}; 76};
diff --git a/net/netfilter/nf_nat_proto_udplite.c b/net/netfilter/nf_nat_proto_udplite.c
index 776a0d1317b1..368f14e01e75 100644
--- a/net/netfilter/nf_nat_proto_udplite.c
+++ b/net/netfilter/nf_nat_proto_udplite.c
@@ -69,7 +69,7 @@ static const struct nf_nat_l4proto nf_nat_l4proto_udplite = {
69 .manip_pkt = udplite_manip_pkt, 69 .manip_pkt = udplite_manip_pkt,
70 .in_range = nf_nat_l4proto_in_range, 70 .in_range = nf_nat_l4proto_in_range,
71 .unique_tuple = udplite_unique_tuple, 71 .unique_tuple = udplite_unique_tuple,
72#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 72#if IS_ENABLED(CONFIG_NF_CT_NETLINK)
73 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range, 73 .nlattr_to_range = nf_nat_l4proto_nlattr_to_range,
74#endif 74#endif
75}; 75};
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index d292c8d286eb..a11c5ff2f720 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -773,6 +773,7 @@ nfulnl_recv_unsupp(struct sock *ctnl, struct sk_buff *skb,
773 773
774static struct nf_logger nfulnl_logger __read_mostly = { 774static struct nf_logger nfulnl_logger __read_mostly = {
775 .name = "nfnetlink_log", 775 .name = "nfnetlink_log",
776 .type = NF_LOG_TYPE_ULOG,
776 .logfn = &nfulnl_log_packet, 777 .logfn = &nfulnl_log_packet,
777 .me = THIS_MODULE, 778 .me = THIS_MODULE,
778}; 779};
@@ -1105,6 +1106,9 @@ MODULE_DESCRIPTION("netfilter userspace logging");
1105MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 1106MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
1106MODULE_LICENSE("GPL"); 1107MODULE_LICENSE("GPL");
1107MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG); 1108MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_ULOG);
1109MODULE_ALIAS_NF_LOGGER(AF_INET, 1);
1110MODULE_ALIAS_NF_LOGGER(AF_INET6, 1);
1111MODULE_ALIAS_NF_LOGGER(AF_BRIDGE, 1);
1108 1112
1109module_init(nfnetlink_log_init); 1113module_init(nfnetlink_log_init);
1110module_exit(nfnetlink_log_fini); 1114module_exit(nfnetlink_log_fini);
diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
index 10cfb156cdf4..bde05f28cf14 100644
--- a/net/netfilter/nft_log.c
+++ b/net/netfilter/nft_log.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net> 2 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
3 * Copyright (c) 2012-2014 Pablo Neira Ayuso <pablo@netfilter.org>
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
@@ -41,6 +42,8 @@ static const struct nla_policy nft_log_policy[NFTA_LOG_MAX + 1] = {
41 [NFTA_LOG_PREFIX] = { .type = NLA_STRING }, 42 [NFTA_LOG_PREFIX] = { .type = NLA_STRING },
42 [NFTA_LOG_SNAPLEN] = { .type = NLA_U32 }, 43 [NFTA_LOG_SNAPLEN] = { .type = NLA_U32 },
43 [NFTA_LOG_QTHRESHOLD] = { .type = NLA_U16 }, 44 [NFTA_LOG_QTHRESHOLD] = { .type = NLA_U16 },
45 [NFTA_LOG_LEVEL] = { .type = NLA_U32 },
46 [NFTA_LOG_FLAGS] = { .type = NLA_U32 },
44}; 47};
45 48
46static int nft_log_init(const struct nft_ctx *ctx, 49static int nft_log_init(const struct nft_ctx *ctx,
@@ -50,6 +53,7 @@ static int nft_log_init(const struct nft_ctx *ctx,
50 struct nft_log *priv = nft_expr_priv(expr); 53 struct nft_log *priv = nft_expr_priv(expr);
51 struct nf_loginfo *li = &priv->loginfo; 54 struct nf_loginfo *li = &priv->loginfo;
52 const struct nlattr *nla; 55 const struct nlattr *nla;
56 int ret;
53 57
54 nla = tb[NFTA_LOG_PREFIX]; 58 nla = tb[NFTA_LOG_PREFIX];
55 if (nla != NULL) { 59 if (nla != NULL) {
@@ -57,30 +61,74 @@ static int nft_log_init(const struct nft_ctx *ctx,
57 if (priv->prefix == NULL) 61 if (priv->prefix == NULL)
58 return -ENOMEM; 62 return -ENOMEM;
59 nla_strlcpy(priv->prefix, nla, nla_len(nla) + 1); 63 nla_strlcpy(priv->prefix, nla, nla_len(nla) + 1);
60 } else 64 } else {
61 priv->prefix = (char *)nft_log_null_prefix; 65 priv->prefix = (char *)nft_log_null_prefix;
66 }
62 67
63 li->type = NF_LOG_TYPE_ULOG; 68 li->type = NF_LOG_TYPE_LOG;
69 if (tb[NFTA_LOG_LEVEL] != NULL &&
70 tb[NFTA_LOG_GROUP] != NULL)
71 return -EINVAL;
64 if (tb[NFTA_LOG_GROUP] != NULL) 72 if (tb[NFTA_LOG_GROUP] != NULL)
73 li->type = NF_LOG_TYPE_ULOG;
74
75 switch (li->type) {
76 case NF_LOG_TYPE_LOG:
77 if (tb[NFTA_LOG_LEVEL] != NULL) {
78 li->u.log.level =
79 ntohl(nla_get_be32(tb[NFTA_LOG_LEVEL]));
80 } else {
81 li->u.log.level = 4;
82 }
83 if (tb[NFTA_LOG_FLAGS] != NULL) {
84 li->u.log.logflags =
85 ntohl(nla_get_be32(tb[NFTA_LOG_FLAGS]));
86 }
87 break;
88 case NF_LOG_TYPE_ULOG:
65 li->u.ulog.group = ntohs(nla_get_be16(tb[NFTA_LOG_GROUP])); 89 li->u.ulog.group = ntohs(nla_get_be16(tb[NFTA_LOG_GROUP]));
90 if (tb[NFTA_LOG_SNAPLEN] != NULL) {
91 li->u.ulog.copy_len =
92 ntohl(nla_get_be32(tb[NFTA_LOG_SNAPLEN]));
93 }
94 if (tb[NFTA_LOG_QTHRESHOLD] != NULL) {
95 li->u.ulog.qthreshold =
96 ntohs(nla_get_be16(tb[NFTA_LOG_QTHRESHOLD]));
97 }
98 break;
99 }
66 100
67 if (tb[NFTA_LOG_SNAPLEN] != NULL) 101 if (ctx->afi->family == NFPROTO_INET) {
68 li->u.ulog.copy_len = ntohl(nla_get_be32(tb[NFTA_LOG_SNAPLEN])); 102 ret = nf_logger_find_get(NFPROTO_IPV4, li->type);
69 if (tb[NFTA_LOG_QTHRESHOLD] != NULL) { 103 if (ret < 0)
70 li->u.ulog.qthreshold = 104 return ret;
71 ntohs(nla_get_be16(tb[NFTA_LOG_QTHRESHOLD])); 105
106 ret = nf_logger_find_get(NFPROTO_IPV6, li->type);
107 if (ret < 0) {
108 nf_logger_put(NFPROTO_IPV4, li->type);
109 return ret;
110 }
111 return 0;
72 } 112 }
73 113
74 return 0; 114 return nf_logger_find_get(ctx->afi->family, li->type);
75} 115}
76 116
77static void nft_log_destroy(const struct nft_ctx *ctx, 117static void nft_log_destroy(const struct nft_ctx *ctx,
78 const struct nft_expr *expr) 118 const struct nft_expr *expr)
79{ 119{
80 struct nft_log *priv = nft_expr_priv(expr); 120 struct nft_log *priv = nft_expr_priv(expr);
121 struct nf_loginfo *li = &priv->loginfo;
81 122
82 if (priv->prefix != nft_log_null_prefix) 123 if (priv->prefix != nft_log_null_prefix)
83 kfree(priv->prefix); 124 kfree(priv->prefix);
125
126 if (ctx->afi->family == NFPROTO_INET) {
127 nf_logger_put(NFPROTO_IPV4, li->type);
128 nf_logger_put(NFPROTO_IPV6, li->type);
129 } else {
130 nf_logger_put(ctx->afi->family, li->type);
131 }
84} 132}
85 133
86static int nft_log_dump(struct sk_buff *skb, const struct nft_expr *expr) 134static int nft_log_dump(struct sk_buff *skb, const struct nft_expr *expr)
@@ -91,17 +139,33 @@ static int nft_log_dump(struct sk_buff *skb, const struct nft_expr *expr)
91 if (priv->prefix != nft_log_null_prefix) 139 if (priv->prefix != nft_log_null_prefix)
92 if (nla_put_string(skb, NFTA_LOG_PREFIX, priv->prefix)) 140 if (nla_put_string(skb, NFTA_LOG_PREFIX, priv->prefix))
93 goto nla_put_failure; 141 goto nla_put_failure;
94 if (li->u.ulog.group) 142 switch (li->type) {
95 if (nla_put_be16(skb, NFTA_LOG_GROUP, htons(li->u.ulog.group))) 143 case NF_LOG_TYPE_LOG:
96 goto nla_put_failure; 144 if (nla_put_be32(skb, NFTA_LOG_LEVEL, htonl(li->u.log.level)))
97 if (li->u.ulog.copy_len)
98 if (nla_put_be32(skb, NFTA_LOG_SNAPLEN,
99 htonl(li->u.ulog.copy_len)))
100 goto nla_put_failure; 145 goto nla_put_failure;
101 if (li->u.ulog.qthreshold) 146
102 if (nla_put_be16(skb, NFTA_LOG_QTHRESHOLD, 147 if (li->u.log.logflags) {
103 htons(li->u.ulog.qthreshold))) 148 if (nla_put_be32(skb, NFTA_LOG_FLAGS,
149 htonl(li->u.log.logflags)))
150 goto nla_put_failure;
151 }
152 break;
153 case NF_LOG_TYPE_ULOG:
154 if (nla_put_be16(skb, NFTA_LOG_GROUP, htons(li->u.ulog.group)))
104 goto nla_put_failure; 155 goto nla_put_failure;
156
157 if (li->u.ulog.copy_len) {
158 if (nla_put_be32(skb, NFTA_LOG_SNAPLEN,
159 htonl(li->u.ulog.copy_len)))
160 goto nla_put_failure;
161 }
162 if (li->u.ulog.qthreshold) {
163 if (nla_put_be16(skb, NFTA_LOG_QTHRESHOLD,
164 htons(li->u.ulog.qthreshold)))
165 goto nla_put_failure;
166 }
167 break;
168 }
105 return 0; 169 return 0;
106 170
107nla_put_failure: 171nla_put_failure:
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 227aa11e8409..47b978bc3100 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -711,28 +711,15 @@ void xt_free_table_info(struct xt_table_info *info)
711{ 711{
712 int cpu; 712 int cpu;
713 713
714 for_each_possible_cpu(cpu) { 714 for_each_possible_cpu(cpu)
715 if (info->size <= PAGE_SIZE) 715 kvfree(info->entries[cpu]);
716 kfree(info->entries[cpu]);
717 else
718 vfree(info->entries[cpu]);
719 }
720 716
721 if (info->jumpstack != NULL) { 717 if (info->jumpstack != NULL) {
722 if (sizeof(void *) * info->stacksize > PAGE_SIZE) { 718 for_each_possible_cpu(cpu)
723 for_each_possible_cpu(cpu) 719 kvfree(info->jumpstack[cpu]);
724 vfree(info->jumpstack[cpu]); 720 kvfree(info->jumpstack);
725 } else {
726 for_each_possible_cpu(cpu)
727 kfree(info->jumpstack[cpu]);
728 }
729 } 721 }
730 722
731 if (sizeof(void **) * nr_cpu_ids > PAGE_SIZE)
732 vfree(info->jumpstack);
733 else
734 kfree(info->jumpstack);
735
736 free_percpu(info->stackptr); 723 free_percpu(info->stackptr);
737 724
738 kfree(info); 725 kfree(info);
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c
index 5ab24843370a..c13b79440ede 100644
--- a/net/netfilter/xt_LOG.c
+++ b/net/netfilter/xt_LOG.c
@@ -27,806 +27,6 @@
27#include <linux/netfilter/xt_LOG.h> 27#include <linux/netfilter/xt_LOG.h>
28#include <linux/netfilter_ipv6/ip6_tables.h> 28#include <linux/netfilter_ipv6/ip6_tables.h>
29#include <net/netfilter/nf_log.h> 29#include <net/netfilter/nf_log.h>
30#include <net/netfilter/xt_log.h>
31
32static struct nf_loginfo default_loginfo = {
33 .type = NF_LOG_TYPE_LOG,
34 .u = {
35 .log = {
36 .level = 5,
37 .logflags = NF_LOG_MASK,
38 },
39 },
40};
41
42static int dump_udp_header(struct sbuff *m, const struct sk_buff *skb,
43 u8 proto, int fragment, unsigned int offset)
44{
45 struct udphdr _udph;
46 const struct udphdr *uh;
47
48 if (proto == IPPROTO_UDP)
49 /* Max length: 10 "PROTO=UDP " */
50 sb_add(m, "PROTO=UDP ");
51 else /* Max length: 14 "PROTO=UDPLITE " */
52 sb_add(m, "PROTO=UDPLITE ");
53
54 if (fragment)
55 goto out;
56
57 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
58 uh = skb_header_pointer(skb, offset, sizeof(_udph), &_udph);
59 if (uh == NULL) {
60 sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
61
62 return 1;
63 }
64
65 /* Max length: 20 "SPT=65535 DPT=65535 " */
66 sb_add(m, "SPT=%u DPT=%u LEN=%u ", ntohs(uh->source), ntohs(uh->dest),
67 ntohs(uh->len));
68
69out:
70 return 0;
71}
72
73static int dump_tcp_header(struct sbuff *m, const struct sk_buff *skb,
74 u8 proto, int fragment, unsigned int offset,
75 unsigned int logflags)
76{
77 struct tcphdr _tcph;
78 const struct tcphdr *th;
79
80 /* Max length: 10 "PROTO=TCP " */
81 sb_add(m, "PROTO=TCP ");
82
83 if (fragment)
84 return 0;
85
86 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
87 th = skb_header_pointer(skb, offset, sizeof(_tcph), &_tcph);
88 if (th == NULL) {
89 sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - offset);
90 return 1;
91 }
92
93 /* Max length: 20 "SPT=65535 DPT=65535 " */
94 sb_add(m, "SPT=%u DPT=%u ", ntohs(th->source), ntohs(th->dest));
95 /* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
96 if (logflags & XT_LOG_TCPSEQ)
97 sb_add(m, "SEQ=%u ACK=%u ", ntohl(th->seq), ntohl(th->ack_seq));
98
99 /* Max length: 13 "WINDOW=65535 " */
100 sb_add(m, "WINDOW=%u ", ntohs(th->window));
101 /* Max length: 9 "RES=0x3C " */
102 sb_add(m, "RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(th) &
103 TCP_RESERVED_BITS) >> 22));
104 /* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
105 if (th->cwr)
106 sb_add(m, "CWR ");
107 if (th->ece)
108 sb_add(m, "ECE ");
109 if (th->urg)
110 sb_add(m, "URG ");
111 if (th->ack)
112 sb_add(m, "ACK ");
113 if (th->psh)
114 sb_add(m, "PSH ");
115 if (th->rst)
116 sb_add(m, "RST ");
117 if (th->syn)
118 sb_add(m, "SYN ");
119 if (th->fin)
120 sb_add(m, "FIN ");
121 /* Max length: 11 "URGP=65535 " */
122 sb_add(m, "URGP=%u ", ntohs(th->urg_ptr));
123
124 if ((logflags & XT_LOG_TCPOPT) && th->doff*4 > sizeof(struct tcphdr)) {
125 u_int8_t _opt[60 - sizeof(struct tcphdr)];
126 const u_int8_t *op;
127 unsigned int i;
128 unsigned int optsize = th->doff*4 - sizeof(struct tcphdr);
129
130 op = skb_header_pointer(skb, offset + sizeof(struct tcphdr),
131 optsize, _opt);
132 if (op == NULL) {
133 sb_add(m, "OPT (TRUNCATED)");
134 return 1;
135 }
136
137 /* Max length: 127 "OPT (" 15*4*2chars ") " */
138 sb_add(m, "OPT (");
139 for (i = 0; i < optsize; i++)
140 sb_add(m, "%02X", op[i]);
141
142 sb_add(m, ") ");
143 }
144
145 return 0;
146}
147
148static void dump_sk_uid_gid(struct sbuff *m, struct sock *sk)
149{
150 if (!sk || sk->sk_state == TCP_TIME_WAIT)
151 return;
152
153 read_lock_bh(&sk->sk_callback_lock);
154 if (sk->sk_socket && sk->sk_socket->file) {
155 const struct cred *cred = sk->sk_socket->file->f_cred;
156 sb_add(m, "UID=%u GID=%u ",
157 from_kuid_munged(&init_user_ns, cred->fsuid),
158 from_kgid_munged(&init_user_ns, cred->fsgid));
159 }
160 read_unlock_bh(&sk->sk_callback_lock);
161}
162
163/* One level of recursion won't kill us */
164static void dump_ipv4_packet(struct sbuff *m,
165 const struct nf_loginfo *info,
166 const struct sk_buff *skb,
167 unsigned int iphoff)
168{
169 struct iphdr _iph;
170 const struct iphdr *ih;
171 unsigned int logflags;
172
173 if (info->type == NF_LOG_TYPE_LOG)
174 logflags = info->u.log.logflags;
175 else
176 logflags = NF_LOG_MASK;
177
178 ih = skb_header_pointer(skb, iphoff, sizeof(_iph), &_iph);
179 if (ih == NULL) {
180 sb_add(m, "TRUNCATED");
181 return;
182 }
183
184 /* Important fields:
185 * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
186 /* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
187 sb_add(m, "SRC=%pI4 DST=%pI4 ",
188 &ih->saddr, &ih->daddr);
189
190 /* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
191 sb_add(m, "LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
192 ntohs(ih->tot_len), ih->tos & IPTOS_TOS_MASK,
193 ih->tos & IPTOS_PREC_MASK, ih->ttl, ntohs(ih->id));
194
195 /* Max length: 6 "CE DF MF " */
196 if (ntohs(ih->frag_off) & IP_CE)
197 sb_add(m, "CE ");
198 if (ntohs(ih->frag_off) & IP_DF)
199 sb_add(m, "DF ");
200 if (ntohs(ih->frag_off) & IP_MF)
201 sb_add(m, "MF ");
202
203 /* Max length: 11 "FRAG:65535 " */
204 if (ntohs(ih->frag_off) & IP_OFFSET)
205 sb_add(m, "FRAG:%u ", ntohs(ih->frag_off) & IP_OFFSET);
206
207 if ((logflags & XT_LOG_IPOPT) &&
208 ih->ihl * 4 > sizeof(struct iphdr)) {
209 const unsigned char *op;
210 unsigned char _opt[4 * 15 - sizeof(struct iphdr)];
211 unsigned int i, optsize;
212
213 optsize = ih->ihl * 4 - sizeof(struct iphdr);
214 op = skb_header_pointer(skb, iphoff+sizeof(_iph),
215 optsize, _opt);
216 if (op == NULL) {
217 sb_add(m, "TRUNCATED");
218 return;
219 }
220
221 /* Max length: 127 "OPT (" 15*4*2chars ") " */
222 sb_add(m, "OPT (");
223 for (i = 0; i < optsize; i++)
224 sb_add(m, "%02X", op[i]);
225 sb_add(m, ") ");
226 }
227
228 switch (ih->protocol) {
229 case IPPROTO_TCP:
230 if (dump_tcp_header(m, skb, ih->protocol,
231 ntohs(ih->frag_off) & IP_OFFSET,
232 iphoff+ih->ihl*4, logflags))
233 return;
234 break;
235 case IPPROTO_UDP:
236 case IPPROTO_UDPLITE:
237 if (dump_udp_header(m, skb, ih->protocol,
238 ntohs(ih->frag_off) & IP_OFFSET,
239 iphoff+ih->ihl*4))
240 return;
241 break;
242 case IPPROTO_ICMP: {
243 struct icmphdr _icmph;
244 const struct icmphdr *ich;
245 static const size_t required_len[NR_ICMP_TYPES+1]
246 = { [ICMP_ECHOREPLY] = 4,
247 [ICMP_DEST_UNREACH]
248 = 8 + sizeof(struct iphdr),
249 [ICMP_SOURCE_QUENCH]
250 = 8 + sizeof(struct iphdr),
251 [ICMP_REDIRECT]
252 = 8 + sizeof(struct iphdr),
253 [ICMP_ECHO] = 4,
254 [ICMP_TIME_EXCEEDED]
255 = 8 + sizeof(struct iphdr),
256 [ICMP_PARAMETERPROB]
257 = 8 + sizeof(struct iphdr),
258 [ICMP_TIMESTAMP] = 20,
259 [ICMP_TIMESTAMPREPLY] = 20,
260 [ICMP_ADDRESS] = 12,
261 [ICMP_ADDRESSREPLY] = 12 };
262
263 /* Max length: 11 "PROTO=ICMP " */
264 sb_add(m, "PROTO=ICMP ");
265
266 if (ntohs(ih->frag_off) & IP_OFFSET)
267 break;
268
269 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
270 ich = skb_header_pointer(skb, iphoff + ih->ihl * 4,
271 sizeof(_icmph), &_icmph);
272 if (ich == NULL) {
273 sb_add(m, "INCOMPLETE [%u bytes] ",
274 skb->len - iphoff - ih->ihl*4);
275 break;
276 }
277
278 /* Max length: 18 "TYPE=255 CODE=255 " */
279 sb_add(m, "TYPE=%u CODE=%u ", ich->type, ich->code);
280
281 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
282 if (ich->type <= NR_ICMP_TYPES &&
283 required_len[ich->type] &&
284 skb->len-iphoff-ih->ihl*4 < required_len[ich->type]) {
285 sb_add(m, "INCOMPLETE [%u bytes] ",
286 skb->len - iphoff - ih->ihl*4);
287 break;
288 }
289
290 switch (ich->type) {
291 case ICMP_ECHOREPLY:
292 case ICMP_ECHO:
293 /* Max length: 19 "ID=65535 SEQ=65535 " */
294 sb_add(m, "ID=%u SEQ=%u ",
295 ntohs(ich->un.echo.id),
296 ntohs(ich->un.echo.sequence));
297 break;
298
299 case ICMP_PARAMETERPROB:
300 /* Max length: 14 "PARAMETER=255 " */
301 sb_add(m, "PARAMETER=%u ",
302 ntohl(ich->un.gateway) >> 24);
303 break;
304 case ICMP_REDIRECT:
305 /* Max length: 24 "GATEWAY=255.255.255.255 " */
306 sb_add(m, "GATEWAY=%pI4 ", &ich->un.gateway);
307 /* Fall through */
308 case ICMP_DEST_UNREACH:
309 case ICMP_SOURCE_QUENCH:
310 case ICMP_TIME_EXCEEDED:
311 /* Max length: 3+maxlen */
312 if (!iphoff) { /* Only recurse once. */
313 sb_add(m, "[");
314 dump_ipv4_packet(m, info, skb,
315 iphoff + ih->ihl*4+sizeof(_icmph));
316 sb_add(m, "] ");
317 }
318
319 /* Max length: 10 "MTU=65535 " */
320 if (ich->type == ICMP_DEST_UNREACH &&
321 ich->code == ICMP_FRAG_NEEDED)
322 sb_add(m, "MTU=%u ", ntohs(ich->un.frag.mtu));
323 }
324 break;
325 }
326 /* Max Length */
327 case IPPROTO_AH: {
328 struct ip_auth_hdr _ahdr;
329 const struct ip_auth_hdr *ah;
330
331 if (ntohs(ih->frag_off) & IP_OFFSET)
332 break;
333
334 /* Max length: 9 "PROTO=AH " */
335 sb_add(m, "PROTO=AH ");
336
337 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
338 ah = skb_header_pointer(skb, iphoff+ih->ihl*4,
339 sizeof(_ahdr), &_ahdr);
340 if (ah == NULL) {
341 sb_add(m, "INCOMPLETE [%u bytes] ",
342 skb->len - iphoff - ih->ihl*4);
343 break;
344 }
345
346 /* Length: 15 "SPI=0xF1234567 " */
347 sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
348 break;
349 }
350 case IPPROTO_ESP: {
351 struct ip_esp_hdr _esph;
352 const struct ip_esp_hdr *eh;
353
354 /* Max length: 10 "PROTO=ESP " */
355 sb_add(m, "PROTO=ESP ");
356
357 if (ntohs(ih->frag_off) & IP_OFFSET)
358 break;
359
360 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
361 eh = skb_header_pointer(skb, iphoff+ih->ihl*4,
362 sizeof(_esph), &_esph);
363 if (eh == NULL) {
364 sb_add(m, "INCOMPLETE [%u bytes] ",
365 skb->len - iphoff - ih->ihl*4);
366 break;
367 }
368
369 /* Length: 15 "SPI=0xF1234567 " */
370 sb_add(m, "SPI=0x%x ", ntohl(eh->spi));
371 break;
372 }
373 /* Max length: 10 "PROTO 255 " */
374 default:
375 sb_add(m, "PROTO=%u ", ih->protocol);
376 }
377
378 /* Max length: 15 "UID=4294967295 " */
379 if ((logflags & XT_LOG_UID) && !iphoff)
380 dump_sk_uid_gid(m, skb->sk);
381
382 /* Max length: 16 "MARK=0xFFFFFFFF " */
383 if (!iphoff && skb->mark)
384 sb_add(m, "MARK=0x%x ", skb->mark);
385
386 /* Proto Max log string length */
387 /* IP: 40+46+6+11+127 = 230 */
388 /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */
389 /* UDP: 10+max(25,20) = 35 */
390 /* UDPLITE: 14+max(25,20) = 39 */
391 /* ICMP: 11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
392 /* ESP: 10+max(25)+15 = 50 */
393 /* AH: 9+max(25)+15 = 49 */
394 /* unknown: 10 */
395
396 /* (ICMP allows recursion one level deep) */
397 /* maxlen = IP + ICMP + IP + max(TCP,UDP,ICMP,unknown) */
398 /* maxlen = 230+ 91 + 230 + 252 = 803 */
399}
400
401static void dump_ipv4_mac_header(struct sbuff *m,
402 const struct nf_loginfo *info,
403 const struct sk_buff *skb)
404{
405 struct net_device *dev = skb->dev;
406 unsigned int logflags = 0;
407
408 if (info->type == NF_LOG_TYPE_LOG)
409 logflags = info->u.log.logflags;
410
411 if (!(logflags & XT_LOG_MACDECODE))
412 goto fallback;
413
414 switch (dev->type) {
415 case ARPHRD_ETHER:
416 sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
417 eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
418 ntohs(eth_hdr(skb)->h_proto));
419 return;
420 default:
421 break;
422 }
423
424fallback:
425 sb_add(m, "MAC=");
426 if (dev->hard_header_len &&
427 skb->mac_header != skb->network_header) {
428 const unsigned char *p = skb_mac_header(skb);
429 unsigned int i;
430
431 sb_add(m, "%02x", *p++);
432 for (i = 1; i < dev->hard_header_len; i++, p++)
433 sb_add(m, ":%02x", *p);
434 }
435 sb_add(m, " ");
436}
437
438static void
439log_packet_common(struct sbuff *m,
440 u_int8_t pf,
441 unsigned int hooknum,
442 const struct sk_buff *skb,
443 const struct net_device *in,
444 const struct net_device *out,
445 const struct nf_loginfo *loginfo,
446 const char *prefix)
447{
448 sb_add(m, KERN_SOH "%c%sIN=%s OUT=%s ",
449 '0' + loginfo->u.log.level, prefix,
450 in ? in->name : "",
451 out ? out->name : "");
452#ifdef CONFIG_BRIDGE_NETFILTER
453 if (skb->nf_bridge) {
454 const struct net_device *physindev;
455 const struct net_device *physoutdev;
456
457 physindev = skb->nf_bridge->physindev;
458 if (physindev && in != physindev)
459 sb_add(m, "PHYSIN=%s ", physindev->name);
460 physoutdev = skb->nf_bridge->physoutdev;
461 if (physoutdev && out != physoutdev)
462 sb_add(m, "PHYSOUT=%s ", physoutdev->name);
463 }
464#endif
465}
466
467
468static void
469ipt_log_packet(struct net *net,
470 u_int8_t pf,
471 unsigned int hooknum,
472 const struct sk_buff *skb,
473 const struct net_device *in,
474 const struct net_device *out,
475 const struct nf_loginfo *loginfo,
476 const char *prefix)
477{
478 struct sbuff *m;
479
480 /* FIXME: Disabled from containers until syslog ns is supported */
481 if (!net_eq(net, &init_net))
482 return;
483
484 m = sb_open();
485
486 if (!loginfo)
487 loginfo = &default_loginfo;
488
489 log_packet_common(m, pf, hooknum, skb, in, out, loginfo, prefix);
490
491 if (in != NULL)
492 dump_ipv4_mac_header(m, loginfo, skb);
493
494 dump_ipv4_packet(m, loginfo, skb, 0);
495
496 sb_close(m);
497}
498
499#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
500/* One level of recursion won't kill us */
501static void dump_ipv6_packet(struct sbuff *m,
502 const struct nf_loginfo *info,
503 const struct sk_buff *skb, unsigned int ip6hoff,
504 int recurse)
505{
506 u_int8_t currenthdr;
507 int fragment;
508 struct ipv6hdr _ip6h;
509 const struct ipv6hdr *ih;
510 unsigned int ptr;
511 unsigned int hdrlen = 0;
512 unsigned int logflags;
513
514 if (info->type == NF_LOG_TYPE_LOG)
515 logflags = info->u.log.logflags;
516 else
517 logflags = NF_LOG_MASK;
518
519 ih = skb_header_pointer(skb, ip6hoff, sizeof(_ip6h), &_ip6h);
520 if (ih == NULL) {
521 sb_add(m, "TRUNCATED");
522 return;
523 }
524
525 /* Max length: 88 "SRC=0000.0000.0000.0000.0000.0000.0000.0000 DST=0000.0000.0000.0000.0000.0000.0000.0000 " */
526 sb_add(m, "SRC=%pI6 DST=%pI6 ", &ih->saddr, &ih->daddr);
527
528 /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
529 sb_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
530 ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
531 (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
532 ih->hop_limit,
533 (ntohl(*(__be32 *)ih) & 0x000fffff));
534
535 fragment = 0;
536 ptr = ip6hoff + sizeof(struct ipv6hdr);
537 currenthdr = ih->nexthdr;
538 while (currenthdr != NEXTHDR_NONE && ip6t_ext_hdr(currenthdr)) {
539 struct ipv6_opt_hdr _hdr;
540 const struct ipv6_opt_hdr *hp;
541
542 hp = skb_header_pointer(skb, ptr, sizeof(_hdr), &_hdr);
543 if (hp == NULL) {
544 sb_add(m, "TRUNCATED");
545 return;
546 }
547
548 /* Max length: 48 "OPT (...) " */
549 if (logflags & XT_LOG_IPOPT)
550 sb_add(m, "OPT ( ");
551
552 switch (currenthdr) {
553 case IPPROTO_FRAGMENT: {
554 struct frag_hdr _fhdr;
555 const struct frag_hdr *fh;
556
557 sb_add(m, "FRAG:");
558 fh = skb_header_pointer(skb, ptr, sizeof(_fhdr),
559 &_fhdr);
560 if (fh == NULL) {
561 sb_add(m, "TRUNCATED ");
562 return;
563 }
564
565 /* Max length: 6 "65535 " */
566 sb_add(m, "%u ", ntohs(fh->frag_off) & 0xFFF8);
567
568 /* Max length: 11 "INCOMPLETE " */
569 if (fh->frag_off & htons(0x0001))
570 sb_add(m, "INCOMPLETE ");
571
572 sb_add(m, "ID:%08x ", ntohl(fh->identification));
573
574 if (ntohs(fh->frag_off) & 0xFFF8)
575 fragment = 1;
576
577 hdrlen = 8;
578
579 break;
580 }
581 case IPPROTO_DSTOPTS:
582 case IPPROTO_ROUTING:
583 case IPPROTO_HOPOPTS:
584 if (fragment) {
585 if (logflags & XT_LOG_IPOPT)
586 sb_add(m, ")");
587 return;
588 }
589 hdrlen = ipv6_optlen(hp);
590 break;
591 /* Max Length */
592 case IPPROTO_AH:
593 if (logflags & XT_LOG_IPOPT) {
594 struct ip_auth_hdr _ahdr;
595 const struct ip_auth_hdr *ah;
596
597 /* Max length: 3 "AH " */
598 sb_add(m, "AH ");
599
600 if (fragment) {
601 sb_add(m, ")");
602 return;
603 }
604
605 ah = skb_header_pointer(skb, ptr, sizeof(_ahdr),
606 &_ahdr);
607 if (ah == NULL) {
608 /*
609 * Max length: 26 "INCOMPLETE [65535
610 * bytes] )"
611 */
612 sb_add(m, "INCOMPLETE [%u bytes] )",
613 skb->len - ptr);
614 return;
615 }
616
617 /* Length: 15 "SPI=0xF1234567 */
618 sb_add(m, "SPI=0x%x ", ntohl(ah->spi));
619
620 }
621
622 hdrlen = (hp->hdrlen+2)<<2;
623 break;
624 case IPPROTO_ESP:
625 if (logflags & XT_LOG_IPOPT) {
626 struct ip_esp_hdr _esph;
627 const struct ip_esp_hdr *eh;
628
629 /* Max length: 4 "ESP " */
630 sb_add(m, "ESP ");
631
632 if (fragment) {
633 sb_add(m, ")");
634 return;
635 }
636
637 /*
638 * Max length: 26 "INCOMPLETE [65535 bytes] )"
639 */
640 eh = skb_header_pointer(skb, ptr, sizeof(_esph),
641 &_esph);
642 if (eh == NULL) {
643 sb_add(m, "INCOMPLETE [%u bytes] )",
644 skb->len - ptr);
645 return;
646 }
647
648 /* Length: 16 "SPI=0xF1234567 )" */
649 sb_add(m, "SPI=0x%x )", ntohl(eh->spi));
650
651 }
652 return;
653 default:
654 /* Max length: 20 "Unknown Ext Hdr 255" */
655 sb_add(m, "Unknown Ext Hdr %u", currenthdr);
656 return;
657 }
658 if (logflags & XT_LOG_IPOPT)
659 sb_add(m, ") ");
660
661 currenthdr = hp->nexthdr;
662 ptr += hdrlen;
663 }
664
665 switch (currenthdr) {
666 case IPPROTO_TCP:
667 if (dump_tcp_header(m, skb, currenthdr, fragment, ptr,
668 logflags))
669 return;
670 break;
671 case IPPROTO_UDP:
672 case IPPROTO_UDPLITE:
673 if (dump_udp_header(m, skb, currenthdr, fragment, ptr))
674 return;
675 break;
676 case IPPROTO_ICMPV6: {
677 struct icmp6hdr _icmp6h;
678 const struct icmp6hdr *ic;
679
680 /* Max length: 13 "PROTO=ICMPv6 " */
681 sb_add(m, "PROTO=ICMPv6 ");
682
683 if (fragment)
684 break;
685
686 /* Max length: 25 "INCOMPLETE [65535 bytes] " */
687 ic = skb_header_pointer(skb, ptr, sizeof(_icmp6h), &_icmp6h);
688 if (ic == NULL) {
689 sb_add(m, "INCOMPLETE [%u bytes] ", skb->len - ptr);
690 return;
691 }
692
693 /* Max length: 18 "TYPE=255 CODE=255 " */
694 sb_add(m, "TYPE=%u CODE=%u ", ic->icmp6_type, ic->icmp6_code);
695
696 switch (ic->icmp6_type) {
697 case ICMPV6_ECHO_REQUEST:
698 case ICMPV6_ECHO_REPLY:
699 /* Max length: 19 "ID=65535 SEQ=65535 " */
700 sb_add(m, "ID=%u SEQ=%u ",
701 ntohs(ic->icmp6_identifier),
702 ntohs(ic->icmp6_sequence));
703 break;
704 case ICMPV6_MGM_QUERY:
705 case ICMPV6_MGM_REPORT:
706 case ICMPV6_MGM_REDUCTION:
707 break;
708
709 case ICMPV6_PARAMPROB:
710 /* Max length: 17 "POINTER=ffffffff " */
711 sb_add(m, "POINTER=%08x ", ntohl(ic->icmp6_pointer));
712 /* Fall through */
713 case ICMPV6_DEST_UNREACH:
714 case ICMPV6_PKT_TOOBIG:
715 case ICMPV6_TIME_EXCEED:
716 /* Max length: 3+maxlen */
717 if (recurse) {
718 sb_add(m, "[");
719 dump_ipv6_packet(m, info, skb,
720 ptr + sizeof(_icmp6h), 0);
721 sb_add(m, "] ");
722 }
723
724 /* Max length: 10 "MTU=65535 " */
725 if (ic->icmp6_type == ICMPV6_PKT_TOOBIG)
726 sb_add(m, "MTU=%u ", ntohl(ic->icmp6_mtu));
727 }
728 break;
729 }
730 /* Max length: 10 "PROTO=255 " */
731 default:
732 sb_add(m, "PROTO=%u ", currenthdr);
733 }
734
735 /* Max length: 15 "UID=4294967295 " */
736 if ((logflags & XT_LOG_UID) && recurse)
737 dump_sk_uid_gid(m, skb->sk);
738
739 /* Max length: 16 "MARK=0xFFFFFFFF " */
740 if (recurse && skb->mark)
741 sb_add(m, "MARK=0x%x ", skb->mark);
742}
743
744static void dump_ipv6_mac_header(struct sbuff *m,
745 const struct nf_loginfo *info,
746 const struct sk_buff *skb)
747{
748 struct net_device *dev = skb->dev;
749 unsigned int logflags = 0;
750
751 if (info->type == NF_LOG_TYPE_LOG)
752 logflags = info->u.log.logflags;
753
754 if (!(logflags & XT_LOG_MACDECODE))
755 goto fallback;
756
757 switch (dev->type) {
758 case ARPHRD_ETHER:
759 sb_add(m, "MACSRC=%pM MACDST=%pM MACPROTO=%04x ",
760 eth_hdr(skb)->h_source, eth_hdr(skb)->h_dest,
761 ntohs(eth_hdr(skb)->h_proto));
762 return;
763 default:
764 break;
765 }
766
767fallback:
768 sb_add(m, "MAC=");
769 if (dev->hard_header_len &&
770 skb->mac_header != skb->network_header) {
771 const unsigned char *p = skb_mac_header(skb);
772 unsigned int len = dev->hard_header_len;
773 unsigned int i;
774
775 if (dev->type == ARPHRD_SIT) {
776 p -= ETH_HLEN;
777
778 if (p < skb->head)
779 p = NULL;
780 }
781
782 if (p != NULL) {
783 sb_add(m, "%02x", *p++);
784 for (i = 1; i < len; i++)
785 sb_add(m, ":%02x", *p++);
786 }
787 sb_add(m, " ");
788
789 if (dev->type == ARPHRD_SIT) {
790 const struct iphdr *iph =
791 (struct iphdr *)skb_mac_header(skb);
792 sb_add(m, "TUNNEL=%pI4->%pI4 ", &iph->saddr,
793 &iph->daddr);
794 }
795 } else
796 sb_add(m, " ");
797}
798
799static void
800ip6t_log_packet(struct net *net,
801 u_int8_t pf,
802 unsigned int hooknum,
803 const struct sk_buff *skb,
804 const struct net_device *in,
805 const struct net_device *out,
806 const struct nf_loginfo *loginfo,
807 const char *prefix)
808{
809 struct sbuff *m;
810
811 /* FIXME: Disabled from containers until syslog ns is supported */
812 if (!net_eq(net, &init_net))
813 return;
814
815 m = sb_open();
816
817 if (!loginfo)
818 loginfo = &default_loginfo;
819
820 log_packet_common(m, pf, hooknum, skb, in, out, loginfo, prefix);
821
822 if (in != NULL)
823 dump_ipv6_mac_header(m, loginfo, skb);
824
825 dump_ipv6_packet(m, loginfo, skb, skb_network_offset(skb), 1);
826
827 sb_close(m);
828}
829#endif
830 30
831static unsigned int 31static unsigned int
832log_tg(struct sk_buff *skb, const struct xt_action_param *par) 32log_tg(struct sk_buff *skb, const struct xt_action_param *par)
@@ -839,17 +39,8 @@ log_tg(struct sk_buff *skb, const struct xt_action_param *par)
839 li.u.log.level = loginfo->level; 39 li.u.log.level = loginfo->level;
840 li.u.log.logflags = loginfo->logflags; 40 li.u.log.logflags = loginfo->logflags;
841 41
842 if (par->family == NFPROTO_IPV4) 42 nf_log_packet(net, par->family, par->hooknum, skb, par->in, par->out,
843 ipt_log_packet(net, NFPROTO_IPV4, par->hooknum, skb, par->in, 43 &li, "%s", loginfo->prefix);
844 par->out, &li, loginfo->prefix);
845#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
846 else if (par->family == NFPROTO_IPV6)
847 ip6t_log_packet(net, NFPROTO_IPV6, par->hooknum, skb, par->in,
848 par->out, &li, loginfo->prefix);
849#endif
850 else
851 WARN_ON_ONCE(1);
852
853 return XT_CONTINUE; 44 return XT_CONTINUE;
854} 45}
855 46
@@ -870,7 +61,12 @@ static int log_tg_check(const struct xt_tgchk_param *par)
870 return -EINVAL; 61 return -EINVAL;
871 } 62 }
872 63
873 return 0; 64 return nf_logger_find_get(par->family, NF_LOG_TYPE_LOG);
65}
66
67static void log_tg_destroy(const struct xt_tgdtor_param *par)
68{
69 nf_logger_put(par->family, NF_LOG_TYPE_LOG);
874} 70}
875 71
876static struct xt_target log_tg_regs[] __read_mostly = { 72static struct xt_target log_tg_regs[] __read_mostly = {
@@ -880,6 +76,7 @@ static struct xt_target log_tg_regs[] __read_mostly = {
880 .target = log_tg, 76 .target = log_tg,
881 .targetsize = sizeof(struct xt_log_info), 77 .targetsize = sizeof(struct xt_log_info),
882 .checkentry = log_tg_check, 78 .checkentry = log_tg_check,
79 .destroy = log_tg_destroy,
883 .me = THIS_MODULE, 80 .me = THIS_MODULE,
884 }, 81 },
885#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) 82#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
@@ -889,78 +86,19 @@ static struct xt_target log_tg_regs[] __read_mostly = {
889 .target = log_tg, 86 .target = log_tg,
890 .targetsize = sizeof(struct xt_log_info), 87 .targetsize = sizeof(struct xt_log_info),
891 .checkentry = log_tg_check, 88 .checkentry = log_tg_check,
89 .destroy = log_tg_destroy,
892 .me = THIS_MODULE, 90 .me = THIS_MODULE,
893 }, 91 },
894#endif 92#endif
895}; 93};
896 94
897static struct nf_logger ipt_log_logger __read_mostly = {
898 .name = "ipt_LOG",
899 .logfn = &ipt_log_packet,
900 .me = THIS_MODULE,
901};
902
903#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
904static struct nf_logger ip6t_log_logger __read_mostly = {
905 .name = "ip6t_LOG",
906 .logfn = &ip6t_log_packet,
907 .me = THIS_MODULE,
908};
909#endif
910
911static int __net_init log_net_init(struct net *net)
912{
913 nf_log_set(net, NFPROTO_IPV4, &ipt_log_logger);
914#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
915 nf_log_set(net, NFPROTO_IPV6, &ip6t_log_logger);
916#endif
917 return 0;
918}
919
920static void __net_exit log_net_exit(struct net *net)
921{
922 nf_log_unset(net, &ipt_log_logger);
923#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
924 nf_log_unset(net, &ip6t_log_logger);
925#endif
926}
927
928static struct pernet_operations log_net_ops = {
929 .init = log_net_init,
930 .exit = log_net_exit,
931};
932
933static int __init log_tg_init(void) 95static int __init log_tg_init(void)
934{ 96{
935 int ret; 97 return xt_register_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
936
937 ret = register_pernet_subsys(&log_net_ops);
938 if (ret < 0)
939 goto err_pernet;
940
941 ret = xt_register_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
942 if (ret < 0)
943 goto err_target;
944
945 nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
946#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
947 nf_log_register(NFPROTO_IPV6, &ip6t_log_logger);
948#endif
949 return 0;
950
951err_target:
952 unregister_pernet_subsys(&log_net_ops);
953err_pernet:
954 return ret;
955} 98}
956 99
957static void __exit log_tg_exit(void) 100static void __exit log_tg_exit(void)
958{ 101{
959 unregister_pernet_subsys(&log_net_ops);
960 nf_log_unregister(&ipt_log_logger);
961#if IS_ENABLED(CONFIG_IP6_NF_IPTABLES)
962 nf_log_unregister(&ip6t_log_logger);
963#endif
964 xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs)); 102 xt_unregister_targets(log_tg_regs, ARRAY_SIZE(log_tg_regs));
965} 103}
966 104