updates for [nf|ct]netlink and event API
Subsystems (3)
PATCH 1/2 updates for [nf|ct]netlink and event API
Hi Harald,
This patchset introduces tons of updates for the nfnetlink, ctnetlink and the conntrack event API. I haven't attached the file since it's that big, about 100K.
You can get an incremental diff against SVN from:
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/SVN-patches/ctnetlink-ctevent-nfnetlink-update-2.6.12.patch
Please apply.
I've split this big patch above into four pieces to make it easier to understand the changes:
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/2.6.11-vs-2.6.12/
So these four patches shouldn't be applied, just they are meant to make your life easier to track the changes.
Summary of changes
------------------
o conntrack event API
- Don't kill NFC_IP_* stuff, keep it there to ensure for old iptables versions compilation.
- new file ip_conntrack_events.h that contains all event related functions to reduce pollution in ip_conntrack.h
- IPCT_DELIVERED bit. Loopback reports event are reported twice, this bit is set once event are delivered. I just came up with a better idea, reset nfcache once the events have been delivered, but I'll apply this change in the next patchset.
o nfnetlink
- kill unused list.
- kill nfnl_exlock(), not needed anymore.
- kill duplicated check: NFNL_SUBSYS_ID(type) > NFNL_SUBSYS_COUNT.
- kill unneeded initialization of subsys_table to NULL, since it's in BSS section (already set to zero).
- kill dead define CONFIG_NF_NETLINK.
o ctnetlink
- merge ctnetlink_get_mcgroups and ctnetlink_get_exp_mcgroups
- implemented NAT handlings
- kill unused ctnetlink_kill
- use __u64 id's for conntracks
- stop using NLMSG_DONE to report the end of a dump, use explicite ACK instead (NLM_F_ACK).
- fixed broken expectation timeout dumping.
- kill unused ctnetlink_exp_dump_proto
- kill ctnetlink_exp_dump: fairly small and just used once
- kill NFNL_SUBSYS_CTNETLINK_EXP, use NFNL_SUBSYS_CTNETLINK instead
- Fix expectation table dumping
- Fix expectation creation
- implemented flushing of the expect table
TODO
----
- Implement ip_conntrack_stats dumping and reset (accounting)
- Implement get conntrack and destroy (accounting)
- Kill event/dump mask based (?). Although it's unique, I think that it could be useful for weak conntrack event notification (think of just new, established and destroy event notification to reduce performance impact).
Once ip_conntrack_netlink gets fully featured and people don't report bugs for quite some time. I'll create a nf_conntrack_netlink tree.
--
Pablo
Quoted 8 lines · Pablo Neira
Hi Harald,
This patchset introduces tons of updates for the nfnetlink, ctnetlink and the conntrack event API. I haven't attached the file since it's that big, about 100K.
You can get an incremental diff against SVN from:
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/SVN-patches/ctnetlink-ctevent-nfnetlink-update-2.6.12.patch
the patch removes the whole old ip_conntrack_netlink.c file and replaces it with a new one. I don't really see why. An, now, you changed the directory name from 2.6.11 to 2.6.12. Is this neccessarry? Why would your recent changes to ctnetlink not work with a 2.6.11 kernel?
If there is no good reason, I would suggest to just patch the existing files in the 2.6.11 subdirectory.
Quoted 3 lines
I've split this big patch above into four pieces to make it easier to understand the changes:
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/2.6.11-vs-2.6.12/
please remove stuff like
Review
Quoted 3 lines
(quoted diff) +1
-1-#if 0 +#if 1 #define DEBUGP printk
before releasing a patch, thanks.
Also, I would rather not like to have NFNL_SUBSYS_CTNETLINK_EXP deleted. I thought it would be nice to have expect handling separated from conntracks, since they really are two seperate data structures.
Apart from that I'm fine with all of your modifications.
I don't understand why the order of the expectation list was changed, though. Would you please explain why this was done?
Quoted 1 line
- Implement
ip_conntrack_statsdumping and reset (accounting)
you want to dump the statistics via netlink? i'm not sure whether that is required. lnstat is the only program using those counters, and using /proc seems fine for that.
Quoted 1 line
- Implement get conntrack and destroy (accounting)
sorry, what are you referring to?
Quoted 4 lines
- Kill event/dump mask based (?). Although it's unique, I think that it could be useful for weak conntrack event notification (think of just new, established and destroy event notification to reduce performance impact).
well, an interesting optimization. My major problem with this whole system (like the other IPCTNL_MSG_CONFIG stuff) is: how to correctly deal with multipel users.
Now, I think there is a way to do it right. Basically every application would only request the events that it is interested in, and the kernel would bitwise-or those events to create the event mask that actually is to be dumped into userspace.
It's a bit like multicast membership subscription with IGMP...
So the only question remaining is: how does the kernel clean up / expire the masks? If apps only subscribe but never unsubscribe, we would never clean up.
I'm not sure if we could somehow (cleanly) tie into the scoket close/destroy code. If yes, we could check if we can reduce the mask at socket destroy time.
Another approach would be timer-based, so applications would have to re-subscribe to 'their' groups in regular intervals if they are still interested in certain events. Sounds racy and ugly, though :(
I'm always open for better solutions, though :)
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
Quoted 4 lines · Harald Welte
the patch removes the whole old
ip_conntrack_netlink.cfile and replaces it with a new one. I don't really see why. An, now, you changed the directory name from 2.6.11 to 2.6.12. Is this neccessarry? Why would your recent changes to ctnetlink not work with a 2.6.11 kernel?
I did that because of the file linux-2.6.patch, the 2.6.11 version differs from the new 2.6.12 one. Can we have in pom-ng two different file patches for every version? I mean, something like linux-2.6.11.patch and linux-2.6.12.patch living in ctnetlink. If so, please add the patch attached to ctnetlink.
Quoted 10 lines
Quoted 2 lines
I've split this big patch above into four pieces to make it easier to understand the changes:
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/2.6.11-vs-2.6.12/please remove stuff like
Quoted 3 lines
(quoted diff) +1
-1-#if 0 +#if 1#define DEBUGP printk
before releasing a patch, thanks.
OK, I'll do so.
Quoted 8 lines
Also, I would rather not like to have
NFNL_SUBSYS_CTNETLINK_EXPdeleted. I thought it would be nice to have expect handling separated from conntracks, since they really are two seperate data structures.Apart from that I'm fine with all of your modifications.
I don't understand why the order of the expectation list was changed, though. Would you please explain why this was done?
Because of the table dumping logic I was using.
- if (ct->id <= *id)
+ if (ct->id >= *id)
continue;
I needed to add the conntracks at the tail. This isn't really needed so I've just reverted this change in the linux-2.6.12.patch attached.
Please see that you have to apply the patch 05ctnetlink.patch to ctnetlink as well.
Quoted 5 lines
Quoted 1 line
- Implement
ip_conntrack_statsdumping and reset (accounting)you want to dump the statistics via netlink? i'm not sure whether that is required. lnstat is the only program using those counters, and using /proc seems fine for that.
Could this be useful for accounting purposes? I mean, dump and reset as a single operation, something similar to conntrack -L -z, say conntrack -S -z.
Quoted 3 lines
Quoted 1 line
- Implement get conntrack and destroy (accounting)
sorry, what are you referring to?
An atomical operation to dump conntrack information and then destroy it. For example, if someone does:
conntrack -D --orig-src 1.1.1.1 --orig-dst 2.2.2.2 -p tcp --orig-src-port 10 --orig-dst-port 20
the it sends the conntrack info and destroy it. This could be worth it for accounting.
Quoted 7 lines
Quoted 2 lines
- Kill event/dump mask based (?). Although it's unique, I think that it
could be useful for weak conntrack event notification (think of just new, established and destroy event notification to reduce performance impact).well, an interesting optimization. My major problem with this whole system (like the other
IPCTNL_MSG_CONFIGstuff) is: how to correctly deal with multipel users.
Yes, this is a problem.
Quoted 7 lines
Now, I think there is a way to do it right. Basically every application would only request the events that it is interested in, and the kernel would bitwise-or those events to create the event mask that actually is to be dumped into userspace.
It's a bit like multicast membership subscription with IGMP...
Quoted 7 lines
So the only question remaining is: how does the kernel clean up / expire the masks? If apps only subscribe but never unsubscribe, we would never clean up.
I'm not sure if we could somehow (cleanly) tie into the scoket close/destroy code. If yes, we could check if we can reduce the mask at socket destroy time.
I think there's no sane way to do this but let me check the netlink code again. I could use multicast netlink subscrition, so the client can get subscribed to those events that the user considers interesting.
Initially the purpose of the mask based event notification was reducing the impact of an socket overrun under big stress situations. Say you've got a firewall very loaded, so conntrack-netlink subsys has to send tons of update messages, in that case the buffer can overrun and some messages will be drop.
To avoid this I could use an approach similar to what you do in ULOG and just keep the mask in userspace. Anyway, this hurts performance as well, since unneeded messages will be delivered to userspace and dropped if the client doesn't consider them interesting. This solution isn't that bad though since the conntrack-netlink subsys will send burst of messages in once.
--
Pablo
net/ipv4/netfilter/ip_conntrack_amanda.c +1 -0
@@ -151,6 +151,7 @@ .mask = { .src = { .u = { 0xFFFF } }, .dst = { .protonum = 0xFF }, }, + .change_help = ip_ct_generic_change_help, }; static void __exit fini(void)
net/ipv4/netfilter/ip_conntrack_core.c +156 -45
377 lines not on this page · raw message
net/ipv4/netfilter/ip_conntrack_ftp.c +2 -0
@@ -481,6 +481,8 @@ ftp[i].timeout =5 *60 ;/* 5 minutes */ ftp[i].me =THIS_MODULE ; ftp[i].help = help; + ftp[i].lock = &ip_ftp_lock; + ftp[i].change_help = ip_ct_generic_change_help; tmpname = &ftp_names[i][0 ];if (ports[i] ==FTP_PORT )
net/ipv4/netfilter/ip_conntrack_irc.c +2 -0
@@ -275,6 +275,8 @@ hlpr->timeout = dcc_timeout; hlpr->me =THIS_MODULE ; hlpr->help = help; + hlpr->lock = &irc_buffer_lock; + hlpr->change_help = ip_ct_generic_change_help; tmpname = &irc_names[i][0 ];if (ports[i] ==IRC_PORT )
net/ipv4/netfilter/ip_conntrack_proto_icmp.c +20 -6
@@ -109,16 +109,17 @@return NF_ACCEPT ; } +static u_int8_t valid_new[] = { + [ICMP_ECHO ] =1 , + [ICMP_TIMESTAMP ] =1 , + [ICMP_INFO_REQUEST ] =1 , + [ICMP_ADDRESS ] =1 +}; +/* Called when a new connection for this protocol found. */ static int icmp_new (struct ip_conntrack *conntrack,const struct sk_buff *skb) { -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. */
@@ -266,6 +267,17 @@return icmp_error_message (skb, ctinfo, hooknum); } +static int icmp_change_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 ; +} +struct ip_conntrack_protocol ip_conntrack_protocol_icmp = { .proto =IPPROTO_ICMP ,
@@ -277,4 +289,6 @@ .packet = icmp_packet, .new = icmp_new, .error = icmp_error, + .change_check_tuples = icmp_change_check_tuples, + .change_proto = ip_ct_generic_change_proto, };
net/ipv4/netfilter/ip_conntrack_proto_sctp.c +3 -1
@@ -499,6 +499,7 @@static struct ip_conntrack_protocol ip_conntrack_protocol_sctp = { .proto =IPPROTO_SCTP , .name ="sctp" , + .lock = &sctp_lock, .pkt_to_tuple = sctp_pkt_to_tuple, .invert_tuple = sctp_invert_tuple, .print_tuple = sctp_print_tuple,
@@ -506,7 +507,8 @@ .packet = sctp_packet, .new = sctp_new, .destroy = NULL, - .me = THIS_MODULE + .me = THIS_MODULE, + .change_proto = ip_ct_generic_change_proto, };#ifdef CONFIG_SYSCTL
net/ipv4/netfilter/ip_conntrack_proto_tcp.c +2 -0
@@ -1094,6 +1094,7 @@ { .proto = IPPROTO_TCP, .name = "tcp", + .lock = &tcp_lock, .pkt_to_tuple = tcp_pkt_to_tuple, .invert_tuple = tcp_invert_tuple, .print_tuple = tcp_print_tuple,
@@ -1101,4 +1102,5 @@ .packet = tcp_packet, .new = tcp_new, .error = tcp_error, + .change_proto = ip_ct_generic_change_proto };
net/ipv4/netfilter/ip_conntrack_proto_udp.c +1 -0
@@ -144,4 +144,5 @@ .packet = udp_packet, .new = udp_new, .error = udp_error, + .change_proto = ip_ct_generic_change_proto };
net/ipv4/netfilter/ip_conntrack_standalone.c +13 -1
@@ -963,6 +963,19 @@ { } +EXPORT_SYMBOL (ip_ct_unlink_destroy_expect); +EXPORT_SYMBOL (ip_conntrack_flush); +EXPORT_SYMBOL (__ip_conntrack_expect_find); +EXPORT_SYMBOL (__ip_conntrack_find); +EXPORT_SYMBOL (ip_conntrack_expect_list); +EXPORT_SYMBOL (ip_ct_generic_change_proto); +EXPORT_SYMBOL (ip_ct_generic_change_help); +EXPORT_SYMBOL (ip_conntrack_expect_find_get); +EXPORT_SYMBOL (ip_conntrack_alloc); +EXPORT_SYMBOL (ip_conntrack_free); +EXPORT_SYMBOL (ip_conntrack_hash_insert); +EXPORT_SYMBOL (ip_ct_remove_expectations); +EXPORT_SYMBOL (ip_ct_find_helper);#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS EXPORT_SYMBOL (ip_conntrack_chain);EXPORT_SYMBOL (ip_conntrack_expect_chain);
@@ -993,7 +1006,6 @@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
net/ipv4/netfilter/ip_conntrack_tftp.c +1 -0
@@ -134,6 +134,7 @@ tftp[i].timeout =5 *60 ;/* 5 minutes */ tftp[i].me =THIS_MODULE ; tftp[i].help = tftp_help; + tftp[i].change_help = ip_ct_generic_change_help; tmpname = &tftp_names[i][0 ];if (ports[i] ==TFTP_PORT )
include/linux/netfilter_ipv4/ip_conntrack_amanda.h +2 -0
@@ -3,9 +3,11 @@/* AMANDA tracking. */ struct ip_conntrack_expect ; +#ifdef __KERNEL__extern unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb,enum ip_conntrack_info ctinfo,unsigned int matchoff,unsigned int matchlen,struct ip_conntrack_expect *exp); +#endif #endif /* _IP_CONNTRACK_AMANDA_H */
include/linux/netfilter_ipv4/ip_conntrack_ftp.h +2 -0
@@ -31,6 +31,7 @@struct ip_conntrack_expect ; +#ifdef __KERNEL__/* For NAT to hook in when we find a packet which describes what other * connection we should expect. */ extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
@@ -40,4 +41,5 @@unsigned int matchlen, struct ip_conntrack_expect *exp, u32 *seq); +#endif #endif /* _IP_CONNTRACK_FTP_H */
include/linux/netfilter_ipv4/ip_conntrack.h +49 -13
111 lines not on this page · raw message
include/linux/netfilter_ipv4/ip_conntrack_helper.h +7 -0
@@ -9,6 +9,8 @@ {struct list_head list;/* Internal use. */ +spinlock_t *lock;/* protect private info and buffer */ +const char *name;/* name of the module */ struct module *me;/* pointer to self */ unsigned int max_expected;/* Maximum number of concurrent
@@ -24,6 +26,8 @@int (*help)(struct sk_buff **pskb,struct ip_conntrack *ct,enum ip_conntrack_info conntrackinfo); + +void (*change_help)(struct ip_conntrack *,union ip_conntrack_help *); };extern int ip_conntrack_helper_register (struct ip_conntrack_helper *);
@@ -38,4 +42,7 @@extern int ip_conntrack_expect_related (struct ip_conntrack_expect *exp);extern void ip_conntrack_unexpect_related (struct ip_conntrack_expect *exp); +extern void ip_ct_generic_change_help (struct ip_conntrack *ct, +union ip_conntrack_help *h); +#endif /*_IP_CONNTRACK_HELPER_H*/
include/linux/netfilter_ipv4/ip_conntrack_protocol.h +15 -0
@@ -10,6 +10,8 @@/* Protocol number. */ u_int8_t proto; +rwlock_t *lock; +/* Protocol name */ const char *name;
@@ -47,6 +49,17 @@int (*error)(struct sk_buff *skb,enum ip_conntrack_info *ctinfo,unsigned int hooknum); +/* check if tuples are valid for a new connection */ +int (*change_check_tuples)(struct ip_conntrack_tuple *orig, +struct ip_conntrack_tuple *reply); + +/* check protocol data is valid */ +int (*change_check_proto)(union ip_conntrack_proto *p); + +/* change protocol info on behalf of ctnetlink */ +void (*change_proto)(struct ip_conntrack *ct, +union ip_conntrack_proto *p); +/* Module (if any) which this is connected to. */ struct module *me; };
@@ -57,6 +70,8 @@/* Protocol registration. */ extern int ip_conntrack_protocol_register (struct ip_conntrack_protocol *proto);extern void ip_conntrack_protocol_unregister (struct ip_conntrack_protocol *proto); +extern void ip_ct_generic_change_proto (struct ip_conntrack *conntrack, +union ip_conntrack_proto *p);static inline struct ip_conntrack_protocol *ip_ct_find_proto (u_int8_t protocol) {
net/ipv4/netfilter/ip_conntrack_netlink.c +3 -3
@@ -455,7 +455,7 @@if (DIRECTION (h) !=IP_CT_DIR_ORIGINAL )continue ; ct =tuplehash_to_ctrack (h); -if (ct->id <= *id) +if (ct->id >= *id)continue ; if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
@@ -491,7 +491,7 @@if (DIRECTION (h) !=IP_CT_DIR_ORIGINAL )continue ; ct =tuplehash_to_ctrack (h); -if (ct->id <= *id) +if (ct->id >= *id)continue ; if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
@@ -1060,7 +1060,7 @@READ_LOCK (&ip_conntrack_lock);list_for_each (i, &ip_conntrack_expect_list) { exp = (struct ip_conntrack_expect *) i; -if (exp->id <= *id) +if (exp->id >= *id)continue ; if (ctnetlink_exp_fill_info(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
Pablo Neira
maintainerReview
Quoted 10 lines · Pablo Neira
Quoted 2 lines · Harald Welte
I don't understand why the order of the expectation list was changed, though. Would you please explain why this was done?
Because of the table dumping logic I was using.
(quoted diff) +1
-1- if (ct->id <= *id) + if (ct->id >= *id) continue;
Please ignore the patches I've sent you.
I need to insert conntracks and expectations at the tail because of the nature of netlink dumping. *id (that points to cb->args[1]) will be initialized to zero, so I need to insert conntracks ordered from lesser to bigger id's, otherwise I'd need to set *id to ~0UL and that's not possible.
Please, add the following patch to ctnetlink.
--
Pablo
net/ipv4/netfilter/ip_conntrack_amanda.c +1 -0
@@ -151,6 +151,7 @@ .mask = { .src = { .u = { 0xFFFF } }, .dst = { .protonum = 0xFF }, }, + .change_help = ip_ct_generic_change_help, }; static void __exit fini(void)
net/ipv4/netfilter/ip_conntrack_core.c +156 -45
377 lines not on this page · raw message
net/ipv4/netfilter/ip_conntrack_ftp.c +2 -0
@@ -481,6 +481,8 @@ ftp[i].timeout =5 *60 ;/* 5 minutes */ ftp[i].me =THIS_MODULE ; ftp[i].help = help; + ftp[i].lock = &ip_ftp_lock; + ftp[i].change_help = ip_ct_generic_change_help; tmpname = &ftp_names[i][0 ];if (ports[i] ==FTP_PORT )
net/ipv4/netfilter/ip_conntrack_irc.c +2 -0
@@ -275,6 +275,8 @@ hlpr->timeout = dcc_timeout; hlpr->me =THIS_MODULE ; hlpr->help = help; + hlpr->lock = &irc_buffer_lock; + hlpr->change_help = ip_ct_generic_change_help; tmpname = &irc_names[i][0 ];if (ports[i] ==IRC_PORT )
net/ipv4/netfilter/ip_conntrack_proto_icmp.c +20 -6
@@ -109,16 +109,17 @@return NF_ACCEPT ; } +static u_int8_t valid_new[] = { + [ICMP_ECHO ] =1 , + [ICMP_TIMESTAMP ] =1 , + [ICMP_INFO_REQUEST ] =1 , + [ICMP_ADDRESS ] =1 +}; +/* Called when a new connection for this protocol found. */ static int icmp_new (struct ip_conntrack *conntrack,const struct sk_buff *skb) { -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. */
@@ -266,6 +267,17 @@return icmp_error_message (skb, ctinfo, hooknum); } +static int icmp_change_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 ; +} +struct ip_conntrack_protocol ip_conntrack_protocol_icmp = { .proto =IPPROTO_ICMP ,
@@ -277,4 +289,6 @@ .packet = icmp_packet, .new = icmp_new, .error = icmp_error, + .change_check_tuples = icmp_change_check_tuples, + .change_proto = ip_ct_generic_change_proto, };
net/ipv4/netfilter/ip_conntrack_proto_sctp.c +3 -1
@@ -499,6 +499,7 @@static struct ip_conntrack_protocol ip_conntrack_protocol_sctp = { .proto =IPPROTO_SCTP , .name ="sctp" , + .lock = &sctp_lock, .pkt_to_tuple = sctp_pkt_to_tuple, .invert_tuple = sctp_invert_tuple, .print_tuple = sctp_print_tuple,
@@ -506,7 +507,8 @@ .packet = sctp_packet, .new = sctp_new, .destroy = NULL, - .me = THIS_MODULE + .me = THIS_MODULE, + .change_proto = ip_ct_generic_change_proto, };#ifdef CONFIG_SYSCTL
net/ipv4/netfilter/ip_conntrack_proto_tcp.c +2 -0
@@ -1094,6 +1094,7 @@ { .proto = IPPROTO_TCP, .name = "tcp", + .lock = &tcp_lock, .pkt_to_tuple = tcp_pkt_to_tuple, .invert_tuple = tcp_invert_tuple, .print_tuple = tcp_print_tuple,
@@ -1101,4 +1102,5 @@ .packet = tcp_packet, .new = tcp_new, .error = tcp_error, + .change_proto = ip_ct_generic_change_proto };
net/ipv4/netfilter/ip_conntrack_proto_udp.c +1 -0
@@ -144,4 +144,5 @@ .packet = udp_packet, .new = udp_new, .error = udp_error, + .change_proto = ip_ct_generic_change_proto };
net/ipv4/netfilter/ip_conntrack_standalone.c +13 -1
@@ -963,6 +963,19 @@ { } +EXPORT_SYMBOL (ip_ct_unlink_destroy_expect); +EXPORT_SYMBOL (ip_conntrack_flush); +EXPORT_SYMBOL (__ip_conntrack_expect_find); +EXPORT_SYMBOL (__ip_conntrack_find); +EXPORT_SYMBOL (ip_conntrack_expect_list); +EXPORT_SYMBOL (ip_ct_generic_change_proto); +EXPORT_SYMBOL (ip_ct_generic_change_help); +EXPORT_SYMBOL (ip_conntrack_expect_find_get); +EXPORT_SYMBOL (ip_conntrack_alloc); +EXPORT_SYMBOL (ip_conntrack_free); +EXPORT_SYMBOL (ip_conntrack_hash_insert); +EXPORT_SYMBOL (ip_ct_remove_expectations); +EXPORT_SYMBOL (ip_ct_find_helper);#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS EXPORT_SYMBOL (ip_conntrack_chain);EXPORT_SYMBOL (ip_conntrack_expect_chain);
@@ -993,7 +1006,6 @@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
net/ipv4/netfilter/ip_conntrack_tftp.c +1 -0
@@ -134,6 +134,7 @@ tftp[i].timeout =5 *60 ;/* 5 minutes */ tftp[i].me =THIS_MODULE ; tftp[i].help = tftp_help; + tftp[i].change_help = ip_ct_generic_change_help; tmpname = &tftp_names[i][0 ];if (ports[i] ==TFTP_PORT )
include/linux/netfilter_ipv4/ip_conntrack_amanda.h +2 -0
@@ -3,9 +3,11 @@/* AMANDA tracking. */ struct ip_conntrack_expect ; +#ifdef __KERNEL__extern unsigned int (*ip_nat_amanda_hook)(struct sk_buff **pskb,enum ip_conntrack_info ctinfo,unsigned int matchoff,unsigned int matchlen,struct ip_conntrack_expect *exp); +#endif #endif /* _IP_CONNTRACK_AMANDA_H */
include/linux/netfilter_ipv4/ip_conntrack_ftp.h +2 -0
@@ -31,6 +31,7 @@struct ip_conntrack_expect ; +#ifdef __KERNEL__/* For NAT to hook in when we find a packet which describes what other * connection we should expect. */ extern unsigned int (*ip_nat_ftp_hook)(struct sk_buff **pskb,
@@ -40,4 +41,5 @@unsigned int matchlen, struct ip_conntrack_expect *exp, u32 *seq); +#endif #endif /* _IP_CONNTRACK_FTP_H */
include/linux/netfilter_ipv4/ip_conntrack.h +49 -13
111 lines not on this page · raw message
include/linux/netfilter_ipv4/ip_conntrack_helper.h +7 -0
@@ -9,6 +9,8 @@ {struct list_head list;/* Internal use. */ +spinlock_t *lock;/* protect private info and buffer */ +const char *name;/* name of the module */ struct module *me;/* pointer to self */ unsigned int max_expected;/* Maximum number of concurrent
@@ -24,6 +26,8 @@int (*help)(struct sk_buff **pskb,struct ip_conntrack *ct,enum ip_conntrack_info conntrackinfo); + +void (*change_help)(struct ip_conntrack *,union ip_conntrack_help *); };extern int ip_conntrack_helper_register (struct ip_conntrack_helper *);
@@ -38,4 +42,7 @@extern int ip_conntrack_expect_related (struct ip_conntrack_expect *exp);extern void ip_conntrack_unexpect_related (struct ip_conntrack_expect *exp); +extern void ip_ct_generic_change_help (struct ip_conntrack *ct, +union ip_conntrack_help *h); +#endif /*_IP_CONNTRACK_HELPER_H*/
include/linux/netfilter_ipv4/ip_conntrack_protocol.h +15 -0
@@ -10,6 +10,8 @@/* Protocol number. */ u_int8_t proto; +rwlock_t *lock; +/* Protocol name */ const char *name;
@@ -47,6 +49,17 @@int (*error)(struct sk_buff *skb,enum ip_conntrack_info *ctinfo,unsigned int hooknum); +/* check if tuples are valid for a new connection */ +int (*change_check_tuples)(struct ip_conntrack_tuple *orig, +struct ip_conntrack_tuple *reply); + +/* check protocol data is valid */ +int (*change_check_proto)(union ip_conntrack_proto *p); + +/* change protocol info on behalf of ctnetlink */ +void (*change_proto)(struct ip_conntrack *ct, +union ip_conntrack_proto *p); +/* Module (if any) which this is connected to. */ struct module *me; };
@@ -57,6 +70,8 @@/* Protocol registration. */ extern int ip_conntrack_protocol_register (struct ip_conntrack_protocol *proto);extern void ip_conntrack_protocol_unregister (struct ip_conntrack_protocol *proto); +extern void ip_ct_generic_change_proto (struct ip_conntrack *conntrack, +union ip_conntrack_proto *p);static inline struct ip_conntrack_protocol *ip_ct_find_proto (u_int8_t protocol) {
Quoted 9 lines · Pablo Neira
Quoted 7 lines · Pablo Neira
Quoted 2 lines · Harald Welte
I don't understand why the order of the expectation list was changed, though. Would you please explain why this was done?
Quoted 8 lines
Review
Quoted 5 lines
Because of the table dumping logic I was using.
(quoted diff) +1
-1- if (ct->id <= *id) + if (ct->id >= *id) continue;Please ignore the patches I've sent you.
Damn, I'm tired, wrong patch again :(. Ignore it, I'll send a new digest that applies to SVN tomorrow morning.
--
Pablo
Quoted 10 lines · Pablo Neira
Quoted 5 lines · Harald Welte
Quoted 1 line
- Implement
ip_conntrack_statsdumping and reset (accounting)you want to dump the statistics via netlink? i'm not sure whether that is required. lnstat is the only program using those counters, and using /proc seems fine for that.
Could this be useful for accounting purposes? I mean, dump and reset as a single operation, something similar to conntrack -L -z, say conntrack -S -z.
I think it is convenient for anyone wanting to access these statistics without parsing /proc to have everything accessible through a single interface.
Quoted 4 lines
Quoted 3 lines
Quoted 1 line
- Implement get conntrack and destroy (accounting)
sorry, what are you referring to?
Quoted 8 lines
An atomical operation to dump conntrack information and then destroy it. For example, if someone does:
conntrack -D --orig-src 1.1.1.1 --orig-dst 2.2.2.2 -p tcp --orig-src-port 10 --orig-dst-port 20
the it sends the conntrack info and destroy it. This could be worth it for accounting.
destroy notifications are sent anyway, so we get the stats. What's the difference to normal destruction?
Quoted 2 lines
I could use multicast netlink subscrition, so the client can get subscribed to those events that the user considers interesting.
That sounds like the right thing to do.
Regards
Patrick
Quoted 8 lines · Patrick McHardy
Quoted 7 lines · Pablo Neira
Quoted 5 lines · Harald Welte
Quoted 1 line
- Implement
ip_conntrack_statsdumping and reset (accounting)you want to dump the statistics via netlink? i'm not sure whether that is required. lnstat is the only program using those counters, and using /proc seems fine for that.
Quoted 7 lines
Quoted 3 lines
Could this be useful for accounting purposes? I mean, dump and reset as a single operation, something similar to conntrack -L -z, say conntrack -S -z.
I think it is convenient for anyone wanting to access these statistics without parsing /proc to have everything accessible through a single interface.
... and it is already implemented in current svn ;)
Quoted 2 lines
destroy notifications are sent anyway, so we get the stats. What's the difference to normal destruction?
I agree.
Quoted 4 lines
Quoted 2 lines
I could use multicast netlink subscrition, so the client can get subscribed to those events that the user considers interesting.
That sounds like the right thing to do.
well, but we still create a horrible amount of event messages, let's say in case of a syn flood...
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
Quoted 6 lines · Patrick McHardy
Quoted 4 lines · Pablo Neira
Quoted 2 lines · Harald Welte
Quoted 1 line
- Implement
ip_conntrack_statsdumping and reset (accounting)
Quoted 7 lines
Quoted 7 lines
Quoted 3 lines
you want to dump the statistics via netlink? i'm not sure whether that is required. lnstat is the only program using those counters, and using /proc seems fine for that.
Could this be useful for accounting purposes? I mean, dump and reset as a single operation, something similar to conntrack -L -z, say conntrack -S -z.
I use this, reading and zeroing conntracks at the same time.
Quoted 3 lines
I think it is convenient for anyone wanting to access these statistics without parsing /proc to have everything accessible through a single interface.
Yes; it also preserves synchronicity.
In other words it is nice to be sure if an event-update comes chronologically before or after the stats for the same conntrack were read.
Over netlink this is easy, over netlink AND /proc is impossible.
Azez
Quoted 4 lines · Pablo Neira
Quoted 2 lines
I don't understand why the order of the expectation list was changed, though. Would you please explain why this was done?
Because of the table dumping logic I was using.
I see.
Quoted 9 lines
Quoted 5 lines
Quoted 1 line
- Implement
ip_conntrack_statsdumping and reset (accounting)you want to dump the statistics via netlink? i'm not sure whether that is required. lnstat is the only program using those counters, and using /proc seems fine for that.
Could this be useful for accounting purposes? I mean, dump and reset as a single operation, something similar to conntrack -L -z, say conntrack -S -z.
oh, you're referring to ip_conntrack_acct (the accounting), not ip_conntrack_stat (the statistics) ? /me is confused.
Isn't that what the CTRZERO message type already does?
Quoted 8 lines
An atomical operation to dump conntrack information and then destroy it. For example, if someone does:
conntrack -D --orig-src 1.1.1.1 --orig-dst 2.2.2.2 -p tcp --orig-src-port 10 --orig-dst-port 20
the it sends the conntrack info and destroy it. This could be worth it for accounting.
I think it could be useful, indeed.
Quoted 7 lines
Quoted 3 lines
I'm not sure if we could somehow (cleanly) tie into the scoket close/destroy code. If yes, we could check if we can reduce the mask at socket destroy time.
I think there's no sane way to do this but let me check the netlink code again. I could use multicast netlink subscrition, so the client can get subscribed to those events that the user considers interesting.
Well, maybe we can extend the netlink code to achieve what we're interested in.
Multicast netlink groups are already used for my clumsy tcp/udp/icmp/... distinction. I think it is not a good solution for ctnetlink, since the kernel then sends all events, independent of any process interested in them or not.
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
Quoted 8 lines · Pablo Neira
Hi Harald,
This patchset introduces tons of updates for the nfnetlink, ctnetlink and the conntrack event API. I haven't attached the file since it's that big, about 100K.
You can get an incremental diff against SVN from:
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/SVN-patches/ctnetlink-ctevent-nfnetlink-update-2.6.12.patch
I haven't looked at the patch for a long time, and it removes and adds the whole file, so not sure if it is new ..
+ /* This is tricky but it works. ip_nat_setup_info needs the
+ * hook number as parameter, so let's do the correct
+ * conversion and run away */
+ if (*status & IPS_SRC_NAT_DONE)
+ hooknum = NF_IP_POST_ROUTING; /* IP_NAT_MANIP_SRC */
+ else if (*status & IPS_DST_NAT_DONE)
+ hooknum = NF_IP_PRE_ROUTING; /* IP_NAT_MANIP_DST */
+ else
+ return -EINVAL; /* Missing NAT flags */
This doesn't work reliably, locally generated packets never enter PRE_ROUTING but can be DNATed. I think the hook should be supplied by the user.
Regards
Patrick
Quoted 4 lines · Patrick McHardy
Pablo Neira wrote:
I haven't looked at the patch for a long time, and it removes and adds the whole file, so not sure if it is new ..
Yes, that's new. Ick, it seems I didn't express fine myself. Together with the big and confusing patch I uploaded a splitted version that makes easier the review as well:
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/2.6.11-vs-2.6.12/
Quoted 10 lines
(quoted diff) +9
-0+ /* This is tricky but it works. ip_nat_setup_info needs the + * hook number as parameter, so let's do the correct + * conversion and run away */ + if (*status & IPS_SRC_NAT_DONE) + hooknum = NF_IP_POST_ROUTING; /* IP_NAT_MANIP_SRC */ + else if (*status & IPS_DST_NAT_DONE) + hooknum = NF_IP_PRE_ROUTING; /* IP_NAT_MANIP_DST */ + else + return -EINVAL; /* Missing NAT flags */
Quoted 3 lines
This doesn't work reliably, locally generated packets never enter
PRE_ROUTINGbut can be DNATed. I think the hook should be supplied by the user.
The macro HOOK2MANIP used is ip_nat_setup_info returns the same value (maniptype) for NF_IP_PRE_ROUTING and NF_IP_LOCAL_IN, so the same manipulation (DNAT) will be applied to such conntrack. Since we works with conntracks, I don't mind where the packets came from, just want to apply the NAT handling that the user has requested.
--
Pablo
Quoted 10 lines · Pablo Neira
Quoted 3 lines · Patrick McHardy
This doesn't work reliably, locally generated packets never enter
PRE_ROUTINGbut can be DNATed. I think the hook should be supplied by the user.The macro HOOK2MANIP used is
ip_nat_setup_inforeturns the same value (maniptype) forNF_IP_PRE_ROUTINGandNF_IP_LOCAL_IN, so the same manipulation (DNAT) will be applied to such conntrack. Since we works with conntracks, I don't mind where the packets came from, just want to apply the NAT handling that the user has requested.
You're right, I'm still not familiar with the new NAT code ..
Regards
Patrick
Quoted 3 lines · Pablo Neira
This patchset introduces tons of updates for the nfnetlink, ctnetlink and the conntrack event API. I haven't attached the file since it's that big, about 100K.
Looks good. A couple more comments on the patch, most are probably not related to recent changes. I remember beeing responsible for at least some of this :)
+struct cta_proto {
+ unsigned char num_proto; /* Protocol number IPPROTO_X */
+ union ip_conntrack_proto proto;
+};
These should be changed not to use internal conntrack structures, it will hurt us when we want to change them. Instead it should replicate the fields interesting for the user. Also please use fixed-size types instead of unions etc. All structures including u64 types should be padded to multiples of 8 so they are equally sized on 32-bit and 64-bit systems.
+#define CTA_HELP_MAXNAMESZ 31
+
+struct cta_help {
+ char name[CTA_HELP_MAXNAMESZ]; /* name of conntrack helper */
+ union ip_conntrack_help help;
+};
I suggest to use 32, the length in the kernel is not fixed AFAICS and it will be padded to 32 in netlink messages anyway.
+/* ctnetlink multicast groups: reports any change of ctinfo,
+ * ctstatus, or protocol state change.
+ */
+#define NFGRP_IPV4_CT_TCP 0x01 +#define NFGRP_IPV4_CT_UDP 0x02 +#define NFGRP_IPV4_CT_ICMP 0x04 +#define NFGRP_IPV4_CT_OTHER 0x08
I'm not sure how useful these groups are. I think groups for different event-types might be more useful to reduce the noise.
+ h->name[CTA_HELP_MAXNAMESZ - 1] = '\0';
+ if (strcmp(helper->name, h->name))
+ return -EINVAL;
We changed ipt_helper to accept a null-byte string as wildcard string, probably a good idea to do the same here.
+ ct = ip_conntrack_alloc(otuple, rtuple);
+ if (ct == NULL || IS_ERR(ct))
+ return -ENOMEM;
ip_conntrack_alloc doesn't return ERR_PTR()
+ exp = ip_conntrack_expect_find_get(tuple);
+ if (!exp)
+ return -ENOENT;
I couldn't find this function, but in 2.6.12 expectations aren't refcounted anymore. If they are again by this patch, the refcnt would be leaked in the following lines:
+ skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!skb2)
+ return -ENOMEM;
++
++ /* Events were delivered: loopback mustn't notify events twice */ ++ IPCT_DELIVERED_BIT = 11, ++ IPCT_DELIVERED = (1 << IPCT_DELIVERED_BIT),
I couldn't find any users, probably since this can't work with a per-conntrack flag since events are generated by packets.
++ IPEXP_TIMEOUT_BIT = 1,
++ IPEXP_TIMEOUT = (1 << IPEXP_TIMEOUT_BIT),
++};
++
No user here either.
It would be great if you could send a patch without renaming the file, that makes reviewing the changes a lot easier. Renaming can then be done in a seperate patch that doesn't change anything.
Regards
Patrick
Quoted 10 lines · Patrick McHardy
Quoted 3 lines · Pablo Neira
This patchset introduces tons of updates for the nfnetlink, ctnetlink and the conntrack event API. I haven't attached the file since it's that big, about 100K.
Looks good. A couple more comments on the patch, most are probably not related to recent changes. I remember beeing responsible for at least some of this :)
Fine. BTW, thanks a lot for the feedback you both, appreciated :)
Quoted 11 lines
(quoted diff) +4
-0+struct cta_proto { + unsigned char num_proto; /* Protocol number IPPROTO_X */ + union ip_conntrack_proto proto; +};These should be changed not to use internal conntrack structures, it will hurt us when we want to change them. Instead it should replicate the fields interesting for the user. Also please use fixed-size types instead of unions etc. All structures including u64 types should be padded to multiples of 8 so they are equally sized on 32-bit and 64-bit systems.
OK, I'll kill those in the next digest, added to my TODO.
Quoted 9 lines
(quoted diff) +6
-0+#define CTA_HELP_MAXNAMESZ 31 + +struct cta_help { + char name[CTA_HELP_MAXNAMESZ]; /* name of conntrack helper */ + union ip_conntrack_help help; +};I suggest to use 32, the length in the kernel is not fixed AFAICS and it will be padded to 32 in netlink messages anyway.
OK added.
Quoted 10 lines
(quoted diff) +7
-0+/* ctnetlink multicast groups: reports any change of ctinfo, + * ctstatus, or protocol state change. + */ +#define NFGRP_IPV4_CT_TCP 0x01 +#define NFGRP_IPV4_CT_UDP 0x02 +#define NFGRP_IPV4_CT_ICMP 0x04 +#define NFGRP_IPV4_CT_OTHER 0x08I'm not sure how useful these groups are. I think groups for different event-types might be more useful to reduce the noise.
Yes, this looks fine. So we could kill those and use an event subscription.
Quoted 13 lines
(quoted diff) +3
-0+ h->name[CTA_HELP_MAXNAMESZ - 1] = '\0'; + if (strcmp(helper->name, h->name)) + return -EINVAL;We changed
ipt_helperto accept a null-byte string as wildcard string, probably a good idea to do the same here.(quoted diff) +3
-0+ ct = ip_conntrack_alloc(otuple, rtuple); + if (ct == NULL || IS_ERR(ct)) + return -ENOMEM;
Quoted 1 line
ip_conntrack_allocdoesn't returnERR_PTR()
It didn't use to, but now it does in the updated patch:
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/2.6.11-vs-2.6.12/02modifs.patch
Review
Quoted 11 lines
(quoted diff) +3
-0+ exp = ip_conntrack_expect_find_get(tuple); + if (!exp) + return -ENOENT;I couldn't find this function, but in 2.6.12 expectations aren't refcounted anymore. If they are again by this patch, the refcnt would be leaked in the following lines:
(quoted diff) +3
-0+ skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb2) + return -ENOMEM;
Thanks for catching up this, I'll fix it. I recovered the refcounting for expectations to avoid any possible race condition since I could be working with an expectation whose timeout has expired.
Quoted 7 lines
++
++ /* Events were delivered: loopback mustn't notify events twice */ ++ IPCT_DELIVERED_BIT = 11, ++ IPCT_DELIVERED = (1 << IPCT_DELIVERED_BIT),I couldn't find any users, probably since this can't work with a per-conntrack flag since events are generated by packets.
This must dissapear, I introduced this to fix a loopback event notification (was done twice). This is ugly, so I'll kill it and reset nfcache once the events has been delivered to avoid such event duplication.
Quoted 6 lines
++
IPEXP_TIMEOUT_BIT= 1,
++IPEXP_TIMEOUT= (1 <<IPEXP_TIMEOUT_BIT),
++};
++No user here either.
Right, not yet. I have problems to complete the expectation part of the conntrack event API since most events should be delivered holding ip_conntrack_lock and that's really ugly.
Quoted 3 lines
It would be great if you could send a patch without renaming the file, that makes reviewing the changes a lot easier. Renaming can then be done in a seperate patch that doesn't change anything.
Does this help? Hope so.
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/2.6.11-vs-2.6.12/04ctnetlink.patch
I'll send another patch that includes all your suggestion. Thanks.
--
Pablo
Quoted 10 lines · Pablo Neira
Quoted 8 lines · Patrick McHardy
(quoted diff) +7
-0+/* ctnetlink multicast groups: reports any change of ctinfo, + * ctstatus, or protocol state change. + */ +#define NFGRP_IPV4_CT_TCP 0x01 +#define NFGRP_IPV4_CT_UDP 0x02 +#define NFGRP_IPV4_CT_ICMP 0x04 +#define NFGRP_IPV4_CT_OTHER 0x08
Quoted 5 lines
Quoted 2 lines
I'm not sure how useful these groups are. I think groups for different event-types might be more useful to reduce the noise.
Yes, this looks fine. So we could kill those and use an event subscription.
Yes. The question is how to define the groups. One group per event seems wasteful, we probably need some sensible grouping. What events types are there currently?
Quoted 4 lines
Quoted 4 lines
I couldn't find this function, but in 2.6.12 expectations aren't refcounted anymore. If they are again by this patch, the refcnt would be leaked in the following lines:
Quoted 8 lines
Review
Quoted 3 lines
(quoted diff) +3
-0+ skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); + if (!skb2) + return -ENOMEM;Thanks for catching up this, I'll fix it. I recovered the refcounting for expectations to avoid any possible race condition since I could be working with an expectation whose timeout has expired.
Great. I wanted to restore it anyway for "permanent expectations" for the H.323 helper.
Quoted 2 lines
Does this help? Hope so.
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/2.6.11-vs-2.6.12/04ctnetlink.patch
I'll continue tomorrow, its getting late here ..
Regards
Patrick
Quoted 11 lines · Patrick McHardy
(quoted diff) +4
-0+struct cta_proto { + unsigned char num_proto; /* Protocol number IPPROTO_X */ + union ip_conntrack_proto proto; +};These should be changed not to use internal conntrack structures, it will hurt us when we want to change them. Instead it should replicate the fields interesting for the user. Also please use fixed-size types instead of unions etc. All structures including u64 types should be padded to multiples of 8 so they are equally sized on 32-bit and 64-bit systems.
agreed. However, we still don't have some kind of versioning in the protocol, too. I think we've learned by now that we need versioned structures ;)
Quoted 10 lines
(quoted diff) +7
-0+/* ctnetlink multicast groups: reports any change of ctinfo, + * ctstatus, or protocol state change. + */ +#define NFGRP_IPV4_CT_TCP 0x01 +#define NFGRP_IPV4_CT_UDP 0x02 +#define NFGRP_IPV4_CT_ICMP 0x04 +#define NFGRP_IPV4_CT_OTHER 0x08I'm not sure how useful these groups are. I think groups for different event-types might be more useful to reduce the noise.
that was my idea in the beginning (since I didn't think of events at that point).
Still, I think creating messages for any kind of event (even if noone listens) is too much overhead. netlink needs to be extended to deal with that issue.
Maybe the 'which socket is subscribed to which group' accounting should be done by the core netlink layer, which would then only export a merged bitmask of all netlink sockets. This way ctnetlink can easily check whether it makes sense to create a certain event message or not.
This should be useful for other netlink users, too.
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
Quoted 9 lines · Harald Welte
Quoted 6 lines · Patrick McHardy
These should be changed not to use internal conntrack structures, it will hurt us when we want to change them. Instead it should replicate the fields interesting for the user. Also please use fixed-size types instead of unions etc. All structures including u64 types should be padded to multiples of 8 so they are equally sized on 32-bit and 64-bit systems.
Quoted 3 lines
agreed. However, we still don't have some kind of versioning in the protocol, too. I think we've learned by now that we need versioned structures ;)
Netlink is easy to extend by adding new fields at the end if users only check for msgsize >= sizeof(struct). Do you think we should have versioning anyway?
Quoted 19 lines
Quoted 10 lines
(quoted diff) +7
-0+/* ctnetlink multicast groups: reports any change of ctinfo, + * ctstatus, or protocol state change. + */ +#define NFGRP_IPV4_CT_TCP 0x01 +#define NFGRP_IPV4_CT_UDP 0x02 +#define NFGRP_IPV4_CT_ICMP 0x04 +#define NFGRP_IPV4_CT_OTHER 0x08I'm not sure how useful these groups are. I think groups for different event-types might be more useful to reduce the noise.
that was my idea in the beginning (since I didn't think of events at that point).
Still, I think creating messages for any kind of event (even if noone listens) is too much overhead. netlink needs to be extended to deal with that issue.
Quoted 6 lines
Maybe the 'which socket is subscribed to which group' accounting should be done by the core netlink layer, which would then only export a merged bitmask of all netlink sockets. This way ctnetlink can easily check whether it makes sense to create a certain event message or not.
This should be useful for other netlink users, too.
Sounds like a good idea.
Regards
Patrick
Quoted 12 lines · Patrick McHardy
Quoted 10 lines · Harald Welte
Quoted 6 lines · Patrick McHardy
These should be changed not to use internal conntrack structures, it will hurt us when we want to change them. Instead it should replicate the fields interesting for the user. Also please use fixed-size types instead of unions etc. All structures including u64 types should be padded to multiples of 8 so they are equally sized on 32-bit and 64-bit systems.
Quoted 7 lines
Quoted 3 lines
agreed. However, we still don't have some kind of versioning in the protocol, too. I think we've learned by now that we need versioned structures ;)
Netlink is easy to extend by adding new fields at the end if users only check for msgsize >= sizeof(struct). Do you think we should have versioning anyway?
I think that we could split the structure into fine grain fields. For example, CTA_TUPLE_ORIG would composed of:
CTA_ORIG_IPV4_SRCCTA_ORIG_IPV4_DSTCTA_L4_PROTONUMCTA_PROTO_IPV4_SRCCTA_PROTO_IPV4_DSTCTA_DIR
So, instead of sending a packet that contains a reference to an ip_conntrack_tuple (CTA_TUPLE_ORIG), we'll have a set of fields (CTA_ORIG_IPV4_SRC + CTA_ORIG_IPV4_DST + ...) that compose such structure.
But I'll need a function to glue all the fields to create a ip_conntrack_tuple. Maybe too bloated?
Quoted 19 lines
Quoted 19 lines
Quoted 10 lines
(quoted diff) +7
-0+/* ctnetlink multicast groups: reports any change of ctinfo, + * ctstatus, or protocol state change. + */ +#define NFGRP_IPV4_CT_TCP 0x01 +#define NFGRP_IPV4_CT_UDP 0x02 +#define NFGRP_IPV4_CT_ICMP 0x04 +#define NFGRP_IPV4_CT_OTHER 0x08I'm not sure how useful these groups are. I think groups for different event-types might be more useful to reduce the noise.
that was my idea in the beginning (since I didn't think of events at that point).
Still, I think creating messages for any kind of event (even if noone listens) is too much overhead. netlink needs to be extended to deal with that issue.
Quoted 6 lines
Quoted 6 lines
Maybe the 'which socket is subscribed to which group' accounting should be done by the core netlink layer, which would then only export a merged bitmask of all netlink sockets. This way ctnetlink can easily check whether it makes sense to create a certain event message or not.
This should be useful for other netlink users, too.
Isn't netlink broadcast subscription enough? netlink_broadcast doesn't enqueue packets for a socket that isn't subscribed to a group, so the process never gets useless packets.
So I think that we can group event, say:
level 1 (weak):
- IPCT_NEW
- IPCT_DESTROY
level 2 (normal):
- IPCT_NEW
- IPCT_UPDATE
- IPCT_STATUS
- ...
- IPCT_DESTROY
At reserve some groups to let the user define some level whenever he wants. Although such level would be unique.
OTOH, there are 10 events currently, why is that bad creating a group per event?
--
Pablo
Quoted 10 lines · Pablo Neira
I think that we could split the structure into fine grain fields. For example,
CTA_TUPLE_ORIGwould composed of:
CTA_ORIG_IPV4_SRCCTA_ORIG_IPV4_DSTCTA_L4_PROTONUMCTA_PROTO_IPV4_SRCCTA_PROTO_IPV4_DSTCTA_DIR
Quoted 6 lines
So, instead of sending a packet that contains a reference to an
ip_conntrack_tuple(CTA_TUPLE_ORIG), we'll have a set of fields (CTA_ORIG_IPV4_SRC+CTA_ORIG_IPV4_DST+ ...) that compose such structure.But I'll need a function to glue all the fields to create a
ip_conntrack_tuple. Maybe too bloated?
I think its fine, but CTA_PROTO_IPV4_{SRC,DST} should be CTA_PROTO_{SRC,DST}, there's nothing related to IPv4 in them. Please nest all attributes related to a tuple in CTA_TUPLE instead of adding them to the top-level.
Quoted 9 lines
Quoted 9 lines
Quoted 9 lines
Still, I think creating messages for any kind of event (even if noone listens) is too much overhead. netlink needs to be extended to deal with that issue.
Maybe the 'which socket is subscribed to which group' accounting should be done by the core netlink layer, which would then only export a merged bitmask of all netlink sockets. This way ctnetlink can easily check whether it makes sense to create a certain event message or not.
Quoted 6 lines
Quoted 1 line
Quoted 1 line
This should be useful for other netlink users, too.
Isn't netlink broadcast subscription enough?
netlink_broadcastdoesn't enqueue packets for a socket that isn't subscribed to a group, so the process never gets useless packets.
But we still spent time building them, just to have them thrown away.
Quoted 13 lines
So I think that we can group event, say:
level 1 (weak):
-IPCT_NEW
-IPCT_DESTROYlevel 2 (normal):
-IPCT_NEW
-IPCT_UPDATE
-IPCT_STATUS
- ...
-IPCT_DESTROY
Quoted 5 lines
At reserve some groups to let the user define some level whenever he wants. Although such level would be unique.
OTOH, there are 10 events currently, why is that bad creating a group per event?
I don't think its bad, but I fear hitting the 32 group limit some day. Probably that fear is unfounded and we're never going to reach 32 different types of events. Harald, what do you think?
Regards
Patrick
Quoted 16 lines · Patrick McHardy
Quoted 16 lines
So I think that we can group event, say:
level 1 (weak):
-IPCT_NEW
-IPCT_DESTROYlevel 2 (normal):
-IPCT_NEW
-IPCT_UPDATE
-IPCT_STATUS
- ...
-IPCT_DESTROYAt reserve some groups to let the user define some level whenever he wants. Although such level would be unique.
Quoted 6 lines
Quoted 2 lines
OTOH, there are 10 events currently, why is that bad creating a group per event?
I don't think its bad, but I fear hitting the 32 group limit some day. Probably that fear is unfounded and we're never going to reach 32 different types of events. Harald, what do you think?
I think it's not all that much of a problem. I doubt that conntrack will get 22 more events anytime soon. The other problem is, don't we overlap with other nfnetlink-based groups?
nfnetlink acts as a a multiplex between netlink and the higher layers, so I guess we only have 32groups for nfnetlink as a whole... and there is other stuff like ip_queue and ULOG that is to be ported on top of nfnetlink...
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
Quoted 26 lines · Harald Welte
Quoted 16 lines · Patrick McHardy
Quoted 16 lines
So I think that we can group event, say:
level 1 (weak):
-IPCT_NEW
-IPCT_DESTROYlevel 2 (normal):
-IPCT_NEW
-IPCT_UPDATE
-IPCT_STATUS
- ...
-IPCT_DESTROYAt reserve some groups to let the user define some level whenever he wants. Although such level would be unique.
Quoted 6 lines
Quoted 2 lines
OTOH, there are 10 events currently, why is that bad creating a group per event?
I don't think its bad, but I fear hitting the 32 group limit some day. Probably that fear is unfounded and we're never going to reach 32 different types of events. Harald, what do you think?
Quoted 8 lines
I think it's not all that much of a problem. I doubt that conntrack will get 22 more events anytime soon. The other problem is, don't we overlap with other nfnetlink-based groups?
nfnetlink acts as a a multiplex between netlink and the higher layers, so I guess we only have 32groups for nfnetlink as a whole... and there is other stuff like
ip_queueand ULOG that is to be ported on top of nfnetlink...
You're right, we can't do that. In short:
nfnetlink currently relies on the fact that is the user program that decides if a packet was sent to it or not. In case that it wasn't, the program drops it.
Say we've got ip_queue and ip_conntrack_netlink on top of nfnetlink: ip_queue sends a packet to user space and ip_conntrack_netlink sends event notifications. If both the ipqueue userspace program and libctnetlink are subscribed to the same group, they both will receive spam from each other.
To avoid this spamming situation, every subsystem could reserve just one group and user programs must get subscribed to the corresponding group that is interested in. In conclusion, nfnetlink would support up to 32 subsystems but user space programs won't get spam from other subsystem.
So, back to ip_conntrack_netlink, we still have the performance issue with regards to the events. Userspace programs will decide if the event received is interesting for them or not.
a) We could extend netlink code with some kind of ioctl that sets a mask to say what kind of events are interesting for a given userspace program.
b) The fact that we can send events and nobody's listening to them is more difficult to catch up. Maybe a function that checks if there are listeners available before sending an event could help: In that case such function would be kind of racy because we can lose some messages while a userspace program is binding to a given netlink socket. This isn't that annoying, I prefer losing a couple of messages than hurting performance generating messages that won't be ever delivered.
--
Pablo
Quoted 11 lines · Pablo Neira
Quoted 8 lines · Harald Welte
I think it's not all that much of a problem. I doubt that conntrack will get 22 more events anytime soon. The other problem is, don't we overlap with other nfnetlink-based groups?
nfnetlink acts as a a multiplex between netlink and the higher layers, so I guess we only have 32groups for nfnetlink as a whole... and there is other stuff like
ip_queueand ULOG that is to be ported on top of nfnetlink...
Quoted 5 lines
You're right, we can't do that. In short:
nfnetlink currently relies on the fact that is the user program that decides if a packet was sent to it or not. In case that it wasn't, the program drops it.
That's not true, A programm can do pure unicast communication with the kernel, but can also subscribe to the multicast-groups it is interested in. Events are sent to multicast groups and, if they happend in response to a request, to the unicast address. Same for dumps.
Quoted 5 lines
Say we've got
ip_queueandip_conntrack_netlinkon top of nfnetlink:ip_queuesends a packet to user space andip_conntrack_netlinksends event notifications. If both the ipqueue userspace program and libctnetlink are subscribed to the same group, they both will receive spam from each other.
Sure, they both need different groups.
Quoted 4 lines
To avoid this spamming situation, every subsystem could reserve just one group and user programs must get subscribed to the corresponding group that is interested in. In conclusion, nfnetlink would support up to 32 subsystems but user space programs won't get spam from other subsystem.
That's how it should be done. Conntrack is an exceptional case in that it is the only part in the kernel I know of that generates asynchronous netlink messages at high speed, so I think reserving multiple groups is the right way.
Quoted 6 lines
So, back to
ip_conntrack_netlink, we still have the performance issue with regards to the events. Userspace programs will decide if the event received is interesting for them or not.a) We could extend netlink code with some kind of ioctl that sets a mask to say what kind of events are interesting for a given userspace program.
Please no ioctls. Groups are fine, if one group per event is too much we need to group them somehow. Maybe:
1) creation/destruction
2) status changes
3) timeout
4) protoinfo
5) helper
6) nat
7) expectations
Quoted 7 lines
b) The fact that we can send events and nobody's listening to them is more difficult to catch up. Maybe a function that checks if there are listeners available before sending an event could help: In that case such function would be kind of racy because we can lose some messages while a userspace program is binding to a given netlink socket. This isn't that annoying, I prefer losing a couple of messages than hurting performance generating messages that won't be ever delivered.
That race shouldn't be a problem. Userspace can't know when exactly it will start receiving events anyway.
Regards
Patrick
Quoted 11 lines · Patrick McHardy
Quoted 4 lines · Pablo Neira
To avoid this spamming situation, every subsystem could reserve just one group and user programs must get subscribed to the corresponding group that is interested in. In conclusion, nfnetlink would support up to 32 subsystems but user space programs won't get spam from other subsystem.
That's how it should be done. Conntrack is an exceptional case in that it is the only part in the kernel I know of that generates asynchronous netlink messages at high speed, so I think reserving multiple groups is the right way.
OK, I'm fine with the solution based on groups. Then I'll go that way.
Quoted 29 lines
Quoted 6 lines
So, back to
ip_conntrack_netlink, we still have the performance issue with regards to the events. Userspace programs will decide if the event received is interesting for them or not.a) We could extend netlink code with some kind of ioctl that sets a mask to say what kind of events are interesting for a given userspace program.
Please no ioctls. Groups are fine, if one group per event is too much we need to group them somehow. Maybe:
1) creation/destruction
2) status changes
3) timeout
4) protoinfo
5) helper
6) nat
7) expectationsQuoted 7 lines
b) The fact that we can send events and nobody's listening to them is more difficult to catch up. Maybe a function that checks if there are listeners available before sending an event could help: In that case such function would be kind of racy because we can lose some messages while a userspace program is binding to a given netlink socket. This isn't that annoying, I prefer losing a couple of messages than hurting performance generating messages that won't be ever delivered.
Quoted 2 lines
That race shouldn't be a problem. Userspace can't know when exactly it will start receiving events anyway.
So, should be a netlink function to check if there are currently listeners worth it?
--
Pablo
Quoted 2 lines · Pablo Neira
So, should be a netlink function to check if there are currently listeners worth it?
That sounds fine. Messages should then only be built if there is a listener for this group or if it is a reply to a unicast request. BTW, I noticed nfnetlink_send is always called with pid = 0 and echo = 0. This needs to be fixed, whenever anything happens in response to a request the correct pid and echo = 1 need to be used.
Regards
Patrick
Quoted 16 lines · Patrick McHardy
Quoted 14 lines · Pablo Neira
I think that we could split the structure into fine grain fields. For example,
CTA_TUPLE_ORIGwould composed of:
CTA_ORIG_IPV4_SRCCTA_ORIG_IPV4_DSTCTA_L4_PROTONUMCTA_PROTO_IPV4_SRCCTA_PROTO_IPV4_DSTCTA_DIRSo, instead of sending a packet that contains a reference to an
ip_conntrack_tuple(CTA_TUPLE_ORIG), we'll have a set of fields (CTA_ORIG_IPV4_SRC+CTA_ORIG_IPV4_DST+ ...) that compose such structure.
Quoted 6 lines
Quoted 2 lines
But I'll need a function to glue all the fields to create a
ip_conntrack_tuple. Maybe too bloated?I think its fine, but CTA_PROTO_IPV4_{SRC,DST} should be CTA_PROTO_{SRC,DST}, there's nothing related to IPv4 in them.
That could be fine for nf_conntrack to differenciate between conntracks that represents an ipv4 and ipv6 connections.
CTA_PROTO_IPV4_SRC and CTA_PROTO_IPV6_SRC
Quoted 2 lines
Please nest all attributes related to a tuple in
CTA_TUPLEinstead of adding them to the top-level.
Sorry, how that will look like?
--
Pablo
Quoted 10 lines · Pablo Neira
Quoted 3 lines · Patrick McHardy
I think its fine, but CTA_PROTO_IPV4_{SRC,DST} should be CTA_PROTO_{SRC,DST}, there's nothing related to IPv4 in them.
That could be fine for
nf_conntrackto differenciate between conntracks that represents an ipv4 and ipv6 connections.
CTA_PROTO_IPV4_SRCandCTA_PROTO_IPV6_SRC
It can do that by looking at the IP attributes (CTA_ORIG_IPV4_SRC and CTA_IPV6_SRC).
Quoted 4 lines
Quoted 2 lines
Please nest all attributes related to a tuple in
CTA_TUPLEinstead of adding them to the top-level.Sorry, how that will look like?
You add a new nfattr header with the type set to CTA_TUPLE and note the position of skb->tail. Then you add the nested attributes as usual. When you're done you set the length of the nfattr header to skb->tail - old_tail. The RTA_NEST/RTA_NEST_END macros handle this for rtnetlink (include/linux/rtnetlink.h).
Regards
Patrick
* Patrick McHardy <[email protected]> 2005-06-30 03:00
Quoted 5 lines
You add a new nfattr header with the type set to
CTA_TUPLEand note the position ofskb->tail. Then you add the nested attributes as usual. When you're done you set the length of the nfattr header toskb->tail-old_tail. The RTA_NEST/RTA_NEST_END macros handle this for rtnetlink (include/linux/rtnetlink.h).
At some point we should introduce a "generic" attribute architecture for all netlink families. The connector stuff will need it as well, so maybe the time has come to actually do it.
Quoted 9 lines · Thomas Graf
* Patrick McHardy <[email protected]> 2005-06-30 03:00
Quoted 5 lines
You add a new nfattr header with the type set to
CTA_TUPLEand note the position ofskb->tail. Then you add the nested attributes as usual. When you're done you set the length of the nfattr header toskb->tail-old_tail. The RTA_NEST/RTA_NEST_END macros handle this for rtnetlink (include/linux/rtnetlink.h).
Quoted 4 lines
At some point we should introduce a "generic" attribute architecture for all netlink families. The connector stuff will need it as well, so maybe the time has come to actually do it.
I agree, most of the macros are just copied without modification anyway. One more thing I would like to change is the excessive use of RTA_PUT with structures on the stack. Using __RTA_PUT and putting together these structures in-place would be much nicer. nfnetlink has copied this part of rtnetlink.
Regards
Patrick
* Patrick McHardy <[email protected]> 2005-06-30 03:53
Quoted 11 lines
Quoted 4 lines · Thomas Graf
At some point we should introduce a "generic" attribute architecture for all netlink families. The connector stuff will need it as well, so maybe the time has come to actually do it.
I agree, most of the macros are just copied without modification anyway. One more thing I would like to change is the excessive use of
RTA_PUTwith structures on the stack. Using__RTA_PUTand putting together these structures in-place would be much nicer. nfnetlink has copied this part of rtnetlink.
Good point, after all, I think structs have been used too often and we now suffer from backwards compatbility issues. The points likely to be argueable are things like trim responsibility in the error handling, i.e. delegate it down to the function which also created the header or trim on every level. Other than that the whole thing should be pretty straight forward.
What do you think about naming it nlattr?
Quoted 6 lines · Thomas Graf
Good point, after all, I think structs have been used too often and we now suffer from backwards compatbility issues. The points likely to be argueable are things like trim responsibility in the error handling, i.e. delegate it down to the function which also created the header or trim on every level. Other than that the whole thing should be pretty straight forward.
I think for nested attributes error handling should happen on the outer level. Just trimming on the inner level would leave a half-finished nested attribute.
Quoted 1 line
What do you think about naming it nlattr?
Sounds good.
Regards
Patrick
* Patrick McHardy <[email protected]> 2005-06-30 15:27
Quoted 11 lines
Quoted 6 lines · Thomas Graf
Good point, after all, I think structs have been used too often and we now suffer from backwards compatbility issues. The points likely to be argueable are things like trim responsibility in the error handling, i.e. delegate it down to the function which also created the header or trim on every level. Other than that the whole thing should be pretty straight forward.
I think for nested attributes error handling should happen on the outer level. Just trimming on the inner level would leave a half-finished nested attribute.
I can agree with this, the question that remains is: do we want to trim in functions where no nesting is done at all? i.e. things like the generic network statistics dumping interface.
Quoted 9 lines · Thomas Graf
* Patrick McHardy <[email protected]> 2005-06-30 15:27
Quoted 3 lines
I think for nested attributes error handling should happen on the outer level. Just trimming on the inner level would leave a half-finished nested attribute.
I can agree with this, the question that remains is: do we want to trim in functions where no nesting is done at all? i.e. things like the generic network statistics dumping interface.
Trimming isn't required in this case since the length is know and checked in advance. An error should still be propagated back of course so potential outer levels can do trimming.
Regards
Patrick
* Patrick McHardy <[email protected]> 2005-06-30 23:26
Quoted 7 lines
Quoted 6 lines · Thomas Graf
* Patrick McHardy <[email protected]> 2005-06-30 15:27
Quoted 3 lines
I think for nested attributes error handling should happen on the outer level. Just trimming on the inner level would leave a half-finished nested attribute.
Quoted 7 lines
Quoted 3 lines
I can agree with this, the question that remains is: do we want to trim in functions where no nesting is done at all? i.e. things like the generic network statistics dumping interface.
Trimming isn't required in this case since the length is know and checked in advance. An error should still be propagated back of course so potential outer levels can do trimming.
This is only true if one attribute is added. What I really meant is something like em_text_dump() in em_text.c. Assuming we rework areas like this one in order to avoid structs on the stack, we'll have a lot of such cases where we might hit the limit while not really knowing about the start of the nested tlv.
Anyways, I think this is a minor issue and we can safely ignore it and delegate the trimming responsibility to the underlying layer which "started" the nested tlv.
The gnet_stats interface was a bad example since it doesn't have such a case.
David S. Miller
maintainerFrom: Thomas Graf <[email protected]>
Date: Thu, 30 Jun 2005 23:34:59 +0200
Quoted 2 lines
This is only true if one attribute is added. What I really meant is something like
em_text_dump()inem_text.c.
Speaking of em_text.c, when one loads ematch rules into that module it does a printk(). I assume that's a thinko and should be removed?
* David S. Miller <[email protected]> 2005-06-30 14:49
Quoted 9 lines
From: Thomas Graf <[email protected]>
Date: Thu, 30 Jun 2005 23:34:59 +0200Quoted 2 lines
This is only true if one attribute is added. What I really meant is something like
em_text_dump()inem_text.c.Speaking of
em_text.c, when one loads ematch rules into that module it does aprintk(). I assume that's a thinko and should be removed?
Yes, it's a debugging leftover but I'll keep it in until rc3 so if problems appear I have some debugging information. Given that is acceptable.
David S. Miller
maintainerFrom: Thomas Graf <[email protected]>
Date: Fri, 1 Jul 2005 00:08:14 +0200
Quoted 2 lines
Yes, it's a debugging leftover but I'll keep it in until rc3 so if problems appear I have some debugging information. Given that is acceptable.
No problem.
ctnetlink attributes [was: Re: [PATCH 1/2] updates for [nf|ct]netlink and event API]
In reply to Patrick McHardyHi,
Here below a candidate of attributes for ctnetlink. As you could see some attributes are still missing, for example, those to modify internal helper structures like ip_ct_ftp... but that would be easy to add later.
enum ctattr_type {
CTA_UNSPEC,
CTA_TUPLE,
CTA_STATUS,
CTA_PROTOINFO,
CTA_HELP,
CTA_NAT,
CTA_TIMEOUT,
CTA_MARK,
CTA_COUNTERS,
CTA_EXPECT,
__CTA_MAX
};enum ctattr_tuple {
CTA_TUPLE_DIR,
CTA_TUPLE_IP,
CTA_TUPLE_PROTO,
__CTA_TUPLE_MAX
};enum ctattr_ip {
CTA_IP_V4_SRC,
CTA_IP_V4_DST,
CTA_IP_V6_SRC,
CTA_IP_V6_DST,
__CTA_IP_MAX
};enum ctattr_l4proto {
CTA_PROTO_NUM,
CTA_PROTO_TCP_SRC,
CTA_PROTO_TCP_DST,
CTA_PROTO_UDP_SRC,
CTA_PROTO_UDP_DST,
CTA_PROTO_ICMP_TYPE,
CTA_PROTO_ICMP_CODE,
CTA_PROTO_SCTP_CODE,
__CTA_PROTO_MAX
};enum ctattr_protoinfo {
CTA_PROTOINFO_TCP,
__CTA_PROTOINFO_MAX
};
enum ctattr_protoinfo_tcp {
CTA_TCP_STATE,
__CTA_TCP_MAX
};enum ctattr_counters {
CTA_COUNTERS_PACKETS,
CTA_COUNTERS_BYTES,
__CTA_COUNTERS_MAX
};
enum ctattr_nat {
CTA_NAT_MINIP,
CTA_NAT_MAXIP,
CTA_NAT_PROTO,
__CTA_NAT_MAX
};enum ctattr_protonat {
CTA_PROTONAT_MINIP,
CTA_PROTONAT_MAXIP,
CTA_PROTONAT_TCP,
CTA_PROTONAT_UDP,
__CTA_PROTONAT_MAX
};
enum ctattr_expect {
CTA_EXPECT_TUPLE,
CTA_EXPECT_MASK,
CTA_EXPECT_TIMEOUT,
__CTA_EXPECT_MAX
};
enum ctattr_help {
CTA_HELP_NAME,
__CTA_HELP_MAX
};Comments welcome.
--
Pablo
Re: ctnetlink attributes [was: Re: [PATCH 1/2] updates for [nf|ct]netlink and event API]
I'm interested in adding MAC addr attributes and CTA_TUPLE_MAC; not just because of my fixation with MAC addresses but also to use conntrack to record flow data for non IP-related protocols.
I realise it is not the current intent of conntrack to do this, but as much as conntrack solves the high-load problems of ulog, it is desirable for it to keep counters for non-ip protocols.
As fast as protocol handlers can be devised it will become "conntrack" again instead of "flowtrack", but the universal identifier between hosts involved in a connection is the mac address and protocol. The IP addresses and direction and and even port numbers etc can only be resolved by some higher level protocol hanlders.
The question is, how do others feel about conntrack tracking non-ip connections? I intend to provide patches to do this if it is welcome.
Amin
Quoted 96 lines · Pablo Neira
Hi,
Here below a candidate of attributes for ctnetlink. As you could see some attributes are still missing, for example, those to modify internal helper structures like
ip_ct_ftp... but that would be easy to add later.enum ctattr_type { CTA_UNSPEC, CTA_TUPLE, CTA_STATUS, CTA_PROTOINFO, CTA_HELP, CTA_NAT, CTA_TIMEOUT, CTA_MARK, CTA_COUNTERS, CTA_EXPECT, __CTA_MAX };enum ctattr_tuple { CTA_TUPLE_DIR, CTA_TUPLE_IP, CTA_TUPLE_PROTO, __CTA_TUPLE_MAX };enum ctattr_ip { CTA_IP_V4_SRC, CTA_IP_V4_DST, CTA_IP_V6_SRC, CTA_IP_V6_DST, __CTA_IP_MAX };enum ctattr_l4proto { CTA_PROTO_NUM, CTA_PROTO_TCP_SRC, CTA_PROTO_TCP_DST, CTA_PROTO_UDP_SRC, CTA_PROTO_UDP_DST, CTA_PROTO_ICMP_TYPE, CTA_PROTO_ICMP_CODE, CTA_PROTO_SCTP_CODE, __CTA_PROTO_MAX };enum
ctattr_protoinfo{
CTA_PROTOINFO_TCP,
__CTA_PROTOINFO_MAX
};enum ctattr_protoinfo_tcp { CTA_TCP_STATE, __CTA_TCP_MAX };enum
ctattr_counters{
CTA_COUNTERS_PACKETS,
CTA_COUNTERS_BYTES,
__CTA_COUNTERS_MAX
};enum ctattr_nat { CTA_NAT_MINIP, CTA_NAT_MAXIP, CTA_NAT_PROTO, __CTA_NAT_MAX };enum
ctattr_protonat{
CTA_PROTONAT_MINIP,
CTA_PROTONAT_MAXIP,
CTA_PROTONAT_TCP,
CTA_PROTONAT_UDP,
__CTA_PROTONAT_MAX
};enum
ctattr_expect{
CTA_EXPECT_TUPLE,
CTA_EXPECT_MASK,
CTA_EXPECT_TIMEOUT,
__CTA_EXPECT_MAX
};enum ctattr_help { CTA_HELP_NAME, __CTA_HELP_MAX };Comments welcome.
Signature · 1 line
Pablo
Re: ctnetlink attributes [was: Re: [PATCH 1/2] updates for [nf|ct]netlink and event API]
Quoted 3 lines
I'm interested in adding MAC addr attributes and
CTA_TUPLE_MAC; not just because of my fixation with MAC addresses but also to use conntrack to record flow data for non IP-related protocols.
Can't this be done with ebtables?
On another note, how about bringing ebt and ipt closer together, maybe merge them?
Jan Engelhardt
Re: ctnetlink attributes [was: Re: [PATCH 1/2] updates for [nf|ct]netlink and event API]
Quoted 8 lines · Jan Engelhardt
Quoted 3 lines
I'm interested in adding MAC addr attributes and
CTA_TUPLE_MAC; not just because of my fixation with MAC addresses but also to use conntrack to record flow data for non IP-related protocols.Can't this be done with ebtables?
On another note, how about bringing ebt and ipt closer together, maybe merge them?
yes, the good old pkttables idea. Unfortunately the ever growing number of gpl infringing companies keeps me from tackling this rater large project :(
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
Re: ctnetlink attributes [was: Re: [PATCH 1/2] updates for [nf|ct]netlink and event API]
Quoted 7 lines
Quoted 3 lines
On another note, how about bringing ebt and ipt closer together, maybe merge them?
yes, the good old pkttables idea. Unfortunately the ever growing number of gpl infringing companies keeps me from tackling this rater large project :(
Where is the (legal) problem?
Jan Engelhardt
Signature · 1 line
| Alphagate Systems, http://alphagate.hopto.org/
Re: ctnetlink attributes [was: Re: [PATCH 1/2] updates for [nf|ct]netlink and event API]
Quoted 9 lines · Jan Engelhardt
Quoted 7 lines
Quoted 3 lines
On another note, how about bringing ebt and ipt closer together, maybe merge them?
yes, the good old pkttables idea. Unfortunately the ever growing number of gpl infringing companies keeps me from tackling this rater large project :(
Where is the (legal) problem?
I'm not talking about legal problems. I'm just talking about the ever-growing percentage of my daily working time that is consumed with handling those cases. My initial hope was that a number of high-profile cases would cause enough publicity to reduce the amount of GPL violations we're seeing. At the moment I'd say rather is the opposite way. I hope we'll reach break-even at some point...
Please follow-up to private mail, if there is the need to. This is off-topic on netfilter-devel, and I merely mentioned it as an excuse for my lack of time.
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
Re: ctnetlink attributes [was: Re: [PATCH 1/2] updates for [nf|ct]netlink and event API]
In reply to Amin AzezQuoted 3 lines · Amin Azez
I'm interested in adding MAC addr attributes and
CTA_TUPLE_MAC; not just because of my fixation with MAC addresses but also to use conntrack to record flow data for non IP-related protocols.
ctnetlink MAC attributes are IMHO nonsense because there is no mac address tracking in conntrack.
Quoted 3 lines
I realise it is not the current intent of conntrack to do this, but as much as conntrack solves the high-load problems of ulog, it is desirable for it to keep counters for non-ip protocols.
Also, MAC address tracking doesn't really make sense since as an intermediate router there is no way that the assumption "source and destination mac never change" is ever valid.
Quoted 3 lines
As fast as protocol handlers can be devised it will become "conntrack" again instead of "flowtrack", but the universal identifier between hosts involved in a connection is the mac address and protocol.
no. you always only see the next hop mac address. let's say you have an upsteram and a downstream router, then all your 'connections' would be between the same two mac addresses.
Quoted 2 lines
The question is, how do others feel about conntrack tracking non-ip connections? I intend to provide patches to do this if it is welcome.
nf_conntrack goes the way to layer-3-independent connection tracking. However, conntrack will remain to happen at layer3 and 4 (with minor exceptions to higher layers in the case of conntrack helpers).
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
Re: ctnetlink attributes [was: Re: [PATCH 1/2] updates for [nf|ct]netlink and event API]
Quoted 4 lines
nf_conntrackgoes the way to layer-3-independent connection tracking. However, conntrack will remain to happen at layer3 and 4 (with minor exceptions to higher layers in the case of conntrack helpers).
Minor? Hehe that's good :p Reminds me of l7-filter.sf.net (It's not even a helper as in ip_conntrack_irc, but a match module)
Jan Engelhardt
Re: ctnetlink attributes [was: Re: [PATCH 1/2] updates for [nf|ct]netlink and event API]
Quoted 7 lines · Jan Engelhardt
Quoted 4 lines
nf_conntrackgoes the way to layer-3-independent connection tracking. However, conntrack will remain to happen at layer3 and 4 (with minor exceptions to higher layers in the case of conntrack helpers).Minor? Hehe that's good :p Reminds me of l7-filter.sf.net (It's not even a helper as in
ip_conntrack_irc, but a match module)
exactly, it's an iptables match module and therefore not related to nf_conntrack or ip_conntrack. And there is a reason I don't like the idea of pushing it into mainline...
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
Re: ctnetlink attributes [was: Re: [PATCH 1/2] updates for [nf|ct]netlink and event API]
In reply to Harald WelteQuoted 13 lines · Harald Welte
Quoted 5 lines · Amin Azez
I'm interested in adding MAC addr attributes and
CTA_TUPLE_MAC; not just because of my fixation with MAC addresses but also to use conntrack to record flow data for non IP-related protocols.ctnetlink MAC attributes are IMHO nonsense because there is no mac address tracking in conntrack.
Indeed; I was proposing that it be so, I'm currently maintaining conntrack patches where mac addresses are part of the conntrack.
Quoted 11 lines
Quoted 5 lines
I realise it is not the current intent of conntrack to do this, but as much as conntrack solves the high-load problems of ulog, it is desirable for it to keep counters for non-ip protocols.
Also, MAC address tracking doesn't really make sense since as an intermediate router there is no way that the assumption "source and destination mac never change" is ever valid.
This is also true, there are few circumstances that the mac address could change within the life of a connection and maintain the connection, and it is uncertain in the scenario I proposed how this should be handled.
Quoted 11 lines
Quoted 5 lines
As fast as protocol handlers can be devised it will become "conntrack" again instead of "flowtrack", but the universal identifier between hosts involved in a connection is the mac address and protocol.
no. you always only see the next hop mac address. let's say you have an upsteram and a downstream router, then all your 'connections' would be between the same two mac addresses.
The use would be limited to switched or transparently bridged networks which is where most non-ip trafffic will be kept. I don't think this particularly limits the use; many protocols do not employ a global address space anyway.
SPX protocol uses the MAC address in conjunction with a network number for node addressing.
Quoted 10 lines
Quoted 4 lines
The question is, how do others feel about conntrack tracking non-ip connections? I intend to provide patches to do this if it is welcome.
nf_conntrackgoes the way to layer-3-independent connection tracking. However, conntrack will remain to happen at layer3 and 4 (with minor exceptions to higher layers in the case of conntrack helpers).
So you are not against tracking non-IP traffic as such?
I agree that it is ideal to break open the layer 3 addressing for use in the conntrack tuple, I was suggesting using mac address and protocol as a fallback when this was not available.
Amin
Quoted 6 lines · Pablo Neira
o conntrack event API
-
IPCT_DELIVEREDbit. Loopback reports event are reported twice, this bit is set once event are delivered. I just came up with a better idea, reset nfcache once the events have been delivered, but I'll apply this change in the next patchset.
Hi Pablo,
I noticed this with my flow module, any interface connecting to itself would create two IPCT_NEW events. I had made my own patch to your linux-2.6.11.conntrack-event-api.patch to call ip_conntrack_event_cache_init() after the events were delivered. I was gonna send it your way but other things came up and there were other problems that I was trying to figure out that were not quite working the way I thought they should. I investigated further and think I've found the problem, but I'm not sure how to move further on it, so now it's time to ask the list:
Can anyone explain why in ip_conntrack_proto_icmp.c
we delete the conntrack of an ICMP packet as soon as all replies are seen instead of letting ip_conntrack_icmp_timeout take the conntrack like other protocol types? As far as I can see, this breaks the conntrack event API because I get the following sequence of notifications for an ICMP echo request to the host (this is with the ip_conntrack_event_cache_init() patch after notifications have been delivered so I don't get two IPCT_NEW events):
IPCT_NEWIPCT_DESTROYIPCT_STATUS
I think nfct->use is still held and the conntrack is never really destroyed after death_by_timeout(), so later when the reply comes the conntrack still exists in the hash and the conntrack API fires a IPCT_STATUS event after the IPCT_DESTROY event was fired, which I'm assuming is an invalid sequence of events. ;)
So, what would be the harm in the following patch to ip_conntrack_proto_icmp.c?
ip_conntrack_proto_icmp.c 2005-06-28 16:52:46.000000000 -0500 renamed from ip_conntrack_proto_icmp.c 2005-06-28 16:52:18.000000000 -0500 +1 -9
@@ -92,15 +92,7 @@ const struct sk_buff *skb, enum ip_conntrack_info ctinfo) { - /* Try to delete connection immediately after all replies: - won't actually vanish as we still have skb, and del_timer - means this will only run once even if count hits zero twice - (theoretically possible with SMP) */ - if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { - if (atomic_dec_and_test(&ct->proto.icmp.count) - && del_timer(&ct->timeout)) - ct->timeout.function((unsigned long)ct); - } else { + if (CTINFO2DIR(ctinfo) != IP_CT_DIR_REPLY) { atomic_inc(&ct->proto.icmp.count); ip_ct_refresh_acct(ct, ctinfo, skb, ip_ct_icmp_timeout); }
Otherwise you'll need to move the IPCT_DESTROY event out of death_by_timeout() and into destroy_conntrack(). I like the former option because then ICMP can actually be utilized in the flow module. The only reservations I have with it lie in the other ip_conntrack_proto_* files that may have del_timer() followed by death_by_timeout(), this may create other gotchas in the connection event API sequence, I'm not sure. Perhaps both changes could be made? :)
Cheers,
-Josh
Hi Josh,
Quoted 5 lines · Josh Samuelson
Quoted 1 line · Pablo Neira
o conntrack event API
Quoted 7 lines
Quoted 2 lines
-
IPCT_DELIVEREDbit. Loopback reports event are reported twice, this
bit is set once event are delivered. I just came up with a better idea, reset nfcache once the events have been delivered, but I'll apply this change in the next patchset.I noticed this with my flow module, any interface connecting to itself would create two
IPCT_NEWevents. I had made my own patch to your linux-2.6.11.conntrack-event-api.patch to callip_conntrack_event_cache_init()after the events were delivered.
Indeed, this is what I planned to fix this problem ;). Just killed the IPCT_DELIVERED bit, it will be included in next version of the ctevent-api. I'll post it soon.
Quoted 19 lines
I was gonna send it your way but other things came up and there were other problems that I was trying to figure out that were not quite working the way I thought they should. I investigated further and think I've found the problem, but I'm not sure how to move further on it, so now it's time to ask the list:
Can anyone explain why in
ip_conntrack_proto_icmp.c
we delete the conntrack of an ICMP packet as soon as all replies are seen instead of lettingip_conntrack_icmp_timeouttake the conntrack like other protocol types? As far as I can see, this breaks the conntrack event API because I get the following sequence of notifications for an ICMP echo request to the host (this is with theip_conntrack_event_cache_init()patch after notifications have been delivered so I don't get twoIPCT_NEWevents):
IPCT_NEWIPCT_DESTROYIPCT_STATUS
Quoted 5 lines
I think
nfct->useis still held and the conntrack is never really destroyed afterdeath_by_timeout(), so later when the reply comes the conntrack still exists in the hash and the conntrack API fires aIPCT_STATUSevent after theIPCT_DESTROYevent was fired, which I'm assuming is an invalid sequence of events. ;)
OK, I moved the IPCT_DESTROY event to destroy_conntrack instead of death_by_timeout, this must fix the problem of out of sequence events.
Quoted 13 lines
So, what would be the harm in the following patch to
ip_conntrack_proto_icmp.c?diff -u
a/ip_conntrack_proto_icmp.cb/ip_conntrack_proto_icmp.cip_conntrack_proto_icmp.c 2005-06-28 16:52:46.000000000 -0500 renamed from ip_conntrack_proto_icmp.c 2005-06-28 16:52:18.000000000 -0500 +0
-3@@ -92,15 +92,7 @@ const struct sk_buff *skb, enum ip_conntrack_info ctinfo) { - /* Try to delete connection immediately after all replies: - won't actually vanish as we still have skb, and del_timer - means this will only run once even if count hits zero twice
ip_conntrack_proto_icmp.c 2005-06-28 16:52:46.000000000 -0500 line 98
Quoted 10 lines
ip_conntrack_proto_icmp.c 2005-06-28 16:52:46.000000000 -0500 renamed from ip_conntrack_proto_icmp.c 2005-06-28 16:52:18.000000000 -0500 +1
-6- (theoretically possible with SMP) */ - if (CTINFO2DIR(ctinfo) == IP_CT_DIR_REPLY) { - if (atomic_dec_and_test(&ct->proto.icmp.count) - && del_timer(&ct->timeout)) - ct->timeout.function((unsigned long)ct); - } else { + if (CTINFO2DIR(ctinfo) != IP_CT_DIR_REPLY) { atomic_inc(&ct->proto.icmp.count); ip_ct_refresh_acct(ct, ctinfo, skb, ip_ct_icmp_timeout); }
I don't want to change the current icmp tracking logic, the connection tracking table could get full sooner because of icmp entries that has already seen their reply wanting to timeout.
--
Pablo
NETLINK_NETFILTER and NETLINK_FIB_LOOKUP
In reply to Pablo Neira2.6-git defines
#define NETLINK_FIB_LOOKUP 10
which conflicts with
#define NETLINK_NETFILTER 10 /* netfilter subsystem */
Are we going to have to change number again?
Should we push this definition upstream just to get a fixed number reserved? I don't think netfilter is going away any time soon.
Azez
Pablo, I realise that there was a lot of dicussion on various parts of your rework of conntrack.
Is the SVN patch at
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/SVN-patches/ctnetlink-ctevent-nfnetlink-update-2.6.12.patch
still preferred, or has all that you intend been committed to SVN already?
Thanks
Amin
Quoted 73 lines · Pablo Neira
Hi Harald,
This patchset introduces tons of updates for the nfnetlink, ctnetlink and the conntrack event API. I haven't attached the file since it's that big, about 100K.
You can get an incremental diff against SVN from:
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/SVN-patches/ctnetlink-ctevent-nfnetlink-update-2.6.12.patchPlease apply.
I've split this big patch above into four pieces to make it easier to understand the changes:
http://people.netfilter.org/~pablo/ctnetlink-2.6.12/2.6.11-vs-2.6.12/So these four patches shouldn't be applied, just they are meant to make your life easier to track the changes.
Summary of changes
------------------o conntrack event API
- Don't kill NFC_IP_* stuff, keep it there to ensure for old iptables versions compilation.
- new fileip_conntrack_events.hthat contains all event related functions to reduce pollution inip_conntrack.h
-IPCT_DELIVEREDbit. Loopback reports event are reported twice, this bit is set once event are delivered. I just came up with a better idea, reset nfcache once the events have been delivered, but I'll apply this change in the next patchset.o nfnetlink
- kill unused list.
- killnfnl_exlock(), not needed anymore.
- kill duplicated check:NFNL_SUBSYS_ID(type)>NFNL_SUBSYS_COUNT.
- kill unneeded initialization ofsubsys_tableto NULL, since it's in BSS section (already set to zero).
- kill dead defineCONFIG_NF_NETLINK.o ctnetlink
- mergectnetlink_get_mcgroupsandctnetlink_get_exp_mcgroups
- implemented NAT handlings
- kill unusedctnetlink_kill
- use__u64id's for conntracks
- stop usingNLMSG_DONEto report the end of a dump, use explicite ACK instead (NLM_F_ACK).
- fixed broken expectation timeout dumping.
- kill unusedctnetlink_exp_dump_proto
- killctnetlink_exp_dump: fairly small and just used once
- killNFNL_SUBSYS_CTNETLINK_EXP, useNFNL_SUBSYS_CTNETLINKinstead
- Fix expectation table dumping
- Fix expectation creation
- implemented flushing of the expect tableTODO
----- Implement
ip_conntrack_statsdumping and reset (accounting)
- Implement get conntrack and destroy (accounting)
- Kill event/dump mask based (?). Although it's unique, I think that it could be useful for weak conntrack event notification (think of just new, established and destroy event notification to reduce performance impact).Once
ip_conntrack_netlinkgets fully featured and people don't report bugs for quite some time. I'll create anf_conntrack_netlinktree.Signature · 1 line
Pablo