Skip to contentSkip to conversation

updated ctnetlink patches: ctnetlink-0.11-0.12.diff

RFC New Patrick McHardy 1 participant 1 message May 28, 2003

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

RFC 1/1 updated ctnetlink patches: ctnetlink-0.11-0.12.diff

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1228 -> 1.1229
# net/ipv4/netfilter/ip_conntrack_proto_udp.c 1.5 -> 1.6
# net/ipv4/netfilter/ip_conntrack_core.c 1.20 -> 1.21
# net/ipv4/netfilter/ip_conntrack_proto_icmp.c 1.4 -> 1.5
# net/ipv4/netfilter/nfnetlink.c 1.1 -> 1.2
# net/ipv4/netfilter/ip_nat_core.c 1.17 -> 1.18
# include/linux/nfnetlink_conntrack.h 1.1 -> 1.2
# net/ipv4/netfilter/ip_conntrack_proto_generic.c 1.4 -> 1.5
# include/linux/netfilter_ipv4/ip_conntrack.h 1.10 -> 1.11
# net/ipv4/netfilter/ip_conntrack_standalone.c 1.11 -> 1.12
# net/ipv4/netfilter/Config.in 1.15 -> 1.16
# net/ipv4/netfilter/nfnetlink_conntrack.c 1.1 -> 1.2
# net/ipv4/netfilter/ip_conntrack_ftp.c 1.9 -> 1.10
# include/linux/netfilter_ipv4/ip_conntrack_protocol.h 1.4 -> 1.5
# net/ipv4/netfilter/ip_conntrack_proto_tcp.c 1.8 -> 1.9
# include/linux/netfilter_ipv4/ip_conntrack_core.h 1.4 -> 1.5
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/05/27 [email protected] 1.1229

# import ctnetlink 0.12 changes
# --------------------------------------------
#
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
--- a/include/linux/netfilter_ipv4/ip_conntrack.h	Tue May 27 19:24:12 2003
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h	Tue May 27 19:24:12 2003
@@ -156,6 +156,18 @@
 	union ip_conntrack_expect_help help;
 };

