Skip to contentSkip to conversation

ctnetlink

PATCH In review Harald Welte 2 participants 2 messages Jul 22, 2005

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

PATCH 1/1 ctnetlink

Hi Dave!

This is a patch for your net-2.6.14 tree (incremental to the expect-double-free fix). It adds the ctnetlink code, and all the required core conntrack/nat changes that it needs.

Please apply, Thanks!

Signature · 5 lines
- Harald Welte <[email protected]>                 http://netfilter.org/
============================================================================
  "Fragmentation is like classful addressing -- an interesting early
   architectural error that shows how much experimentation was going
   on while IP was being designed."                    -- Paul Vixie

Add ctnetlink subsystem for userspace-access to ip_conntrack table. This allows reading and updating of existing entries, as well as creating new ones (and new expect's) via nfnetlink.

Please noe the 'strange' byte order: nfattr (tag+length) are in host byte order, while the payload is always guaranteed to be in network byte order. This allows a simple userspace process to encapsulate netlink messages into arch-independent udp packets by just processing/swapping the headers and not knowing anything about the actual payload.

---
commit 7a379b7c1a60b65fe735a87bd55d01e141a69014
tree 28afcc784ef8bfda0d4b9d17bb15f8618316f7c5
parent 3b9186c6b1ac5d33789b35f8fe29ff39cbbe0872
author laforge <[email protected]> Fr, 22 Jul 2005 08:56:28 -0400 committer laforge <[email protected]> Fr, 22 Jul 2005 08:56:28 -0400

 include/linux/netfilter/nfnetlink.h                |    3 
 include/linux/netfilter/nfnetlink_conntrack.h      |  123 ++
 include/linux/netfilter_ipv4/ip_conntrack.h        |   46 +
 include/linux/netfilter_ipv4/ip_conntrack_core.h   |    5 
 include/linux/netfilter_ipv4/ip_conntrack_helper.h |    2 
 clude/linux/netfilter_ipv4/ip_conntrack_protocol.h |   24 
 include/linux/netfilter_ipv4/ip_nat_protocol.h     |   25 
 net/ipv4/netfilter/Kconfig                         |    7 
 net/ipv4/netfilter/Makefile                        |    4 
 net/ipv4/netfilter/ip_conntrack_core.c             |  278 +++-
 net/ipv4/netfilter/ip_conntrack_netlink.c          | 1588 ++++++++++++++++++++
 net/ipv4/netfilter/ip_conntrack_proto_icmp.c       |   58 +
 net/ipv4/netfilter/ip_conntrack_proto_sctp.c       |    4 
 net/ipv4/netfilter/ip_conntrack_proto_tcp.c        |   17 
 net/ipv4/netfilter/ip_conntrack_proto_udp.c        |    2 
 net/ipv4/netfilter/ip_conntrack_standalone.c       |   36 
 net/ipv4/netfilter/ip_nat_core.c                   |   96 +
 net/ipv4/netfilter/ip_nat_proto_icmp.c             |    6 
 net/ipv4/netfilter/ip_nat_proto_tcp.c              |    7 
 net/ipv4/netfilter/ip_nat_proto_udp.c              |    6 
 net/ipv4/netfilter/ip_nat_proto_unknown.c          |    2 
 net/ipv4/netfilter/ip_nat_standalone.c             |    2 
 22 files changed, 2241 insertions(+), 100 deletions(-)
include/linux/netfilter/nfnetlink.h +2 -1
@@ -56,7 +56,7 @@ struct nfgenmsg {
 	u_int16_t res_id;		/* resource id */
 } __attribute__ ((packed));
 
-#define NFNETLINK_V1	1
+#define NFNETLINK_V0	0
 
 #define NFM_NFA(n)      ((struct nfattr *)(((char *)(n)) \
         + NLMSG_ALIGN(sizeof(struct nfgenmsg))))