+enum ip_conntrack_events
+{
+ IPCT_NEW,
+ IPCT_DESTROY,
+ IPCT_STATUS,
+ IPCT_REFRESH,
+ IPCT_PROTOINFO,
+ IPCT_HELPINFO,
+ IPCT_NATINFO,
+ IPCT_MARK
+};
+
#include <linux/netfilter_ipv4/ip_conntrack_helper.h> struct ip_conntrack
{
@@ -166,6 +178,13 @@
/* These are my tuples; original and reply */ struct ip_conntrack_tuple_hash tuplehash[IP_CT_DIR_MAX];

+ /* ordered list member - for table dumping over netlink */
+ struct list_head olist;
+
+ /* unique id (assigned when placing in hashtables) - for table dumping
+ * over netlink */
+ unsigned int id;
+
/* Have we seen traffic both ways yet? (bitset) */ unsigned long status;

@@ -242,6 +261,11 @@

extern struct module *ip_conntrack_module;

+struct ip_conntrack_protocol;
+extern int invert_tuple(struct ip_conntrack_tuple *inverse,
+ const struct ip_conntrack_tuple *orig,
+ const struct ip_conntrack_protocol *protocol);
+
extern int invert_tuplepr(struct ip_conntrack_tuple *inverse,
const struct ip_conntrack_tuple *orig);

@@ -262,6 +286,17 @@
ip_ct_selective_cleanup(int (*kill)(const struct ip_conntrack *i, void *data),
void *data);

+/* returns new ip_conntrack struct or NULL */ +extern struct ip_conntrack * +ip_conntrack_alloc(const struct ip_conntrack_tuple *,
+ const struct ip_conntrack_tuple *);
+
+/* free conntrack structure */
+extern void ip_conntrack_free(struct ip_conntrack *); +
+/* put connrack in hash and ordered list */
+extern void ip_conntrack_put_in_lists(struct ip_conntrack *); +
/* It's confirmed if it is, or has been in the hash table. */ static inline int is_confirmed(struct ip_conntrack *ct) {
@@ -269,5 +304,47 @@
}

extern unsigned int ip_conntrack_htable_size;
+extern struct list_head ip_conntrack_ordered_list;
+
+/* register notifier for conntrack events */
+extern int ip_conntrack_notify_register(struct notifier_block *); +extern int ip_conntrack_notify_unregister(struct notifier_block *); +
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+#include <linux/notifier.h>
+
+extern struct notifier_block *ip_conntrack_chain;
+extern unsigned long ip_conntrack_event_cache[NR_CPUS];
+
+static inline void ip_conntrack_event(enum ip_conntrack_events event,
+ struct ip_conntrack *ct)
+{
+ notifier_call_chain(&ip_conntrack_chain, 1 << event, ct);
+}
+
+static inline void ip_conntrack_event_cache_init(void)
+{
+ ip_conntrack_event_cache[smp_processor_id()] = 0UL;
+}
+
+static inline void ip_conntrack_cache_event(enum ip_conntrack_events event) +{
+ ip_conntrack_event_cache[smp_processor_id()] |= 1 << event;
+}
+
+static inline void ip_conntrack_do_cached_events(struct ip_conntrack *ct) +{
+ unsigned long events = ip_conntrack_event_cache[smp_processor_id()];
+
+ if (events)
+ notifier_call_chain(&ip_conntrack_chain, events, ct);
+}
+#else /* CONFIG_IP_NF_CONNTRACK_EVENTS */
+static inline void ip_conntrack_event(enum ip_conntrack_events event,
+ struct ip_conntrack *ct) {}
+static inline void ip_conntrack_event_cache_init(void) {}
+static inline void ip_conntrack_cache_event(enum ip_conntrack_events event) {}
+static inline void ip_conntrack_do_cached_events(struct ip_conntrack *ct) {}
+#endif /* CONFIG_IP_CONNTRACK_EVENTS */
#endif /* __KERNEL__ */
#endif /* _IP_CONNTRACK_H */

include/linux/netfilter_ipv4/ip_conntrack_core.h +5 -0
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_core.h b/include/linux/netfilter_ipv4/ip_conntrack_core.h
@@ -32,6 +32,11 @@
 struct ip_conntrack_tuple_hash *
 ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
 		      const struct ip_conntrack *ignored_conntrack);
+/* non-locked version */
+struct ip_conntrack_tuple_hash *
+__ip_conntrack_find_get(const struct ip_conntrack_tuple *tuple,
+                        const struct ip_conntrack *ignored_conntrack);
+
 
 extern int __ip_conntrack_confirm(struct nf_ct_info *nfct);
 
include/linux/netfilter_ipv4/ip_conntrack_protocol.h +14 -0
diff -Nru a/include/linux/netfilter_ipv4/ip_conntrack_protocol.h b/include/linux/netfilter_ipv4/ip_conntrack_protocol.h
@@ -42,6 +42,20 @@
 	int (*new)(struct ip_conntrack *conntrack, struct iphdr *iph,
 		   size_t len);
 
+	/* check if tuples are valid for a new connection */
+	int (*ctnl_check_tuples)(struct ip_conntrack_tuple *orig,
+	                         struct ip_conntrack_tuple *reply);
+
+	/* check protocol data is valid */
+	int (*ctnl_check_private)(union ip_conntrack_proto *p);
+
+	/* create new entry on behalf of ctnetlink */
+	void (*ctnl_new)(struct ip_conntrack *ct, union ip_conntrack_proto *p);
+
+	/* change protocol info on behalf of ctnetlink */
+	void (*ctnl_change)(struct ip_conntrack *ct,
+                            union ip_conntrack_proto *p);
+
 	/* Called when a conntrack entry is destroyed */
 	void (*destroy)(struct ip_conntrack *conntrack);
 