@@ -81,6 +81,7 @@ enum nfnl_subsys_id {
 
 #ifdef __KERNEL__
 
+#include <linux/netlink.h>
 #include <linux/capability.h>
 
 struct nfnl_callback
include/linux/netfilter/nfnetlink_conntrack.h new file +123 -0

123 lines not on this page · raw message

include/linux/netfilter_ipv4/ip_conntrack.h +45 -1

70 lines not on this page · raw message

include/linux/netfilter_ipv4/ip_conntrack_core.h +5 -0
@@ -2,6 +2,9 @@
 #define _IP_CONNTRACK_CORE_H
 #include <linux/netfilter.h>
 
+#define MAX_IP_CT_PROTO 256
+extern struct ip_conntrack_protocol *ip_ct_protos[MAX_IP_CT_PROTO];
+
 /* This header is used to share core functionality between the
    standalone connection tracking module, and the compatibility layer's use
    of connection tracking. */
@@ -53,6 +56,8 @@ struct ip_conntrack_ecache;
 extern void __ip_ct_deliver_cached_events(struct ip_conntrack_ecache *ec);
 #endif
 
+extern void __ip_ct_expect_unlink_destroy(struct ip_conntrack_expect *exp);
+
 extern struct list_head *ip_conntrack_hash;
 extern struct list_head ip_conntrack_expect_list;
 extern rwlock_t ip_conntrack_lock;
include/linux/netfilter_ipv4/ip_conntrack_helper.h +2 -0
@@ -24,6 +24,8 @@ struct ip_conntrack_helper
 	int (*help)(struct sk_buff **pskb,
 		    struct ip_conntrack *ct,
 		    enum ip_conntrack_info conntrackinfo);
+
+	int (*to_nfattr)(struct sk_buff *skb, const struct ip_conntrack *ct);
 };
 
 extern int ip_conntrack_helper_register(struct ip_conntrack_helper *);
include/linux/netfilter_ipv4/ip_conntrack_protocol.h +15 -9
@@ -2,6 +2,7 @@
 #ifndef _IP_CONNTRACK_PROTOCOL_H
 #define _IP_CONNTRACK_PROTOCOL_H
 #include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
 
 struct seq_file;
 
@@ -47,22 +48,22 @@ struct ip_conntrack_protocol
 	int (*error)(struct sk_buff *skb, enum ip_conntrack_info *ctinfo,
 		     unsigned int hooknum);
 
+	/* convert protoinfo to nfnetink attributes */
+	int (*to_nfattr)(struct sk_buff *skb, struct nfattr *nfa,
+			 const struct ip_conntrack *ct);
+
+	int (*tuple_to_nfattr)(struct sk_buff *skb,
+			       const struct ip_conntrack_tuple *t);
+	int (*nfattr_to_tuple)(struct nfattr *tb[],
+			       struct ip_conntrack_tuple *t);
+
 	/* Module (if any) which this is connected to. */
 	struct module *me;
 };
 
-#define MAX_IP_CT_PROTO 256
-extern struct ip_conntrack_protocol *ip_ct_protos[MAX_IP_CT_PROTO];
-
 /* Protocol registration. */
 extern int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto);
 extern void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto);
-
-static inline struct ip_conntrack_protocol *ip_ct_find_proto(u_int8_t protocol)
-{
-	return ip_ct_protos[protocol];
-}
-
 /* Existing built-in protocols */
 extern struct ip_conntrack_protocol ip_conntrack_protocol_tcp;
 extern struct ip_conntrack_protocol ip_conntrack_protocol_udp;
@@ -73,6 +74,11 @@ extern int ip_conntrack_protocol_tcp_ini
 /* Log invalid packets */
 extern unsigned int ip_ct_log_invalid;
 
+extern int ip_ct_port_tuple_to_nfattr(struct sk_buff *,
+				      const struct ip_conntrack_tuple *);
+extern int ip_ct_port_nfattr_to_tuple(struct nfattr *tb[],
+				      struct ip_conntrack_tuple *);
+
 #ifdef CONFIG_SYSCTL
 #ifdef DEBUG_INVALID_PACKETS
 #define LOG_INVALID(proto) \
include/linux/netfilter_ipv4/ip_nat_protocol.h +18 -7
@@ -4,6 +4,9 @@
 #include <linux/init.h>
 #include <linux/list.h>
 
+#include <linux/netfilter_ipv4/ip_nat.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
+
 struct iphdr;
 struct ip_nat_range;
 
@@ -15,6 +18,8 @@ struct ip_nat_protocol
 	/* Protocol number. */
 	unsigned int protonum;
 
+	struct module *me;
+
 	/* Translate a packet to the target according to manip type.
 	   Return true if succeeded. */
 	int (*manip_pkt)(struct sk_buff **pskb,
@@ -43,19 +48,20 @@ struct ip_nat_protocol
 
 	unsigned int (*print_range)(char *buffer,
 				    const struct ip_nat_range *range);
-};
 
-#define MAX_IP_NAT_PROTO 256
-extern struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO];
+	int (*range_to_nfattr)(struct sk_buff *skb,
+			       const struct ip_nat_range *range);
+
+	int (*nfattr_to_range)(struct nfattr *tb[],
+			       struct ip_nat_range *range);
+};
 
 /* Protocol registration. */
 extern int ip_nat_protocol_register(struct ip_nat_protocol *proto);
 extern void ip_nat_protocol_unregister(struct ip_nat_protocol *proto);
 
-static inline struct ip_nat_protocol *ip_nat_find_proto(u_int8_t protocol)
-{
-	return ip_nat_protos[protocol];
-}
+extern struct ip_nat_protocol *ip_nat_proto_find_get(u_int8_t protocol);
+extern void ip_nat_proto_put(struct ip_nat_protocol *proto);
 
 /* Built-in protocols. */
 extern struct ip_nat_protocol ip_nat_protocol_tcp;
@@ -67,4 +73,9 @@ extern int init_protocols(void) __init;
 extern void cleanup_protocols(void);
 extern struct ip_nat_protocol *find_nat_proto(u_int16_t protonum);
 
+extern int ip_nat_port_range_to_nfattr(struct sk_buff *skb,
+				       const struct ip_nat_range *range);
+extern int ip_nat_port_nfattr_to_range(struct nfattr *tb[],
+				       struct ip_nat_range *range);
+
 #endif /*_IP_NAT_PROTO_H*/
net/ipv4/netfilter/Kconfig +7 -0
@@ -702,5 +702,12 @@ config IP_NF_ARP_MANGLE
 	  Allows altering the ARP packet payload: source and destination
 	  hardware and network addresses.
 
+config IP_NF_CONNTRACK_NETLINK
+        tristate 'Connection tracking netlink interface'
+        depends on IP_NF_CONNTRACK && NETFILTER_NETLINK
+        help
+          This option enables support for a netlink-based userspace interface
+
+
 endmenu
 
net/ipv4/netfilter/Makefile +4 -0
@@ -9,6 +9,10 @@ iptable_nat-objs	:= ip_nat_standalone.o 
 # connection tracking
 obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
 
+# conntrack netlink interface
+obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o
+
+
 # SCTP protocol connection tracking
 obj-$(CONFIG_IP_NF_CT_PROTO_SCTP) += ip_conntrack_proto_sctp.o
 
net/ipv4/netfilter/ip_conntrack_core.c +225 -53

463 lines not on this page · raw message

net/ipv4/netfilter/ip_conntrack_netlink.c new file +1588 -0

1,588 lines not on this page · raw message

net/ipv4/netfilter/ip_conntrack_proto_icmp.c +51 -7

96 lines not on this page · raw message

net/ipv4/netfilter/ip_conntrack_proto_sctp.c +3 -1
@@ -505,7 +505,9 @@ static struct ip_conntrack_protocol ip_c
 	.packet 	 = sctp_packet, 
 	.new 		 = sctp_new, 
 	.destroy 	 = NULL, 
-	.me 		 = THIS_MODULE 
+	.me 		 = THIS_MODULE,
+	.tuple_to_nfattr = ip_ct_port_tuple_to_nfattr,
+	.nfattr_to_tuple = ip_ct_port_nfattr_to_tuple,
 };
 
 #ifdef CONFIG_SYSCTL
net/ipv4/netfilter/ip_conntrack_proto_tcp.c +17 -0
@@ -336,6 +336,20 @@ static int tcp_print_conntrack(struct se
 	return seq_printf(s, "%s ", tcp_conntrack_names[state]);
 }
 
+static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
+			 const struct ip_conntrack *ct)
+{
+	read_lock_bh(&tcp_lock);
+	NFA_PUT(skb, CTA_PROTOINFO_TCP_STATE, sizeof(u_int8_t),
+		&ct->proto.tcp.state);
+	read_unlock_bh(&tcp_lock);
+
+	return 0;
+
+nfattr_failure:
+	return -1;
+}
+
 static unsigned int get_conntrack_index(const struct tcphdr *tcph)
 {
 	if (tcph->rst) return TCP_RST_SET;
@@ -1100,4 +1114,7 @@ struct ip_conntrack_protocol ip_conntrac
 	.packet 		= tcp_packet,
 	.new 			= tcp_new,
 	.error			= tcp_error,
+	.to_nfattr		= tcp_to_nfattr,
+	.tuple_to_nfattr	= ip_ct_port_tuple_to_nfattr,
+	.nfattr_to_tuple	= ip_ct_port_nfattr_to_tuple,
 };