include/linux/nfnetlink_conntrack.h +2 -3
diff -Nru a/include/linux/nfnetlink_conntrack.h b/include/linux/nfnetlink_conntrack.h
@@ -26,14 +26,13 @@
 	CTA_UNSPEC,     /* [none] I don't know (unspecified). */
 	CTA_ORIG,       /* [ip_conntrack_tuple] Original tuple. */
 	CTA_RPLY,       /* [ip_conntrack_tuple] Reply tuple. */
-	CTA_IIF,        /* [char] Input interface name (ie eth0). */
-	CTA_OIF,        /* [char] Output interface name (ie eth1). */
 	CTA_STATUS,     /* [unsigned long] Status of connection. */
 	CTA_INFO,       /* [unsigned long] Information (ctinfo). */
 	CTA_PROTOINFO,  /* [cta_proto] Protocol specific ct information. */
 	CTA_HELPINFO,   /* [cta_help] Helper specific information. */
 	CTA_NATINFO,    /* [cta_nat] Any NAT transformations. */
-	CTA_TIMEOUT,	/* [unsigne long] timer */
+	CTA_TIMEOUT,    /* [unsigned long] timer */
+	CTA_MARK,       /* [unsigned long] mark .*/
 
 	CTA_EXP_TIMEOUT,/* [fixme] timer */
 	CTA_EXP_TUPLE,	/* [ip_conntrack_tuple] Expected tuple */
net/ipv4/netfilter/Config.in +1 -0
diff -Nru a/net/ipv4/netfilter/Config.in b/net/ipv4/netfilter/Config.in
@@ -8,6 +8,7 @@
 
 tristate 'Connection tracking (required for masq/NAT)' CONFIG_IP_NF_CONNTRACK
 if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then
+  bool 'Connection tracking event notifications' CONFIG_IP_NF_CONNTRACK_EVENTS
   if [ "$CONFIG_IP_NF_CONNTRACK" = "y" ]; then
     dep_tristate '  Connection tracking netlink interface' CONFIG_IP_NF_NETLINK_CONNTRACK $CONFIG_IP_NF_NETLINK
   else
net/ipv4/netfilter/ip_conntrack_core.c +113 -42

301 lines not on this page · raw message

net/ipv4/netfilter/ip_conntrack_ftp.c +1 -0
diff -Nru a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -287,6 +287,7 @@
 			ct_ftp_info->seq_aft_nl[dir] = 
 						ntohl(tcph->seq) + datalen;
 			ct_ftp_info->seq_aft_nl_set[dir] = 1;
+			ip_conntrack_cache_event(IPCT_HELPINFO);
 		}
 	}
 	UNLOCK_BH(&ip_ftp_lock);
net/ipv4/netfilter/ip_conntrack_proto_generic.c +2 -1
diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_generic.c b/net/ipv4/netfilter/ip_conntrack_proto_generic.c
@@ -57,5 +57,6 @@
 struct ip_conntrack_protocol ip_conntrack_generic_protocol
 = { { NULL, NULL }, 0, "unknown",
     generic_pkt_to_tuple, generic_invert_tuple, generic_print_tuple,
-    generic_print_conntrack, established, new, NULL, NULL, NULL };
+    generic_print_conntrack, established, new, NULL, NULL, NULL, NULL, NULL,
+    NULL, NULL };
 
net/ipv4/netfilter/ip_conntrack_proto_icmp.c +28 -7
diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
@@ -14,6 +14,13 @@
 #define DEBUGP(format, args...)
 #endif
 
+static u_int8_t valid_new[] = {
+	[ICMP_ECHO] = 1,
+	[ICMP_TIMESTAMP] = 1,
+	[ICMP_INFO_REQUEST] = 1,
+	[ICMP_ADDRESS] = 1
+};
+
 static int icmp_pkt_to_tuple(const void *datah, size_t datalen,
 			     struct ip_conntrack_tuple *tuple)
 {
@@ -82,6 +89,7 @@
 			ct->timeout.function((unsigned long)ct);
 	} else {
 		atomic_inc(&ct->proto.icmp.count);
+		ip_conntrack_cache_event(IPCT_PROTOINFO);
 		ip_ct_refresh(ct, ICMP_TIMEOUT);
 	}
 
@@ -92,12 +100,6 @@
 static int icmp_new(struct ip_conntrack *conntrack,
 		    struct iphdr *iph, size_t len)
 {
-	static u_int8_t valid_new[]
-		= { [ICMP_ECHO] = 1,
-		    [ICMP_TIMESTAMP] = 1,
-		    [ICMP_INFO_REQUEST] = 1,
-		    [ICMP_ADDRESS] = 1 };
-
 	if (conntrack->tuplehash[0].tuple.dst.u.icmp.type >= sizeof(valid_new)
 	    || !valid_new[conntrack->tuplehash[0].tuple.dst.u.icmp.type]) {
 		/* Can't create a new ICMP `conn' with this. */
@@ -110,7 +112,26 @@
 	return 1;
 }
 
+static int icmp_ctnl_check_tuples(struct ip_conntrack_tuple *orig,
+                                  struct ip_conntrack_tuple *reply)
+{
+	unsigned int type = orig->dst.u.icmp.type;
+
+	if (type >= sizeof(valid_new) || !valid_new[type])
+		return -EINVAL;
+
+	return 0;
+}
+
+static void icmp_ctnl_new(struct ip_conntrack *conntrack,
+                          union ip_conntrack_proto *p)
+{
+	conntrack->proto.icmp = *(struct ip_ct_icmp *)p;
+}
+
 struct ip_conntrack_protocol ip_conntrack_protocol_icmp
 = { { NULL, NULL }, IPPROTO_ICMP, "icmp",
     icmp_pkt_to_tuple, icmp_invert_tuple, icmp_print_tuple,
-    icmp_print_conntrack, icmp_packet, icmp_new, NULL, NULL, NULL };
+    icmp_print_conntrack, icmp_packet, icmp_new,
+    icmp_ctnl_check_tuples, NULL, icmp_ctnl_new, icmp_ctnl_new,
+    NULL, NULL, NULL };
net/ipv4/netfilter/ip_conntrack_proto_tcp.c +32 -3
diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -178,13 +178,17 @@
 	}
 
 	conntrack->proto.tcp.state = newconntrack;