net/ipv4/netfilter/ip_conntrack_proto_udp.c +2 -0
@@ -145,4 +145,6 @@ struct ip_conntrack_protocol ip_conntrac
 	.packet			= udp_packet,
 	.new			= udp_new,
 	.error			= udp_error,
+	.tuple_to_nfattr	= ip_ct_port_tuple_to_nfattr,
+	.nfattr_to_tuple	= ip_ct_port_nfattr_to_tuple,
 };
net/ipv4/netfilter/ip_conntrack_standalone.c +29 -7
@@ -5,7 +5,7 @@
 */
 
 /* (C) 1999-2001 Paul `Rusty' Russell
- * (C) 2002-2004 Netfilter Core Team <[email protected]>
+ * (C) 2002-2005 Netfilter Core Team <[email protected]>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -147,8 +147,7 @@ static int ct_seq_show(struct seq_file *
 	if (DIRECTION(hash))
 		return 0;
 
-	proto = ip_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
-			       .tuple.dst.protonum);
+	proto = __ip_conntrack_proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
 	IP_NF_ASSERT(proto);
 
 	if (seq_printf(s, "%-8s %u %ld ",
@@ -283,7 +282,7 @@ static int exp_seq_show(struct seq_file 
 	seq_printf(s, "proto=%u ", expect->tuple.dst.protonum);
 
 	print_tuple(s, &expect->tuple,
-		    ip_ct_find_proto(expect->tuple.dst.protonum));
+		    __ip_conntrack_proto_find(expect->tuple.dst.protonum));
 	return seq_putc(s, '\n');
 }
 
@@ -992,12 +991,16 @@ EXPORT_SYMBOL(ip_conntrack_helper_regist
 EXPORT_SYMBOL(ip_conntrack_helper_unregister);
 EXPORT_SYMBOL(ip_ct_iterate_cleanup);
 EXPORT_SYMBOL(ip_ct_refresh_acct);
-EXPORT_SYMBOL(ip_ct_protos);
-EXPORT_SYMBOL(ip_ct_find_proto);
+
 EXPORT_SYMBOL(ip_conntrack_expect_alloc);
 EXPORT_SYMBOL(ip_conntrack_expect_put);
+EXPORT_SYMBOL_GPL(ip_conntrack_expect_find_get);
 EXPORT_SYMBOL(ip_conntrack_expect_related);
 EXPORT_SYMBOL(ip_conntrack_unexpect_related);
+EXPORT_SYMBOL_GPL(ip_conntrack_expect_list);
+EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find);
+EXPORT_SYMBOL_GPL(__ip_ct_expect_unlink_destroy);
+
 EXPORT_SYMBOL(ip_conntrack_tuple_taken);
 EXPORT_SYMBOL(ip_ct_gather_frags);
 EXPORT_SYMBOL(ip_conntrack_htable_size);
@@ -1005,7 +1008,26 @@ EXPORT_SYMBOL(ip_conntrack_lock);
 EXPORT_SYMBOL(ip_conntrack_hash);
 EXPORT_SYMBOL(ip_conntrack_untracked);
 EXPORT_SYMBOL_GPL(ip_conntrack_find_get);
-EXPORT_SYMBOL_GPL(ip_conntrack_put);
 #ifdef CONFIG_IP_NF_NAT_NEEDED
 EXPORT_SYMBOL(ip_conntrack_tcp_update);
 #endif
+
+EXPORT_SYMBOL_GPL(ip_conntrack_flush);
+EXPORT_SYMBOL_GPL(__ip_conntrack_find);
+
+EXPORT_SYMBOL_GPL(ip_conntrack_alloc);
+EXPORT_SYMBOL_GPL(ip_conntrack_free);
+EXPORT_SYMBOL_GPL(ip_conntrack_hash_insert);
+
+EXPORT_SYMBOL_GPL(ip_ct_remove_expectations);
+
+EXPORT_SYMBOL_GPL(ip_conntrack_helper_find_get);
+EXPORT_SYMBOL_GPL(ip_conntrack_helper_put);
+EXPORT_SYMBOL_GPL(__ip_conntrack_helper_find_byname);
+
+EXPORT_SYMBOL_GPL(ip_conntrack_proto_find_get);
+EXPORT_SYMBOL_GPL(ip_conntrack_proto_put);
+EXPORT_SYMBOL_GPL(__ip_conntrack_proto_find);
+
+EXPORT_SYMBOL_GPL(ip_ct_port_tuple_to_nfattr);
+EXPORT_SYMBOL_GPL(ip_ct_port_nfattr_to_tuple);
net/ipv4/netfilter/ip_nat_core.c +89 -7

154 lines not on this page · raw message

net/ipv4/netfilter/ip_nat_proto_icmp.c +4 -2
@@ -106,10 +106,12 @@ icmp_print_range(char *buffer, const str
 }
 
 struct ip_nat_protocol ip_nat_protocol_icmp
-= { "ICMP", IPPROTO_ICMP,
+= { "ICMP", IPPROTO_ICMP, THIS_MODULE,
     icmp_manip_pkt,
     icmp_in_range,
     icmp_unique_tuple,
     icmp_print,
-    icmp_print_range
+    icmp_print_range,
+    ip_nat_port_range_to_nfattr,
+    ip_nat_port_nfattr_to_range,
 };
net/ipv4/netfilter/ip_nat_proto_tcp.c +5 -2
@@ -12,6 +12,7 @@
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/if.h>
+#include <linux/netfilter/nfnetlink_conntrack.h>
 #include <linux/netfilter_ipv4/ip_nat.h>
 #include <linux/netfilter_ipv4/ip_nat_rule.h>
 #include <linux/netfilter_ipv4/ip_nat_protocol.h>
@@ -169,10 +170,12 @@ tcp_print_range(char *buffer, const stru
 }
 
 struct ip_nat_protocol ip_nat_protocol_tcp
-= { "TCP", IPPROTO_TCP,
+= { "TCP", IPPROTO_TCP, THIS_MODULE,
     tcp_manip_pkt,
     tcp_in_range,
     tcp_unique_tuple,
     tcp_print,
-    tcp_print_range
+    tcp_print_range,
+    ip_nat_port_range_to_nfattr,
+    ip_nat_port_nfattr_to_range,
 };
net/ipv4/netfilter/ip_nat_proto_udp.c +4 -2
@@ -156,10 +156,12 @@ udp_print_range(char *buffer, const stru
 }
 
 struct ip_nat_protocol ip_nat_protocol_udp
-= { "UDP", IPPROTO_UDP,
+= { "UDP", IPPROTO_UDP, THIS_MODULE,
     udp_manip_pkt,
     udp_in_range,
     udp_unique_tuple,
     udp_print,
-    udp_print_range
+    udp_print_range,
+    ip_nat_port_range_to_nfattr,
+    ip_nat_port_nfattr_to_range,
 };
net/ipv4/netfilter/ip_nat_proto_unknown.c +1 -1
@@ -61,7 +61,7 @@ unknown_print_range(char *buffer, const 
 }
 
 struct ip_nat_protocol ip_nat_unknown_protocol = {
-	"unknown", 0,
+	"unknown", 0, THIS_MODULE,
 	unknown_manip_pkt,
 	unknown_in_range,
 	unknown_unique_tuple,
net/ipv4/netfilter/ip_nat_standalone.c +2 -0
@@ -390,6 +390,8 @@ module_exit(fini);
 EXPORT_SYMBOL(ip_nat_setup_info);
 EXPORT_SYMBOL(ip_nat_protocol_register);
 EXPORT_SYMBOL(ip_nat_protocol_unregister);
+EXPORT_SYMBOL_GPL(ip_nat_proto_find_get);
+EXPORT_SYMBOL_GPL(ip_nat_proto_put);
 EXPORT_SYMBOL(ip_nat_cheat_check);
 EXPORT_SYMBOL(ip_nat_mangle_tcp_packet);
 EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
maintainer
#1 lore raw

From: Harald Welte <[email protected]>
Date: Fri, 22 Jul 2005 09:11:30 -0400

Quoted 3 lines

This is a patch for your net-2.6.14 tree (incremental to the expect-double-free fix). It adds the ctnetlink code, and all the required core conntrack/nat changes that it needs.

Applied and pushed to net-2.6.14