+	if (newconntrack != oldtcpstate)
+		ip_conntrack_cache_event(IPCT_PROTOINFO);
 
 	/* Poor man's window tracking: record SYN/ACK for handshake check */
 	if (oldtcpstate == TCP_CONNTRACK_SYN_SENT
 	    && CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY
-	    && tcph->syn && tcph->ack)
+	    && tcph->syn && tcph->ack) {
 		conntrack->proto.tcp.handshake_ack
 			= htonl(ntohl(tcph->seq) + 1);
+		ip_conntrack_cache_event(IPCT_PROTOINFO);
+	}
 
 	/* If only reply is a RST, we can consider ourselves not to
 	   have an established connection: this is a fairly common
@@ -199,8 +203,10 @@
 		if (oldtcpstate == TCP_CONNTRACK_SYN_RECV
 		    && CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL
 		    && tcph->ack && !tcph->syn
-		    && tcph->ack_seq == conntrack->proto.tcp.handshake_ack)
+		    && tcph->ack_seq == conntrack->proto.tcp.handshake_ack) {
 			set_bit(IPS_ASSURED_BIT, &conntrack->status);
+			ip_conntrack_cache_event(IPCT_STATUS);
+		}
 
 		WRITE_UNLOCK(&tcp_lock);
 		ip_ct_refresh(conntrack, tcp_timeouts[newconntrack]);
@@ -231,6 +237,28 @@
 	return 1;
 }
 
+static int tcp_ctnl_check_private(union ip_conntrack_proto *p)
+{
+	struct ip_ct_tcp *tcp = (struct ip_ct_tcp *)p;
+	if (tcp->state >= TCP_CONNTRACK_MAX)
+		return -EINVAL;
+	return 0;
+}
+
+static void tcp_ctnl_new(struct ip_conntrack *conntrack,
+                         union ip_conntrack_proto *p)
+{
+	conntrack->proto.tcp = *(struct ip_ct_tcp *)p;
+}
+
+static void tcp_ctnl_change(struct ip_conntrack *conntrack,
+                            union ip_conntrack_proto *p)
+{
+	WRITE_LOCK(&tcp_lock);
+	conntrack->proto.tcp = *(struct ip_ct_tcp *)p;
+	WRITE_UNLOCK(&tcp_lock);
+}
+
 static int tcp_exp_matches_pkt(struct ip_conntrack_expect *exp,
 			       struct sk_buff **pskb)
 {
@@ -246,4 +274,5 @@
 struct ip_conntrack_protocol ip_conntrack_protocol_tcp
 = { { NULL, NULL }, IPPROTO_TCP, "tcp",
     tcp_pkt_to_tuple, tcp_invert_tuple, tcp_print_tuple, tcp_print_conntrack,
-    tcp_packet, tcp_new, NULL, tcp_exp_matches_pkt, NULL };
+    tcp_packet, tcp_new, NULL, tcp_ctnl_check_private, tcp_ctnl_new,
+    tcp_ctnl_change, NULL, tcp_exp_matches_pkt, NULL };
net/ipv4/netfilter/ip_conntrack_proto_udp.c +5 -2
diff -Nru a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
@@ -54,7 +54,10 @@
 	if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
 		ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT);
 		/* Also, more likely to be important, and not a probe */
-		set_bit(IPS_ASSURED_BIT, &conntrack->status);
+		if (!test_bit(IPS_ASSURED_BIT, &conntrack->status)) {
+			set_bit(IPS_ASSURED_BIT, &conntrack->status);
+			ip_conntrack_cache_event(IPCT_STATUS);
+		}
 	} else
 		ip_ct_refresh(conntrack, UDP_TIMEOUT);
 
@@ -71,4 +74,4 @@
 struct ip_conntrack_protocol ip_conntrack_protocol_udp
 = { { NULL, NULL }, IPPROTO_UDP, "udp",
     udp_pkt_to_tuple, udp_invert_tuple, udp_print_tuple, udp_print_conntrack,
-    udp_packet, udp_new, NULL, NULL, NULL };
+    udp_packet, udp_new, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
net/ipv4/netfilter/ip_conntrack_standalone.c +13 -1
diff -Nru a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -105,7 +105,7 @@
 	len += sprintf(buffer + len, "use=%u ",
 		       atomic_read(&conntrack->ct_general.use));
 #if defined(CONFIG_IP_NF_CONNTRACK_MARK)
-	len += sprintf(buffer + len, "mark=%ld ", conntrack->mark);
+	len += sprintf(buffer + len, "mark=%lu ", conntrack->mark);
 #endif
 	len += sprintf(buffer + len, "\n");
 
@@ -354,7 +354,11 @@
 
 EXPORT_SYMBOL(ip_conntrack_protocol_register);
 EXPORT_SYMBOL(ip_conntrack_protocol_unregister);
+EXPORT_SYMBOL(invert_tuple);
 EXPORT_SYMBOL(invert_tuplepr);
+EXPORT_SYMBOL(ip_conntrack_alloc);
+EXPORT_SYMBOL(ip_conntrack_free);
+EXPORT_SYMBOL(ip_conntrack_put_in_lists);
 EXPORT_SYMBOL(ip_conntrack_alter_reply);
 EXPORT_SYMBOL(ip_conntrack_destroyed);
 EXPORT_SYMBOL(ip_conntrack_get);
@@ -375,7 +379,15 @@
 EXPORT_SYMBOL(ip_ct_gather_frags);
 EXPORT_SYMBOL(ip_conntrack_htable_size);
 EXPORT_SYMBOL(ip_conntrack_expect_list);
+EXPORT_SYMBOL(ip_conntrack_ordered_list);
 EXPORT_SYMBOL(ip_conntrack_lock);
 EXPORT_SYMBOL(ip_conntrack_hash);
 EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
+EXPORT_SYMBOL_GPL(__ip_conntrack_find_get);
 EXPORT_SYMBOL_GPL(ip_conntrack_put);
+EXPORT_SYMBOL(ip_conntrack_notify_register);
+EXPORT_SYMBOL(ip_conntrack_notify_unregister);
+#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
+EXPORT_SYMBOL(ip_conntrack_event_cache);
+EXPORT_SYMBOL(ip_conntrack_chain);
+#endif /* CONFIG_IP_NF_CONNTRACK_EVENTS */
net/ipv4/netfilter/ip_nat_core.c +3 -0
diff -Nru a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
@@ -6,6 +6,7 @@
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/timer.h>
+#include <linux/notifier.h>
 #include <linux/skbuff.h>
 #include <linux/netfilter_ipv4.h>
 #include <linux/brlock.h>
@@ -630,6 +631,8 @@
 			   IP_NAT_MANIP_SRC, inv_tuple.src });
 		IP_NF_ASSERT(info->num_manips <= IP_NAT_MAX_MANIPS);
 	}
+
+	ip_conntrack_event(IPCT_NATINFO, conntrack);
 
 	/* If there's a helper, assign it; based on new tuple. */
 	if (!conntrack->master)
net/ipv4/netfilter/nfnetlink.c +17 -7
diff -Nru a/net/ipv4/netfilter/nfnetlink.c b/net/ipv4/netfilter/nfnetlink.c
@@ -39,11 +39,18 @@
 
 MODULE_LICENSE("GPL");
 
-char nfversion[] = "0.11";
-int nf_debug_level = 1;
-#define nf_debug(level, format, arg...) \
-        if(nf_debug_level > level)  \
-                printk(__FUNCTION__ ": " format, ## arg)
+static char __initdata nfversion[] = "0.12";
+
+#if 1
+static int nf_debug_level = 1;
+#define nf_debug(level, format, arg...)					       \
+	do {								       \
+		if (nf_debug_level > level)				       \
+			printk(KERN_DEBUG "%s: " format, __FUNCTION__, ## arg);\
+	} while(0)
+#else
+#define nf_debug(level, format, arg...)
+#endif
 
 static struct sock *nfnl = NULL;
 static LIST_HEAD(subsys_list);
@@ -141,7 +148,7 @@
 
 int nfattr_parse(struct nfattr *tb[], int maxattr, struct nfattr *nfa, int len)
 {
-	memset(tb, 0, sizeof(struct nfattr *)*maxattr);
+	memset(tb, 0, sizeof(struct nfattr *) * maxattr);
 
 	while (NFA_OK(nfa, len)) {
 		unsigned flavor = nfa->nfa_type;
@@ -167,6 +174,8 @@
 {
 	int min_len;
 
+	memset(cda, 0, sizeof(struct nfattr *) * subsys->attr_count);
+
 	/* check attribute lengths. */
 	min_len = sizeof(struct nfgenmsg);
 	if (nlh->nlmsg_len < min_len)
@@ -193,12 +202,13 @@
 
 int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
 {
+	int allocation = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL;
 	int err = 0;
 
 	NETLINK_CB(skb).dst_groups = group;
 	if (echo)
 		atomic_inc(&skb->users);
-	netlink_broadcast(nfnl, skb, pid, group, GFP_KERNEL);
+	netlink_broadcast(nfnl, skb, pid, group, allocation);
 	if (echo)
 		err = netlink_unicast(nfnl, skb, pid, MSG_DONTWAIT);
 
net/ipv4/netfilter/nfnetlink_conntrack.c +550 -174

899 lines not on this page · raw message