From 735a6fc681809beb52c160b09507aa0999fbc6ba Mon Sep 17 00:00:00 2001 From: "Ayuso/emailAddress=pablo@netfilter.org" Date: Fri, 21 Dec 2007 18:15:04 +0000 Subject: rename `examples' directory to `doc' --- doc/sync/alarm/README | 1 + doc/sync/alarm/node1/conntrackd.conf | 140 +++++++++++++++++++++++++++++++++++ doc/sync/alarm/node1/keepalived.conf | 39 ++++++++++ doc/sync/alarm/node2/conntrackd.conf | 140 +++++++++++++++++++++++++++++++++++ doc/sync/alarm/node2/keepalived.conf | 39 ++++++++++ doc/sync/alarm/script_backup.sh | 3 + doc/sync/alarm/script_master.sh | 4 + 7 files changed, 366 insertions(+) create mode 100644 doc/sync/alarm/README create mode 100644 doc/sync/alarm/node1/conntrackd.conf create mode 100644 doc/sync/alarm/node1/keepalived.conf create mode 100644 doc/sync/alarm/node2/conntrackd.conf create mode 100644 doc/sync/alarm/node2/keepalived.conf create mode 100644 doc/sync/alarm/script_backup.sh create mode 100644 doc/sync/alarm/script_master.sh (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/README b/doc/sync/alarm/README new file mode 100644 index 0000000..dfd8474 --- /dev/null +++ b/doc/sync/alarm/README @@ -0,0 +1 @@ +This directory contains the files for the ALARM based protocol diff --git a/doc/sync/alarm/node1/conntrackd.conf b/doc/sync/alarm/node1/conntrackd.conf new file mode 100644 index 0000000..3004d07 --- /dev/null +++ b/doc/sync/alarm/node1/conntrackd.conf @@ -0,0 +1,140 @@ +# +# Synchronizer settings +# +Sync { + Mode ALARM { + # + # If a conntrack entry is not modified in <= 15 seconds, then + # a message is broadcasted. This mechanism is used to + # resynchronize nodes that just joined the multicast group + # + RefreshTime 15 + + # + # If we don't receive a notification about the state of + # an entry in the external cache after N seconds, then + # remove it. + # + CacheTimeout 180 + + # + # Entries committed to the connection tracking table + # starts with a limited timeout of N seconds until the + # takeover process is completed. + # + CommitTimeout 180 + } + + # + # Multicast IP and interface where messages are + # broadcasted (dedicated link). IMPORTANT: Make sure + # that iptables accepts traffic for destination + # 225.0.0.50, eg: + # + # iptables -I INPUT -d 225.0.0.50 -j ACCEPT + # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT + # + Multicast { + IPv4_address 225.0.0.50 + IPv4_interface 192.168.100.100 # IP of dedicated link + Interface eth2 + Group 3780 + } + + # Enable/Disable message checksumming + Checksum on + + # Uncomment this if you want to replicate just certain TCP states. + # This option introduces a tradeoff in the replication: it reduces + # CPU consumption and lost messages rate at the cost of having + # backup replicas that don't contain the current state that the active + # replica holds. TCP states are: SYN_SENT, SYN_RECV, ESTABLISHED, + # FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE, LISTEN. + # + # Replicate ESTABLISHED TIME_WAIT for TCP + + # If you have a multiprimary setup (active-active) without connection + # persistency, ie. you can't know which firewall handles a packet + # that is part of a connection, then you need direct commit of + # conntrack entries to the kernel conntrack table. OSPF setups must + # set on this option. Default is Off. + # + # CacheWriteThrough On +} + +# +# General settings +# +General { + # + # Number of buckets in the caches: hash table + # + HashSize 8192 + + # + # Maximum number of conntracks: + # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max + # + HashLimit 65535 + + # + # Logfile: on, off, or a filename + # Default: on (/var/log/conntrackd.log) + # + #LogFile off + + # + # Syslog: on, off or a facility name (daemon (default) or local0..7) + # Default: off + # + #Syslog on + + # + # Lockfile + # + LockFile /var/lock/conntrack.lock + + # + # Unix socket configuration + # + UNIX { + Path /tmp/sync.sock + Backlog 20 + } + + # + # Netlink socket buffer size + # + SocketBufferSize 262142 + + # + # Increase the socket buffer up to maximum if required + # + SocketBufferSizeMaxGrown 655355 +} + +# +# Ignore traffic for a certain set of IP's: Usually +# all the IP assigned to the firewall since local +# traffic must be ignored, just forwarded connections +# are worth to replicate +# +IgnoreTrafficFor { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.1 + IPv4_address 192.168.1.1 + IPv4_address 192.168.100.100 # dedicated link ip + IPv4_address 192.168.0.100 # virtual IP 1 + IPv4_address 192.168.1.100 # virtual IP 2 +} + +# +# Do not replicate certain protocol traffic +# +IgnoreProtocol { + UDP + ICMP + IGMP + VRRP + # numeric numbers also valid +} diff --git a/doc/sync/alarm/node1/keepalived.conf b/doc/sync/alarm/node1/keepalived.conf new file mode 100644 index 0000000..f937467 --- /dev/null +++ b/doc/sync/alarm/node1/keepalived.conf @@ -0,0 +1,39 @@ +vrrp_sync_group G1 { # must be before vrrp_instance declaration + group { + VI_1 + VI_2 + } + notify_master /etc/conntrackd/script_master.sh + notify_backup /etc/conntrackd/script_backup.sh +# notify_fault /etc/conntrackd/script_fault.sh +} + +vrrp_instance VI_1 { + interface eth1 + state SLAVE + virtual_router_id 61 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.0.100 # default CIDR mask is /32 + } +} + +vrrp_instance VI_2 { + interface eth0 + state SLAVE + virtual_router_id 62 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.1.100 + } +} diff --git a/doc/sync/alarm/node2/conntrackd.conf b/doc/sync/alarm/node2/conntrackd.conf new file mode 100644 index 0000000..fb12130 --- /dev/null +++ b/doc/sync/alarm/node2/conntrackd.conf @@ -0,0 +1,140 @@ +# +# Synchronizer settings +# +Sync { + Mode ALARM { + # + # If a conntrack entry is not modified in <= 15 seconds, then + # a message is broadcasted. This mechanism is used to + # resynchronize nodes that just joined the multicast group + # + RefreshTime 15 + + # + # If we don't receive a notification about the state of + # an entry in the external cache after N seconds, then + # remove it. + # + CacheTimeout 180 + + # + # Entries committed to the connection tracking table + # starts with a limited timeout of N seconds until the + # takeover process is completed. + # + CommitTimeout 180 + } + + # + # Multicast IP and interface where messages are + # broadcasted (dedicated link). IMPORTANT: Make sure + # that iptables accepts traffic for destination + # 225.0.0.50, eg: + # + # iptables -I INPUT -d 225.0.0.50 -j ACCEPT + # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT + # + Multicast { + IPv4_address 225.0.0.50 + IPv4_interface 192.168.100.200 # IP of dedicated link + Interface eth2 + Group 3780 + } + + # Enable/Disable message checksumming + Checksum on + + # Uncomment this if you want to replicate just certain TCP states. + # This option introduces a tradeoff in the replication: it reduces + # CPU consumption and lost messages rate at the cost of having + # backup replicas that don't contain the current state that the active + # replica holds. TCP states are: SYN_SENT, SYN_RECV, ESTABLISHED, + # FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE, LISTEN. + # + # Replicate ESTABLISHED TIME_WAIT for TCP + + # If you have a multiprimary setup (active-active) without connection + # persistency, ie. you can't know which firewall handles a packet + # that is part of a connection, then you need direct commit of + # conntrack entries to the kernel conntrack table. OSPF setups must + # set on this option. Default is Off. + # + # CacheWriteThrough On +} + +# +# General settings +# +General { + # + # Number of buckets in the caches: hash table + # + HashSize 8192 + + # + # Maximum number of conntracks: + # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max + # + HashLimit 65535 + + # + # Logfile: on, off, or a filename + # Default: on (/var/log/conntrackd.log) + # + #LogFile off + + # + # Syslog: on, off or a facility name (daemon (default) or local0..7) + # Default: off + # + #Syslog on + + # + # Lockfile + # + LockFile /var/lock/conntrack.lock + + # + # Unix socket configuration + # + UNIX { + Path /tmp/sync.sock + Backlog 20 + } + + # + # Netlink socket buffer size + # + SocketBufferSize 262142 + + # + # Increase the socket buffer up to maximum if required + # + SocketBufferSizeMaxGrown 655355 +} + +# +# Ignore traffic for a certain set of IP's: Usually +# all the IP assigned to the firewall since local +# traffic must be ignored, just forwarded connections +# are worth to replicate +# +IgnoreTrafficFor { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.2 + IPv4_address 192.168.1.2 + IPv4_address 192.168.100.200 # dedicated link ip + IPv4_address 192.168.0.200 # virtual IP 1 + IPv4_address 192.168.1.200 # virtual IP 2 +} + +# +# Do not replicate certain protocol traffic +# +IgnoreProtocol { + UDP + ICMP + IGMP + VRRP + # numeric numbers also valid +} diff --git a/doc/sync/alarm/node2/keepalived.conf b/doc/sync/alarm/node2/keepalived.conf new file mode 100644 index 0000000..f937467 --- /dev/null +++ b/doc/sync/alarm/node2/keepalived.conf @@ -0,0 +1,39 @@ +vrrp_sync_group G1 { # must be before vrrp_instance declaration + group { + VI_1 + VI_2 + } + notify_master /etc/conntrackd/script_master.sh + notify_backup /etc/conntrackd/script_backup.sh +# notify_fault /etc/conntrackd/script_fault.sh +} + +vrrp_instance VI_1 { + interface eth1 + state SLAVE + virtual_router_id 61 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.0.100 # default CIDR mask is /32 + } +} + +vrrp_instance VI_2 { + interface eth0 + state SLAVE + virtual_router_id 62 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.1.100 + } +} diff --git a/doc/sync/alarm/script_backup.sh b/doc/sync/alarm/script_backup.sh new file mode 100644 index 0000000..8ea2ad8 --- /dev/null +++ b/doc/sync/alarm/script_backup.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +/usr/sbin/conntrackd -B diff --git a/doc/sync/alarm/script_master.sh b/doc/sync/alarm/script_master.sh new file mode 100644 index 0000000..70c26c9 --- /dev/null +++ b/doc/sync/alarm/script_master.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +/usr/sbin/conntrackd -c +/usr/sbin/conntrackd -R -- cgit v1.2.3 From da8717a4bfa8884a411ae2445b9f1654b0550a64 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 20 May 2008 15:52:06 +0200 Subject: add Mcast[Snd|Rcv]SocketBuffer clauses to tune multicast socket buffers --- ChangeLog | 1 + doc/sync/alarm/node1/conntrackd.conf | 22 ++++++++++++++++++++++ doc/sync/alarm/node2/conntrackd.conf | 22 ++++++++++++++++++++++ doc/sync/ftfw/node1/conntrackd.conf | 22 ++++++++++++++++++++++ doc/sync/ftfw/node2/conntrackd.conf | 22 ++++++++++++++++++++++ include/mcast.h | 2 ++ src/mcast.c | 31 +++++++++++++++++++++++++++++++ src/read_config_lex.l | 2 ++ src/read_config_yy.y | 12 +++++++++++- src/sync-mode.c | 6 ++++++ 10 files changed, 141 insertions(+), 1 deletion(-) (limited to 'doc/sync/alarm') diff --git a/ChangeLog b/ChangeLog index 4458830..0b30f4f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,7 @@ o remove (misleading) counters and use information from the statistics mode o use generic nfct_copy() from libnetfilter_conntrack to update objects o use generic nfct_cmp() to compare objects o improve network message sanity checkings +o add Mcast[Snd|Rcv]SocketBuffer clauses to tune multicast socket buffers version 0.9.6 (2008/03/08) ------------------------------ diff --git a/doc/sync/alarm/node1/conntrackd.conf b/doc/sync/alarm/node1/conntrackd.conf index 3004d07..56bef0c 100644 --- a/doc/sync/alarm/node1/conntrackd.conf +++ b/doc/sync/alarm/node1/conntrackd.conf @@ -39,6 +39,28 @@ Sync { IPv4_interface 192.168.100.100 # IP of dedicated link Interface eth2 Group 3780 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 + + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. + # + # McastRcvSocketBuffer 1249280 } # Enable/Disable message checksumming diff --git a/doc/sync/alarm/node2/conntrackd.conf b/doc/sync/alarm/node2/conntrackd.conf index fb12130..e0cb375 100644 --- a/doc/sync/alarm/node2/conntrackd.conf +++ b/doc/sync/alarm/node2/conntrackd.conf @@ -39,6 +39,28 @@ Sync { IPv4_interface 192.168.100.200 # IP of dedicated link Interface eth2 Group 3780 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 + + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. + # + # McastRcvSocketBuffer 1249280 } # Enable/Disable message checksumming diff --git a/doc/sync/ftfw/node1/conntrackd.conf b/doc/sync/ftfw/node1/conntrackd.conf index fadeb9d..f3211db 100644 --- a/doc/sync/ftfw/node1/conntrackd.conf +++ b/doc/sync/ftfw/node1/conntrackd.conf @@ -34,6 +34,28 @@ Sync { IPv4_interface 192.168.100.100 # IP of dedicated link Interface eth2 Group 3780 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 + # + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. + # + # McastRcvSocketBuffer 1249280 } # Enable/Disable message checksumming diff --git a/doc/sync/ftfw/node2/conntrackd.conf b/doc/sync/ftfw/node2/conntrackd.conf index 59ffc4f..9c26ff5 100644 --- a/doc/sync/ftfw/node2/conntrackd.conf +++ b/doc/sync/ftfw/node2/conntrackd.conf @@ -33,6 +33,28 @@ Sync { IPv4_interface 192.168.100.200 # IP of dedicated link Interface eth2 Group 3780 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 + # + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. + # + # McastRcvSocketBuffer 1249280 } # Enable/Disable message checksumming diff --git a/include/mcast.h b/include/mcast.h index c2fd3ec..7c4b1d6 100644 --- a/include/mcast.h +++ b/include/mcast.h @@ -19,6 +19,8 @@ struct mcast_conf { unsigned int interface_index6; } ifa; int mtu; + int sndbuf; + int rcvbuf; char iface[IFNAMSIZ]; }; diff --git a/src/mcast.c b/src/mcast.c index f945511..16d8856 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -28,6 +28,7 @@ #include #include #include +#include struct mcast_sock *mcast_server_create(struct mcast_conf *conf) { @@ -37,6 +38,7 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) struct ipv6_mreq ipv6; } mreq; struct mcast_sock *m; + socklen_t socklen = sizeof(int); m = (struct mcast_sock *) malloc(sizeof(struct mcast_sock)); if (!m) @@ -96,6 +98,20 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) return NULL; } + if (conf->rcvbuf && + setsockopt(m->fd, SOL_SOCKET, SO_RCVBUFFORCE, &conf->rcvbuf, + sizeof(int)) == -1) { + /* not supported in linux kernel < 2.6.14 */ + if (errno != ENOPROTOOPT) { + debug("mcast_sock_server_create:setsockopt2"); + close(m->fd); + free(m); + return NULL; + } + } + + getsockopt(m->fd, SOL_SOCKET, SO_RCVBUF, &conf->rcvbuf, &socklen); + if (bind(m->fd, (struct sockaddr *) &m->addr, m->sockaddr_len) == -1) { debug("mcast_sock_server_create:bind"); close(m->fd); @@ -195,6 +211,7 @@ struct mcast_sock *mcast_client_create(struct mcast_conf *conf) { int ret; struct mcast_sock *m; + socklen_t socklen = sizeof(int); m = (struct mcast_sock *) malloc(sizeof(struct mcast_sock)); if (!m) @@ -215,6 +232,20 @@ struct mcast_sock *mcast_client_create(struct mcast_conf *conf) return NULL; } + if (conf->sndbuf && + setsockopt(m->fd, SOL_SOCKET, SO_SNDBUFFORCE, &conf->sndbuf, + sizeof(int)) == -1) { + /* not supported in linux kernel < 2.6.14 */ + if (errno != ENOPROTOOPT) { + debug("mcast_sock_server_create:setsockopt2"); + close(m->fd); + free(m); + return NULL; + } + } + + getsockopt(m->fd, SOL_SOCKET, SO_SNDBUF, &conf->sndbuf, &socklen); + switch(conf->ipproto) { case AF_INET: ret = __mcast_client_create_ipv4(m, conf); diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 1350afc..eb3368a 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -104,6 +104,8 @@ ftfw [F|f][T|t][F|f][W|w] "LISTEN" { return T_LISTEN; } "LogFileBufferSize" { return T_STAT_BUFFER_SIZE; } "DestroyTimeout" { return T_DESTROY_TIMEOUT; } +"McastSndSocketBuffer" { return T_MCAST_SNDBUFF; } +"McastRcvSocketBuffer" { return T_MCAST_RCVBUFF; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 0bc5e3c..7fb3d5b 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -53,7 +53,7 @@ struct ct_conf conf; %token T_ESTABLISHED T_SYN_SENT T_SYN_RECV T_FIN_WAIT %token T_CLOSE_WAIT T_LAST_ACK T_TIME_WAIT T_CLOSE T_LISTEN %token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT - +%token T_MCAST_RCVBUFF T_MCAST_SNDBUFF %token T_IP T_PATH_VAL %token T_NUMBER @@ -344,6 +344,16 @@ multicast_option : T_GROUP T_NUMBER conf.mcast.port = $2; }; +multicast_option: T_MCAST_SNDBUFF T_NUMBER +{ + conf.mcast.sndbuf = $2; +}; + +multicast_option: T_MCAST_RCVBUFF T_NUMBER +{ + conf.mcast.rcvbuf = $2; +}; + hashsize : T_HASHSIZE T_NUMBER { conf.hashsize = $2; diff --git a/src/sync-mode.c b/src/sync-mode.c index 7d73e2f..ad55adc 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -211,6 +211,9 @@ static int init_sync(void) return -1; } + dlog(LOG_NOTICE, "multicast server socket receiver queue " + "has been set to %d bytes", CONFIG(mcast).rcvbuf); + /* multicast client to send events on the wire */ STATE_SYNC(mcast_client) = mcast_client_create(&CONFIG(mcast)); if (STATE_SYNC(mcast_client) == NULL) { @@ -219,6 +222,9 @@ static int init_sync(void) return -1; } + dlog(LOG_NOTICE, "multicast client socket sender queue " + "has been set to %d bytes", CONFIG(mcast).sndbuf); + if (mcast_buffered_init(&CONFIG(mcast)) == -1) { dlog(LOG_ERR, "can't init tx buffer!"); mcast_server_destroy(STATE_SYNC(mcast_server)); -- cgit v1.2.3 From 77b1fdb824eb45213df4f57224e8e799fed43ded Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 22 Jul 2008 12:13:43 +0200 Subject: Major rework of the user-space event filtering This patch reworks the user-space filtering. Although we have kernel-space filtering since Linux kernel >= 2.6.26, we keep userspace filtering to ensure backward compatibility. Moreover, this patch prepares the implementation of the kernel-space filtering via libnetfilter_conntrack's high-level berkeley socket filter API. Signed-off-by: Pablo Neira Ayuso --- doc/stats/conntrackd.conf | 54 ++++--- doc/sync/alarm/node1/conntrackd.conf | 65 +++++---- doc/sync/alarm/node2/conntrackd.conf | 65 +++++---- doc/sync/ftfw/node1/conntrackd.conf | 65 +++++---- doc/sync/ftfw/node2/conntrackd.conf | 65 +++++---- doc/sync/notrack/node1/conntrackd.conf | 65 +++++---- doc/sync/notrack/node2/conntrackd.conf | 65 +++++---- include/Makefile.am | 4 +- include/bitops.h | 36 +++++ include/conntrackd.h | 4 +- include/filter.h | 31 ++++ include/ignore.h | 18 --- include/state_helper.h | 22 --- src/Makefile.am | 3 +- src/filter.c | 250 ++++++++++++++++++++++++++++++++ src/ignore_pool.c | 155 -------------------- src/netlink.c | 16 +-- src/read_config_lex.l | 14 +- src/read_config_yy.y | 255 +++++++++++++++++++++++++-------- src/run.c | 4 +- src/state_helper.c | 44 ------ src/state_helper_tcp.c | 35 ----- src/sync-mode.c | 4 - 23 files changed, 807 insertions(+), 532 deletions(-) create mode 100644 include/bitops.h create mode 100644 include/filter.h delete mode 100644 include/ignore.h delete mode 100644 include/state_helper.h create mode 100644 src/filter.c delete mode 100644 src/ignore_pool.c delete mode 100644 src/state_helper.c delete mode 100644 src/state_helper_tcp.c (limited to 'doc/sync/alarm') diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index 4bc5642..b63c2c3 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -47,6 +47,39 @@ General { # Increase the socket buffer up to maximun if required # SocketBufferSizeMaxGrown 655355 + + # + # Event filtering: This clause allows you to filter certain traffic, + # There are currently three filter-sets: Protocol, Address and + # State. The filter is attached to an action that can be: Accept or + # Ignore. Thus, you can define the event filtering policy of the + # filter-sets in positive or negative logic depending on your needs. + # + Filter { + # + # Accept only certain protocols: You may want to log the + # state of flows depending on their layer 4 protocol. + # + Protocol Accept { + TCP + } + + # + # Ignore traffic for a certain set of IP's. + # + Address Ignore { + IPv4_address 127.0.0.1 # loopback + } + + # + # Uncomment this line below if you want to filter by flow state. + # The existing TCP states are: SYN_SENT, SYN_RECV, ESTABLISHED, + # FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSED, LISTEN. + # + # State Accept { + # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP + # } + } } Stats { @@ -66,24 +99,3 @@ Stats { # #Syslog on } - -# -# Ignore traffic for a certain set of IP's: Usually -# all the IP assigned to the firewall since local -# traffic must be ignored, just forwarded connections -# are worth to replicate -# -IgnoreTrafficFor { - IPv4_address 127.0.0.1 # loopback -} - -# -# Do not replicate certain protocol traffic -# -IgnoreProtocol { - UDP -# ICMP -# IGMP -# VRRP - # numeric numbers also valid -} diff --git a/doc/sync/alarm/node1/conntrackd.conf b/doc/sync/alarm/node1/conntrackd.conf index 56bef0c..c3c4da4 100644 --- a/doc/sync/alarm/node1/conntrackd.conf +++ b/doc/sync/alarm/node1/conntrackd.conf @@ -133,30 +133,47 @@ General { # Increase the socket buffer up to maximum if required # SocketBufferSizeMaxGrown 655355 -} -# -# Ignore traffic for a certain set of IP's: Usually -# all the IP assigned to the firewall since local -# traffic must be ignored, just forwarded connections -# are worth to replicate -# -IgnoreTrafficFor { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.1 - IPv4_address 192.168.1.1 - IPv4_address 192.168.100.100 # dedicated link ip - IPv4_address 192.168.0.100 # virtual IP 1 - IPv4_address 192.168.1.100 # virtual IP 2 -} + # + # Event filtering: This clause allows you to filter certain traffic, + # There are currently three filter-sets: Protocol, Address and + # State. The filter is attached to an action that can be: Accept or + # Ignore. Thus, you can define the event filtering policy of the + # filter-sets in positive or negative logic depending on your needs. + # + Filter { + # + # Accept only certain protocols: You may want to replicate + # the state of flows depending on their layer 4 protocol. + # + Protocol Accept { + TCP + } -# -# Do not replicate certain protocol traffic -# -IgnoreProtocol { - UDP - ICMP - IGMP - VRRP - # numeric numbers also valid + # + # Ignore traffic for a certain set of IP's: Usually all the + # IP assigned to the firewall since local traffic must be + # ignored, only forwarded connections are worth to replicate. + # + Address Ignore { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.1 + IPv4_address 192.168.1.1 + IPv4_address 192.168.100.100 # dedicated link ip + IPv4_address 192.168.0.100 # virtual IP 1 + IPv4_address 192.168.1.100 # virtual IP 2 + } + + # + # Uncomment this line below if you want to filter by flow state. + # This option introduces a trade-off in the replication: it + # reduces CPU consumption at the cost of having lazy backup + # firewall replicas. The existing TCP states are: SYN_SENT, + # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, + # TIME_WAIT, CLOSED, LISTEN. + # + # State Accept { + # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP + # } + } } diff --git a/doc/sync/alarm/node2/conntrackd.conf b/doc/sync/alarm/node2/conntrackd.conf index e0cb375..e61e76a 100644 --- a/doc/sync/alarm/node2/conntrackd.conf +++ b/doc/sync/alarm/node2/conntrackd.conf @@ -133,30 +133,47 @@ General { # Increase the socket buffer up to maximum if required # SocketBufferSizeMaxGrown 655355 -} -# -# Ignore traffic for a certain set of IP's: Usually -# all the IP assigned to the firewall since local -# traffic must be ignored, just forwarded connections -# are worth to replicate -# -IgnoreTrafficFor { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.2 - IPv4_address 192.168.1.2 - IPv4_address 192.168.100.200 # dedicated link ip - IPv4_address 192.168.0.200 # virtual IP 1 - IPv4_address 192.168.1.200 # virtual IP 2 -} + # + # Event filtering: This clause allows you to filter certain traffic, + # There are currently three filter-sets: Protocol, Address and + # State. The filter is attached to an action that can be: Accept or + # Ignore. Thus, you can define the event filtering policy of the + # filter-sets in positive or negative logic depending on your needs. + # + Filter { + # + # Accept only certain protocols: You may want to replicate + # the state of flows depending on their layer 4 protocol. + # + Protocol Accept { + TCP + } -# -# Do not replicate certain protocol traffic -# -IgnoreProtocol { - UDP - ICMP - IGMP - VRRP - # numeric numbers also valid + # + # Ignore traffic for a certain set of IP's: Usually all the + # IP assigned to the firewall since local traffic must be + # ignored, only forwarded connections are worth to replicate. + # + Address Ignore { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.2 + IPv4_address 192.168.1.2 + IPv4_address 192.168.100.200 # dedicated link ip + IPv4_address 192.168.0.100 # virtual IP 1 + IPv4_address 192.168.1.100 # virtual IP 2 + } + + # + # Uncomment this line below if you want to filter by flow state. + # This option introduces a trade-off in the replication: it + # reduces CPU consumption at the cost of having lazy backup + # firewall replicas. The existing TCP states are: SYN_SENT, + # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, + # TIME_WAIT, CLOSED, LISTEN. + # + # State Accept { + # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP + # } + } } diff --git a/doc/sync/ftfw/node1/conntrackd.conf b/doc/sync/ftfw/node1/conntrackd.conf index f3211db..98ad581 100644 --- a/doc/sync/ftfw/node1/conntrackd.conf +++ b/doc/sync/ftfw/node1/conntrackd.conf @@ -128,30 +128,47 @@ General { # Increase the socket buffer up to maximum if required # SocketBufferSizeMaxGrown 655355 -} -# -# Ignore traffic for a certain set of IP's: Usually -# all the IP assigned to the firewall since local -# traffic must be ignored, just forwarded connections -# are worth to replicate -# -IgnoreTrafficFor { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.1 - IPv4_address 192.168.1.1 - IPv4_address 192.168.100.100 # dedicated link ip - IPv4_address 192.168.0.100 # virtual IP 1 - IPv4_address 192.168.1.100 # virtual IP 2 -} + # + # Event filtering: This clause allows you to filter certain traffic, + # There are currently three filter-sets: Protocol, Address and + # State. The filter is attached to an action that can be: Accept or + # Ignore. Thus, you can define the event filtering policy of the + # filter-sets in positive or negative logic depending on your needs. + # + Filter { + # + # Accept only certain protocols: You may want to replicate + # the state of flows depending on their layer 4 protocol. + # + Protocol Accept { + TCP + } -# -# Do not replicate certain protocol traffic -# -IgnoreProtocol { - UDP - ICMP - IGMP - VRRP - # numeric numbers also valid + # + # Ignore traffic for a certain set of IP's: Usually all the + # IP assigned to the firewall since local traffic must be + # ignored, only forwarded connections are worth to replicate. + # + Address Ignore { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.1 + IPv4_address 192.168.1.1 + IPv4_address 192.168.100.100 # dedicated link ip + IPv4_address 192.168.0.100 # virtual IP 1 + IPv4_address 192.168.1.100 # virtual IP 2 + } + + # + # Uncomment this line below if you want to filter by flow state. + # This option introduces a trade-off in the replication: it + # reduces CPU consumption at the cost of having lazy backup + # firewall replicas. The existing TCP states are: SYN_SENT, + # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, + # TIME_WAIT, CLOSED, LISTEN. + # + # State Accept { + # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP + # } + } } diff --git a/doc/sync/ftfw/node2/conntrackd.conf b/doc/sync/ftfw/node2/conntrackd.conf index 9c26ff5..2fab830 100644 --- a/doc/sync/ftfw/node2/conntrackd.conf +++ b/doc/sync/ftfw/node2/conntrackd.conf @@ -127,30 +127,47 @@ General { # Increase the socket buffer up to maximum if required # SocketBufferSizeMaxGrown 655355 -} -# -# Ignore traffic for a certain set of IP's: Usually -# all the IP assigned to the firewall since local -# traffic must be ignored, just forwarded connections -# are worth to replicate -# -IgnoreTrafficFor { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.2 - IPv4_address 192.168.1.2 - IPv4_address 192.168.100.200 # dedicated link ip - IPv4_address 192.168.0.200 # virtual IP 1 - IPv4_address 192.168.1.200 # virtual IP 2 -} + # + # Event filtering: This clause allows you to filter certain traffic, + # There are currently three filter-sets: Protocol, Address and + # State. The filter is attached to an action that can be: Accept or + # Ignore. Thus, you can define the event filtering policy of the + # filter-sets in positive or negative logic depending on your needs. + # + Filter { + # + # Accept only certain protocols: You may want to replicate + # the state of flows depending on their layer 4 protocol. + # + Protocol Accept { + TCP + } -# -# Do not replicate certain protocol traffic -# -IgnoreProtocol { - UDP - ICMP - IGMP - VRRP - # numeric numbers also valid + # + # Ignore traffic for a certain set of IP's: Usually all the + # IP assigned to the firewall since local traffic must be + # ignored, only forwarded connections are worth to replicate. + # + Address Ignore { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.2 + IPv4_address 192.168.1.2 + IPv4_address 192.168.100.200 # dedicated link ip + IPv4_address 192.168.0.100 # virtual IP 1 + IPv4_address 192.168.1.100 # virtual IP 2 + } + + # + # Uncomment this line below if you want to filter by flow state. + # This option introduces a trade-off in the replication: it + # reduces CPU consumption at the cost of having lazy backup + # firewall replicas. The existing TCP states are: SYN_SENT, + # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, + # TIME_WAIT, CLOSED, LISTEN. + # + # State Accept { + # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP + # } + } } diff --git a/doc/sync/notrack/node1/conntrackd.conf b/doc/sync/notrack/node1/conntrackd.conf index 1185351..724183a 100644 --- a/doc/sync/notrack/node1/conntrackd.conf +++ b/doc/sync/notrack/node1/conntrackd.conf @@ -121,30 +121,47 @@ General { # Increase the socket buffer up to maximum if required # SocketBufferSizeMaxGrown 655355 -} -# -# Ignore traffic for a certain set of IP's: Usually -# all the IP assigned to the firewall since local -# traffic must be ignored, just forwarded connections -# are worth to replicate -# -IgnoreTrafficFor { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.1 - IPv4_address 192.168.1.1 - IPv4_address 192.168.100.100 # dedicated link ip - IPv4_address 192.168.0.100 # virtual IP 1 - IPv4_address 192.168.1.100 # virtual IP 2 -} + # + # Event filtering: This clause allows you to filter certain traffic, + # There are currently three filter-sets: Protocol, Address and + # State. The filter is attached to an action that can be: Accept or + # Ignore. Thus, you can define the event filtering policy of the + # filter-sets in positive or negative logic depending on your needs. + # + Filter { + # + # Accept only certain protocols: You may want to replicate + # the state of flows depending on their layer 4 protocol. + # + Protocol Accept { + TCP + } -# -# Do not replicate certain protocol traffic -# -IgnoreProtocol { - UDP - ICMP - IGMP - VRRP - # numeric numbers also valid + # + # Ignore traffic for a certain set of IP's: Usually all the + # IP assigned to the firewall since local traffic must be + # ignored, only forwarded connections are worth to replicate. + # + Address Ignore { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.1 + IPv4_address 192.168.1.1 + IPv4_address 192.168.100.100 # dedicated link ip + IPv4_address 192.168.0.100 # virtual IP 1 + IPv4_address 192.168.1.100 # virtual IP 2 + } + + # + # Uncomment this line below if you want to filter by flow state. + # This option introduces a trade-off in the replication: it + # reduces CPU consumption at the cost of having lazy backup + # firewall replicas. The existing TCP states are: SYN_SENT, + # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, + # TIME_WAIT, CLOSED, LISTEN. + # + # State Accept { + # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP + # } + } } diff --git a/doc/sync/notrack/node2/conntrackd.conf b/doc/sync/notrack/node2/conntrackd.conf index 7881d46..cbf5cee 100644 --- a/doc/sync/notrack/node2/conntrackd.conf +++ b/doc/sync/notrack/node2/conntrackd.conf @@ -120,30 +120,47 @@ General { # Increase the socket buffer up to maximum if required # SocketBufferSizeMaxGrown 655355 -} -# -# Ignore traffic for a certain set of IP's: Usually -# all the IP assigned to the firewall since local -# traffic must be ignored, just forwarded connections -# are worth to replicate -# -IgnoreTrafficFor { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.2 - IPv4_address 192.168.1.2 - IPv4_address 192.168.100.200 # dedicated link ip - IPv4_address 192.168.0.200 # virtual IP 1 - IPv4_address 192.168.1.200 # virtual IP 2 -} + # + # Event filtering: This clause allows you to filter certain traffic, + # There are currently three filter-sets: Protocol, Address and + # State. The filter is attached to an action that can be: Accept or + # Ignore. Thus, you can define the event filtering policy of the + # filter-sets in positive or negative logic depending on your needs. + # + Filter { + # + # Accept only certain protocols: You may want to replicate + # the state of flows depending on their layer 4 protocol. + # + Protocol Accept { + TCP + } -# -# Do not replicate certain protocol traffic -# -IgnoreProtocol { - UDP - ICMP - IGMP - VRRP - # numeric numbers also valid + # + # Ignore traffic for a certain set of IP's: Usually all the + # IP assigned to the firewall since local traffic must be + # ignored, only forwarded connections are worth to replicate. + # + Address Ignore { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.2 + IPv4_address 192.168.1.2 + IPv4_address 192.168.100.200 # dedicated link ip + IPv4_address 192.168.0.100 # virtual IP 1 + IPv4_address 192.168.1.100 # virtual IP 2 + } + + # + # Uncomment this line below if you want to filter by flow state. + # This option introduces a trade-off in the replication: it + # reduces CPU consumption at the cost of having lazy backup + # firewall replicas. The existing TCP states are: SYN_SENT, + # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, + # TIME_WAIT, CLOSED, LISTEN. + # + # State Accept { + # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP + # } + } } diff --git a/include/Makefile.am b/include/Makefile.am index 01be0df..3287a0c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -2,6 +2,6 @@ noinst_HEADERS = alarm.h jhash.h slist.h cache.h linux_list.h linux_rbtree.h \ sync.h conntrackd.h local.h us-conntrack.h \ debug.h log.h hash.h mcast.h conntrack.h \ - state_helper.h network.h ignore.h queue.h \ - traffic_stats.h netlink.h fds.h event.h + network.h filter.h queue.h \ + traffic_stats.h netlink.h fds.h event.h bitops.h diff --git a/include/bitops.h b/include/bitops.h new file mode 100644 index 0000000..51f4289 --- /dev/null +++ b/include/bitops.h @@ -0,0 +1,36 @@ +#ifndef _BITOPS_H_ +#define _BITOPS_H_ + +#include + +static inline void set_bit_u32(int nr, u_int32_t *addr) +{ + addr[nr >> 5] |= (1UL << (nr & 31)); +} + +static inline void unset_bit_u32(int nr, u_int32_t *addr) +{ + addr[nr >> 5] &= ~(1UL << (nr & 31)); +} + +static inline int test_bit_u32(int nr, const u_int32_t *addr) +{ + return ((1UL << (nr & 31)) & (addr[nr >> 5])) != 0; +} + +static inline void set_bit_u16(int nr, u_int16_t *addr) +{ + addr[nr >> 4] |= (1UL << (nr & 15)); +} + +static inline void unset_bit_u16(int nr, u_int16_t *addr) +{ + addr[nr >> 4] &= ~(1UL << (nr & 15)); +} + +static inline int test_bit_u16(int nr, const u_int16_t *addr) +{ + return ((1UL << (nr & 15)) & (addr[nr >> 4])) != 0; +} + +#endif diff --git a/include/conntrackd.h b/include/conntrackd.h index 8a6e8d2..cd02f1f 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -4,6 +4,7 @@ #include "mcast.h" #include "local.h" #include "alarm.h" +#include "filter.h" #include #include @@ -80,7 +81,6 @@ struct ct_conf { int del_timeout; unsigned int netlink_buffer_size; unsigned int netlink_buffer_size_max_grown; - unsigned char ignore_protocol[IPPROTO_MAX]; union inet_address *listen_to; unsigned int listen_to_len; unsigned int flags; @@ -103,7 +103,7 @@ struct ct_general_state { FILE *stats_log; struct local_server local; struct ct_mode *mode; - struct ignore_pool *ignore_pool; + struct ct_filter *us_filter; struct nfct_handle *event; /* event handler */ struct nfct_handle *dump; /* dump handler */ diff --git a/include/filter.h b/include/filter.h new file mode 100644 index 0000000..de0754e --- /dev/null +++ b/include/filter.h @@ -0,0 +1,31 @@ +#ifndef _FILTER_H_ +#define _FILTER_H_ + +#include + +enum ct_filter_type { + CT_FILTER_L4PROTO, + CT_FILTER_STATE, + CT_FILTER_ADDRESS, + CT_FILTER_MAX +}; + +enum ct_filter_logic { + CT_FILTER_NEGATIVE = 0, + CT_FILTER_POSITIVE = 1, +}; + +struct nf_conntrack; +struct ct_filter; + +struct ct_filter *ct_filter_create(void); +void ct_filter_destroy(struct ct_filter *filter); +int ct_filter_add_ip(struct ct_filter *filter, void *data, uint8_t family); +void ct_filter_add_proto(struct ct_filter *filter, int protonum); +void ct_filter_add_state(struct ct_filter *f, int protonum, int state); +void ct_filter_set_logic(struct ct_filter *f, + enum ct_filter_type type, + enum ct_filter_logic logic); +int ct_filter_check(struct ct_filter *filter, struct nf_conntrack *ct); + +#endif diff --git a/include/ignore.h b/include/ignore.h deleted file mode 100644 index e5e96ff..0000000 --- a/include/ignore.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _IGNORE_H_ -#define _IGNORE_H_ - -#include - -struct nf_conntrack; - -struct ignore_pool { - struct hashtable *h; - struct hashtable *h6; -}; - -struct ignore_pool *ignore_pool_create(void); -void ignore_pool_destroy(struct ignore_pool *ip); -int ignore_pool_add(struct ignore_pool *ip, void *data, uint8_t family); -int ignore_pool_test(struct ignore_pool *ip, struct nf_conntrack *ct); - -#endif diff --git a/include/state_helper.h b/include/state_helper.h deleted file mode 100644 index 1a68b04..0000000 --- a/include/state_helper.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef _STATE_HELPER_H_ -#define _STATE_HELPER_H_ - -#include - -enum { - ST_H_SKIP, - ST_H_REPLICATE -}; - -struct state_replication_helper { - uint8_t proto; - unsigned int state; - - int (*verdict)(const struct state_replication_helper *h, - const struct nf_conntrack *ct); -}; - -int state_helper_verdict(int type, struct nf_conntrack *ct); -void state_helper_register(struct state_replication_helper *h, int h_state); - -#endif diff --git a/src/Makefile.am b/src/Makefile.am index 69ddcfd..805e50d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,13 +12,12 @@ conntrack_LDFLAGS = $(all_libraries) @LIBNETFILTER_CONNTRACK_LIBS@ conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \ local.c log.c mcast.c netlink.c \ - ignore_pool.c fds.c event.c \ + filter.c fds.c event.c \ cache.c cache_iterators.c \ cache_lifetime.c cache_timer.c cache_wt.c \ sync-mode.c sync-alarm.c sync-ftfw.c sync-notrack.c \ traffic_stats.c stats-mode.c \ network.c \ - state_helper.c state_helper_tcp.c \ build.c parse.c \ read_config_yy.y read_config_lex.l diff --git a/src/filter.c b/src/filter.c new file mode 100644 index 0000000..6e4d64a --- /dev/null +++ b/src/filter.c @@ -0,0 +1,250 @@ +/* + * (C) 2006-2008 by Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "filter.h" +#include "bitops.h" +#include "jhash.h" +#include "hash.h" +#include "conntrackd.h" +#include "log.h" + +#include +#include +#include +#include + +struct ct_filter { + int logic[CT_FILTER_MAX]; + u_int32_t l4protomap[IPPROTO_MAX/32]; + u_int16_t statemap[IPPROTO_MAX]; + struct hashtable *h; + struct hashtable *h6; +}; + +/* XXX: These should be configurable, better use a rb-tree */ +#define FILTER_POOL_SIZE 128 +#define FILTER_POOL_LIMIT INT_MAX + +static uint32_t hash(const void *data, struct hashtable *table) +{ + const uint32_t *f = data; + + return jhash_1word(*f, 0) % table->hashsize; +} + +static uint32_t hash6(const void *data, struct hashtable *table) +{ + return jhash(data, sizeof(uint32_t)*4, 0) % table->hashsize; +} + +static int compare(const void *data1, const void *data2) +{ + const uint32_t *f1 = data1; + const uint32_t *f2 = data2; + + return *f1 == *f2; +} + +static int compare6(const void *data1, const void *data2) +{ + return memcmp(data1, data2, sizeof(uint32_t)*4) == 0; +} + +struct ct_filter *ct_filter_create(void) +{ + int i; + struct ct_filter *filter; + + filter = calloc(sizeof(struct ct_filter), 1); + if (!filter) + return NULL; + + filter->h = hashtable_create(FILTER_POOL_SIZE, + FILTER_POOL_LIMIT, + sizeof(uint32_t), + hash, + compare); + if (!filter->h) { + free(filter); + return NULL; + } + + filter->h6 = hashtable_create(FILTER_POOL_SIZE, + FILTER_POOL_LIMIT, + sizeof(uint32_t)*4, + hash6, + compare6); + if (!filter->h6) { + free(filter->h); + free(filter); + return NULL; + } + + for (i=0; ilogic[i] = -1; + + return filter; +} + +void ct_filter_destroy(struct ct_filter *filter) +{ + hashtable_destroy(filter->h); + hashtable_destroy(filter->h6); + free(filter); +} + +/* this is ugly, but it simplifies read_config_yy.y */ +static struct ct_filter *__filter_alloc(struct ct_filter *filter) +{ + if (!STATE(us_filter)) { + STATE(us_filter) = ct_filter_create(); + if (!STATE(us_filter)) { + fprintf(stderr, "Can't create ignore pool!\n"); + exit(EXIT_FAILURE); + } + } + + return STATE(us_filter); +} + +void ct_filter_set_logic(struct ct_filter *filter, + enum ct_filter_type type, + enum ct_filter_logic logic) +{ + filter = __filter_alloc(filter); + filter->logic[type] = logic; +} + +int ct_filter_add_ip(struct ct_filter *filter, void *data, uint8_t family) +{ + filter = __filter_alloc(filter); + + switch(family) { + case AF_INET: + if (!hashtable_add(filter->h, data)) + return 0; + break; + case AF_INET6: + if (!hashtable_add(filter->h6, data)) + return 0; + break; + } + return 1; +} + +void ct_filter_add_proto(struct ct_filter *f, int protonum) +{ + f = __filter_alloc(f); + + set_bit_u32(protonum, f->l4protomap); +} + +void ct_filter_add_state(struct ct_filter *f, int protonum, int val) +{ + f = __filter_alloc(f); + + set_bit_u16(val, &f->statemap[protonum]); +} + +static int +__ct_filter_test_ipv4(struct ct_filter *f, struct nf_conntrack *ct) +{ + if (!f->h) + return 0; + + return (hashtable_test(f->h, nfct_get_attr(ct, ATTR_ORIG_IPV4_SRC)) || + hashtable_test(f->h, nfct_get_attr(ct, ATTR_ORIG_IPV4_DST)) || + hashtable_test(f->h, nfct_get_attr(ct, ATTR_REPL_IPV4_SRC)) || + hashtable_test(f->h, nfct_get_attr(ct, ATTR_REPL_IPV4_DST))); +} + +static int +__ct_filter_test_ipv6(struct ct_filter *f, struct nf_conntrack *ct) +{ + if (!f->h6) + return 0; + + return (hashtable_test(f->h6, nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC)) || + hashtable_test(f->h6, nfct_get_attr(ct, ATTR_ORIG_IPV6_DST)) || + hashtable_test(f->h6, nfct_get_attr(ct, ATTR_REPL_IPV6_SRC)) || + hashtable_test(f->h6, nfct_get_attr(ct, ATTR_REPL_IPV6_DST))); +} + +static int __ct_filter_test_state(struct ct_filter *f, struct nf_conntrack *ct) +{ + uint16_t val = 0; + uint8_t protonum = nfct_get_attr_u8(ct, ATTR_L4PROTO); + + switch(protonum) { + case IPPROTO_TCP: + val = nfct_get_attr_u8(ct, ATTR_TCP_STATE); + break; + default: + return -1; + } + + return test_bit_u16(val, &f->statemap[protonum]); +} + +int ct_filter_check(struct ct_filter *f, struct nf_conntrack *ct) +{ + int ret, protonum = nfct_get_attr_u8(ct, ATTR_L4PROTO); + + /* no event filtering at all */ + if (f == NULL) + return 1; + + if (f->logic[CT_FILTER_L4PROTO] != -1) { + ret = test_bit_u32(protonum, f->l4protomap); + if (ret == 0 && f->logic[CT_FILTER_L4PROTO]) + return 0; + else if (ret == 1 && !f->logic[CT_FILTER_L4PROTO]) + return 0; + } + + if (f->logic[CT_FILTER_ADDRESS] != -1) { + switch(nfct_get_attr_u8(ct, ATTR_L3PROTO)) { + case AF_INET: + ret = __ct_filter_test_ipv4(f, ct); + if (ret == 0 && f->logic[CT_FILTER_ADDRESS]) + return 0; + else if (ret == 1 && !f->logic[CT_FILTER_ADDRESS]) + return 0; + break; + case AF_INET6: + ret = __ct_filter_test_ipv6(f, ct); + if (ret == 0 && f->logic[CT_FILTER_ADDRESS]) + return 0; + else if (ret == 1 && !f->logic[CT_FILTER_ADDRESS]) + return 0; + break; + default: + break; + } + } + + if (f->logic[CT_FILTER_STATE] != -1) { + ret = __ct_filter_test_state(f, ct); + if (ret == 0 && f->logic[CT_FILTER_STATE]) + return 0; + else if (ret == 1 && !f->logic[CT_FILTER_STATE]) + return 0; + } + + return 1; +} diff --git a/src/ignore_pool.c b/src/ignore_pool.c deleted file mode 100644 index 2f951e8..0000000 --- a/src/ignore_pool.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * (C) 2006-2007 by Pablo Neira Ayuso - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "ignore.h" -#include "jhash.h" -#include "hash.h" -#include "conntrackd.h" -#include "log.h" - -#include -#include -#include -#include - -/* XXX: These should be configurable, better use a rb-tree */ -#define IGNORE_POOL_SIZE 128 -#define IGNORE_POOL_LIMIT INT_MAX - -static uint32_t hash(const void *data, struct hashtable *table) -{ - const uint32_t *ip = data; - - return jhash_1word(*ip, 0) % table->hashsize; -} - -static uint32_t hash6(const void *data, struct hashtable *table) -{ - return jhash(data, sizeof(uint32_t)*4, 0) % table->hashsize; -} - -static int compare(const void *data1, const void *data2) -{ - const uint32_t *ip1 = data1; - const uint32_t *ip2 = data2; - - return *ip1 == *ip2; -} - -static int compare6(const void *data1, const void *data2) -{ - return memcmp(data1, data2, sizeof(uint32_t)*4) == 0; -} - -struct ignore_pool *ignore_pool_create(void) -{ - struct ignore_pool *ip; - - ip = malloc(sizeof(struct ignore_pool)); - if (!ip) - return NULL; - memset(ip, 0, sizeof(struct ignore_pool)); - - ip->h = hashtable_create(IGNORE_POOL_SIZE, - IGNORE_POOL_LIMIT, - sizeof(uint32_t), - hash, - compare); - if (!ip->h) { - free(ip); - return NULL; - } - - ip->h6 = hashtable_create(IGNORE_POOL_SIZE, - IGNORE_POOL_LIMIT, - sizeof(uint32_t)*4, - hash6, - compare6); - if (!ip->h6) { - free(ip->h); - free(ip); - return NULL; - } - - return ip; -} - -void ignore_pool_destroy(struct ignore_pool *ip) -{ - hashtable_destroy(ip->h); - hashtable_destroy(ip->h6); - free(ip); -} - -int ignore_pool_add(struct ignore_pool *ip, void *data, uint8_t family) -{ - switch(family) { - case AF_INET: - if (!hashtable_add(ip->h, data)) - return 0; - break; - case AF_INET6: - if (!hashtable_add(ip->h6, data)) - return 0; - break; - } - return 1; -} - -static int -__ignore_pool_test_ipv4(struct ignore_pool *ip, struct nf_conntrack *ct) -{ - if (!ip->h) - return 0; - - return (hashtable_test(ip->h, nfct_get_attr(ct, ATTR_ORIG_IPV4_SRC)) || - hashtable_test(ip->h, nfct_get_attr(ct, ATTR_ORIG_IPV4_DST)) || - hashtable_test(ip->h, nfct_get_attr(ct, ATTR_REPL_IPV4_SRC)) || - hashtable_test(ip->h, nfct_get_attr(ct, ATTR_REPL_IPV4_DST))); -} - -static int -__ignore_pool_test_ipv6(struct ignore_pool *ip, struct nf_conntrack *ct) -{ - if (!ip->h6) - return 0; - - return (hashtable_test(ip->h6, nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC)) || - hashtable_test(ip->h6, nfct_get_attr(ct, ATTR_ORIG_IPV6_DST)) || - hashtable_test(ip->h6, nfct_get_attr(ct, ATTR_REPL_IPV6_SRC)) || - hashtable_test(ip->h6, nfct_get_attr(ct, ATTR_REPL_IPV6_DST))); -} - -int ignore_pool_test(struct ignore_pool *ip, struct nf_conntrack *ct) -{ - int ret = 0; - - switch(nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO)) { - case AF_INET: - ret = __ignore_pool_test_ipv4(ip, ct); - break; - case AF_INET6: - ret = __ignore_pool_test_ipv6(ip, ct); - break; - default: - dlog(LOG_WARNING, "unknown layer 3 protocol?"); - break; - } - - return ret; -} diff --git a/src/netlink.c b/src/netlink.c index 387062d..1823280 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -19,7 +19,7 @@ #include "netlink.h" #include "conntrackd.h" #include "traffic_stats.h" -#include "ignore.h" +#include "filter.h" #include "log.h" #include "debug.h" @@ -28,10 +28,6 @@ int ignore_conntrack(struct nf_conntrack *ct) { - /* ignore a certain protocol */ - if (CONFIG(ignore_protocol)[nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO)]) - return 1; - /* Accept DNAT'ed traffic: not really coming to the local machine */ if (nfct_getobjopt(ct, NFCT_GOPT_IS_DNAT)) { debug_ct(ct, "DNAT"); @@ -45,7 +41,7 @@ int ignore_conntrack(struct nf_conntrack *ct) } /* Ignore traffic */ - if (ignore_pool_test(STATE(ignore_pool), ct)) { + if (!ct_filter_check(STATE(us_filter), ct)) { debug_ct(ct, "ignore traffic"); return 1; } @@ -57,10 +53,6 @@ static int event_handler(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) { - /* - * Ignore this conntrack: it talks about a - * connection that is not interesting for us. - */ if (ignore_conntrack(ct)) return NFCT_CB_STOP; @@ -125,10 +117,6 @@ static int dump_handler(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) { - /* - * Ignore this conntrack: it talks about a - * connection that is not interesting for us. - */ if (ignore_conntrack(ct)) return NFCT_CB_CONTINUE; diff --git a/src/read_config_lex.l b/src/read_config_lex.l index bdde3b6..584a4a3 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -68,11 +68,6 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "HashLimit" { return T_HASHLIMIT; } "Path" { return T_PATH; } "IgnoreProtocol" { return T_IGNORE_PROTOCOL; } -"UDP" { return T_UDP; } -"ICMP" { return T_ICMP; } -"VRRP" { return T_VRRP; } -"IGMP" { return T_IGMP; } -"TCP" { return T_TCP; } "IgnoreTrafficFor" { return T_IGNORE_TRAFFIC; } "StripNAT" { return T_STRIP_NAT; } "Backlog" { return T_BACKLOG; } @@ -103,12 +98,19 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "CLOSE_WAIT" { return T_CLOSE_WAIT; } "LAST_ACK" { return T_LAST_ACK; } "TIME_WAIT" { return T_TIME_WAIT; } -"CLOSE" { return T_CLOSE; } +"CLOSE" { return T_CLOSE; /* alias of CLOSED */ } +"CLOSED" { return T_CLOSE; } "LISTEN" { return T_LISTEN; } "LogFileBufferSize" { return T_STAT_BUFFER_SIZE; } "DestroyTimeout" { return T_DESTROY_TIMEOUT; } "McastSndSocketBuffer" { return T_MCAST_SNDBUFF; } "McastRcvSocketBuffer" { return T_MCAST_RCVBUFF; } +"Filter" { return T_FILTER; } +"Protocol" { return T_PROTOCOL; } +"Address" { return T_ADDRESS; } +"State" { return T_STATE; } +"Accept" { return T_ACCEPT; } +"Ignore" { return T_IGNORE; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index b9c53be..2a1c88c 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -22,14 +22,13 @@ #include #include #include +#include #include #include "conntrackd.h" -#include "ignore.h" +#include "bitops.h" #include #include -extern struct state_replication_helper tcp_state_helper; - extern char *yytext; extern int yylineno; @@ -44,7 +43,7 @@ struct ct_conf conf; %token T_IPV4_ADDR T_IPV4_IFACE T_PORT T_HASHSIZE T_HASHLIMIT T_MULTICAST %token T_PATH T_UNIX T_REFRESH T_IPV6_ADDR T_IPV6_IFACE %token T_IGNORE_UDP T_IGNORE_ICMP T_IGNORE_TRAFFIC T_BACKLOG T_GROUP -%token T_LOG T_UDP T_ICMP T_IGMP T_VRRP T_TCP T_IGNORE_PROTOCOL +%token T_LOG T_UDP T_ICMP T_IGMP T_VRRP T_IGNORE_PROTOCOL %token T_LOCK T_STRIP_NAT T_BUFFER_SIZE_MAX_GROWN T_EXPIRE T_TIMEOUT %token T_GENERAL T_SYNC T_STATS T_RELAX_TRANSITIONS T_BUFFER_SIZE T_DELAY %token T_SYNC_MODE T_LISTEN_TO T_FAMILY T_RESEND_BUFFER_SIZE @@ -54,6 +53,7 @@ struct ct_conf conf; %token T_CLOSE_WAIT T_LAST_ACK T_TIME_WAIT T_CLOSE T_LISTEN %token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT %token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK +%token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE %token T_IP T_PATH_VAL %token T_NUMBER @@ -169,7 +169,15 @@ checksum: T_CHECKSUM T_OFF conf.mcast.checksum = 1; }; -ignore_traffic : T_IGNORE_TRAFFIC '{' ignore_traffic_options '}'; +ignore_traffic : T_IGNORE_TRAFFIC '{' ignore_traffic_options '}' +{ + ct_filter_set_logic(STATE(us_filter), + CT_FILTER_ADDRESS, + CT_FILTER_NEGATIVE); + + fprintf(stderr, "WARNING: The clause `IgnoreTrafficFor' is obsolete. " + "Use `Filter' instead.\n"); +}; ignore_traffic_options : | ignore_traffic_options ignore_traffic_option; @@ -185,15 +193,7 @@ ignore_traffic_option : T_IPV4_ADDR T_IP break; } - if (!STATE(ignore_pool)) { - STATE(ignore_pool) = ignore_pool_create(); - if (!STATE(ignore_pool)) { - fprintf(stderr, "Can't create ignore pool!\n"); - exit(EXIT_FAILURE); - } - } - - if (!ignore_pool_add(STATE(ignore_pool), &ip, AF_INET)) { + if (!ct_filter_add_ip(STATE(us_filter), &ip, AF_INET)) { if (errno == EEXIST) fprintf(stderr, "IP %s is repeated " "in the ignore pool\n", $2); @@ -218,15 +218,7 @@ ignore_traffic_option : T_IPV6_ADDR T_IP break; #endif - if (!STATE(ignore_pool)) { - STATE(ignore_pool) = ignore_pool_create(); - if (!STATE(ignore_pool)) { - fprintf(stderr, "Can't create ignore pool!\n"); - exit(EXIT_FAILURE); - } - } - - if (!ignore_pool_add(STATE(ignore_pool), &ip, AF_INET6)) { + if (!ct_filter_add_ip(STATE(us_filter), &ip, AF_INET6)) { if (errno == EEXIST) fprintf(stderr, "IP %s is repeated " "in the ignore pool\n", $2); @@ -380,7 +372,15 @@ unix_option : T_BACKLOG T_NUMBER conf.local.backlog = $2; }; -ignore_protocol: T_IGNORE_PROTOCOL '{' ignore_proto_list '}'; +ignore_protocol: T_IGNORE_PROTOCOL '{' ignore_proto_list '}' +{ + ct_filter_set_logic(STATE(us_filter), + CT_FILTER_L4PROTO, + CT_FILTER_NEGATIVE); + + fprintf(stderr, "WARNING: The clause `IgnoreProtocol' is obsolete. " + "Use `Filter' instead.\n"); +}; ignore_proto_list: | ignore_proto_list ignore_proto @@ -389,29 +389,22 @@ ignore_proto_list: ignore_proto: T_NUMBER { if ($1 < IPPROTO_MAX) - conf.ignore_protocol[$1] = 1; + ct_filter_add_proto(STATE(us_filter), $1); else fprintf(stderr, "Protocol number `%d' is freak\n", $1); }; -ignore_proto: T_UDP +ignore_proto: T_STRING { - conf.ignore_protocol[IPPROTO_UDP] = 1; -}; + struct protoent *pent; -ignore_proto: T_ICMP -{ - conf.ignore_protocol[IPPROTO_ICMP] = 1; -}; - -ignore_proto: T_VRRP -{ - conf.ignore_protocol[IPPROTO_VRRP] = 1; -}; - -ignore_proto: T_IGMP -{ - conf.ignore_protocol[IPPROTO_IGMP] = 1; + pent = getprotobyname($1); + if (pent == NULL) { + fprintf(stderr, "getprotobyname() cannot find " + "protocol `%s' in /etc/protocols.\n", $1); + break; + } + ct_filter_add_proto(STATE(us_filter), pent->p_proto); }; sync: T_SYNC '{' sync_list '}' @@ -538,49 +531,81 @@ listen_to: T_LISTEN_TO T_IP } }; -state_replication: T_REPLICATE states T_FOR state_proto; +state_replication: T_REPLICATE states T_FOR state_proto +{ + ct_filter_set_logic(STATE(us_filter), + CT_FILTER_STATE, + CT_FILTER_POSITIVE); + + fprintf(stderr, "WARNING: The clause `Replicate' is obsolete. " + "Use `Filter' instead.\n"); +}; states: | states state; -state_proto: T_TCP; +state_proto: T_STRING +{ + if (strncmp($1, "TCP", strlen("TCP")) != 0) { + fprintf(stderr, "Unsupported protocol `%s' in line %d.\n", + $1, yylineno); + } +}; state: tcp_state; tcp_state: T_SYN_SENT { - state_helper_register(&tcp_state_helper, TCP_CONNTRACK_SYN_SENT); + ct_filter_add_state(STATE(us_filter), + IPPROTO_TCP, + TCP_CONNTRACK_SYN_SENT); }; tcp_state: T_SYN_RECV { - state_helper_register(&tcp_state_helper, TCP_CONNTRACK_SYN_RECV); + ct_filter_add_state(STATE(us_filter), + IPPROTO_TCP, + TCP_CONNTRACK_SYN_RECV); }; tcp_state: T_ESTABLISHED { - state_helper_register(&tcp_state_helper, TCP_CONNTRACK_ESTABLISHED); + ct_filter_add_state(STATE(us_filter), + IPPROTO_TCP, + TCP_CONNTRACK_ESTABLISHED); }; tcp_state: T_FIN_WAIT { - state_helper_register(&tcp_state_helper, TCP_CONNTRACK_FIN_WAIT); + ct_filter_add_state(STATE(us_filter), + IPPROTO_TCP, + TCP_CONNTRACK_FIN_WAIT); }; tcp_state: T_CLOSE_WAIT { - state_helper_register(&tcp_state_helper, TCP_CONNTRACK_CLOSE_WAIT); + ct_filter_add_state(STATE(us_filter), + IPPROTO_TCP, + TCP_CONNTRACK_CLOSE_WAIT); }; tcp_state: T_LAST_ACK { - state_helper_register(&tcp_state_helper, TCP_CONNTRACK_LAST_ACK); + ct_filter_add_state(STATE(us_filter), + IPPROTO_TCP, + TCP_CONNTRACK_LAST_ACK); }; tcp_state: T_TIME_WAIT { - state_helper_register(&tcp_state_helper, TCP_CONNTRACK_TIME_WAIT); + ct_filter_add_state(STATE(us_filter), + IPPROTO_TCP, + TCP_CONNTRACK_TIME_WAIT); }; tcp_state: T_CLOSE { - state_helper_register(&tcp_state_helper, TCP_CONNTRACK_CLOSE); + ct_filter_add_state(STATE(us_filter), + IPPROTO_TCP, + TCP_CONNTRACK_CLOSE); }; tcp_state: T_LISTEN { - state_helper_register(&tcp_state_helper, TCP_CONNTRACK_LISTEN); + ct_filter_add_state(STATE(us_filter), + IPPROTO_TCP, + TCP_CONNTRACK_LISTEN); }; cache_writethrough: T_WRITE_THROUGH T_ON @@ -610,6 +635,7 @@ general_line: hashsize | netlink_buffer_size | netlink_buffer_size_max_grown | family + | filter ; netlink_buffer_size: T_BUFFER_SIZE T_NUMBER @@ -630,6 +656,122 @@ family : T_FAMILY T_STRING conf.family = AF_INET; }; +filter : T_FILTER '{' filter_list '}'; + +filter_list : + | filter_list filter_item; + +filter_item : T_PROTOCOL T_ACCEPT '{' filter_protocol_list '}' +{ + ct_filter_set_logic(STATE(us_filter), + CT_FILTER_L4PROTO, + CT_FILTER_POSITIVE); +}; + +filter_item : T_PROTOCOL T_IGNORE '{' filter_protocol_list '}' +{ + ct_filter_set_logic(STATE(us_filter), + CT_FILTER_L4PROTO, + CT_FILTER_NEGATIVE); +}; + +filter_protocol_list : + | filter_protocol_list filter_protocol_item; + +filter_protocol_item : T_STRING +{ + struct protoent *pent; + + pent = getprotobyname($1); + if (pent == NULL) { + fprintf(stderr, "getprotobyname() cannot find " + "protocol `%s' in /etc/protocols.\n", $1); + break; + } + ct_filter_add_proto(STATE(us_filter), pent->p_proto); +}; + +filter_item : T_ADDRESS T_ACCEPT '{' filter_address_list '}' +{ + ct_filter_set_logic(STATE(us_filter), + CT_FILTER_ADDRESS, + CT_FILTER_POSITIVE); +}; + +filter_item : T_ADDRESS T_IGNORE '{' filter_address_list '}' +{ + ct_filter_set_logic(STATE(us_filter), + CT_FILTER_ADDRESS, + CT_FILTER_NEGATIVE); +}; + +filter_address_list : + | filter_address_list filter_address_item; + +filter_address_item : T_IPV4_ADDR T_IP +{ + union inet_address ip; + + memset(&ip, 0, sizeof(union inet_address)); + + if (!inet_aton($2, &ip.ipv4)) { + fprintf(stderr, "%s is not a valid IPv4, ignoring", $2); + break; + } + + if (!ct_filter_add_ip(STATE(us_filter), &ip, AF_INET)) { + if (errno == EEXIST) + fprintf(stderr, "IP %s is repeated " + "in the ignore pool\n", $2); + if (errno == ENOSPC) + fprintf(stderr, "Too many IP in the ignore pool!\n"); + } +}; + +filter_address_item : T_IPV6_ADDR T_IP +{ + union inet_address ip; + + memset(&ip, 0, sizeof(union inet_address)); + +#ifdef HAVE_INET_PTON_IPV6 + if (inet_pton(AF_INET6, $2, &ip.ipv6) <= 0) { + fprintf(stderr, "%s is not a valid IPv6, ignoring", $2); + break; + } +#else + fprintf(stderr, "Cannot find inet_pton(), IPv6 unsupported!"); + break; +#endif + + if (!ct_filter_add_ip(STATE(us_filter), &ip, AF_INET6)) { + if (errno == EEXIST) + fprintf(stderr, "IP %s is repeated " + "in the ignore pool\n", $2); + if (errno == ENOSPC) + fprintf(stderr, "Too many IP in the ignore pool!\n"); + } +}; + +filter_item : T_STATE T_ACCEPT '{' filter_state_list '}' +{ + ct_filter_set_logic(STATE(us_filter), + CT_FILTER_STATE, + CT_FILTER_POSITIVE); +}; + +filter_item : T_STATE T_IGNORE '{' filter_state_list '}' +{ + ct_filter_set_logic(STATE(us_filter), + CT_FILTER_STATE, + CT_FILTER_NEGATIVE); +}; + +filter_state_list : + | filter_state_list filter_state_item; + +filter_state_item : states T_FOR state_proto ; + stats: T_STATS '{' stats_list '}' { if (conf.flags & CTD_SYNC_MODE) { @@ -762,15 +904,6 @@ init_config(char *filename) if (CONFIG(resend_queue_size) == 0) CONFIG(resend_queue_size) = 262144; - /* create empty pool */ - if (!STATE(ignore_pool)) { - STATE(ignore_pool) = ignore_pool_create(); - if (!STATE(ignore_pool)) { - fprintf(stderr, "Can't create ignore pool!\n"); - exit(EXIT_FAILURE); - } - } - /* default to a window size of 20 packets */ if (CONFIG(window_size) == 0) CONFIG(window_size) = 20; diff --git a/src/run.c b/src/run.c index cadcb4d..cf570d8 100644 --- a/src/run.c +++ b/src/run.c @@ -20,7 +20,7 @@ #include "conntrackd.h" #include "netlink.h" -#include "ignore.h" +#include "filter.h" #include "log.h" #include "alarm.h" #include "fds.h" @@ -39,7 +39,7 @@ void killer(int foo) nfct_close(STATE(event)); - ignore_pool_destroy(STATE(ignore_pool)); + ct_filter_destroy(STATE(us_filter)); local_server_destroy(&STATE(local)); STATE(mode)->kill(); diff --git a/src/state_helper.c b/src/state_helper.c deleted file mode 100644 index 9034864..0000000 --- a/src/state_helper.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * (C) 2006-2007 by Pablo Neira Ayuso - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "conntrackd.h" -#include "state_helper.h" - -static struct state_replication_helper *helper[IPPROTO_MAX]; - -int state_helper_verdict(int type, struct nf_conntrack *ct) -{ - uint8_t l4proto; - - if (type == NFCT_Q_DESTROY) - return ST_H_REPLICATE; - - l4proto = nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO); - if (helper[l4proto]) - return helper[l4proto]->verdict(helper[l4proto], ct); - - return ST_H_REPLICATE; -} - -void state_helper_register(struct state_replication_helper *h, int h_state) -{ - if (helper[h->proto] == NULL) - helper[h->proto] = h; - - helper[h->proto]->state |= (1 << h_state); -} diff --git a/src/state_helper_tcp.c b/src/state_helper_tcp.c deleted file mode 100644 index 88af35e..0000000 --- a/src/state_helper_tcp.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * (C) 2006-2007 by Pablo Neira Ayuso - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "conntrackd.h" -#include "state_helper.h" - -static int tcp_verdict(const struct state_replication_helper *h, - const struct nf_conntrack *ct) -{ - uint8_t t_state = nfct_get_attr_u8(ct, ATTR_TCP_STATE); - if (h->state & (1 << t_state)) - return ST_H_REPLICATE; - - return ST_H_SKIP; -} - -struct state_replication_helper tcp_state_helper = { - .proto = IPPROTO_TCP, - .verdict = tcp_verdict, -}; diff --git a/src/sync-mode.c b/src/sync-mode.c index 4b36935..0f3760e 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -20,7 +20,6 @@ #include "netlink.h" #include "traffic_stats.h" #include "log.h" -#include "state_helper.h" #include "cache.h" #include "conntrackd.h" #include "us-conntrack.h" @@ -390,9 +389,6 @@ static void mcast_send_sync(struct us_conntrack *u, int query) size_t len; struct nethdr *net; - if (!state_helper_verdict(query, u->ct)) - return; - net = BUILD_NETMSG(u->ct, query); len = prepare_send_netmsg(STATE_SYNC(mcast_client), net); -- cgit v1.2.3 From d400ecfef1fd16a9bed90ddaf8270622476337bb Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 1 Aug 2008 11:35:27 +0200 Subject: cleanup: remove obsolete clause Replicate in the example conffiles Remove obsolete clause Replicate in the example configuration files. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/node1/conntrackd.conf | 9 --------- doc/sync/alarm/node2/conntrackd.conf | 9 --------- doc/sync/ftfw/node1/conntrackd.conf | 9 --------- doc/sync/ftfw/node2/conntrackd.conf | 9 --------- doc/sync/notrack/node1/conntrackd.conf | 9 --------- doc/sync/notrack/node2/conntrackd.conf | 9 --------- 6 files changed, 54 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/node1/conntrackd.conf b/doc/sync/alarm/node1/conntrackd.conf index c3c4da4..ff86918 100644 --- a/doc/sync/alarm/node1/conntrackd.conf +++ b/doc/sync/alarm/node1/conntrackd.conf @@ -66,15 +66,6 @@ Sync { # Enable/Disable message checksumming Checksum on - # Uncomment this if you want to replicate just certain TCP states. - # This option introduces a tradeoff in the replication: it reduces - # CPU consumption and lost messages rate at the cost of having - # backup replicas that don't contain the current state that the active - # replica holds. TCP states are: SYN_SENT, SYN_RECV, ESTABLISHED, - # FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE, LISTEN. - # - # Replicate ESTABLISHED TIME_WAIT for TCP - # If you have a multiprimary setup (active-active) without connection # persistency, ie. you can't know which firewall handles a packet # that is part of a connection, then you need direct commit of diff --git a/doc/sync/alarm/node2/conntrackd.conf b/doc/sync/alarm/node2/conntrackd.conf index e61e76a..ab34f70 100644 --- a/doc/sync/alarm/node2/conntrackd.conf +++ b/doc/sync/alarm/node2/conntrackd.conf @@ -66,15 +66,6 @@ Sync { # Enable/Disable message checksumming Checksum on - # Uncomment this if you want to replicate just certain TCP states. - # This option introduces a tradeoff in the replication: it reduces - # CPU consumption and lost messages rate at the cost of having - # backup replicas that don't contain the current state that the active - # replica holds. TCP states are: SYN_SENT, SYN_RECV, ESTABLISHED, - # FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE, LISTEN. - # - # Replicate ESTABLISHED TIME_WAIT for TCP - # If you have a multiprimary setup (active-active) without connection # persistency, ie. you can't know which firewall handles a packet # that is part of a connection, then you need direct commit of diff --git a/doc/sync/ftfw/node1/conntrackd.conf b/doc/sync/ftfw/node1/conntrackd.conf index 98ad581..e256f67 100644 --- a/doc/sync/ftfw/node1/conntrackd.conf +++ b/doc/sync/ftfw/node1/conntrackd.conf @@ -61,15 +61,6 @@ Sync { # Enable/Disable message checksumming Checksum on - # Uncomment this if you want to replicate just certain TCP states. - # This option introduces a tradeoff in the replication: it reduces - # CPU consumption and lost messages rate at the cost of having - # backup replicas that don't contain the current state that the active - # replica holds. TCP states are: SYN_SENT, SYN_RECV, ESTABLISHED, - # FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE, LISTEN. - # - # Replicate ESTABLISHED TIME_WAIT for TCP - # If you have a multiprimary setup (active-active) without connection # persistency, ie. you can't know which firewall handles a packet # that is part of a connection, then you need direct commit of diff --git a/doc/sync/ftfw/node2/conntrackd.conf b/doc/sync/ftfw/node2/conntrackd.conf index 2fab830..b22ab06 100644 --- a/doc/sync/ftfw/node2/conntrackd.conf +++ b/doc/sync/ftfw/node2/conntrackd.conf @@ -60,15 +60,6 @@ Sync { # Enable/Disable message checksumming Checksum on - # Uncomment this if you want to replicate just certain TCP states. - # This option introduces a tradeoff in the replication: it reduces - # CPU consumption and lost messages rate at the cost of having - # backup replicas that don't contain the current state that the active - # replica holds. TCP states are: SYN_SENT, SYN_RECV, ESTABLISHED, - # FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE, LISTEN. - # - # Replicate ESTABLISHED TIME_WAIT for TCP - # If you have a multiprimary setup (active-active) without connection # persistency, ie. you can't know which firewall handles a packet # that is part of a connection, then you need direct commit of diff --git a/doc/sync/notrack/node1/conntrackd.conf b/doc/sync/notrack/node1/conntrackd.conf index 724183a..6c5ec3d 100644 --- a/doc/sync/notrack/node1/conntrackd.conf +++ b/doc/sync/notrack/node1/conntrackd.conf @@ -54,15 +54,6 @@ Sync { # Enable/Disable message checksumming Checksum on - # Uncomment this if you want to replicate just certain TCP states. - # This option introduces a tradeoff in the replication: it reduces - # CPU consumption and lost messages rate at the cost of having - # backup replicas that don't contain the current state that the active - # replica holds. TCP states are: SYN_SENT, SYN_RECV, ESTABLISHED, - # FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE, LISTEN. - # - # Replicate ESTABLISHED TIME_WAIT for TCP - # If you have a multiprimary setup (active-active) without connection # persistency, ie. you can't know which firewall handles a packet # that is part of a connection, then you need direct commit of diff --git a/doc/sync/notrack/node2/conntrackd.conf b/doc/sync/notrack/node2/conntrackd.conf index cbf5cee..ba83e5a 100644 --- a/doc/sync/notrack/node2/conntrackd.conf +++ b/doc/sync/notrack/node2/conntrackd.conf @@ -53,15 +53,6 @@ Sync { # Enable/Disable message checksumming Checksum on - # Uncomment this if you want to replicate just certain TCP states. - # This option introduces a tradeoff in the replication: it reduces - # CPU consumption and lost messages rate at the cost of having - # backup replicas that don't contain the current state that the active - # replica holds. TCP states are: SYN_SENT, SYN_RECV, ESTABLISHED, - # FIN_WAIT, CLOSE_WAIT, LAST_ACK, TIME_WAIT, CLOSE, LISTEN. - # - # Replicate ESTABLISHED TIME_WAIT for TCP - # If you have a multiprimary setup (active-active) without connection # persistency, ie. you can't know which firewall handles a packet # that is part of a connection, then you need direct commit of -- cgit v1.2.3 From 9ad0b747e0a2f433192235fb04e4d291ce07b7e6 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 1 Aug 2008 11:59:55 +0200 Subject: fix: wrong information related to default logging action Logging is set off by default instead of what the example files state. Signed-off-by: Pablo Neira Ayuso --- doc/stats/conntrackd.conf | 6 +++--- doc/sync/alarm/node1/conntrackd.conf | 6 +++--- doc/sync/alarm/node2/conntrackd.conf | 6 +++--- doc/sync/ftfw/node1/conntrackd.conf | 6 +++--- doc/sync/ftfw/node2/conntrackd.conf | 6 +++--- doc/sync/notrack/node1/conntrackd.conf | 6 +++--- doc/sync/notrack/node2/conntrackd.conf | 6 +++--- 7 files changed, 21 insertions(+), 21 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index b63c2c3..4f0a6e2 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -14,10 +14,10 @@ General { HashLimit 65535 # - # Logfile: on, off, or a filename - # Default: on (/var/log/conntrackd.log) + # Logfile: on (/var/log/conntrackd.log), off, or a filename + # Default: off # - #LogFile off + #LogFile on # # Syslog: on, off or a facility name (daemon (default) or local0..7) diff --git a/doc/sync/alarm/node1/conntrackd.conf b/doc/sync/alarm/node1/conntrackd.conf index ff86918..ffd6b4a 100644 --- a/doc/sync/alarm/node1/conntrackd.conf +++ b/doc/sync/alarm/node1/conntrackd.conf @@ -91,10 +91,10 @@ General { HashLimit 65535 # - # Logfile: on, off, or a filename - # Default: on (/var/log/conntrackd.log) + # Logfile: on (/var/log/conntrackd.log), off, or a filename + # Default: off # - #LogFile off + #LogFile on # # Syslog: on, off or a facility name (daemon (default) or local0..7) diff --git a/doc/sync/alarm/node2/conntrackd.conf b/doc/sync/alarm/node2/conntrackd.conf index ab34f70..8f7abb2 100644 --- a/doc/sync/alarm/node2/conntrackd.conf +++ b/doc/sync/alarm/node2/conntrackd.conf @@ -91,10 +91,10 @@ General { HashLimit 65535 # - # Logfile: on, off, or a filename - # Default: on (/var/log/conntrackd.log) + # Logfile: on (/var/log/conntrackd.log), off, or a filename + # Default: off # - #LogFile off + #LogFile on # # Syslog: on, off or a facility name (daemon (default) or local0..7) diff --git a/doc/sync/ftfw/node1/conntrackd.conf b/doc/sync/ftfw/node1/conntrackd.conf index e256f67..2da2e5f 100644 --- a/doc/sync/ftfw/node1/conntrackd.conf +++ b/doc/sync/ftfw/node1/conntrackd.conf @@ -86,10 +86,10 @@ General { HashLimit 65535 # - # Logfile: on, off, or a filename - # Default: on (/var/log/conntrackd.log) + # Logfile: on (/var/log/conntrackd.log), off, or a filename + # Default: off # - #LogFile off + #LogFile on # # Syslog: on, off or a facility name (daemon (default) or local0..7) diff --git a/doc/sync/ftfw/node2/conntrackd.conf b/doc/sync/ftfw/node2/conntrackd.conf index b22ab06..8a7c214 100644 --- a/doc/sync/ftfw/node2/conntrackd.conf +++ b/doc/sync/ftfw/node2/conntrackd.conf @@ -85,10 +85,10 @@ General { HashLimit 65535 # - # Logfile: on, off, or a filename - # Default: on (/var/log/conntrackd.log) + # Logfile: on (/var/log/conntrackd.log), off, or a filename + # Default: off # - #LogFile off + #LogFile on # # Syslog: on, off or a facility name (daemon (default) or local0..7) diff --git a/doc/sync/notrack/node1/conntrackd.conf b/doc/sync/notrack/node1/conntrackd.conf index 6c5ec3d..15781a5 100644 --- a/doc/sync/notrack/node1/conntrackd.conf +++ b/doc/sync/notrack/node1/conntrackd.conf @@ -79,10 +79,10 @@ General { HashLimit 65535 # - # Logfile: on, off, or a filename - # Default: on (/var/log/conntrackd.log) + # Logfile: on (/var/log/conntrackd.log), off, or a filename + # Default: off # - #LogFile off + #LogFile on # # Syslog: on, off or a facility name (daemon (default) or local0..7) diff --git a/doc/sync/notrack/node2/conntrackd.conf b/doc/sync/notrack/node2/conntrackd.conf index ba83e5a..0257ddc 100644 --- a/doc/sync/notrack/node2/conntrackd.conf +++ b/doc/sync/notrack/node2/conntrackd.conf @@ -78,10 +78,10 @@ General { HashLimit 65535 # - # Logfile: on, off, or a filename - # Default: on (/var/log/conntrackd.log) + # Logfile: on (/var/log/conntrackd.log), off, or a filename + # Default: off # - #LogFile off + #LogFile on # # Syslog: on, off or a facility name (daemon (default) or local0..7) -- cgit v1.2.3 From 03f7de56efc6747eb6b4895c03aa2efaaed80efe Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 1 Aug 2008 18:31:25 +0200 Subject: doc: remove duplicated example files This patch removes the directories node1/ and node2/ since the differences are few small and the user should be able to get it running if he RTFM. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 198 +++++++++++++++++++++++++++++++++ doc/sync/alarm/keepalived.conf | 39 +++++++ doc/sync/alarm/node1/conntrackd.conf | 170 ---------------------------- doc/sync/alarm/node1/keepalived.conf | 39 ------- doc/sync/alarm/node2/conntrackd.conf | 170 ---------------------------- doc/sync/alarm/node2/keepalived.conf | 39 ------- doc/sync/ftfw/conntrackd.conf | 193 ++++++++++++++++++++++++++++++++ doc/sync/ftfw/keepalived.conf | 39 +++++++ doc/sync/ftfw/node1/conntrackd.conf | 165 --------------------------- doc/sync/ftfw/node1/keepalived.conf | 39 ------- doc/sync/ftfw/node2/conntrackd.conf | 164 --------------------------- doc/sync/ftfw/node2/keepalived.conf | 39 ------- doc/sync/notrack/conntrackd.conf | 186 +++++++++++++++++++++++++++++++ doc/sync/notrack/keepalived.conf | 39 +++++++ doc/sync/notrack/node1/conntrackd.conf | 158 -------------------------- doc/sync/notrack/node1/keepalived.conf | 39 ------- doc/sync/notrack/node2/conntrackd.conf | 157 -------------------------- doc/sync/notrack/node2/keepalived.conf | 39 ------- 18 files changed, 694 insertions(+), 1218 deletions(-) create mode 100644 doc/sync/alarm/conntrackd.conf create mode 100644 doc/sync/alarm/keepalived.conf delete mode 100644 doc/sync/alarm/node1/conntrackd.conf delete mode 100644 doc/sync/alarm/node1/keepalived.conf delete mode 100644 doc/sync/alarm/node2/conntrackd.conf delete mode 100644 doc/sync/alarm/node2/keepalived.conf create mode 100644 doc/sync/ftfw/conntrackd.conf create mode 100644 doc/sync/ftfw/keepalived.conf delete mode 100644 doc/sync/ftfw/node1/conntrackd.conf delete mode 100644 doc/sync/ftfw/node1/keepalived.conf delete mode 100644 doc/sync/ftfw/node2/conntrackd.conf delete mode 100644 doc/sync/ftfw/node2/keepalived.conf create mode 100644 doc/sync/notrack/conntrackd.conf create mode 100644 doc/sync/notrack/keepalived.conf delete mode 100644 doc/sync/notrack/node1/conntrackd.conf delete mode 100644 doc/sync/notrack/node1/keepalived.conf delete mode 100644 doc/sync/notrack/node2/conntrackd.conf delete mode 100644 doc/sync/notrack/node2/keepalived.conf (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf new file mode 100644 index 0000000..a65a378 --- /dev/null +++ b/doc/sync/alarm/conntrackd.conf @@ -0,0 +1,198 @@ +# +# Synchronizer settings +# +Sync { + Mode ALARM { + # + # If a conntrack entry is not modified in <= 15 seconds, then + # a message is broadcasted. This mechanism is used to + # resynchronize nodes that just joined the multicast group + # + RefreshTime 15 + + # + # If we don't receive a notification about the state of + # an entry in the external cache after N seconds, then + # remove it. + # + CacheTimeout 180 + + # + # Entries committed to the connection tracking table + # starts with a limited timeout of N seconds until the + # takeover process is completed. + # + CommitTimeout 180 + } + + # + # Multicast IP and interface where messages are + # broadcasted (dedicated link). IMPORTANT: Make sure + # that iptables accepts traffic for destination + # 225.0.0.50, eg: + # + # iptables -I INPUT -d 225.0.0.50 -j ACCEPT + # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT + # + Multicast { + # + # Multicast address: The address that you use as destination + # in the synchronization messages. You do not have to add + # this IP to any of your existing interfaces. If any doubt, + # do not modify this value. + # + IPv4_address 225.0.0.50 + + # + # The multicast group that identifies the cluster. If any + # doubt, do not modify this value. + # + Group 3780 + + # + # IP address of the interface that you are going to use to + # send the synchronization messages. Remember that you must + # use a dedicated link for the synchronization messages. + # + IPv4_interface 192.168.100.100 + + # + # The name of the interface that you are going to use to + # send the synchronization messages. + # + Interface eth2 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 + + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. + # + # McastRcvSocketBuffer 1249280 + } + + # + # Enable/Disable message checksumming. This is a good property to + # achieve fault-tolerance. In case of doubt, do not modify this value. + # + Checksum on + + # If you have a multiprimary setup (active-active) without connection + # persistency, ie. you can't know which firewall handles a packet + # that is part of a connection, then you need direct commit of + # conntrack entries to the kernel conntrack table. OSPF setups must + # set on this option. If you have a simple primary-backup scenario. + # Do not set it on. Default is off. + # + # CacheWriteThrough On +} + +# +# General settings +# +General { + # + # Number of buckets in the caches: hash table. + # + HashSize 8192 + + # + # Maximum number of conntracks: + # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max + # + HashLimit 65535 + + # + # Logfile: on (/var/log/conntrackd.log), off, or a filename + # Default: off + # + LogFile on + + # + # Syslog: on, off or a facility name (daemon (default) or local0..7) + # Default: off + # + #Syslog on + + # + # Lockfile + # + LockFile /var/lock/conntrack.lock + + # + # Unix socket configuration + # + UNIX { + Path /tmp/sync.sock + Backlog 20 + } + + # + # Netlink socket buffer size + # + SocketBufferSize 262142 + + # + # Increase the socket buffer up to maximum if required + # + SocketBufferSizeMaxGrown 655355 + + # + # Event filtering: This clause allows you to filter certain traffic, + # There are currently three filter-sets: Protocol, Address and + # State. The filter is attached to an action that can be: Accept or + # Ignore. Thus, you can define the event filtering policy of the + # filter-sets in positive or negative logic depending on your needs. + # + Filter { + # + # Accept only certain protocols: You may want to replicate + # the state of flows depending on their layer 4 protocol. + # + Protocol Accept { + TCP + } + + # + # Ignore traffic for a certain set of IP's: Usually all the + # IP assigned to the firewall since local traffic must be + # ignored, only forwarded connections are worth to replicate. + # Note that these values depends on the local IPs that are + # assigned to the firewall. + # + Address Ignore { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.100 # virtual IP 1 + IPv4_address 192.168.1.100 # virtual IP 2 + IPv4_address 192.168.0.1 + IPv4_address 192.168.1.1 + IPv4_address 192.168.100.100 # dedicated link ip + } + + # + # Uncomment this line below if you want to filter by flow state. + # This option introduces a trade-off in the replication: it + # reduces CPU consumption at the cost of having lazy backup + # firewall replicas. The existing TCP states are: SYN_SENT, + # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, + # TIME_WAIT, CLOSED, LISTEN. + # + # State Accept { + # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP + # } + } +} diff --git a/doc/sync/alarm/keepalived.conf b/doc/sync/alarm/keepalived.conf new file mode 100644 index 0000000..f937467 --- /dev/null +++ b/doc/sync/alarm/keepalived.conf @@ -0,0 +1,39 @@ +vrrp_sync_group G1 { # must be before vrrp_instance declaration + group { + VI_1 + VI_2 + } + notify_master /etc/conntrackd/script_master.sh + notify_backup /etc/conntrackd/script_backup.sh +# notify_fault /etc/conntrackd/script_fault.sh +} + +vrrp_instance VI_1 { + interface eth1 + state SLAVE + virtual_router_id 61 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.0.100 # default CIDR mask is /32 + } +} + +vrrp_instance VI_2 { + interface eth0 + state SLAVE + virtual_router_id 62 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.1.100 + } +} diff --git a/doc/sync/alarm/node1/conntrackd.conf b/doc/sync/alarm/node1/conntrackd.conf deleted file mode 100644 index ffd6b4a..0000000 --- a/doc/sync/alarm/node1/conntrackd.conf +++ /dev/null @@ -1,170 +0,0 @@ -# -# Synchronizer settings -# -Sync { - Mode ALARM { - # - # If a conntrack entry is not modified in <= 15 seconds, then - # a message is broadcasted. This mechanism is used to - # resynchronize nodes that just joined the multicast group - # - RefreshTime 15 - - # - # If we don't receive a notification about the state of - # an entry in the external cache after N seconds, then - # remove it. - # - CacheTimeout 180 - - # - # Entries committed to the connection tracking table - # starts with a limited timeout of N seconds until the - # takeover process is completed. - # - CommitTimeout 180 - } - - # - # Multicast IP and interface where messages are - # broadcasted (dedicated link). IMPORTANT: Make sure - # that iptables accepts traffic for destination - # 225.0.0.50, eg: - # - # iptables -I INPUT -d 225.0.0.50 -j ACCEPT - # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT - # - Multicast { - IPv4_address 225.0.0.50 - IPv4_interface 192.168.100.100 # IP of dedicated link - Interface eth2 - Group 3780 - - # The multicast sender uses a buffer to enqueue the packets - # that are going to be transmitted. The default size of this - # socket buffer is available at /proc/sys/net/core/wmem_default. - # This value determines the chances to have an overrun in the - # sender queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size - # of the sender buffer. - # - # McastSndSocketBuffer 1249280 - - # The multicast receiver uses a buffer to enqueue the packets - # that the socket is pending to handle. The default size of this - # socket buffer is available at /proc/sys/net/core/rmem_default. - # This value determines the chances to have an overrun in the - # receiver queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size of - # the receiver buffer. - # - # McastRcvSocketBuffer 1249280 - } - - # Enable/Disable message checksumming - Checksum on - - # If you have a multiprimary setup (active-active) without connection - # persistency, ie. you can't know which firewall handles a packet - # that is part of a connection, then you need direct commit of - # conntrack entries to the kernel conntrack table. OSPF setups must - # set on this option. Default is Off. - # - # CacheWriteThrough On -} - -# -# General settings -# -General { - # - # Number of buckets in the caches: hash table - # - HashSize 8192 - - # - # Maximum number of conntracks: - # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max - # - HashLimit 65535 - - # - # Logfile: on (/var/log/conntrackd.log), off, or a filename - # Default: off - # - #LogFile on - - # - # Syslog: on, off or a facility name (daemon (default) or local0..7) - # Default: off - # - #Syslog on - - # - # Lockfile - # - LockFile /var/lock/conntrack.lock - - # - # Unix socket configuration - # - UNIX { - Path /tmp/sync.sock - Backlog 20 - } - - # - # Netlink socket buffer size - # - SocketBufferSize 262142 - - # - # Increase the socket buffer up to maximum if required - # - SocketBufferSizeMaxGrown 655355 - - # - # Event filtering: This clause allows you to filter certain traffic, - # There are currently three filter-sets: Protocol, Address and - # State. The filter is attached to an action that can be: Accept or - # Ignore. Thus, you can define the event filtering policy of the - # filter-sets in positive or negative logic depending on your needs. - # - Filter { - # - # Accept only certain protocols: You may want to replicate - # the state of flows depending on their layer 4 protocol. - # - Protocol Accept { - TCP - } - - # - # Ignore traffic for a certain set of IP's: Usually all the - # IP assigned to the firewall since local traffic must be - # ignored, only forwarded connections are worth to replicate. - # - Address Ignore { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.1 - IPv4_address 192.168.1.1 - IPv4_address 192.168.100.100 # dedicated link ip - IPv4_address 192.168.0.100 # virtual IP 1 - IPv4_address 192.168.1.100 # virtual IP 2 - } - - # - # Uncomment this line below if you want to filter by flow state. - # This option introduces a trade-off in the replication: it - # reduces CPU consumption at the cost of having lazy backup - # firewall replicas. The existing TCP states are: SYN_SENT, - # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, - # TIME_WAIT, CLOSED, LISTEN. - # - # State Accept { - # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP - # } - } -} diff --git a/doc/sync/alarm/node1/keepalived.conf b/doc/sync/alarm/node1/keepalived.conf deleted file mode 100644 index f937467..0000000 --- a/doc/sync/alarm/node1/keepalived.conf +++ /dev/null @@ -1,39 +0,0 @@ -vrrp_sync_group G1 { # must be before vrrp_instance declaration - group { - VI_1 - VI_2 - } - notify_master /etc/conntrackd/script_master.sh - notify_backup /etc/conntrackd/script_backup.sh -# notify_fault /etc/conntrackd/script_fault.sh -} - -vrrp_instance VI_1 { - interface eth1 - state SLAVE - virtual_router_id 61 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.0.100 # default CIDR mask is /32 - } -} - -vrrp_instance VI_2 { - interface eth0 - state SLAVE - virtual_router_id 62 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.1.100 - } -} diff --git a/doc/sync/alarm/node2/conntrackd.conf b/doc/sync/alarm/node2/conntrackd.conf deleted file mode 100644 index 8f7abb2..0000000 --- a/doc/sync/alarm/node2/conntrackd.conf +++ /dev/null @@ -1,170 +0,0 @@ -# -# Synchronizer settings -# -Sync { - Mode ALARM { - # - # If a conntrack entry is not modified in <= 15 seconds, then - # a message is broadcasted. This mechanism is used to - # resynchronize nodes that just joined the multicast group - # - RefreshTime 15 - - # - # If we don't receive a notification about the state of - # an entry in the external cache after N seconds, then - # remove it. - # - CacheTimeout 180 - - # - # Entries committed to the connection tracking table - # starts with a limited timeout of N seconds until the - # takeover process is completed. - # - CommitTimeout 180 - } - - # - # Multicast IP and interface where messages are - # broadcasted (dedicated link). IMPORTANT: Make sure - # that iptables accepts traffic for destination - # 225.0.0.50, eg: - # - # iptables -I INPUT -d 225.0.0.50 -j ACCEPT - # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT - # - Multicast { - IPv4_address 225.0.0.50 - IPv4_interface 192.168.100.200 # IP of dedicated link - Interface eth2 - Group 3780 - - # The multicast sender uses a buffer to enqueue the packets - # that are going to be transmitted. The default size of this - # socket buffer is available at /proc/sys/net/core/wmem_default. - # This value determines the chances to have an overrun in the - # sender queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size - # of the sender buffer. - # - # McastSndSocketBuffer 1249280 - - # The multicast receiver uses a buffer to enqueue the packets - # that the socket is pending to handle. The default size of this - # socket buffer is available at /proc/sys/net/core/rmem_default. - # This value determines the chances to have an overrun in the - # receiver queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size of - # the receiver buffer. - # - # McastRcvSocketBuffer 1249280 - } - - # Enable/Disable message checksumming - Checksum on - - # If you have a multiprimary setup (active-active) without connection - # persistency, ie. you can't know which firewall handles a packet - # that is part of a connection, then you need direct commit of - # conntrack entries to the kernel conntrack table. OSPF setups must - # set on this option. Default is Off. - # - # CacheWriteThrough On -} - -# -# General settings -# -General { - # - # Number of buckets in the caches: hash table - # - HashSize 8192 - - # - # Maximum number of conntracks: - # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max - # - HashLimit 65535 - - # - # Logfile: on (/var/log/conntrackd.log), off, or a filename - # Default: off - # - #LogFile on - - # - # Syslog: on, off or a facility name (daemon (default) or local0..7) - # Default: off - # - #Syslog on - - # - # Lockfile - # - LockFile /var/lock/conntrack.lock - - # - # Unix socket configuration - # - UNIX { - Path /tmp/sync.sock - Backlog 20 - } - - # - # Netlink socket buffer size - # - SocketBufferSize 262142 - - # - # Increase the socket buffer up to maximum if required - # - SocketBufferSizeMaxGrown 655355 - - # - # Event filtering: This clause allows you to filter certain traffic, - # There are currently three filter-sets: Protocol, Address and - # State. The filter is attached to an action that can be: Accept or - # Ignore. Thus, you can define the event filtering policy of the - # filter-sets in positive or negative logic depending on your needs. - # - Filter { - # - # Accept only certain protocols: You may want to replicate - # the state of flows depending on their layer 4 protocol. - # - Protocol Accept { - TCP - } - - # - # Ignore traffic for a certain set of IP's: Usually all the - # IP assigned to the firewall since local traffic must be - # ignored, only forwarded connections are worth to replicate. - # - Address Ignore { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.2 - IPv4_address 192.168.1.2 - IPv4_address 192.168.100.200 # dedicated link ip - IPv4_address 192.168.0.100 # virtual IP 1 - IPv4_address 192.168.1.100 # virtual IP 2 - } - - # - # Uncomment this line below if you want to filter by flow state. - # This option introduces a trade-off in the replication: it - # reduces CPU consumption at the cost of having lazy backup - # firewall replicas. The existing TCP states are: SYN_SENT, - # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, - # TIME_WAIT, CLOSED, LISTEN. - # - # State Accept { - # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP - # } - } -} diff --git a/doc/sync/alarm/node2/keepalived.conf b/doc/sync/alarm/node2/keepalived.conf deleted file mode 100644 index f937467..0000000 --- a/doc/sync/alarm/node2/keepalived.conf +++ /dev/null @@ -1,39 +0,0 @@ -vrrp_sync_group G1 { # must be before vrrp_instance declaration - group { - VI_1 - VI_2 - } - notify_master /etc/conntrackd/script_master.sh - notify_backup /etc/conntrackd/script_backup.sh -# notify_fault /etc/conntrackd/script_fault.sh -} - -vrrp_instance VI_1 { - interface eth1 - state SLAVE - virtual_router_id 61 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.0.100 # default CIDR mask is /32 - } -} - -vrrp_instance VI_2 { - interface eth0 - state SLAVE - virtual_router_id 62 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.1.100 - } -} diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf new file mode 100644 index 0000000..6fec9a1 --- /dev/null +++ b/doc/sync/ftfw/conntrackd.conf @@ -0,0 +1,193 @@ +# +# Synchronizer settings +# +Sync { + Mode FTFW { + # + # Size of the buffer that hold destroy messages for + # possible resends (in bytes) + # + ResendBufferSize 262144 + + # + # Entries committed to the connection tracking table + # starts with a limited timeout of N seconds until the + # takeover process is completed. + # + CommitTimeout 180 + + # Set Acknowledgement window size + ACKWindowSize 20 + } + + # + # Multicast IP and interface where messages are + # broadcasted (dedicated link). IMPORTANT: Make sure + # that iptables accepts traffic for destination + # 225.0.0.50, eg: + # + # iptables -I INPUT -d 225.0.0.50 -j ACCEPT + # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT + # + Multicast { + # + # Multicast address: The address that you use as destination + # in the synchronization messages. You do not have to add + # this IP to any of your existing interfaces. If any doubt, + # do not modify this value. + # + IPv4_address 225.0.0.50 + + # + # The multicast group that identifies the cluster. If any + # doubt, do not modify this value. + # + Group 3780 + + # + # IP address of the interface that you are going to use to + # send the synchronization messages. Remember that you must + # use a dedicated link for the synchronization messages. + # + IPv4_interface 192.168.100.100 + + # + # The name of the interface that you are going to use to + # send the synchronization messages. + # + Interface eth2 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 + # + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. + # + # McastRcvSocketBuffer 1249280 + } + + # + # Enable/Disable message checksumming. This is a good property to + # achieve fault-tolerance. In case of doubt, do not modify this value. + # + Checksum on + + # If you have a multiprimary setup (active-active) without connection + # persistency, ie. you can't know which firewall handles a packet + # that is part of a connection, then you need direct commit of + # conntrack entries to the kernel conntrack table. OSPF setups must + # set on this option. If you have a simple primary-backup scenario. + # Do not set it on. Default is off. + # + # CacheWriteThrough On +} + +# +# General settings +# +General { + # + # Number of buckets in the caches: hash table. + # + HashSize 8192 + + # + # Maximum number of conntracks: + # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max + # + HashLimit 65535 + + # + # Logfile: on (/var/log/conntrackd.log), off, or a filename + # Default: off + # + LogFile on + + # + # Syslog: on, off or a facility name (daemon (default) or local0..7) + # Default: off + # + #Syslog on + + # + # Lockfile + # + LockFile /var/lock/conntrack.lock + + # + # Unix socket configuration + # + UNIX { + Path /tmp/sync.sock + Backlog 20 + } + + # + # Netlink socket buffer size + # + SocketBufferSize 262142 + + # + # Increase the socket buffer up to maximum if required + # + SocketBufferSizeMaxGrown 655355 + + # + # Event filtering: This clause allows you to filter certain traffic, + # There are currently three filter-sets: Protocol, Address and + # State. The filter is attached to an action that can be: Accept or + # Ignore. Thus, you can define the event filtering policy of the + # filter-sets in positive or negative logic depending on your needs. + # + Filter { + # + # Accept only certain protocols: You may want to replicate + # the state of flows depending on their layer 4 protocol. + # + Protocol Accept { + TCP + } + + # + # Ignore traffic for a certain set of IP's: Usually all the + # IP assigned to the firewall since local traffic must be + # ignored, only forwarded connections are worth to replicate. + # Note that these values depends on the local IPs that are + # assigned to the firewall. + # + Address Ignore { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.100 # virtual IP 1 + IPv4_address 192.168.1.100 # virtual IP 2 + IPv4_address 192.168.0.1 + IPv4_address 192.168.1.1 + IPv4_address 192.168.100.100 # dedicated link ip + } + + # + # Uncomment this line below if you want to filter by flow state. + # This option introduces a trade-off in the replication: it + # reduces CPU consumption at the cost of having lazy backup + # firewall replicas. The existing TCP states are: SYN_SENT, + # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, + # TIME_WAIT, CLOSED, LISTEN. + # + # State Accept { + # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP + # } + } +} diff --git a/doc/sync/ftfw/keepalived.conf b/doc/sync/ftfw/keepalived.conf new file mode 100644 index 0000000..f937467 --- /dev/null +++ b/doc/sync/ftfw/keepalived.conf @@ -0,0 +1,39 @@ +vrrp_sync_group G1 { # must be before vrrp_instance declaration + group { + VI_1 + VI_2 + } + notify_master /etc/conntrackd/script_master.sh + notify_backup /etc/conntrackd/script_backup.sh +# notify_fault /etc/conntrackd/script_fault.sh +} + +vrrp_instance VI_1 { + interface eth1 + state SLAVE + virtual_router_id 61 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.0.100 # default CIDR mask is /32 + } +} + +vrrp_instance VI_2 { + interface eth0 + state SLAVE + virtual_router_id 62 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.1.100 + } +} diff --git a/doc/sync/ftfw/node1/conntrackd.conf b/doc/sync/ftfw/node1/conntrackd.conf deleted file mode 100644 index 2da2e5f..0000000 --- a/doc/sync/ftfw/node1/conntrackd.conf +++ /dev/null @@ -1,165 +0,0 @@ -# -# Synchronizer settings -# -Sync { - Mode FTFW { - # - # Size of the buffer that hold destroy messages for - # possible resends (in bytes) - # - ResendBufferSize 262144 - - # - # Entries committed to the connection tracking table - # starts with a limited timeout of N seconds until the - # takeover process is completed. - # - CommitTimeout 180 - - # Set Acknowledgement window size - ACKWindowSize 20 - } - - # - # Multicast IP and interface where messages are - # broadcasted (dedicated link). IMPORTANT: Make sure - # that iptables accepts traffic for destination - # 225.0.0.50, eg: - # - # iptables -I INPUT -d 225.0.0.50 -j ACCEPT - # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT - # - Multicast { - IPv4_address 225.0.0.50 - IPv4_interface 192.168.100.100 # IP of dedicated link - Interface eth2 - Group 3780 - - # The multicast sender uses a buffer to enqueue the packets - # that are going to be transmitted. The default size of this - # socket buffer is available at /proc/sys/net/core/wmem_default. - # This value determines the chances to have an overrun in the - # sender queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size - # of the sender buffer. - # - # McastSndSocketBuffer 1249280 - # - # The multicast receiver uses a buffer to enqueue the packets - # that the socket is pending to handle. The default size of this - # socket buffer is available at /proc/sys/net/core/rmem_default. - # This value determines the chances to have an overrun in the - # receiver queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size of - # the receiver buffer. - # - # McastRcvSocketBuffer 1249280 - } - - # Enable/Disable message checksumming - Checksum on - - # If you have a multiprimary setup (active-active) without connection - # persistency, ie. you can't know which firewall handles a packet - # that is part of a connection, then you need direct commit of - # conntrack entries to the kernel conntrack table. OSPF setups must - # set on this option. Default is Off. - # - # CacheWriteThrough On -} - -# -# General settings -# -General { - # - # Number of buckets in the caches: hash table - # - HashSize 8192 - - # - # Maximum number of conntracks: - # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max - # - HashLimit 65535 - - # - # Logfile: on (/var/log/conntrackd.log), off, or a filename - # Default: off - # - #LogFile on - - # - # Syslog: on, off or a facility name (daemon (default) or local0..7) - # Default: off - # - #Syslog on - - # - # Lockfile - # - LockFile /var/lock/conntrack.lock - - # - # Unix socket configuration - # - UNIX { - Path /tmp/sync.sock - Backlog 20 - } - - # - # Netlink socket buffer size - # - SocketBufferSize 262142 - - # - # Increase the socket buffer up to maximum if required - # - SocketBufferSizeMaxGrown 655355 - - # - # Event filtering: This clause allows you to filter certain traffic, - # There are currently three filter-sets: Protocol, Address and - # State. The filter is attached to an action that can be: Accept or - # Ignore. Thus, you can define the event filtering policy of the - # filter-sets in positive or negative logic depending on your needs. - # - Filter { - # - # Accept only certain protocols: You may want to replicate - # the state of flows depending on their layer 4 protocol. - # - Protocol Accept { - TCP - } - - # - # Ignore traffic for a certain set of IP's: Usually all the - # IP assigned to the firewall since local traffic must be - # ignored, only forwarded connections are worth to replicate. - # - Address Ignore { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.1 - IPv4_address 192.168.1.1 - IPv4_address 192.168.100.100 # dedicated link ip - IPv4_address 192.168.0.100 # virtual IP 1 - IPv4_address 192.168.1.100 # virtual IP 2 - } - - # - # Uncomment this line below if you want to filter by flow state. - # This option introduces a trade-off in the replication: it - # reduces CPU consumption at the cost of having lazy backup - # firewall replicas. The existing TCP states are: SYN_SENT, - # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, - # TIME_WAIT, CLOSED, LISTEN. - # - # State Accept { - # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP - # } - } -} diff --git a/doc/sync/ftfw/node1/keepalived.conf b/doc/sync/ftfw/node1/keepalived.conf deleted file mode 100644 index f937467..0000000 --- a/doc/sync/ftfw/node1/keepalived.conf +++ /dev/null @@ -1,39 +0,0 @@ -vrrp_sync_group G1 { # must be before vrrp_instance declaration - group { - VI_1 - VI_2 - } - notify_master /etc/conntrackd/script_master.sh - notify_backup /etc/conntrackd/script_backup.sh -# notify_fault /etc/conntrackd/script_fault.sh -} - -vrrp_instance VI_1 { - interface eth1 - state SLAVE - virtual_router_id 61 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.0.100 # default CIDR mask is /32 - } -} - -vrrp_instance VI_2 { - interface eth0 - state SLAVE - virtual_router_id 62 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.1.100 - } -} diff --git a/doc/sync/ftfw/node2/conntrackd.conf b/doc/sync/ftfw/node2/conntrackd.conf deleted file mode 100644 index 8a7c214..0000000 --- a/doc/sync/ftfw/node2/conntrackd.conf +++ /dev/null @@ -1,164 +0,0 @@ -# -# Synchronizer settings -# -Sync { - Mode FTFW { - # - # Size of the buffer that hold destroy messages for - # possible resends (in bytes) - # - ResendBufferSize 262144 - - # Entries committed to the connection tracking table - # starts with a limited timeout of N seconds until the - # takeover process is completed. - # - CommitTimeout 180 - - # Set Acknowledgement window size - ACKWindowSize 20 - } - - # - # Multicast IP and interface where messages are - # broadcasted (dedicated link). IMPORTANT: Make sure - # that iptables accepts traffic for destination - # 225.0.0.50, eg: - # - # iptables -I INPUT -d 225.0.0.50 -j ACCEPT - # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT - # - Multicast { - IPv4_address 225.0.0.50 - IPv4_interface 192.168.100.200 # IP of dedicated link - Interface eth2 - Group 3780 - - # The multicast sender uses a buffer to enqueue the packets - # that are going to be transmitted. The default size of this - # socket buffer is available at /proc/sys/net/core/wmem_default. - # This value determines the chances to have an overrun in the - # sender queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size - # of the sender buffer. - # - # McastSndSocketBuffer 1249280 - # - # The multicast receiver uses a buffer to enqueue the packets - # that the socket is pending to handle. The default size of this - # socket buffer is available at /proc/sys/net/core/rmem_default. - # This value determines the chances to have an overrun in the - # receiver queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size of - # the receiver buffer. - # - # McastRcvSocketBuffer 1249280 - } - - # Enable/Disable message checksumming - Checksum on - - # If you have a multiprimary setup (active-active) without connection - # persistency, ie. you can't know which firewall handles a packet - # that is part of a connection, then you need direct commit of - # conntrack entries to the kernel conntrack table. OSPF setups must - # set on this option. Default is Off. - # - # CacheWriteThrough On -} - -# -# General settings -# -General { - # - # Number of buckets in the caches: hash table - # - HashSize 8192 - - # - # Maximum number of conntracks: - # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max - # - HashLimit 65535 - - # - # Logfile: on (/var/log/conntrackd.log), off, or a filename - # Default: off - # - #LogFile on - - # - # Syslog: on, off or a facility name (daemon (default) or local0..7) - # Default: off - # - #Syslog on - - # - # Lockfile - # - LockFile /var/lock/conntrack.lock - - # - # Unix socket configuration - # - UNIX { - Path /tmp/sync.sock - Backlog 20 - } - - # - # Netlink socket buffer size - # - SocketBufferSize 262142 - - # - # Increase the socket buffer up to maximum if required - # - SocketBufferSizeMaxGrown 655355 - - # - # Event filtering: This clause allows you to filter certain traffic, - # There are currently three filter-sets: Protocol, Address and - # State. The filter is attached to an action that can be: Accept or - # Ignore. Thus, you can define the event filtering policy of the - # filter-sets in positive or negative logic depending on your needs. - # - Filter { - # - # Accept only certain protocols: You may want to replicate - # the state of flows depending on their layer 4 protocol. - # - Protocol Accept { - TCP - } - - # - # Ignore traffic for a certain set of IP's: Usually all the - # IP assigned to the firewall since local traffic must be - # ignored, only forwarded connections are worth to replicate. - # - Address Ignore { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.2 - IPv4_address 192.168.1.2 - IPv4_address 192.168.100.200 # dedicated link ip - IPv4_address 192.168.0.100 # virtual IP 1 - IPv4_address 192.168.1.100 # virtual IP 2 - } - - # - # Uncomment this line below if you want to filter by flow state. - # This option introduces a trade-off in the replication: it - # reduces CPU consumption at the cost of having lazy backup - # firewall replicas. The existing TCP states are: SYN_SENT, - # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, - # TIME_WAIT, CLOSED, LISTEN. - # - # State Accept { - # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP - # } - } -} diff --git a/doc/sync/ftfw/node2/keepalived.conf b/doc/sync/ftfw/node2/keepalived.conf deleted file mode 100644 index f937467..0000000 --- a/doc/sync/ftfw/node2/keepalived.conf +++ /dev/null @@ -1,39 +0,0 @@ -vrrp_sync_group G1 { # must be before vrrp_instance declaration - group { - VI_1 - VI_2 - } - notify_master /etc/conntrackd/script_master.sh - notify_backup /etc/conntrackd/script_backup.sh -# notify_fault /etc/conntrackd/script_fault.sh -} - -vrrp_instance VI_1 { - interface eth1 - state SLAVE - virtual_router_id 61 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.0.100 # default CIDR mask is /32 - } -} - -vrrp_instance VI_2 { - interface eth0 - state SLAVE - virtual_router_id 62 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.1.100 - } -} diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf new file mode 100644 index 0000000..d54934a --- /dev/null +++ b/doc/sync/notrack/conntrackd.conf @@ -0,0 +1,186 @@ +# +# Synchronizer settings +# +Sync { + Mode NOTRACK { + # + # Entries committed to the connection tracking table + # starts with a limited timeout of N seconds until the + # takeover process is completed. + # + CommitTimeout 180 + } + + # + # Multicast IP and interface where messages are + # broadcasted (dedicated link). IMPORTANT: Make sure + # that iptables accepts traffic for destination + # 225.0.0.50, eg: + # + # iptables -I INPUT -d 225.0.0.50 -j ACCEPT + # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT + # + Multicast { + # + # Multicast address: The address that you use as destination + # in the synchronization messages. You do not have to add + # this IP to any of your existing interfaces. If any doubt, + # do not modify this value. + # + IPv4_address 225.0.0.50 + + # + # The multicast group that identifies the cluster. If any + # doubt, do not modify this value. + # + Group 3780 + + # + # IP address of the interface that you are going to use to + # send the synchronization messages. Remember that you must + # use a dedicated link for the synchronization messages. + # + IPv4_interface 192.168.100.100 + + # + # The name of the interface that you are going to use to + # send the synchronization messages. + # + Interface eth2 + + # The multicast sender uses a buffer to enqueue the packets + # that are going to be transmitted. The default size of this + # socket buffer is available at /proc/sys/net/core/wmem_default. + # This value determines the chances to have an overrun in the + # sender queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size + # of the sender buffer. Note: This protocol is best effort, + # really recommended to increase the buffer size. + + McastSndSocketBuffer 1249280 + + # The multicast receiver uses a buffer to enqueue the packets + # that the socket is pending to handle. The default size of this + # socket buffer is available at /proc/sys/net/core/rmem_default. + # This value determines the chances to have an overrun in the + # receiver queue. The overrun results packet loss, thus, losing + # state information that would have to be retransmitted. If you + # notice some packet loss, you may want to increase the size of + # the receiver buffer. Note: This protocol is best effort, + # really recommended to increase the buffer size. + + McastRcvSocketBuffer 1249280 + } + + # + # Enable/Disable message checksumming. This is a good property to + # achieve fault-tolerance. In case of doubt, do not modify this value. + # + Checksum on + + # If you have a multiprimary setup (active-active) without connection + # persistency, ie. you can't know which firewall handles a packet + # that is part of a connection, then you need direct commit of + # conntrack entries to the kernel conntrack table. OSPF setups must + # set on this option. If you have a simple primary-backup scenario. + # Do not set it on. Default is off. + # + # CacheWriteThrough On +} + +# +# General settings +# +General { + # + # Number of buckets in the caches: hash table. + # + HashSize 8192 + + # + # Maximum number of conntracks: + # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max + # + HashLimit 65535 + + # + # Logfile: on (/var/log/conntrackd.log), off, or a filename + # Default: off + # + LogFile on + + # + # Syslog: on, off or a facility name (daemon (default) or local0..7) + # Default: off + # + #Syslog on + + # + # Lockfile + # + LockFile /var/lock/conntrack.lock + + # + # Unix socket configuration + # + UNIX { + Path /tmp/sync.sock + Backlog 20 + } + + # + # Netlink socket buffer size + # + SocketBufferSize 262142 + + # + # Increase the socket buffer up to maximum if required + # + SocketBufferSizeMaxGrown 655355 + + # + # Event filtering: This clause allows you to filter certain traffic, + # There are currently three filter-sets: Protocol, Address and + # State. The filter is attached to an action that can be: Accept or + # Ignore. Thus, you can define the event filtering policy of the + # filter-sets in positive or negative logic depending on your needs. + # + Filter { + # + # Accept only certain protocols: You may want to replicate + # the state of flows depending on their layer 4 protocol. + # + Protocol Accept { + TCP + } + + # + # Ignore traffic for a certain set of IP's: Usually all the + # IP assigned to the firewall since local traffic must be + # ignored, only forwarded connections are worth to replicate. + # Note that these values depends on the local IPs that are + # assigned to the firewall. + # + Address Ignore { + IPv4_address 127.0.0.1 # loopback + IPv4_address 192.168.0.100 # virtual IP 1 + IPv4_address 192.168.1.100 # virtual IP 2 + IPv4_address 192.168.0.1 + IPv4_address 192.168.1.1 + IPv4_address 192.168.100.100 # dedicated link ip + } + + # + # Uncomment this line below if you want to filter by flow state. + # This option introduces a trade-off in the replication: it + # reduces CPU consumption at the cost of having lazy backup + # firewall replicas. The existing TCP states are: SYN_SENT, + # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, + # TIME_WAIT, CLOSED, LISTEN. + # + # State Accept { + # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP + # } + } +} diff --git a/doc/sync/notrack/keepalived.conf b/doc/sync/notrack/keepalived.conf new file mode 100644 index 0000000..f937467 --- /dev/null +++ b/doc/sync/notrack/keepalived.conf @@ -0,0 +1,39 @@ +vrrp_sync_group G1 { # must be before vrrp_instance declaration + group { + VI_1 + VI_2 + } + notify_master /etc/conntrackd/script_master.sh + notify_backup /etc/conntrackd/script_backup.sh +# notify_fault /etc/conntrackd/script_fault.sh +} + +vrrp_instance VI_1 { + interface eth1 + state SLAVE + virtual_router_id 61 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.0.100 # default CIDR mask is /32 + } +} + +vrrp_instance VI_2 { + interface eth0 + state SLAVE + virtual_router_id 62 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.1.100 + } +} diff --git a/doc/sync/notrack/node1/conntrackd.conf b/doc/sync/notrack/node1/conntrackd.conf deleted file mode 100644 index 15781a5..0000000 --- a/doc/sync/notrack/node1/conntrackd.conf +++ /dev/null @@ -1,158 +0,0 @@ -# -# Synchronizer settings -# -Sync { - Mode NOTRACK { - # - # Entries committed to the connection tracking table - # starts with a limited timeout of N seconds until the - # takeover process is completed. - # - CommitTimeout 180 - } - - # - # Multicast IP and interface where messages are - # broadcasted (dedicated link). IMPORTANT: Make sure - # that iptables accepts traffic for destination - # 225.0.0.50, eg: - # - # iptables -I INPUT -d 225.0.0.50 -j ACCEPT - # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT - # - Multicast { - IPv4_address 225.0.0.50 - IPv4_interface 192.168.100.100 # IP of dedicated link - Interface eth2 - Group 3780 - - # The multicast sender uses a buffer to enqueue the packets - # that are going to be transmitted. The default size of this - # socket buffer is available at /proc/sys/net/core/wmem_default. - # This value determines the chances to have an overrun in the - # sender queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size - # of the sender buffer. Note: This protocol is best effort, - # really recommended to increase the buffer size. - - McastSndSocketBuffer 1249280 - - # The multicast receiver uses a buffer to enqueue the packets - # that the socket is pending to handle. The default size of this - # socket buffer is available at /proc/sys/net/core/rmem_default. - # This value determines the chances to have an overrun in the - # receiver queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size of - # the receiver buffer. Note: This protocol is best effort, - # really recommended to increase the buffer size. - - McastRcvSocketBuffer 1249280 - } - - # Enable/Disable message checksumming - Checksum on - - # If you have a multiprimary setup (active-active) without connection - # persistency, ie. you can't know which firewall handles a packet - # that is part of a connection, then you need direct commit of - # conntrack entries to the kernel conntrack table. OSPF setups must - # set on this option. Default is Off. - # - # CacheWriteThrough On -} - -# -# General settings -# -General { - # - # Number of buckets in the caches: hash table - # - HashSize 8192 - - # - # Maximum number of conntracks: - # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max - # - HashLimit 65535 - - # - # Logfile: on (/var/log/conntrackd.log), off, or a filename - # Default: off - # - #LogFile on - - # - # Syslog: on, off or a facility name (daemon (default) or local0..7) - # Default: off - # - #Syslog on - - # - # Lockfile - # - LockFile /var/lock/conntrack.lock - - # - # Unix socket configuration - # - UNIX { - Path /tmp/sync.sock - Backlog 20 - } - - # - # Netlink socket buffer size - # - SocketBufferSize 262142 - - # - # Increase the socket buffer up to maximum if required - # - SocketBufferSizeMaxGrown 655355 - - # - # Event filtering: This clause allows you to filter certain traffic, - # There are currently three filter-sets: Protocol, Address and - # State. The filter is attached to an action that can be: Accept or - # Ignore. Thus, you can define the event filtering policy of the - # filter-sets in positive or negative logic depending on your needs. - # - Filter { - # - # Accept only certain protocols: You may want to replicate - # the state of flows depending on their layer 4 protocol. - # - Protocol Accept { - TCP - } - - # - # Ignore traffic for a certain set of IP's: Usually all the - # IP assigned to the firewall since local traffic must be - # ignored, only forwarded connections are worth to replicate. - # - Address Ignore { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.1 - IPv4_address 192.168.1.1 - IPv4_address 192.168.100.100 # dedicated link ip - IPv4_address 192.168.0.100 # virtual IP 1 - IPv4_address 192.168.1.100 # virtual IP 2 - } - - # - # Uncomment this line below if you want to filter by flow state. - # This option introduces a trade-off in the replication: it - # reduces CPU consumption at the cost of having lazy backup - # firewall replicas. The existing TCP states are: SYN_SENT, - # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, - # TIME_WAIT, CLOSED, LISTEN. - # - # State Accept { - # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP - # } - } -} diff --git a/doc/sync/notrack/node1/keepalived.conf b/doc/sync/notrack/node1/keepalived.conf deleted file mode 100644 index f937467..0000000 --- a/doc/sync/notrack/node1/keepalived.conf +++ /dev/null @@ -1,39 +0,0 @@ -vrrp_sync_group G1 { # must be before vrrp_instance declaration - group { - VI_1 - VI_2 - } - notify_master /etc/conntrackd/script_master.sh - notify_backup /etc/conntrackd/script_backup.sh -# notify_fault /etc/conntrackd/script_fault.sh -} - -vrrp_instance VI_1 { - interface eth1 - state SLAVE - virtual_router_id 61 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.0.100 # default CIDR mask is /32 - } -} - -vrrp_instance VI_2 { - interface eth0 - state SLAVE - virtual_router_id 62 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.1.100 - } -} diff --git a/doc/sync/notrack/node2/conntrackd.conf b/doc/sync/notrack/node2/conntrackd.conf deleted file mode 100644 index 0257ddc..0000000 --- a/doc/sync/notrack/node2/conntrackd.conf +++ /dev/null @@ -1,157 +0,0 @@ -# -# Synchronizer settings -# -Sync { - Mode NOTRACK { - # Entries committed to the connection tracking table - # starts with a limited timeout of N seconds until the - # takeover process is completed. - # - CommitTimeout 180 - } - - # - # Multicast IP and interface where messages are - # broadcasted (dedicated link). IMPORTANT: Make sure - # that iptables accepts traffic for destination - # 225.0.0.50, eg: - # - # iptables -I INPUT -d 225.0.0.50 -j ACCEPT - # iptables -I OUTPUT -d 225.0.0.50 -j ACCEPT - # - Multicast { - IPv4_address 225.0.0.50 - IPv4_interface 192.168.100.200 # IP of dedicated link - Interface eth2 - Group 3780 - - # The multicast sender uses a buffer to enqueue the packets - # that are going to be transmitted. The default size of this - # socket buffer is available at /proc/sys/net/core/wmem_default. - # This value determines the chances to have an overrun in the - # sender queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size - # of the sender buffer. Note: This protocol is best effort, - # really recommended to increase the buffer size. - - McastSndSocketBuffer 1249280 - - # The multicast receiver uses a buffer to enqueue the packets - # that the socket is pending to handle. The default size of this - # socket buffer is available at /proc/sys/net/core/rmem_default. - # This value determines the chances to have an overrun in the - # receiver queue. The overrun results packet loss, thus, losing - # state information that would have to be retransmitted. If you - # notice some packet loss, you may want to increase the size of - # the receiver buffer. Note: This protocol is best effort, - # really recommended to increase the buffer size. - - McastRcvSocketBuffer 1249280 - } - - # Enable/Disable message checksumming - Checksum on - - # If you have a multiprimary setup (active-active) without connection - # persistency, ie. you can't know which firewall handles a packet - # that is part of a connection, then you need direct commit of - # conntrack entries to the kernel conntrack table. OSPF setups must - # set on this option. Default is Off. - # - # CacheWriteThrough On -} - -# -# General settings -# -General { - # - # Number of buckets in the caches: hash table - # - HashSize 8192 - - # - # Maximum number of conntracks: - # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max - # - HashLimit 65535 - - # - # Logfile: on (/var/log/conntrackd.log), off, or a filename - # Default: off - # - #LogFile on - - # - # Syslog: on, off or a facility name (daemon (default) or local0..7) - # Default: off - # - #Syslog on - - # - # Lockfile - # - LockFile /var/lock/conntrack.lock - - # - # Unix socket configuration - # - UNIX { - Path /tmp/sync.sock - Backlog 20 - } - - # - # Netlink socket buffer size - # - SocketBufferSize 262142 - - # - # Increase the socket buffer up to maximum if required - # - SocketBufferSizeMaxGrown 655355 - - # - # Event filtering: This clause allows you to filter certain traffic, - # There are currently three filter-sets: Protocol, Address and - # State. The filter is attached to an action that can be: Accept or - # Ignore. Thus, you can define the event filtering policy of the - # filter-sets in positive or negative logic depending on your needs. - # - Filter { - # - # Accept only certain protocols: You may want to replicate - # the state of flows depending on their layer 4 protocol. - # - Protocol Accept { - TCP - } - - # - # Ignore traffic for a certain set of IP's: Usually all the - # IP assigned to the firewall since local traffic must be - # ignored, only forwarded connections are worth to replicate. - # - Address Ignore { - IPv4_address 127.0.0.1 # loopback - IPv4_address 192.168.0.2 - IPv4_address 192.168.1.2 - IPv4_address 192.168.100.200 # dedicated link ip - IPv4_address 192.168.0.100 # virtual IP 1 - IPv4_address 192.168.1.100 # virtual IP 2 - } - - # - # Uncomment this line below if you want to filter by flow state. - # This option introduces a trade-off in the replication: it - # reduces CPU consumption at the cost of having lazy backup - # firewall replicas. The existing TCP states are: SYN_SENT, - # SYN_RECV, ESTABLISHED, FIN_WAIT, CLOSE_WAIT, LAST_ACK, - # TIME_WAIT, CLOSED, LISTEN. - # - # State Accept { - # ESTABLISHED CLOSED TIME_WAIT CLOSE_WAIT for TCP - # } - } -} diff --git a/doc/sync/notrack/node2/keepalived.conf b/doc/sync/notrack/node2/keepalived.conf deleted file mode 100644 index f937467..0000000 --- a/doc/sync/notrack/node2/keepalived.conf +++ /dev/null @@ -1,39 +0,0 @@ -vrrp_sync_group G1 { # must be before vrrp_instance declaration - group { - VI_1 - VI_2 - } - notify_master /etc/conntrackd/script_master.sh - notify_backup /etc/conntrackd/script_backup.sh -# notify_fault /etc/conntrackd/script_fault.sh -} - -vrrp_instance VI_1 { - interface eth1 - state SLAVE - virtual_router_id 61 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.0.100 # default CIDR mask is /32 - } -} - -vrrp_instance VI_2 { - interface eth0 - state SLAVE - virtual_router_id 62 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.1.100 - } -} -- cgit v1.2.3 From c403246424350bae14a30fc6a115608ca15f2aa1 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 2 Aug 2008 18:51:34 +0200 Subject: script: rework scripts that enable interaction with keepalived This patch reworks the documentation section. It removes the replicated keepalived.conf files and merge all the scripts into one to reduce confusion and improve maintainability. It's likely that the documentation directory will suffer more restructurations in the near future. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/keepalived.conf | 39 ---------------- doc/sync/alarm/script_backup.sh | 3 -- doc/sync/alarm/script_master.sh | 4 -- doc/sync/ftfw/keepalived.conf | 39 ---------------- doc/sync/ftfw/script_backup.sh | 3 -- doc/sync/ftfw/script_master.sh | 5 --- doc/sync/keepalived.conf | 42 +++++++++++++++++ doc/sync/notrack/keepalived.conf | 39 ---------------- doc/sync/notrack/script_backup.sh | 3 -- doc/sync/notrack/script_master.sh | 5 --- doc/sync/primary-backup.sh | 94 +++++++++++++++++++++++++++++++++++++++ 11 files changed, 136 insertions(+), 140 deletions(-) delete mode 100644 doc/sync/alarm/keepalived.conf delete mode 100644 doc/sync/alarm/script_backup.sh delete mode 100644 doc/sync/alarm/script_master.sh delete mode 100644 doc/sync/ftfw/keepalived.conf delete mode 100644 doc/sync/ftfw/script_backup.sh delete mode 100644 doc/sync/ftfw/script_master.sh create mode 100644 doc/sync/keepalived.conf delete mode 100644 doc/sync/notrack/keepalived.conf delete mode 100644 doc/sync/notrack/script_backup.sh delete mode 100644 doc/sync/notrack/script_master.sh create mode 100755 doc/sync/primary-backup.sh (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/keepalived.conf b/doc/sync/alarm/keepalived.conf deleted file mode 100644 index f937467..0000000 --- a/doc/sync/alarm/keepalived.conf +++ /dev/null @@ -1,39 +0,0 @@ -vrrp_sync_group G1 { # must be before vrrp_instance declaration - group { - VI_1 - VI_2 - } - notify_master /etc/conntrackd/script_master.sh - notify_backup /etc/conntrackd/script_backup.sh -# notify_fault /etc/conntrackd/script_fault.sh -} - -vrrp_instance VI_1 { - interface eth1 - state SLAVE - virtual_router_id 61 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.0.100 # default CIDR mask is /32 - } -} - -vrrp_instance VI_2 { - interface eth0 - state SLAVE - virtual_router_id 62 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.1.100 - } -} diff --git a/doc/sync/alarm/script_backup.sh b/doc/sync/alarm/script_backup.sh deleted file mode 100644 index 8ea2ad8..0000000 --- a/doc/sync/alarm/script_backup.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -/usr/sbin/conntrackd -B diff --git a/doc/sync/alarm/script_master.sh b/doc/sync/alarm/script_master.sh deleted file mode 100644 index 70c26c9..0000000 --- a/doc/sync/alarm/script_master.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -/usr/sbin/conntrackd -c -/usr/sbin/conntrackd -R diff --git a/doc/sync/ftfw/keepalived.conf b/doc/sync/ftfw/keepalived.conf deleted file mode 100644 index f937467..0000000 --- a/doc/sync/ftfw/keepalived.conf +++ /dev/null @@ -1,39 +0,0 @@ -vrrp_sync_group G1 { # must be before vrrp_instance declaration - group { - VI_1 - VI_2 - } - notify_master /etc/conntrackd/script_master.sh - notify_backup /etc/conntrackd/script_backup.sh -# notify_fault /etc/conntrackd/script_fault.sh -} - -vrrp_instance VI_1 { - interface eth1 - state SLAVE - virtual_router_id 61 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.0.100 # default CIDR mask is /32 - } -} - -vrrp_instance VI_2 { - interface eth0 - state SLAVE - virtual_router_id 62 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.1.100 - } -} diff --git a/doc/sync/ftfw/script_backup.sh b/doc/sync/ftfw/script_backup.sh deleted file mode 100644 index 813e375..0000000 --- a/doc/sync/ftfw/script_backup.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -/usr/sbin/conntrackd -n # request a resync from other nodes via multicast diff --git a/doc/sync/ftfw/script_master.sh b/doc/sync/ftfw/script_master.sh deleted file mode 100644 index ff1dbc0..0000000 --- a/doc/sync/ftfw/script_master.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -/usr/sbin/conntrackd -c # commit the cache -/usr/sbin/conntrackd -f # flush the caches -/usr/sbin/conntrackd -R # resync with kernel conntrack table diff --git a/doc/sync/keepalived.conf b/doc/sync/keepalived.conf new file mode 100644 index 0000000..b7638a7 --- /dev/null +++ b/doc/sync/keepalived.conf @@ -0,0 +1,42 @@ +# +# Simple script for primary-backup setups +# + +vrrp_sync_group G1 { # must be before vrrp_instance declaration + group { + VI_1 + VI_2 + } + notify_master /etc/conntrackd/primary-backup.sh + notify_backup /etc/conntrackd/primary-backup.sh +} + +vrrp_instance VI_1 { + interface eth1 + state SLAVE + virtual_router_id 61 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.0.100 # default CIDR mask is /32 + } +} + +vrrp_instance VI_2 { + interface eth0 + state SLAVE + virtual_router_id 62 + priority 80 + advert_int 3 + authentication { + auth_type PASS + auth_pass papas_con_tomate + } + virtual_ipaddress { + 192.168.1.100 + } +} diff --git a/doc/sync/notrack/keepalived.conf b/doc/sync/notrack/keepalived.conf deleted file mode 100644 index f937467..0000000 --- a/doc/sync/notrack/keepalived.conf +++ /dev/null @@ -1,39 +0,0 @@ -vrrp_sync_group G1 { # must be before vrrp_instance declaration - group { - VI_1 - VI_2 - } - notify_master /etc/conntrackd/script_master.sh - notify_backup /etc/conntrackd/script_backup.sh -# notify_fault /etc/conntrackd/script_fault.sh -} - -vrrp_instance VI_1 { - interface eth1 - state SLAVE - virtual_router_id 61 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.0.100 # default CIDR mask is /32 - } -} - -vrrp_instance VI_2 { - interface eth0 - state SLAVE - virtual_router_id 62 - priority 80 - advert_int 3 - authentication { - auth_type PASS - auth_pass papas_con_tomate - } - virtual_ipaddress { - 192.168.1.100 - } -} diff --git a/doc/sync/notrack/script_backup.sh b/doc/sync/notrack/script_backup.sh deleted file mode 100644 index 813e375..0000000 --- a/doc/sync/notrack/script_backup.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -/usr/sbin/conntrackd -n # request a resync from other nodes via multicast diff --git a/doc/sync/notrack/script_master.sh b/doc/sync/notrack/script_master.sh deleted file mode 100644 index ff1dbc0..0000000 --- a/doc/sync/notrack/script_master.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -/usr/sbin/conntrackd -c # commit the cache -/usr/sbin/conntrackd -f # flush the caches -/usr/sbin/conntrackd -R # resync with kernel conntrack table diff --git a/doc/sync/primary-backup.sh b/doc/sync/primary-backup.sh new file mode 100755 index 0000000..fddff3b --- /dev/null +++ b/doc/sync/primary-backup.sh @@ -0,0 +1,94 @@ +#!/bin/sh +# +# (C) 2008 by Pablo Neira Ayuso +# +# This software may be used and distributed according to the terms +# of the GNU General Public License, incorporated herein by reference. +# +# Description: +# +# This is the script for primary-backup setups for keepalived +# (http://www.keepalived.org). You may adapt it to make it work with other +# high-availability managers. +# +# Do not forget to include the required modifications to your keepalived.conf +# file to invoke this script during keepalived's state transitions. +# +# Contributions to improve this script are welcome :). +# + +CONNTRACKD_BIN=/usr/sbin/conntrackd +CONNTRACKD_LOCK=/var/lock/conntrack.lock +CONNTRACKD_CONFIG=/etc/conntrackd/conntrackd.conf + +case "$1" in + master) + # + # commit the external cache into the kernel table + # + $CONNTRACKD_BIN -C $CONNTRACKD_CONFIG -c + if [ $? -eq 1 ] + logger "ERROR: failed to invoke conntrackd -c" + + # + # flush the internal and the external caches + # + $CONNTRACKD_BIN -C $CONNTRACK_CONFIG -f + if [ $? -eq 1 ] + logger "ERROR: failed to invoke conntrackd -f" + + # + # resynchronize my internal cache to the kernel table + # + $CONNTRACKD_BIN -C $CONNTRACKD_CONFIG -R + if [ $? -eq 1 ] + logger "ERROR: failed to invoke conntrackd -R" + ;; + backup) + # + # is conntrackd running? request some statistics to check it + # + $CONNTRACKD_BIN -C $CONNTRACKD_CONFIG -s + if [ $? -eq 1 ] + then + # + # something's wrong, do we have a lock file? + # + if [ -f $CONNTRACKD_LOCK ] + then + logger "WARNING: conntrackd was not cleanly stopped." + logger "If you suspect that it has crashed:" + logger "1) Enable coredumps" + logger "2) Try to reproduce the problem" + logger "3) Post the coredump to netfilter-devel@vger.kernel.org" + rm -f $CONNTRACKD_LOCK + fi + $CONNTRACKD_BIN -C $CONNTRACKD_CONFIG -d + if [ $? -eq 1 ] + then + logger "ERROR: cannot launch conntrackd" + exit 1 + fi + fi + # + # shorten kernel conntrack timers to remove the zombie entries. + # + $CONNTRACKD_BIN -C $CONNTRACKD_CONFIG -t + if [ $? -eq 1 ] + logger "ERROR: failed to invoke conntrackd -t" + + # + # request resynchronization with master firewall replica (if any) + # Note: this does nothing in the alarm approach. + # + $CONNTRACKD_BIN -C $CONNTRACKD_CONFIG -n + if [ $? -eq 1 ] + logger "ERROR: failed to invoke conntrackd -n" + ;; + *) + echo "Usage: primary-backup.sh {primary|backup}" + exit 1 + ;; +esac + +exit 0 -- cgit v1.2.3 From 6cb33c62c8007593d8a85aa202fa173043877135 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 7 Aug 2008 14:53:12 +0200 Subject: cache iterators: rework cache_reset_timers This patch adds the clause PurgeTimeout that sets the new timer when conntrackd -t is called. This command is particularly useful when the sysadmin triggers hand-overs between several nodes without rebooting as it reduces the timers of the remaining entries in the kernel. Thus, avoiding clashes between new and old entries that may trigger INVALID packets. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 11 +++++++++++ doc/sync/ftfw/conntrackd.conf | 11 +++++++++++ doc/sync/keepalived.conf | 1 + doc/sync/notrack/conntrackd.conf | 11 +++++++++++ doc/sync/primary-backup.sh | 12 +++++++++++- include/conntrackd.h | 1 + src/cache_iterators.c | 17 +++++++++++++---- src/read_config_lex.l | 1 + src/read_config_yy.y | 12 +++++++++++- src/sync-mode.c | 15 --------------- 10 files changed, 71 insertions(+), 21 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index a65a378..d6f7a2a 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -23,6 +23,17 @@ Sync { # takeover process is completed. # CommitTimeout 180 + + # + # If the firewall replica goes from primary to backup, + # the conntrackd -t command is invoked in the script. + # This command resets the timers of the conntracks that + # live in the kernel to this new value. This is useful + # to purge the connection tracking table of zombie entries + # and avoid clashes with old entries if you trigger + # several consecutive hand-overs. + # + PurgeTimeout 15 } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 6fec9a1..8f4d952 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -16,6 +16,17 @@ Sync { # CommitTimeout 180 + # + # If the firewall replica goes from primary to backup, + # the conntrackd -t command is invoked in the script. + # This command resets the timers of the conntracks that + # live in the kernel to this new value. This is useful + # to purge the connection tracking table of zombie entries + # and avoid clashes with old entries if you trigger + # several consecutive hand-overs. + # + PurgeTimeout 15 + # Set Acknowledgement window size ACKWindowSize 20 } diff --git a/doc/sync/keepalived.conf b/doc/sync/keepalived.conf index c9c8ac1..84f1383 100644 --- a/doc/sync/keepalived.conf +++ b/doc/sync/keepalived.conf @@ -9,6 +9,7 @@ vrrp_sync_group G1 { # must be before vrrp_instance declaration } notify_master "/etc/conntrackd/primary-backup.sh primary" notify_backup "/etc/conntrackd/primary-backup.sh backup" + notify_fault "/etc/conntrackd/primary-backup.sh fault" } vrrp_instance VI_1 { diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index d54934a..3ce1fa0 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -9,6 +9,17 @@ Sync { # takeover process is completed. # CommitTimeout 180 + + # + # If the firewall replica goes from primary to backup, + # the conntrackd -t command is invoked in the script. + # This command resets the timers of the conntracks that + # live in the kernel to this new value. This is useful + # to purge the connection tracking table of zombie entries + # and avoid clashes with old entries if you trigger + # several consecutive hand-overs. + # + PurgeTimeout 15 } # diff --git a/doc/sync/primary-backup.sh b/doc/sync/primary-backup.sh index 27fb1c3..e5331e3 100755 --- a/doc/sync/primary-backup.sh +++ b/doc/sync/primary-backup.sh @@ -95,9 +95,19 @@ case "$1" in logger "ERROR: failed to invoke conntrackd -n" fi ;; + fault) + # + # shorten kernel conntrack timers to remove the zombie entries. + # + $CONNTRACKD_BIN -C $CONNTRACKD_CONFIG -t + if [ $? -eq 1 ] + then + logger "ERROR: failed to invoke conntrackd -t" + fi + ;; *) logger "ERROR: unknown state transition" - echo "Usage: primary-backup.sh {primary|backup}" + echo "Usage: primary-backup.sh {primary|backup|fault}" exit 1 ;; esac diff --git a/include/conntrackd.h b/include/conntrackd.h index 60bb2de..23f5306 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -79,6 +79,7 @@ struct ct_conf { int refresh; int cache_timeout; /* cache entries timeout */ int commit_timeout; /* committed entries timeout */ + unsigned int purge_timeout; /* purge kernel entries timeout */ int del_timeout; unsigned int netlink_buffer_size; unsigned int netlink_buffer_size_max_grown; diff --git a/src/cache_iterators.c b/src/cache_iterators.c index a7c6654..8898930 100644 --- a/src/cache_iterators.c +++ b/src/cache_iterators.c @@ -55,6 +55,10 @@ static int do_dump(void *data1, void *data2) if (CONFIG(flags) & CTD_SYNC_FTFW && alarm_pending(&u->alarm)) return 0; + /* do not show cached timeout, this may confuse users */ + if (nfct_attr_is_set(u->ct, ATTR_TIMEOUT)) + nfct_attr_unset(u->ct, ATTR_TIMEOUT); + memset(buf, 0, sizeof(buf)); size = nfct_snprintf(buf, sizeof(buf), @@ -177,13 +181,11 @@ void cache_commit(struct cache *c) static int do_reset_timers(void *data1, void *data2) { int ret; + u_int32_t current_timeout; struct us_conntrack *u = data2; struct nf_conntrack *ct = u->ct; - /* this may increase timers but they will end up dying shortly anyway */ - nfct_set_attr_u32(ct, ATTR_TIMEOUT, CONFIG(commit_timeout)); - - ret = nl_exist_conntrack(ct); + ret = nl_get_conntrack(ct); switch (ret) { case -1: /* the kernel table is not in sync with internal cache */ @@ -191,6 +193,13 @@ static int do_reset_timers(void *data1, void *data2) dlog_ct(STATE(log), ct, NFCT_O_PLAIN); break; case 1: + current_timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT); + /* already about to die, do not touch it */ + if (current_timeout < CONFIG(purge_timeout)) + break; + + nfct_set_attr_u32(ct, ATTR_TIMEOUT, CONFIG(purge_timeout)); + if (nl_update_conntrack(ct) == -1) { if (errno == ETIME || errno == ENOENT) break; diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 584a4a3..79d5b89 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -111,6 +111,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "State" { return T_STATE; } "Accept" { return T_ACCEPT; } "Ignore" { return T_IGNORE; } +"PurgeTimeout" { return T_PURGE; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 33a435c..c7bce82 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -52,7 +52,7 @@ static void __kernel_filter_add_state(int value); %token T_GENERAL T_SYNC T_STATS T_RELAX_TRANSITIONS T_BUFFER_SIZE T_DELAY %token T_SYNC_MODE T_LISTEN_TO T_FAMILY T_RESEND_BUFFER_SIZE %token T_ALARM T_FTFW T_CHECKSUM T_WINDOWSIZE T_ON T_OFF -%token T_REPLICATE T_FOR T_IFACE +%token T_REPLICATE T_FOR T_IFACE T_PURGE %token T_ESTABLISHED T_SYN_SENT T_SYN_RECV T_FIN_WAIT %token T_CLOSE_WAIT T_LAST_ACK T_TIME_WAIT T_CLOSE T_LISTEN %token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT @@ -163,6 +163,11 @@ timeout: T_TIMEOUT T_NUMBER conf.commit_timeout = $2; }; +purge: T_PURGE T_NUMBER +{ + conf.purge_timeout = $2; +}; + checksum: T_CHECKSUM T_ON { conf.mcast.checksum = 0; @@ -427,6 +432,7 @@ sync_list: sync_line: refreshtime | expiretime | timeout + | purge | checksum | multicast_line | relax_transitions @@ -987,6 +993,10 @@ init_config(char *filename) if (CONFIG(commit_timeout) == 0) CONFIG(commit_timeout) = 180; + /* default to 15 seconds: purge kernel entries */ + if (CONFIG(purge_timeout) == 0) + CONFIG(purge_timeout) = 15; + /* default to 60 seconds of refresh time */ if (CONFIG(refresh) == 0) CONFIG(refresh) = 60; diff --git a/src/sync-mode.c b/src/sync-mode.c index 297a500..db199bc 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -378,9 +378,6 @@ static int local_handler_sync(int fd, int type, void *data) static void dump_sync(struct nf_conntrack *ct) { - if (!CONFIG(cache_write_through)) - nfct_attr_unset(ct, ATTR_TIMEOUT); - /* This is required by kernels < 2.6.20 */ nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); @@ -438,9 +435,6 @@ static int overrun_sync(enum nf_conntrack_msg_type type, if (ignore_conntrack(ct)) return NFCT_CB_CONTINUE; - if (!CONFIG(cache_write_through)) - nfct_attr_unset(ct, ATTR_TIMEOUT); - /* This is required by kernels < 2.6.20 */ nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); @@ -462,9 +456,6 @@ static void event_new_sync(struct nf_conntrack *ct) { struct us_conntrack *u; - if (!CONFIG(cache_write_through)) - nfct_attr_unset(ct, ATTR_TIMEOUT); - /* required by linux kernel <= 2.6.20 */ nfct_attr_unset(ct, ATTR_ORIG_COUNTER_BYTES); nfct_attr_unset(ct, ATTR_ORIG_COUNTER_PACKETS); @@ -490,9 +481,6 @@ static void event_update_sync(struct nf_conntrack *ct) { struct us_conntrack *u; - if (!CONFIG(cache_write_through)) - nfct_attr_unset(ct, ATTR_TIMEOUT); - if ((u = cache_update_force(STATE_SYNC(internal), ct)) == NULL) { debug_ct(ct, "can't update"); return; @@ -505,9 +493,6 @@ static int event_destroy_sync(struct nf_conntrack *ct) { struct us_conntrack *u; - if (!CONFIG(cache_write_through)) - nfct_attr_unset(ct, ATTR_TIMEOUT); - u = cache_find(STATE_SYNC(internal), ct); if (u == NULL) { debug_ct(ct, "can't destroy"); -- cgit v1.2.3 From ce7c1553d7720188447d0ae7f7f80ce033b5a8d8 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 18 Sep 2008 18:44:23 +0200 Subject: config: use /var/run to create the UNIX socket file This patch removes the use of /tmp to create the UNIX socket file to communicate with conntrackd in the example configuration files. This was OK in the early alpha days, but not anymore. Signed-off-by: Pablo Neira Ayuso --- doc/stats/conntrackd.conf | 2 +- doc/sync/alarm/conntrackd.conf | 2 +- doc/sync/ftfw/conntrackd.conf | 2 +- doc/sync/notrack/conntrackd.conf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index 4f0a6e2..1fc21af 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -34,7 +34,7 @@ General { # Unix socket configuration # UNIX { - Path /tmp/sync.sock + Path /var/run/conntrackd.ctl Backlog 20 } diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index d6f7a2a..9fc9d03 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -148,7 +148,7 @@ General { # Unix socket configuration # UNIX { - Path /tmp/sync.sock + Path /var/run/conntrackd.ctl Backlog 20 } diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 8f4d952..010ff03 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -143,7 +143,7 @@ General { # Unix socket configuration # UNIX { - Path /tmp/sync.sock + Path /var/run/conntrackd.ctl Backlog 20 } diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 3ce1fa0..0d05e17 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -136,7 +136,7 @@ General { # Unix socket configuration # UNIX { - Path /tmp/sync.sock + Path /var/run/conntrackd.ctl Backlog 20 } -- cgit v1.2.3 From 5936f6852a919a84b89dcdcced182ecc07a21be5 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 20 Oct 2008 16:52:04 +0200 Subject: doc: rise default size of the hashtable in the example file This patch rises the default value of the hashtables in terms of buckets and entries to the default value in nf_conntrack. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 4 ++-- doc/sync/ftfw/conntrackd.conf | 4 ++-- doc/sync/notrack/conntrackd.conf | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 9fc9d03..e48ca2d 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -119,13 +119,13 @@ General { # # Number of buckets in the caches: hash table. # - HashSize 8192 + HashSize 16384 # # Maximum number of conntracks: # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max # - HashLimit 65535 + HashLimit 65536 # # Logfile: on (/var/log/conntrackd.log), off, or a filename diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 010ff03..40f8457 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -114,13 +114,13 @@ General { # # Number of buckets in the caches: hash table. # - HashSize 8192 + HashSize 16384 # # Maximum number of conntracks: # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max # - HashLimit 65535 + HashLimit 65536 # # Logfile: on (/var/log/conntrackd.log), off, or a filename diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 0d05e17..b135814 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -107,13 +107,13 @@ General { # # Number of buckets in the caches: hash table. # - HashSize 8192 + HashSize 16384 # # Maximum number of conntracks: # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max # - HashLimit 65535 + HashLimit 65536 # # Logfile: on (/var/log/conntrackd.log), off, or a filename -- cgit v1.2.3 From 05c78bc9b5c198a3bd9211aabe467acbbb672b8b Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 21 Oct 2008 19:53:23 +0200 Subject: doc: remove example about CacheWriteTrough This patch removes the documentation about the CacheWriteTrhough clause. This feature is scheduled for removal since the asynchronous nature of conntrackd does not allow multi-path routing support. I'm lying, actually there's a chance to support it, but we have to guarantee that the RTT in the message synchronization between the firewall is smaller than the RTT between the peer and the firewalls. Moreover, this option has made more bad than good since people enable it when things don't work. Making the whole troubleshooting more complicated. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 9 --------- doc/sync/ftfw/conntrackd.conf | 9 --------- doc/sync/notrack/conntrackd.conf | 9 --------- 3 files changed, 27 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index e48ca2d..8d34697 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -101,15 +101,6 @@ Sync { # achieve fault-tolerance. In case of doubt, do not modify this value. # Checksum on - - # If you have a multiprimary setup (active-active) without connection - # persistency, ie. you can't know which firewall handles a packet - # that is part of a connection, then you need direct commit of - # conntrack entries to the kernel conntrack table. OSPF setups must - # set on this option. If you have a simple primary-backup scenario. - # Do not set it on. Default is off. - # - # CacheWriteThrough On } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 40f8457..3aa8216 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -96,15 +96,6 @@ Sync { # achieve fault-tolerance. In case of doubt, do not modify this value. # Checksum on - - # If you have a multiprimary setup (active-active) without connection - # persistency, ie. you can't know which firewall handles a packet - # that is part of a connection, then you need direct commit of - # conntrack entries to the kernel conntrack table. OSPF setups must - # set on this option. If you have a simple primary-backup scenario. - # Do not set it on. Default is off. - # - # CacheWriteThrough On } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index b135814..446e981 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -89,15 +89,6 @@ Sync { # achieve fault-tolerance. In case of doubt, do not modify this value. # Checksum on - - # If you have a multiprimary setup (active-active) without connection - # persistency, ie. you can't know which firewall handles a packet - # that is part of a connection, then you need direct commit of - # conntrack entries to the kernel conntrack table. OSPF setups must - # set on this option. If you have a simple primary-backup scenario. - # Do not set it on. Default is off. - # - # CacheWriteThrough On } # -- cgit v1.2.3 From 6d8903cbf33ac10e8e03f884a58e374adc366887 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 18 Nov 2008 10:33:33 +0100 Subject: filter: choose the filtering method via configuration file This patch changes the current behaviour of the filtering selection. Up to now, conntrackd has used the kernel version to select the filtering method based on the following logic: If kernel is >= 2.6.26 we use BSF-based filtering from kernel-space, otherwise, default to userspace. However, this filtering method still lacks of IPv6 support and it requires a patch that got into 2.6.29 to filter IPv6 addresses from kernel-space. To fix this issue, we default to user-space filtering and let the user choose the method via the configuration file. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 12 ++++++++++-- doc/sync/ftfw/conntrackd.conf | 12 ++++++++++-- doc/sync/notrack/conntrackd.conf | 12 ++++++++++-- include/conntrackd.h | 2 +- src/main.c | 4 ---- src/netlink.c | 8 +++++--- src/read_config_lex.l | 3 +++ src/read_config_yy.y | 16 +++++++++++++++- 8 files changed, 54 insertions(+), 15 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 8d34697..6995d6c 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -159,8 +159,16 @@ General { # State. The filter is attached to an action that can be: Accept or # Ignore. Thus, you can define the event filtering policy of the # filter-sets in positive or negative logic depending on your needs. - # - Filter { + # You can select if conntrackd filters the event messages from + # user-space or kernel-space. The kernel-space event filtering + # saves some CPU cycles by avoiding the copy of the event message + # from kernel-space to user-space. The kernel-space event filtering + # is prefered, however, you require a Linux kernel >= 2.6.29 to + # filter from kernel-space. If you want to select kernel-space + # event filtering, use the keyword 'Kernelspace' instead of + # 'Userspace'. + # + Filter from Userspace { # # Accept only certain protocols: You may want to replicate # the state of flows depending on their layer 4 protocol. diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 06c3d15..3a2ed0e 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -163,8 +163,16 @@ General { # State. The filter is attached to an action that can be: Accept or # Ignore. Thus, you can define the event filtering policy of the # filter-sets in positive or negative logic depending on your needs. - # - Filter { + # You can select if conntrackd filters the event messages from + # user-space or kernel-space. The kernel-space event filtering + # saves some CPU cycles by avoiding the copy of the event message + # from kernel-space to user-space. The kernel-space event filtering + # is prefered, however, you require a Linux kernel >= 2.6.29 to + # filter from kernel-space. If you want to select kernel-space + # event filtering, use the keyword 'Kernelspace' instead of + # 'Userspace'. + # + Filter from Userspace { # # Accept only certain protocols: You may want to replicate # the state of flows depending on their layer 4 protocol. diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 446e981..e9835e8 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -147,8 +147,16 @@ General { # State. The filter is attached to an action that can be: Accept or # Ignore. Thus, you can define the event filtering policy of the # filter-sets in positive or negative logic depending on your needs. - # - Filter { + # You can select if conntrackd filters the event messages from + # user-space or kernel-space. The kernel-space event filtering + # saves some CPU cycles by avoiding the copy of the event message + # from kernel-space to user-space. The kernel-space event filtering + # is prefered, however, you require a Linux kernel >= 2.6.29 to + # filter from kernel-space. If you want to select kernel-space + # event filtering, use the keyword 'Kernelspace' instead of + # 'Userspace'. + # + Filter from Userspace { # # Accept only certain protocols: You may want to replicate # the state of flows depending on their layer 4 protocol. diff --git a/include/conntrackd.h b/include/conntrackd.h index 448d594..dc992db 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -91,7 +91,7 @@ struct ct_conf { unsigned int resend_queue_size; /* FTFW protocol */ unsigned int window_size; int cache_write_through; - int kernel_support_netlink_bsf; + int filter_from_kernelspace; struct { char logfile[FILENAME_MAXLEN]; int syslog_facility; diff --git a/src/main.c b/src/main.c index d6aa938..f811acf 100644 --- a/src/main.c +++ b/src/main.c @@ -97,10 +97,6 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - /* BSF filter attaching does not report unsupported operations */ - if (version >= 2 && major >= 6 && minor >= 26) - CONFIG(kernel_support_netlink_bsf) = 1; - for (i=1; i T_IP T_PATH_VAL %token T_NUMBER @@ -686,7 +687,20 @@ family : T_FAMILY T_STRING conf.family = AF_INET; }; -filter : T_FILTER '{' filter_list '}'; +filter : T_FILTER '{' filter_list '}' +{ + CONFIG(filter_from_kernelspace) = 0; +}; + +filter : T_FILTER T_FROM T_USERSPACE '{' filter_list '}' +{ + CONFIG(filter_from_kernelspace) = 0; +}; + +filter : T_FILTER T_FROM T_KERNELSPACE '{' filter_list '}' +{ + CONFIG(filter_from_kernelspace) = 1; +}; filter_list : | filter_list filter_item; -- cgit v1.2.3 From b2edf895af82914ab09a842641a45b7a806e9b1e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 25 Nov 2008 23:34:48 +0100 Subject: filter: CIDR-based filtering support This patch adds CIDR-based filtering support. The current implementation is O(n). This patch also introduces the vector data type which is used to store the IP address and the network mask. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 3 ++ doc/sync/ftfw/conntrackd.conf | 3 ++ doc/sync/notrack/conntrackd.conf | 3 ++ include/Makefile.am | 2 +- include/cidr.h | 8 ++++ include/filter.h | 15 ++++++- include/vector.h | 13 ++++++ src/Makefile.am | 4 +- src/cidr.c | 59 ++++++++++++++++++++++++++ src/filter.c | 90 ++++++++++++++++++++++++++++++++++++++++ src/read_config_lex.l | 6 ++- src/read_config_yy.y | 86 +++++++++++++++++++++++++++++++------- src/vector.c | 88 +++++++++++++++++++++++++++++++++++++++ 13 files changed, 358 insertions(+), 22 deletions(-) create mode 100644 include/cidr.h create mode 100644 include/vector.h create mode 100644 src/cidr.c create mode 100644 src/vector.c (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 6995d6c..31a1a4d 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -191,6 +191,9 @@ General { IPv4_address 192.168.0.1 IPv4_address 192.168.1.1 IPv4_address 192.168.100.100 # dedicated link ip + # + # You can also specify networks in format IP/cidr. + # IPv4_address 192.168.0.0/24 } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 3a2ed0e..ae2fe78 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -195,6 +195,9 @@ General { IPv4_address 192.168.0.1 IPv4_address 192.168.1.1 IPv4_address 192.168.100.100 # dedicated link ip + # + # You can also specify networks in format IP/cidr. + # IPv4_address 192.168.0.0/24 } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index e9835e8..d0e141c 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -179,6 +179,9 @@ General { IPv4_address 192.168.0.1 IPv4_address 192.168.1.1 IPv4_address 192.168.100.100 # dedicated link ip + # + # You can also specify networks in format IP/cidr. + # IPv4_address 192.168.0.0/24 } # diff --git a/include/Makefile.am b/include/Makefile.am index 3287a0c..4d22993 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -2,6 +2,6 @@ noinst_HEADERS = alarm.h jhash.h slist.h cache.h linux_list.h linux_rbtree.h \ sync.h conntrackd.h local.h us-conntrack.h \ debug.h log.h hash.h mcast.h conntrack.h \ - network.h filter.h queue.h \ + network.h filter.h queue.h vector.h \ traffic_stats.h netlink.h fds.h event.h bitops.h diff --git a/include/cidr.h b/include/cidr.h new file mode 100644 index 0000000..f8a4e2a --- /dev/null +++ b/include/cidr.h @@ -0,0 +1,8 @@ +#ifndef _CIDR_H_ + +uint32_t ipv4_cidr2mask_host(uint8_t cidr); +uint32_t ipv4_cidr2mask_net(uint8_t cidr); +void ipv6_cidr2mask_host(uint8_t cidr, uint32_t *res); +void ipv6_cidr2mask_net(uint8_t cidr, uint32_t *res); + +#endif diff --git a/include/filter.h b/include/filter.h index de0754e..567be34 100644 --- a/include/filter.h +++ b/include/filter.h @@ -2,11 +2,13 @@ #define _FILTER_H_ #include +#include +#include enum ct_filter_type { CT_FILTER_L4PROTO, CT_FILTER_STATE, - CT_FILTER_ADDRESS, + CT_FILTER_ADDRESS, /* also for netmask */ CT_FILTER_MAX }; @@ -15,12 +17,23 @@ enum ct_filter_logic { CT_FILTER_POSITIVE = 1, }; +struct ct_filter_netmask_ipv4 { + uint32_t ip; + uint32_t mask; +}; + +struct ct_filter_netmask_ipv6 { + uint32_t ip[4]; + uint32_t mask[4]; +}; + struct nf_conntrack; struct ct_filter; struct ct_filter *ct_filter_create(void); void ct_filter_destroy(struct ct_filter *filter); int ct_filter_add_ip(struct ct_filter *filter, void *data, uint8_t family); +int ct_filter_add_netmask(struct ct_filter *filter, void *data, uint8_t family); void ct_filter_add_proto(struct ct_filter *filter, int protonum); void ct_filter_add_state(struct ct_filter *f, int protonum, int state); void ct_filter_set_logic(struct ct_filter *f, diff --git a/include/vector.h b/include/vector.h new file mode 100644 index 0000000..5b05cba --- /dev/null +++ b/include/vector.h @@ -0,0 +1,13 @@ +#ifndef _VECTOR_H_ +#define _VECTOR_H_ + +#include + +struct vector; + +struct vector *vector_create(size_t size); +void vector_destroy(struct vector *v); +int vector_add(struct vector *v, void *data); +int vector_iterate(struct vector *v, const void *data, int (*fcn)(const void *a, const void *b)); + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index 82f7dfe..64ed2b5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,13 +11,13 @@ conntrack_LDADD = ../extensions/libct_proto_tcp.la ../extensions/libct_proto_udp conntrack_LDFLAGS = $(all_libraries) @LIBNETFILTER_CONNTRACK_LIBS@ conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \ - local.c log.c mcast.c netlink.c \ + local.c log.c mcast.c netlink.c vector.c \ filter.c fds.c event.c \ cache.c cache_iterators.c \ cache_lifetime.c cache_timer.c cache_wt.c \ sync-mode.c sync-alarm.c sync-ftfw.c sync-notrack.c \ traffic_stats.c stats-mode.c \ - network.c \ + network.c cidr.c \ build.c parse.c \ read_config_yy.y read_config_lex.l diff --git a/src/cidr.c b/src/cidr.c new file mode 100644 index 0000000..d43dabc --- /dev/null +++ b/src/cidr.c @@ -0,0 +1,59 @@ +/* + * (C) 2006-2008 by Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include "cidr.h" + +/* returns the netmask in host byte order */ +uint32_t ipv4_cidr2mask_host(uint8_t cidr) +{ + return 0xFFFFFFFF << (32 - cidr); +} + +/* returns the netmask in network byte order */ +uint32_t ipv4_cidr2mask_net(uint8_t cidr) +{ + return htonl(ipv4_cidr2mask_host(cidr)); +} + +void ipv6_cidr2mask_host(uint8_t cidr, uint32_t *res) +{ + int i, j; + + memset(res, 0, sizeof(uint32_t)*4); + for (i = 0; i < 4 && cidr > 32; i++) { + res[i] = 0xFFFFFFFF; + cidr -= 32; + } + res[i] = 0xFFFFFFFF << (32 - cidr); + for (j = i+1; j < 4; j++) { + res[j] = 0; + } +} + +void ipv6_cidr2mask_net(uint8_t cidr, uint32_t *res) +{ + int i; + + ipv6_cidr2mask_host(cidr, res); + for (i=0; i<4; i++) + res[i] = htonl(res[i]); +} + diff --git a/src/filter.c b/src/filter.c index f6da8bb..905d10f 100644 --- a/src/filter.c +++ b/src/filter.c @@ -20,12 +20,14 @@ #include "bitops.h" #include "jhash.h" #include "hash.h" +#include "vector.h" #include "conntrackd.h" #include "log.h" #include #include #include +#include #include struct ct_filter { @@ -34,6 +36,8 @@ struct ct_filter { u_int16_t statemap[IPPROTO_MAX]; struct hashtable *h; struct hashtable *h6; + struct vector *v; + struct vector *v6; }; /* XXX: These should be configurable, better use a rb-tree */ @@ -95,6 +99,23 @@ struct ct_filter *ct_filter_create(void) return NULL; } + filter->v = vector_create(sizeof(struct ct_filter_netmask_ipv4)); + if (!filter->v) { + free(filter->h6); + free(filter->h); + free(filter); + return NULL; + } + + filter->v6 = vector_create(sizeof(struct ct_filter_netmask_ipv6)); + if (!filter->v6) { + free(filter->v); + free(filter->h6); + free(filter->h); + free(filter); + return NULL; + } + for (i=0; ilogic[i] = -1; @@ -105,6 +126,8 @@ void ct_filter_destroy(struct ct_filter *filter) { hashtable_destroy(filter->h); hashtable_destroy(filter->h6); + vector_destroy(filter->v); + vector_destroy(filter->v6); free(filter); } @@ -147,6 +170,39 @@ int ct_filter_add_ip(struct ct_filter *filter, void *data, uint8_t family) return 1; } +static int cmp_ipv4_addr(const void *a, const void *b) +{ + return memcmp(a, b, sizeof(struct ct_filter_netmask_ipv4)) == 0; +} + +static int cmp_ipv6_addr(const void *a, const void *b) +{ + return memcmp(a, b, sizeof(struct ct_filter_netmask_ipv6)) == 0; +} + +int ct_filter_add_netmask(struct ct_filter *filter, void *data, uint8_t family) +{ + filter = __filter_alloc(filter); + + switch(family) { + case AF_INET: + if (vector_iterate(filter->v, data, cmp_ipv4_addr)) { + errno = EEXIST; + return 0; + } + vector_add(filter->v, data); + break; + case AF_INET6: + if (vector_iterate(filter->v, data, cmp_ipv6_addr)) { + errno = EEXIST; + return 0; + } + vector_add(filter->v6, data); + break; + } + return 1; +} + void ct_filter_add_proto(struct ct_filter *f, int protonum) { f = __filter_alloc(f); @@ -176,6 +232,34 @@ __ct_filter_test_ipv6(struct ct_filter *f, struct nf_conntrack *ct) hashtable_test(f->h6, nfct_get_attr(ct, ATTR_REPL_IPV6_SRC))); } +static int +__ct_filter_test_mask4(const void *ptr, const void *ct) +{ + const struct ct_filter_netmask_ipv4 *elem = ptr; + const uint32_t src = nfct_get_attr_u32(ct, ATTR_ORIG_IPV4_SRC); + const uint32_t dst = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC); + + return ((elem->ip & elem->mask) == (src & elem->mask) || + (elem->ip & elem->mask) == (dst & elem->mask)); +} + +static int +__ct_filter_test_mask6(const void *ptr, const void *ct) +{ + const struct ct_filter_netmask_ipv6 *elem = ptr; + const uint32_t *src = nfct_get_attr(ct, ATTR_ORIG_IPV6_SRC); + const uint32_t *dst = nfct_get_attr(ct, ATTR_REPL_IPV6_SRC); + + return (((elem->ip[0] & elem->mask[0]) == (src[0] & elem->mask[0]) && + (elem->ip[1] & elem->mask[1]) == (src[1] & elem->mask[1]) && + (elem->ip[2] & elem->mask[2]) == (src[2] & elem->mask[2]) && + (elem->ip[3] & elem->mask[3]) == (src[3] & elem->mask[3])) || + ((elem->ip[0] & elem->mask[0]) == (dst[0] & elem->mask[0]) && + (elem->ip[1] & elem->mask[1]) == (dst[1] & elem->mask[1]) && + (elem->ip[2] & elem->mask[2]) == (dst[2] & elem->mask[2]) && + (elem->ip[3] & elem->mask[3]) == (dst[3] & elem->mask[3]))); +} + static int __ct_filter_test_state(struct ct_filter *f, struct nf_conntrack *ct) { uint16_t val = 0; @@ -212,11 +296,17 @@ int ct_filter_check(struct ct_filter *f, struct nf_conntrack *ct) if (f->logic[CT_FILTER_ADDRESS] != -1) { switch(nfct_get_attr_u8(ct, ATTR_L3PROTO)) { case AF_INET: + ret = vector_iterate(f->v, ct, __ct_filter_test_mask4); + if (ret ^ f->logic[CT_FILTER_ADDRESS]) + return 0; ret = __ct_filter_test_ipv4(f, ct); if (ret ^ f->logic[CT_FILTER_ADDRESS]) return 0; break; case AF_INET6: + ret = vector_iterate(f->v6, ct, __ct_filter_test_mask6); + if (ret ^ f->logic[CT_FILTER_ADDRESS]) + return 0; ret = __ct_filter_test_ipv6(f, ct); if (ret ^ f->logic[CT_FILTER_ADDRESS]) return 0; diff --git a/src/read_config_lex.l b/src/read_config_lex.l index cbb6ca8..67c95d3 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -36,14 +36,16 @@ is_on [o|O][n|N] is_off [o|O][f|F][f|F] integer [0-9]+ path \/[^\"\n ]* +ip4_cidr \/[0-2]*[0-9]+ ip4_end [0-9]*[0-9]+ ip4_part [0-2]*{ip4_end} -ip4 {ip4_part}\.{ip4_part}\.{ip4_part}\.{ip4_part} +ip4 {ip4_part}\.{ip4_part}\.{ip4_part}\.{ip4_part}{ip4_cidr}? hex_255 [0-9a-fA-F]{1,4} +ip6_cidr \/[0-1]*[0-9]*[0-9]+ ip6_part {hex_255}":"? ip6_form1 {ip6_part}{0,16}"::"{ip6_part}{0,16} ip6_form2 ({hex_255}":"){16}{hex_255} -ip6 {ip6_form1}|{ip6_form2} +ip6 {ip6_form1}{ip6_cidr}?|{ip6_form2}{ip6_cidr}? string [a-zA-Z][a-zA-Z0-9\.]* persistent [P|p][E|e][R|r][S|s][I|i][S|s][T|t][E|e][N|n][T|T] nack [N|n][A|a][C|c][K|k] diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 06ada52..32ddeff 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -26,6 +26,7 @@ #include #include "conntrackd.h" #include "bitops.h" +#include "cidr.h" #include #include #include @@ -780,27 +781,55 @@ filter_address_list : filter_address_item : T_IPV4_ADDR T_IP { union inet_address ip; + char *slash; + unsigned int cidr = 32; memset(&ip, 0, sizeof(union inet_address)); + slash = strchr($2, '/'); + if (slash) { + *slash = '\0'; + cidr = atoi(slash+1); + if (cidr > 32) { + fprintf(stderr, "%s/%d is not a valid network, " + "ignoring\n", $2, cidr); + break; + } + } + if (!inet_aton($2, &ip.ipv4)) { fprintf(stderr, "%s is not a valid IPv4, ignoring", $2); break; } - if (!ct_filter_add_ip(STATE(us_filter), &ip, AF_INET)) { - if (errno == EEXIST) - fprintf(stderr, "IP %s is repeated " - "in the ignore pool\n", $2); - if (errno == ENOSPC) - fprintf(stderr, "Too many IP in the ignore pool!\n"); + if (slash && cidr < 32) { + /* network byte order */ + struct ct_filter_netmask_ipv4 tmp = { + .ip = ip.ipv4, + .mask = ipv4_cidr2mask_net(cidr) + }; + + if (!ct_filter_add_netmask(STATE(us_filter), &tmp, AF_INET)) { + if (errno == EEXIST) + fprintf(stderr, "Netmask %s is repeated " + "in the ignore pool\n", $2); + } + } else { + if (!ct_filter_add_ip(STATE(us_filter), &ip, AF_INET)) { + if (errno == EEXIST) + fprintf(stderr, "IP %s is repeated " + "in the ignore pool\n", $2); + if (errno == ENOSPC) + fprintf(stderr, "Too many IP in the " + "ignore pool!\n"); + } } - __kernel_filter_start(); + /* host byte order */ struct nfct_filter_ipv4 filter_ipv4 = { - .addr = htonl(ip.ipv4), - .mask = 0xffffffff, + .addr = ntohl(ip.ipv4), + .mask = ipv4_cidr2mask_host(cidr), }; nfct_filter_add_attr(STATE(filter), NFCT_FILTER_SRC_IPV4, &filter_ipv4); @@ -810,9 +839,22 @@ filter_address_item : T_IPV4_ADDR T_IP filter_address_item : T_IPV6_ADDR T_IP { union inet_address ip; + char *slash; + int cidr; memset(&ip, 0, sizeof(union inet_address)); + slash = strchr($2, '/'); + if (slash) { + *slash = '\0'; + cidr = atoi(slash+1); + if (cidr > 128) { + fprintf(stderr, "%s/%d is not a valid network, " + "ignoring\n", $2, cidr); + break; + } + } + #ifdef HAVE_INET_PTON_IPV6 if (inet_pton(AF_INET6, $2, &ip.ipv6) <= 0) { fprintf(stderr, "%s is not a valid IPv6, ignoring", $2); @@ -822,13 +864,25 @@ filter_address_item : T_IPV6_ADDR T_IP fprintf(stderr, "Cannot find inet_pton(), IPv6 unsupported!"); break; #endif - - if (!ct_filter_add_ip(STATE(us_filter), &ip, AF_INET6)) { - if (errno == EEXIST) - fprintf(stderr, "IP %s is repeated " - "in the ignore pool\n", $2); - if (errno == ENOSPC) - fprintf(stderr, "Too many IP in the ignore pool!\n"); + if (slash && cidr < 128) { + struct ct_filter_netmask_ipv6 tmp; + + memcpy(tmp.ip, ip.ipv6, sizeof(uint32_t)*4); + ipv6_cidr2mask_net(cidr, tmp.mask); + if (!ct_filter_add_netmask(STATE(us_filter), &tmp, AF_INET6)) { + if (errno == EEXIST) + fprintf(stderr, "Netmask %s is repeated " + "in the ignore pool\n", $2); + } + } else { + if (!ct_filter_add_ip(STATE(us_filter), &ip, AF_INET6)) { + if (errno == EEXIST) + fprintf(stderr, "IP %s is repeated " + "in the ignore pool\n", $2); + if (errno == ENOSPC) + fprintf(stderr, "Too many IP in the " + "ignore pool!\n"); + } } }; diff --git a/src/vector.c b/src/vector.c new file mode 100644 index 0000000..c81e7ce --- /dev/null +++ b/src/vector.c @@ -0,0 +1,88 @@ +/* + * (C) 2006-2008 by Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "vector.h" + +#include +#include + +struct vector { + char *data; + unsigned int cur_elems; + unsigned int max_elems; + size_t size; +}; + +#define DEFAULT_VECTOR_MEMBERS 8 +#define DEFAULT_VECTOR_GROWTH 8 + +struct vector *vector_create(size_t size) +{ + struct vector *v; + + v = calloc(sizeof(struct vector), 1); + if (v == NULL) + return NULL; + + v->size = size; + v->cur_elems = 0; + v->max_elems = DEFAULT_VECTOR_MEMBERS; + + v->data = calloc(size * DEFAULT_VECTOR_MEMBERS, 1); + if (v->data == NULL) { + free(v); + return NULL; + } + + return v; +} + +void vector_destroy(struct vector *v) +{ + free(v->data); + free(v); +} + +int vector_add(struct vector *v, void *data) +{ + if (v->cur_elems >= v->max_elems) { + v->max_elems += DEFAULT_VECTOR_GROWTH; + v->data = realloc(v->data, v->max_elems * v->size); + if (v->data == NULL) { + v->max_elems -= DEFAULT_VECTOR_GROWTH; + return -1; + } + } + memcpy(v->data + (v->size * v->cur_elems), data, v->size); + v->cur_elems++; + return 0; +} + +int vector_iterate(struct vector *v, + const void *data, + int (*fcn)(const void *a, const void *b)) +{ + unsigned int i; + + for (i=0; icur_elems; i++) { + char *ptr = v->data + (v->size * i); + if (fcn(ptr, data)) + return 1; + } + return 0; +} -- cgit v1.2.3 From 1fadc34c80a17e291f5ae86ecb84efbdb2aab265 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 30 Nov 2008 11:40:36 +0100 Subject: config: move `Checksum' inside `Multicast' clause This patch moves `Checksum' into the `Multicast' clause. This property is dependent of the multicast configuration. This patch is required to introduce the redundant dedicated link support that is on the way. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 13 +++++++------ doc/sync/ftfw/conntrackd.conf | 13 +++++++------ doc/sync/notrack/conntrackd.conf | 13 +++++++------ src/read_config_yy.y | 14 ++++++++++++++ 4 files changed, 35 insertions(+), 18 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 31a1a4d..dfdc91d 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -94,13 +94,14 @@ Sync { # the receiver buffer. # # McastRcvSocketBuffer 1249280 - } - # - # Enable/Disable message checksumming. This is a good property to - # achieve fault-tolerance. In case of doubt, do not modify this value. - # - Checksum on + # + # Enable/Disable message checksumming. This is a good + # property to achieve fault-tolerance. In case of doubt, do + # not modify this value. + # + Checksum on + } } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index ae2fe78..bf5711e 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -98,13 +98,14 @@ Sync { # the receiver buffer. # # McastRcvSocketBuffer 1249280 - } - # - # Enable/Disable message checksumming. This is a good property to - # achieve fault-tolerance. In case of doubt, do not modify this value. - # - Checksum on + # + # Enable/Disable message checksumming. This is a good + # property to achieve fault-tolerance. In case of doubt, do + # not modify this value. + # + Checksum on + } } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index d0e141c..90189cd 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -82,13 +82,14 @@ Sync { # really recommended to increase the buffer size. McastRcvSocketBuffer 1249280 - } - # - # Enable/Disable message checksumming. This is a good property to - # achieve fault-tolerance. In case of doubt, do not modify this value. - # - Checksum on + # + # Enable/Disable message checksumming. This is a good + # property to achieve fault-tolerance. In case of doubt, do + # not modify this value. + # + Checksum on + } } # diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 32ddeff..69a7eff 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -172,11 +172,15 @@ purge: T_PURGE T_NUMBER checksum: T_CHECKSUM T_ON { + fprintf(stderr, "WARNING: The use of `Checksum' outside the " + "`Multicast' clause is ambiguous.\n"); conf.mcast.checksum = 0; }; checksum: T_CHECKSUM T_OFF { + fprintf(stderr, "WARNING: The use of `Checksum' outside the " + "`Multicast' clause is ambiguous.\n"); conf.mcast.checksum = 1; }; @@ -357,6 +361,16 @@ multicast_option: T_MCAST_RCVBUFF T_NUMBER conf.mcast.rcvbuf = $2; }; +multicast_option: T_CHECKSUM T_ON +{ + conf.mcast.checksum = 0; +}; + +multicast_option: T_CHECKSUM T_OFF +{ + conf.mcast.checksum = 1; +}; + hashsize : T_HASHSIZE T_NUMBER { conf.hashsize = $2; -- cgit v1.2.3 From 02486b7c22beee4ac8af694a1073d33775d0d388 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 17 Dec 2008 18:38:38 +0100 Subject: doc: fix typo SocketBufferSizeMaxGrowth in example conffiles This patch replaces SocketBufferSizeMaxGrown by SocketBufferSizeMaxGrowth. Both clauses are still valid but better to use the one that has no typos in the configuration files. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 2 +- doc/sync/ftfw/conntrackd.conf | 2 +- doc/sync/notrack/conntrackd.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index dfdc91d..0ace99e 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -152,7 +152,7 @@ General { # # Increase the socket buffer up to maximum if required # - SocketBufferSizeMaxGrown 655355 + SocketBufferSizeMaxGrowth 655355 # # Event filtering: This clause allows you to filter certain traffic, diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index bf5711e..868ee5a 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -156,7 +156,7 @@ General { # # Increase the socket buffer up to maximum if required # - SocketBufferSizeMaxGrown 655355 + SocketBufferSizeMaxGrowth 655355 # # Event filtering: This clause allows you to filter certain traffic, diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 90189cd..514b5ba 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -140,7 +140,7 @@ General { # # Increase the socket buffer up to maximum if required # - SocketBufferSizeMaxGrown 655355 + SocketBufferSizeMaxGrowth 655355 # # Event filtering: This clause allows you to filter certain traffic, -- cgit v1.2.3 From 789cfad661f4fbaa97384efa5843a60027b1ec91 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 17 Dec 2008 18:54:27 +0100 Subject: doc: document the netlink buffer size clauses This patch documents the SocketBufferSize and SocketBufferSizeGrowth clause. It also rises the default values which are fairly small for busy firewalls. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 16 ++++++++++++---- doc/sync/ftfw/conntrackd.conf | 16 ++++++++++++---- doc/sync/notrack/conntrackd.conf | 16 ++++++++++++---- 3 files changed, 36 insertions(+), 12 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 0ace99e..0d4847b 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -145,14 +145,22 @@ General { } # - # Netlink socket buffer size + # Netlink event socket buffer size. If you do not specify this clause, + # the default buffer size value in /proc/net/core/rmem_default is + # used. This default value is usually around 100 Kbytes which is + # fairly small for busy firewalls. This leads to event message dropping + # and high CPU consumption. This example configuration file sets the + # size to 2 MBytes to avoid this sort of problems. # - SocketBufferSize 262142 + SocketBufferSize 2097152 # - # Increase the socket buffer up to maximum if required + # The daemon doubles the size of the netlink event socket buffer size + # if it detects netlink event message dropping. This clause sets the + # maximum buffer size growth that can be reached. This example file + # sets the size to 8 MBytes. # - SocketBufferSizeMaxGrowth 655355 + SocketBufferSizeMaxGrowth 8388608 # # Event filtering: This clause allows you to filter certain traffic, diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 868ee5a..d415fcd 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -149,14 +149,22 @@ General { } # - # Netlink socket buffer size + # Netlink event socket buffer size. If you do not specify this clause, + # the default buffer size value in /proc/net/core/rmem_default is + # used. This default value is usually around 100 Kbytes which is + # fairly small for busy firewalls. This leads to event message dropping + # and high CPU consumption. This example configuration file sets the + # size to 2 MBytes to avoid this sort of problems. # - SocketBufferSize 262142 + SocketBufferSize 2097152 # - # Increase the socket buffer up to maximum if required + # The daemon doubles the size of the netlink event socket buffer size + # if it detects netlink event message dropping. This clause sets the + # maximum buffer size growth that can be reached. This example file + # sets the size to 8 MBytes. # - SocketBufferSizeMaxGrowth 655355 + SocketBufferSizeMaxGrowth 8388608 # # Event filtering: This clause allows you to filter certain traffic, diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 514b5ba..bc1a3a6 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -133,14 +133,22 @@ General { } # - # Netlink socket buffer size + # Netlink event socket buffer size. If you do not specify this clause, + # the default buffer size value in /proc/net/core/rmem_default is + # used. This default value is usually around 100 Kbytes which is + # fairly small for busy firewalls. This leads to event message dropping + # and high CPU consumption. This example configuration file sets the + # size to 2 MBytes to avoid this sort of problems. # - SocketBufferSize 262142 + SocketBufferSize 2097152 # - # Increase the socket buffer up to maximum if required + # The daemon doubles the size of the netlink event socket buffer size + # if it detects netlink event message dropping. This clause sets the + # maximum buffer size growth that can be reached. This example file + # sets the size to 8 MBytes. # - SocketBufferSizeMaxGrowth 655355 + SocketBufferSizeMaxGrowth 8388608 # # Event filtering: This clause allows you to filter certain traffic, -- cgit v1.2.3 From 9bc7d7f8f333e79323495a193f92c9d4f1708da9 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 17 Dec 2008 19:19:21 +0100 Subject: x --- doc/sync/alarm/conntrackd.conf | 10 ++++++---- doc/sync/ftfw/conntrackd.conf | 12 +++++++----- doc/sync/notrack/conntrackd.conf | 16 ++++++++++------ 3 files changed, 23 insertions(+), 15 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 0d4847b..f42a799 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -80,9 +80,10 @@ Sync { # sender queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size - # of the sender buffer. + # of the sender buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. # - # McastSndSocketBuffer 1249280 + McastSndSocketBuffer 1249280 # The multicast receiver uses a buffer to enqueue the packets # that the socket is pending to handle. The default size of this @@ -91,9 +92,10 @@ Sync { # receiver queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size of - # the receiver buffer. + # the receiver buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. # - # McastRcvSocketBuffer 1249280 + McastRcvSocketBuffer 1249280 # # Enable/Disable message checksumming. This is a good diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 047ea48..e12a745 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -88,10 +88,11 @@ Sync { # sender queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size - # of the sender buffer. - # - # McastSndSocketBuffer 1249280 + # of the sender buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. # + McastSndSocketBuffer 1249280 + # The multicast receiver uses a buffer to enqueue the packets # that the socket is pending to handle. The default size of this # socket buffer is available at /proc/sys/net/core/rmem_default. @@ -99,9 +100,10 @@ Sync { # receiver queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size of - # the receiver buffer. + # the receiver buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. # - # McastRcvSocketBuffer 1249280 + McastRcvSocketBuffer 1249280 # # Enable/Disable message checksumming. This is a good diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index bc1a3a6..cbc26ee 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -66,9 +66,11 @@ Sync { # sender queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size - # of the sender buffer. Note: This protocol is best effort, - # really recommended to increase the buffer size. - + # of the sender buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. + # Note: This protocol is best effort, it is really recommended + # to increase the buffer size. + # McastSndSocketBuffer 1249280 # The multicast receiver uses a buffer to enqueue the packets @@ -78,9 +80,11 @@ Sync { # receiver queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size of - # the receiver buffer. Note: This protocol is best effort, - # really recommended to increase the buffer size. - + # of the sender buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. + # Note: This protocol is best effort, it is really recommended + # to increase the buffer size. + # McastRcvSocketBuffer 1249280 # -- cgit v1.2.3 From 8be4e1c72909d7003735d92f2b3c2175ff84d2d9 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 17 Dec 2008 19:31:42 +0100 Subject: doc: revert commit 9bc7d7f8f333e79323495a193f92c9d4f1708da9 Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 10 ++++------ doc/sync/ftfw/conntrackd.conf | 12 +++++------- doc/sync/notrack/conntrackd.conf | 16 ++++++---------- 3 files changed, 15 insertions(+), 23 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index f42a799..0d4847b 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -80,10 +80,9 @@ Sync { # sender queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size - # of the sender buffer. The default size is usually around - # ~100 KBytes which is fairly small for busy firewalls. + # of the sender buffer. # - McastSndSocketBuffer 1249280 + # McastSndSocketBuffer 1249280 # The multicast receiver uses a buffer to enqueue the packets # that the socket is pending to handle. The default size of this @@ -92,10 +91,9 @@ Sync { # receiver queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size of - # the receiver buffer. The default size is usually around - # ~100 KBytes which is fairly small for busy firewalls. + # the receiver buffer. # - McastRcvSocketBuffer 1249280 + # McastRcvSocketBuffer 1249280 # # Enable/Disable message checksumming. This is a good diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index e12a745..047ea48 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -88,11 +88,10 @@ Sync { # sender queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size - # of the sender buffer. The default size is usually around - # ~100 KBytes which is fairly small for busy firewalls. + # of the sender buffer. + # + # McastSndSocketBuffer 1249280 # - McastSndSocketBuffer 1249280 - # The multicast receiver uses a buffer to enqueue the packets # that the socket is pending to handle. The default size of this # socket buffer is available at /proc/sys/net/core/rmem_default. @@ -100,10 +99,9 @@ Sync { # receiver queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size of - # the receiver buffer. The default size is usually around - # ~100 KBytes which is fairly small for busy firewalls. + # the receiver buffer. # - McastRcvSocketBuffer 1249280 + # McastRcvSocketBuffer 1249280 # # Enable/Disable message checksumming. This is a good diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index cbc26ee..bc1a3a6 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -66,11 +66,9 @@ Sync { # sender queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size - # of the sender buffer. The default size is usually around - # ~100 KBytes which is fairly small for busy firewalls. - # Note: This protocol is best effort, it is really recommended - # to increase the buffer size. - # + # of the sender buffer. Note: This protocol is best effort, + # really recommended to increase the buffer size. + McastSndSocketBuffer 1249280 # The multicast receiver uses a buffer to enqueue the packets @@ -80,11 +78,9 @@ Sync { # receiver queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size of - # of the sender buffer. The default size is usually around - # ~100 KBytes which is fairly small for busy firewalls. - # Note: This protocol is best effort, it is really recommended - # to increase the buffer size. - # + # the receiver buffer. Note: This protocol is best effort, + # really recommended to increase the buffer size. + McastRcvSocketBuffer 1249280 # -- cgit v1.2.3 From f9f184dbd989248a3eb4c68a7e950780902fb196 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 17 Dec 2008 19:34:16 +0100 Subject: doc: add note on McastSndSocketBuffer and McastRcvSocketBuffer This patch adds a note on the impact of having small values for the McastSndSocketBuffer and McastRcvSocketBuffer clauses. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 10 ++++++---- doc/sync/ftfw/conntrackd.conf | 12 +++++++----- doc/sync/notrack/conntrackd.conf | 16 ++++++++++------ 3 files changed, 23 insertions(+), 15 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 0d4847b..f42a799 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -80,9 +80,10 @@ Sync { # sender queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size - # of the sender buffer. + # of the sender buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. # - # McastSndSocketBuffer 1249280 + McastSndSocketBuffer 1249280 # The multicast receiver uses a buffer to enqueue the packets # that the socket is pending to handle. The default size of this @@ -91,9 +92,10 @@ Sync { # receiver queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size of - # the receiver buffer. + # the receiver buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. # - # McastRcvSocketBuffer 1249280 + McastRcvSocketBuffer 1249280 # # Enable/Disable message checksumming. This is a good diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 047ea48..e12a745 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -88,10 +88,11 @@ Sync { # sender queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size - # of the sender buffer. - # - # McastSndSocketBuffer 1249280 + # of the sender buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. # + McastSndSocketBuffer 1249280 + # The multicast receiver uses a buffer to enqueue the packets # that the socket is pending to handle. The default size of this # socket buffer is available at /proc/sys/net/core/rmem_default. @@ -99,9 +100,10 @@ Sync { # receiver queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size of - # the receiver buffer. + # the receiver buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. # - # McastRcvSocketBuffer 1249280 + McastRcvSocketBuffer 1249280 # # Enable/Disable message checksumming. This is a good diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index bc1a3a6..cbc26ee 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -66,9 +66,11 @@ Sync { # sender queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size - # of the sender buffer. Note: This protocol is best effort, - # really recommended to increase the buffer size. - + # of the sender buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. + # Note: This protocol is best effort, it is really recommended + # to increase the buffer size. + # McastSndSocketBuffer 1249280 # The multicast receiver uses a buffer to enqueue the packets @@ -78,9 +80,11 @@ Sync { # receiver queue. The overrun results packet loss, thus, losing # state information that would have to be retransmitted. If you # notice some packet loss, you may want to increase the size of - # the receiver buffer. Note: This protocol is best effort, - # really recommended to increase the buffer size. - + # of the sender buffer. The default size is usually around + # ~100 KBytes which is fairly small for busy firewalls. + # Note: This protocol is best effort, it is really recommended + # to increase the buffer size. + # McastRcvSocketBuffer 1249280 # -- cgit v1.2.3 From b28224b0326636ff5832b38817b7720f48070ee7 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 15 Jan 2009 23:19:35 +0100 Subject: run: limit the number of iterations over the event handling Currently, the event handling can starve other event file descriptors. This patch limits the number of event handling iterations. The parameter is tunable via configuration file. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 11 +++++++++++ doc/sync/ftfw/conntrackd.conf | 11 +++++++++++ doc/sync/notrack/conntrackd.conf | 11 +++++++++++ include/conntrackd.h | 2 ++ src/read_config_lex.l | 1 + src/read_config_yy.y | 11 ++++++++++- src/run.c | 11 ++++++++--- 7 files changed, 54 insertions(+), 4 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index f42a799..f16f439 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -164,6 +164,17 @@ General { # SocketBufferSizeMaxGrowth 8388608 + # + # The daemon prioritizes the handling of state-change events coming + # from the core. With this clause, you can set the maximum number of + # state-change events (those coming from kernel-space) that the daemon + # will handle after which it will handle other events coming from the + # network or userspace. A low value improves interactivity (in terms of + # real-time behaviour) at the cost of extra CPU consumption. + # Default (if not set) is 100. + # + # EventIterationLimit 100 + # # Event filtering: This clause allows you to filter certain traffic, # There are currently three filter-sets: Protocol, Address and diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index e12a745..d85fc28 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -172,6 +172,17 @@ General { # SocketBufferSizeMaxGrowth 8388608 + # + # The daemon prioritizes the handling of state-change events coming + # from the core. With this clause, you can set the maximum number of + # state-change events (those coming from kernel-space) that the daemon + # will handle after which it will handle other events coming from the + # network or userspace. A low value improves interactivity (in terms of + # real-time behaviour) at the cost of extra CPU consumption. + # Default (if not set) is 100. + # + # EventIterationLimit 100 + # # Event filtering: This clause allows you to filter certain traffic, # There are currently three filter-sets: Protocol, Address and diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index cbc26ee..4d03234 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -154,6 +154,17 @@ General { # SocketBufferSizeMaxGrowth 8388608 + # + # The daemon prioritizes the handling of state-change events coming + # from the core. With this clause, you can set the maximum number of + # state-change events (those coming from kernel-space) that the daemon + # will handle after which it will handle other events coming from the + # network or userspace. A low value improves interactivity (in terms of + # real-time behaviour) at the cost of extra CPU consumption. + # Default (if not set) is 100. + # + # EventIterationLimit 100 + # # Event filtering: This clause allows you to filter certain traffic, # There are currently three filter-sets: Protocol, Address and diff --git a/include/conntrackd.h b/include/conntrackd.h index df36ec4..67397b8 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -84,6 +84,7 @@ struct ct_conf { unsigned int window_size; int cache_write_through; int filter_from_kernelspace; + int event_iterations_limit; struct { char logfile[FILENAME_MAXLEN]; int syslog_facility; @@ -103,6 +104,7 @@ struct ct_general_state { struct nfct_handle *event; /* event handler */ struct nfct_filter *filter; /* event filter */ + int event_iterations_limit; struct nfct_handle *dump; /* dump handler */ struct nfct_handle *request; /* request handler */ diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 67c95d3..f8b0ba1 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -117,6 +117,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "From" { return T_FROM; } "Userspace" { return T_USERSPACE; } "Kernelspace" { return T_KERNELSPACE; } +"EventIterationLimit" { return T_EVENT_ITER_LIMIT; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 69a7eff..274bfc3 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -59,7 +59,7 @@ static void __kernel_filter_add_state(int value); %token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT %token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK %token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE -%token T_FROM T_USERSPACE T_KERNELSPACE +%token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT %token T_IP T_PATH_VAL %token T_NUMBER @@ -681,6 +681,7 @@ general_line: hashsize | netlink_buffer_size | netlink_buffer_size_max_grown | family + | event_iterations_limit | filter ; @@ -702,6 +703,11 @@ family : T_FAMILY T_STRING conf.family = AF_INET; }; +event_iterations_limit : T_EVENT_ITER_LIMIT T_NUMBER +{ + CONFIG(event_iterations_limit) = $2; +}; + filter : T_FILTER '{' filter_list '}' { CONFIG(filter_from_kernelspace) = 0; @@ -1096,5 +1102,8 @@ init_config(char *filename) if (conf.flags & CTD_SYNC_FTFW && CONFIG(del_timeout) == 0) CONFIG(del_timeout) = 240; + if (CONFIG(event_iterations_limit) == 0) + CONFIG(event_iterations_limit) = 100; + return 0; } diff --git a/src/run.c b/src/run.c index 7958665..caf0b38 100644 --- a/src/run.c +++ b/src/run.c @@ -219,7 +219,7 @@ static int event_handler(enum nf_conntrack_msg_type type, /* skip user-space filtering if already do it in the kernel */ if (ct_filter_conntrack(ct, !CONFIG(filter_from_kernelspace))) { STATE(stats).nl_events_filtered++; - return NFCT_CB_STOP; + goto out; } switch(type) { @@ -238,7 +238,12 @@ static int event_handler(enum nf_conntrack_msg_type type, break; } - return NFCT_CB_CONTINUE; +out: + if (STATE(event_iterations_limit)-- <= 0) { + STATE(event_iterations_limit) = CONFIG(event_iterations_limit); + return NFCT_CB_STOP; + } else + return NFCT_CB_CONTINUE; } static int dump_handler(enum nf_conntrack_msg_type type, @@ -397,7 +402,7 @@ static void __run(struct timeval *next_alarm) /* conntrack event has happened */ if (FD_ISSET(nfct_fd(STATE(event)), &readfds)) { - while ((ret = nfct_catch(STATE(event))) != -1); + ret = nfct_catch(STATE(event)); if (ret == -1) { switch(errno) { case ENOBUFS: -- cgit v1.2.3 From 7ae054f8aae252ee9c57e26327675e466fc1d15d Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 17 Jan 2009 18:03:52 +0100 Subject: src: support for redundant dedicated links This patch adds support for redundant dedicated links. You can add a pool of dedicated links that can be used if the current active fails. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 19 ++++ doc/sync/ftfw/conntrackd.conf | 19 ++++ doc/sync/notrack/conntrackd.conf | 19 ++++ include/conntrackd.h | 10 +- include/mcast.h | 28 ++++- include/netlink.h | 1 + include/network.h | 6 +- src/main.c | 6 +- src/mcast.c | 231 ++++++++++++++++++++++++++++++++++++--- src/netlink.c | 16 +++ src/network.c | 9 +- src/read_config_lex.l | 1 + src/read_config_yy.y | 105 ++++++++++++------ src/sync-mode.c | 109 ++++++++++++++---- 14 files changed, 495 insertions(+), 84 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index f16f439..528ff8f 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -104,6 +104,25 @@ Sync { # Checksum on } + # + # You can specify more than one dedicated link. Thus, if one dedicated + # link fails, conntrackd can fail-over to another. Note that adding + # more than one dedicated link does not mean that state-updates will + # be sent to all of them. There is only one active dedicated link at + # a given moment. The `Default' keyword indicates that this interface + # will be selected as the initial dedicated link. You can have + # up to 4 redundant dedicated links. Note: Use different multicast + # groups for every redundant link. + # + # Multicast Default { + # IPv4_address 225.0.0.51 + # Group 3781 + # IPv4_interface 192.168.100.101 + # Interface eth3 + # # McastSndSocketBuffer 1249280 + # # McastRcvSocketBuffer 1249280 + # Checksum on + # } } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index d85fc28..2e60f2c 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -112,6 +112,25 @@ Sync { # Checksum on } + # + # You can specify more than one dedicated link. Thus, if one dedicated + # link fails, conntrackd can fail-over to another. Note that adding + # more than one dedicated link does not mean that state-updates will + # be sent to all of them. There is only one active dedicated link at + # a given moment. The `Default' keyword indicates that this interface + # will be selected as the initial dedicated link. You can have + # up to 4 redundant dedicated links. Note: Use different multicast + # groups for every redundant link. + # + # Multicast Default { + # IPv4_address 225.0.0.51 + # Group 3781 + # IPv4_interface 192.168.100.101 + # Interface eth3 + # # McastSndSocketBuffer 1249280 + # # McastRcvSocketBuffer 1249280 + # Checksum on + # } } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 4d03234..7f8c8a3 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -94,6 +94,25 @@ Sync { # Checksum on } + # + # You can specify more than one dedicated link. Thus, if one dedicated + # link fails, conntrackd can fail-over to another. Note that adding + # more than one dedicated link does not mean that state-updates will + # be sent to all of them. There is only one active dedicated link at + # a given moment. The `Default' keyword indicates that this interface + # will be selected as the initial dedicated link. You can have + # up to 4 redundant dedicated links. Note: Use different multicast + # groups for every redundant link. + # + # Multicast Default { + # IPv4_address 225.0.0.51 + # Group 3781 + # IPv4_interface 192.168.100.101 + # Interface eth3 + # # McastSndSocketBuffer 1249280 + # # McastRcvSocketBuffer 1249280 + # Checksum on + # } } # diff --git a/include/conntrackd.h b/include/conntrackd.h index 3637e2c..ab5d825 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -29,6 +29,7 @@ #define STATS_NETWORK 28 /* extended network stats */ #define STATS_CACHE 29 /* extended cache stats */ #define STATS_RUNTIME 30 /* extended runtime stats */ +#define STATS_MULTICAST 31 /* multicast network stats */ #define DEFAULT_CONFIGFILE "/etc/conntrackd/conntrackd.conf" #define DEFAULT_LOCKFILE "/var/lock/conntrackd.lock" @@ -66,7 +67,9 @@ struct ct_conf { int syslog_facility; char lockfile[FILENAME_MAXLEN]; int hashsize; /* hashtable size */ - struct mcast_conf mcast; /* multicast settings */ + int mcast_links; + int mcast_default_link; + struct mcast_conf mcast[MCAST_LINKS_MAX]; struct local_conf local; /* unix socket facilities */ int limit; int refresh; @@ -148,8 +151,9 @@ struct ct_sync_state { struct cache *internal; /* internal events cache (netlink) */ struct cache *external; /* external events cache (mcast) */ - struct mcast_sock *mcast_server; /* multicast socket: incoming */ - struct mcast_sock *mcast_client; /* multicast socket: outgoing */ + struct mcast_sock_multi *mcast_server; /* multicast incoming */ + struct mcast_sock_multi *mcast_client; /* multicast outgoing */ + struct nlif_handle *mcast_iface; struct queue *tx_queue; struct sync_mode *sync; /* sync mode */ diff --git a/include/mcast.h b/include/mcast.h index 7c4b1d6..623f390 100644 --- a/include/mcast.h +++ b/include/mcast.h @@ -19,6 +19,7 @@ struct mcast_conf { unsigned int interface_index6; } ifa; int mtu; + int interface_idx; int sndbuf; int rcvbuf; char iface[IFNAMSIZ]; @@ -37,19 +38,42 @@ struct mcast_sock { struct sockaddr_in6 ipv6; } addr; socklen_t sockaddr_len; + int interface_idx; struct mcast_stats stats; }; +#define MCAST_LINKS_MAX 4 + +struct mcast_sock_multi { + int num_links; + int max_mtu; + struct mcast_sock *current_link; + struct mcast_sock *multi[MCAST_LINKS_MAX]; +}; + struct mcast_sock *mcast_server_create(struct mcast_conf *conf); void mcast_server_destroy(struct mcast_sock *m); +struct mcast_sock_multi *mcast_server_create_multi(struct mcast_conf *conf, int conf_len); +void mcast_server_destroy_multi(struct mcast_sock_multi *m); struct mcast_sock *mcast_client_create(struct mcast_conf *conf); void mcast_client_destroy(struct mcast_sock *m); +struct mcast_sock_multi *mcast_client_create_multi(struct mcast_conf *conf, int conf_len); +void mcast_client_destroy_multi(struct mcast_sock_multi*m); ssize_t mcast_send(struct mcast_sock *m, void *data, int size); ssize_t mcast_recv(struct mcast_sock *m, void *data, int size); -struct mcast_stats *mcast_get_stats(struct mcast_sock *m); -void mcast_dump_stats(int fd, struct mcast_sock *s, struct mcast_sock *r); +int mcast_get_fd(struct mcast_sock *m); +int mcast_get_ifidx(struct mcast_sock_multi *m, int i); +int mcast_get_current_ifidx(struct mcast_sock_multi *m); + +struct mcast_sock *mcast_get_current_link(struct mcast_sock_multi *m); +void mcast_set_current_link(struct mcast_sock_multi *m, int i); + +void mcast_dump_stats(int fd, const struct mcast_sock_multi *s, const struct mcast_sock_multi *r); + +struct nlif_handle; +void mcast_dump_stats_extended(int fd, const struct mcast_sock_multi *s, const struct mcast_sock_multi *r, const struct nlif_handle *h); #endif diff --git a/include/netlink.h b/include/netlink.h index 5feb3e9..4bc5ee4 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -10,6 +10,7 @@ struct nfct_handle *nl_init_event_handler(void); struct nfct_handle *nl_init_dump_handler(void); struct nfct_handle *nl_init_request_handler(void); struct nfct_handle *nl_init_overrun_handler(void); +struct nlif_handle *nl_init_interface_handler(void); int nl_overrun_request_resync(struct nfct_handle *h); void nl_resize_socket_buffer(struct nfct_handle *h); diff --git a/include/network.h b/include/network.h index f02d920..740e762 100644 --- a/include/network.h +++ b/include/network.h @@ -76,7 +76,7 @@ enum { __hdr; \ }) -struct mcast_sock; +struct mcast_sock_multi; enum { SEQ_UNKNOWN, @@ -94,8 +94,8 @@ struct mcast_conf; int mcast_buffered_init(int mtu); void mcast_buffered_destroy(void); -int mcast_buffered_send_netmsg(struct mcast_sock *m, const struct nethdr *net); -ssize_t mcast_buffered_pending_netmsg(struct mcast_sock *m); +int mcast_buffered_send_netmsg(struct mcast_sock_multi *m, const struct nethdr *net); +ssize_t mcast_buffered_pending_netmsg(struct mcast_sock_multi *m); #define IS_DATA(x) (x->type <= NET_T_STATE_MAX && \ (x->flags & ~(NET_F_HELLO | NET_F_HELLO_BACK)) == 0) diff --git a/src/main.c b/src/main.c index 929b5c9..061a73e 100644 --- a/src/main.c +++ b/src/main.c @@ -43,7 +43,7 @@ static const char usage_client_commands[] = " -i, display content of the internal cache\n" " -e, display the content of the external cache\n" " -k, kill conntrack daemon\n" - " -s [|network|cache|runtime], dump statistics\n" + " -s [|network|cache|runtime|multicast], dump statistics\n" " -R, resync with kernel conntrack table\n" " -n, request resync with other node (only FT-FW and NOTRACK modes)\n" " -x, dump cache in XML format (requires -i or -e)\n" @@ -169,6 +169,10 @@ int main(int argc, char *argv[]) strlen(argv[i+1])) == 0) { action = STATS_RUNTIME; i++; + } else if (strncmp(argv[i+1], "multicast", + strlen(argv[i+1])) == 0) { + action = STATS_MULTICAST; + i++; } else { fprintf(stderr, "ERROR: unknown " "parameter `%s' for " diff --git a/src/mcast.c b/src/mcast.c index 2bb8743..70205d8 100644 --- a/src/mcast.c +++ b/src/mcast.c @@ -1,5 +1,5 @@ /* - * (C) 2006 by Pablo Neira Ayuso + * (C) 2006-2009 by Pablo Neira Ayuso * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -45,6 +45,8 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) return NULL; memset(m, 0, sizeof(struct mcast_sock)); + m->interface_idx = conf->interface_idx; + switch(conf->ipproto) { case AF_INET: mreq.ipv4.imr_multiaddr.s_addr = conf->in.inet_addr.s_addr; @@ -147,12 +149,52 @@ struct mcast_sock *mcast_server_create(struct mcast_conf *conf) return m; } +struct mcast_sock_multi * +mcast_server_create_multi(struct mcast_conf *conf, int conf_len) +{ + struct mcast_sock_multi *m; + int i, j; + + if (conf_len <= 0 || conf_len > MCAST_LINKS_MAX) + return NULL; + + m = calloc(sizeof(struct mcast_sock_multi), 1); + if (m == NULL) + return NULL; + + m->max_mtu = INT_MAX; + for (i=0; imulti[i] = mcast_server_create(&conf[i]); + if (m->multi[i] == NULL) { + for (j=0; jmulti[j]); + } + free(m); + return NULL; + } + if (m->max_mtu > conf[i].mtu) + m->max_mtu = conf[i].mtu; + } + m->num_links = conf_len; + + return m; +} + void mcast_server_destroy(struct mcast_sock *m) { close(m->fd); free(m); } +void mcast_server_destroy_multi(struct mcast_sock_multi *m) +{ + int i; + + for (i=0; inum_links; i++) + mcast_server_destroy(m->multi[i]); + free(m); +} + static int __mcast_client_create_ipv4(struct mcast_sock *m, struct mcast_conf *conf) { @@ -222,6 +264,8 @@ struct mcast_sock *mcast_client_create(struct mcast_conf *conf) return NULL; memset(m, 0, sizeof(struct mcast_sock)); + m->interface_idx = conf->interface_idx; + if ((m->fd = socket(conf->ipproto, SOCK_DGRAM, 0)) == -1) { debug("mcast_sock_client_create:socket"); free(m); @@ -275,12 +319,52 @@ struct mcast_sock *mcast_client_create(struct mcast_conf *conf) return m; } +struct mcast_sock_multi * +mcast_client_create_multi(struct mcast_conf *conf, int conf_len) +{ + struct mcast_sock_multi *m; + int i, j; + + if (conf_len <= 0 || conf_len > MCAST_LINKS_MAX) + return NULL; + + m = calloc(sizeof(struct mcast_sock_multi), 1); + if (m == NULL) + return NULL; + + m->max_mtu = INT_MAX; + for (i=0; imulti[i] = mcast_client_create(&conf[i]); + if (m->multi[i] == NULL) { + for (j=0; jmulti[j]); + } + free(m); + return NULL; + } + if (m->max_mtu > conf[i].mtu) + m->max_mtu = conf[i].mtu; + } + m->num_links = conf_len; + + return m; +} + void mcast_client_destroy(struct mcast_sock *m) { close(m->fd); free(m); } +void mcast_client_destroy_multi(struct mcast_sock_multi *m) +{ + int i; + + for (i=0; inum_links; i++) + mcast_client_destroy(m->multi[i]); + free(m); +} + ssize_t mcast_send(struct mcast_sock *m, void *data, int size) { ssize_t ret; @@ -326,29 +410,140 @@ ssize_t mcast_recv(struct mcast_sock *m, void *data, int size) return ret; } -struct mcast_stats *mcast_get_stats(struct mcast_sock *m) +void mcast_set_current_link(struct mcast_sock_multi *m, int i) +{ + m->current_link = m->multi[i]; +} + +struct mcast_sock *mcast_get_current_link(struct mcast_sock_multi *m) +{ + return m->current_link; +} + +int mcast_get_fd(struct mcast_sock *m) +{ + return m->fd; +} + +int mcast_get_current_ifidx(struct mcast_sock_multi *m) { - return &m->stats; + return m->current_link->interface_idx; } -void mcast_dump_stats(int fd, struct mcast_sock *s, struct mcast_sock *r) +int mcast_get_ifidx(struct mcast_sock_multi *m, int i) { - char buf[512]; + return m->multi[i]->interface_idx; +} + +static int +mcast_snprintf_stats(char *buf, size_t buflen, char *ifname, + struct mcast_stats *s, struct mcast_stats *r) +{ + size_t size; + + size = snprintf(buf, buflen, "multicast traffic (active device=%s):\n" + "%20llu Bytes sent " + "%20llu Bytes recv\n" + "%20llu Pckts sent " + "%20llu Pckts recv\n" + "%20llu Error send " + "%20llu Error recv\n\n", + ifname, + (unsigned long long)s->bytes, + (unsigned long long)r->bytes, + (unsigned long long)s->messages, + (unsigned long long)r->messages, + (unsigned long long)s->error, + (unsigned long long)r->error); + return size; +} + +static int +mcast_snprintf_stats2(char *buf, size_t buflen, const char *ifname, + const char *status, int active, + struct mcast_stats *s, struct mcast_stats *r) +{ + size_t size; + + size = snprintf(buf, buflen, + "multicast traffic device=%s status=%s role=%s:\n" + "%20llu Bytes sent " + "%20llu Bytes recv\n" + "%20llu Pckts sent " + "%20llu Pckts recv\n" + "%20llu Error send " + "%20llu Error recv\n\n", + ifname, status, active ? "ACTIVE" : "BACKUP", + (unsigned long long)s->bytes, + (unsigned long long)r->bytes, + (unsigned long long)s->messages, + (unsigned long long)r->messages, + (unsigned long long)s->error, + (unsigned long long)r->error); + return size; +} + +void +mcast_dump_stats(int fd, + const struct mcast_sock_multi *s, + const struct mcast_sock_multi *r) +{ + int i; + struct mcast_stats snd = { 0, 0, 0}; + struct mcast_stats rcv = { 0, 0, 0}; + char ifname[IFNAMSIZ], buf[512]; int size; - size = sprintf(buf, "multicast traffic:\n" - "%20llu Bytes sent " - "%20llu Bytes recv\n" - "%20llu Pckts sent " - "%20llu Pckts recv\n" - "%20llu Error send " - "%20llu Error recv\n\n", - (unsigned long long)s->stats.bytes, - (unsigned long long)r->stats.bytes, - (unsigned long long)s->stats.messages, - (unsigned long long)r->stats.messages, - (unsigned long long)s->stats.error, - (unsigned long long)r->stats.error); + /* it is the same for the receiver, no need to do it twice */ + if_indextoname(s->current_link->interface_idx, ifname); + + for (i=0; inum_links && inum_links; i++) { + snd.bytes += s->multi[i]->stats.bytes; + snd.messages += s->multi[i]->stats.messages; + snd.error += s->multi[i]->stats.error; + rcv.bytes += r->multi[i]->stats.bytes; + rcv.messages += r->multi[i]->stats.messages; + rcv.error += r->multi[i]->stats.error; + } + size = mcast_snprintf_stats(buf, sizeof(buf), ifname, &snd, &rcv); + send(fd, buf, size, 0); +} +void +mcast_dump_stats_extended(int fd, + const struct mcast_sock_multi *s, + const struct mcast_sock_multi *r, + const struct nlif_handle *h) +{ + int i; + char buf[4096]; + int size = 0; + + for (i=0; inum_links && inum_links; i++) { + int idx = s->multi[i]->interface_idx, active; + unsigned int flags; + char ifname[IFNAMSIZ]; + const char *status; + + if_indextoname(idx, ifname); + nlif_get_ifflags(h, idx, &flags); + active = (s->multi[i] == s->current_link); + /* + * IFF_UP shows administrative status + * IFF_RUNNING shows carrier status + */ + if (flags & IFF_UP) { + if (!(flags & IFF_RUNNING)) + status = "NO-CARRIER"; + else + status = "RUNNING"; + } else { + status = "DOWN"; + } + size += mcast_snprintf_stats2(buf+size, sizeof(buf), + ifname, status, active, + &s->multi[i]->stats, + &r->multi[i]->stats); + } send(fd, buf, size, 0); } diff --git a/src/netlink.c b/src/netlink.c index 92fbf00..2266201 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -114,6 +114,22 @@ struct nfct_handle *nl_init_request_handler(void) return h; } +struct nlif_handle *nl_init_interface_handler(void) +{ + struct nlif_handle *h; + h = nlif_open(); + if (h == NULL) + return NULL; + + if (nlif_query(h) == -1) { + free(h); + return NULL; + } + fcntl(nlif_fd(h), F_SETFL, O_NONBLOCK); + + return h; +} + static int warned = 0; void nl_resize_socket_buffer(struct nfct_handle *h) diff --git a/src/network.c b/src/network.c index 7a106b1..f71aef0 100644 --- a/src/network.c +++ b/src/network.c @@ -95,7 +95,8 @@ void mcast_buffered_destroy(void) } /* return 0 if it is not sent, otherwise return 1 */ -int mcast_buffered_send_netmsg(struct mcast_sock *m, const struct nethdr *net) +int +mcast_buffered_send_netmsg(struct mcast_sock_multi *m, const struct nethdr *net) { int ret = 0, len = ntohs(net->len); @@ -104,7 +105,7 @@ retry: memcpy(tx_buf + tx_buflen, net, len); tx_buflen += len; } else { - mcast_send(m, tx_buf, tx_buflen); + mcast_send(mcast_get_current_link(m), tx_buf, tx_buflen); ret = 1; tx_buflen = 0; goto retry; @@ -113,14 +114,14 @@ retry: return ret; } -ssize_t mcast_buffered_pending_netmsg(struct mcast_sock *m) +ssize_t mcast_buffered_pending_netmsg(struct mcast_sock_multi *m) { ssize_t ret; if (tx_buflen == 0) return 0; - ret = mcast_send(m, tx_buf, tx_buflen); + ret = mcast_send(mcast_get_current_link(m), tx_buf, tx_buflen); tx_buflen = 0; return ret; diff --git a/src/read_config_lex.l b/src/read_config_lex.l index f8b0ba1..e9e5d43 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -118,6 +118,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "Userspace" { return T_USERSPACE; } "Kernelspace" { return T_KERNELSPACE; } "EventIterationLimit" { return T_EVENT_ITER_LIMIT; } +"Default" { return T_DEFAULT; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 274bfc3..de6cef3 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -38,6 +38,7 @@ struct ct_conf conf; static void __kernel_filter_start(void); static void __kernel_filter_add_state(int value); +static void __max_mcast_dedicated_links_reached(void); %} %union { @@ -59,7 +60,7 @@ static void __kernel_filter_add_state(int value); %token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT %token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK %token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE -%token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT +%token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT %token T_IP T_PATH_VAL %token T_NUMBER @@ -174,14 +175,22 @@ checksum: T_CHECKSUM T_ON { fprintf(stderr, "WARNING: The use of `Checksum' outside the " "`Multicast' clause is ambiguous.\n"); - conf.mcast.checksum = 0; + /* + * XXX: The use of Checksum outside of the Multicast clause is broken + * if we have more than one dedicated links. + */ + conf.mcast[0].checksum = 0; }; checksum: T_CHECKSUM T_OFF { fprintf(stderr, "WARNING: The use of `Checksum' outside the " "`Multicast' clause is ambiguous.\n"); - conf.mcast.checksum = 1; + /* + * XXX: The use of Checksum outside of the Multicast clause is broken + * if we have more than one dedicated links. + */ + conf.mcast[0].checksum = 1; }; ignore_traffic : T_IGNORE_TRAFFIC '{' ignore_traffic_options '}' @@ -243,32 +252,45 @@ ignore_traffic_option : T_IPV6_ADDR T_IP }; -multicast_line : T_MULTICAST '{' multicast_options '}'; +multicast_line : T_MULTICAST '{' multicast_options '}' +{ + conf.mcast_links++; +}; + +multicast_line : T_MULTICAST T_DEFAULT '{' multicast_options '}' +{ + conf.mcast_default_link = conf.mcast_links; + conf.mcast_links++; +}; multicast_options : | multicast_options multicast_option; multicast_option : T_IPV4_ADDR T_IP { - if (!inet_aton($2, &conf.mcast.in)) { + __max_mcast_dedicated_links_reached(); + + if (!inet_aton($2, &conf.mcast[conf.mcast_links].in)) { fprintf(stderr, "%s is not a valid IPv4 address\n", $2); break; } - if (conf.mcast.ipproto == AF_INET6) { + if (conf.mcast[conf.mcast_links].ipproto == AF_INET6) { fprintf(stderr, "Your multicast address is IPv4 but " "is binded to an IPv6 interface? Surely " "this is not what you want\n"); break; } - conf.mcast.ipproto = AF_INET; + conf.mcast[conf.mcast_links].ipproto = AF_INET; }; multicast_option : T_IPV6_ADDR T_IP { + __max_mcast_dedicated_links_reached(); + #ifdef HAVE_INET_PTON_IPV6 - if (inet_pton(AF_INET6, $2, &conf.mcast.in) <= 0) { + if (inet_pton(AF_INET6, $2, &conf.mcast[conf.mcast_links].in) <= 0) { fprintf(stderr, "%s is not a valid IPv6 address\n", $2); break; } @@ -277,16 +299,17 @@ multicast_option : T_IPV6_ADDR T_IP break; #endif - if (conf.mcast.ipproto == AF_INET) { + if (conf.mcast[conf.mcast_links].ipproto == AF_INET) { fprintf(stderr, "Your multicast address is IPv6 but " "is binded to an IPv4 interface? Surely " "this is not what you want\n"); break; } - conf.mcast.ipproto = AF_INET6; + conf.mcast[conf.mcast_links].ipproto = AF_INET6; - if (conf.mcast.iface[0] && !conf.mcast.ifa.interface_index6) { + if (conf.mcast[conf.mcast_links].iface[0] && + !conf.mcast[conf.mcast_links].ifa.interface_index6) { unsigned int idx; idx = if_nametoindex($2); @@ -295,26 +318,28 @@ multicast_option : T_IPV6_ADDR T_IP break; } - conf.mcast.ifa.interface_index6 = idx; - conf.mcast.ipproto = AF_INET6; + conf.mcast[conf.mcast_links].ifa.interface_index6 = idx; + conf.mcast[conf.mcast_links].ipproto = AF_INET6; } }; multicast_option : T_IPV4_IFACE T_IP { - if (!inet_aton($2, &conf.mcast.ifa)) { + __max_mcast_dedicated_links_reached(); + + if (!inet_aton($2, &conf.mcast[conf.mcast_links].ifa)) { fprintf(stderr, "%s is not a valid IPv4 address\n", $2); break; } - if (conf.mcast.ipproto == AF_INET6) { + if (conf.mcast[conf.mcast_links].ipproto == AF_INET6) { fprintf(stderr, "Your multicast interface is IPv4 but " "is binded to an IPv6 interface? Surely " "this is not what you want\n"); break; } - conf.mcast.ipproto = AF_INET; + conf.mcast[conf.mcast_links].ipproto = AF_INET; }; multicast_option : T_IPV6_IFACE T_IP @@ -324,19 +349,22 @@ multicast_option : T_IPV6_IFACE T_IP multicast_option : T_IFACE T_STRING { - strncpy(conf.mcast.iface, $2, IFNAMSIZ); + unsigned int idx; - if (conf.mcast.ipproto == AF_INET6) { - unsigned int idx; + __max_mcast_dedicated_links_reached(); - idx = if_nametoindex($2); - if (!idx) { - fprintf(stderr, "%s is an invalid interface.\n", $2); - break; - } + strncpy(conf.mcast[conf.mcast_links].iface, $2, IFNAMSIZ); + + idx = if_nametoindex($2); + if (!idx) { + fprintf(stderr, "%s is an invalid interface.\n", $2); + break; + } + conf.mcast[conf.mcast_links].interface_idx = idx; - conf.mcast.ifa.interface_index6 = idx; - conf.mcast.ipproto = AF_INET6; + if (conf.mcast[conf.mcast_links].ipproto == AF_INET6) { + conf.mcast[conf.mcast_links].ifa.interface_index6 = idx; + conf.mcast[conf.mcast_links].ipproto = AF_INET6; } }; @@ -348,27 +376,32 @@ multicast_option : T_BACKLOG T_NUMBER multicast_option : T_GROUP T_NUMBER { - conf.mcast.port = $2; + __max_mcast_dedicated_links_reached(); + conf.mcast[conf.mcast_links].port = $2; }; multicast_option: T_MCAST_SNDBUFF T_NUMBER { - conf.mcast.sndbuf = $2; + __max_mcast_dedicated_links_reached(); + conf.mcast[conf.mcast_links].sndbuf = $2; }; multicast_option: T_MCAST_RCVBUFF T_NUMBER { - conf.mcast.rcvbuf = $2; + __max_mcast_dedicated_links_reached(); + conf.mcast[conf.mcast_links].rcvbuf = $2; }; multicast_option: T_CHECKSUM T_ON { - conf.mcast.checksum = 0; + __max_mcast_dedicated_links_reached(); + conf.mcast[conf.mcast_links].checksum = 0; }; multicast_option: T_CHECKSUM T_OFF { - conf.mcast.checksum = 1; + __max_mcast_dedicated_links_reached(); + conf.mcast[conf.mcast_links].checksum = 1; }; hashsize : T_HASHSIZE T_NUMBER @@ -1050,6 +1083,16 @@ static void __kernel_filter_add_state(int value) &filter_proto); } +static void __max_mcast_dedicated_links_reached(void) +{ + if (conf.mcast_links >= MCAST_LINKS_MAX) { + fprintf(stderr, "ERROR: too many dedicated links in " + "the configuration file (Maximum: %d).\n", + MCAST_LINKS_MAX); + exit(EXIT_FAILURE); + } +} + int init_config(char *filename) { diff --git a/src/sync-mode.c b/src/sync-mode.c index 00e2f7b..0dbd12d 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -33,8 +33,10 @@ #include #include #include +#include -static void do_mcast_handler_step(struct nethdr *net, size_t remain) +static void +do_mcast_handler_step(int if_idx, struct nethdr *net, size_t remain) { char __ct[nfct_maxsize()]; struct nf_conntrack *ct = (struct nf_conntrack *)(void*) __ct; @@ -47,6 +49,9 @@ static void do_mcast_handler_step(struct nethdr *net, size_t remain) return; } + if (if_idx != mcast_get_current_ifidx(STATE_SYNC(mcast_client))) + mcast_set_current_link(STATE_SYNC(mcast_client), if_idx); + switch (STATE_SYNC(sync)->recv(net)) { case MSG_DATA: break; @@ -111,13 +116,13 @@ retry: } /* handler for multicast messages received */ -static void mcast_handler(void) +static void mcast_handler(struct mcast_sock *m, int if_idx) { ssize_t numbytes; ssize_t remain; char __net[65536], *ptr = __net; /* XXX: maximum MTU for IPv4 */ - numbytes = mcast_recv(STATE_SYNC(mcast_server), __net, sizeof(__net)); + numbytes = mcast_recv(m, __net, sizeof(__net)); if (numbytes <= 0) return; @@ -160,12 +165,46 @@ static void mcast_handler(void) HDR_NETWORK2HOST(net); - do_mcast_handler_step(net, remain); + do_mcast_handler_step(if_idx, net, remain); ptr += net->len; remain -= net->len; } } +/* select a new interface candidate in a round robin basis */ +static void mcast_iface_candidate(void) +{ + int i, idx; + unsigned int flags; + char buf[IFNAMSIZ]; + + for (i=0; inum_links; i++) { + idx = mcast_get_ifidx(STATE_SYNC(mcast_client), i); + if (idx == mcast_get_current_ifidx(STATE_SYNC(mcast_client))) + continue; + nlif_get_ifflags(STATE_SYNC(mcast_iface), idx, &flags); + if (flags & (IFF_RUNNING | IFF_UP)) { + mcast_set_current_link(STATE_SYNC(mcast_client), i); + dlog(LOG_NOTICE, "device `%s' becomes multicast " + "dedicated link", + if_indextoname(idx, buf)); + return; + } + } + dlog(LOG_ERR, "no dedicated links available!"); +} + +static void mcast_iface_handler(void) +{ + int idx = mcast_get_current_ifidx(STATE_SYNC(mcast_client)); + unsigned int flags; + + nlif_catch(STATE_SYNC(mcast_iface)); + nlif_get_ifflags(STATE_SYNC(mcast_iface), idx, &flags); + if (!(flags & IFF_RUNNING) || !(flags & IFF_UP)) + mcast_iface_candidate(); +} + static int init_sync(void) { state.sync = malloc(sizeof(struct ct_sync_state)); @@ -216,30 +255,35 @@ static int init_sync(void) } /* multicast server to receive events from the wire */ - STATE_SYNC(mcast_server) = mcast_server_create(&CONFIG(mcast)); + STATE_SYNC(mcast_server) = + mcast_server_create_multi(CONFIG(mcast), CONFIG(mcast_links)); if (STATE_SYNC(mcast_server) == NULL) { dlog(LOG_ERR, "can't open multicast server!"); return -1; } - dlog(LOG_NOTICE, "multicast server socket receiver queue " - "has been set to %d bytes", CONFIG(mcast).rcvbuf); - /* multicast client to send events on the wire */ - STATE_SYNC(mcast_client) = mcast_client_create(&CONFIG(mcast)); + STATE_SYNC(mcast_client) = + mcast_client_create_multi(CONFIG(mcast), CONFIG(mcast_links)); if (STATE_SYNC(mcast_client) == NULL) { dlog(LOG_ERR, "can't open client multicast socket"); - mcast_server_destroy(STATE_SYNC(mcast_server)); + mcast_server_destroy_multi(STATE_SYNC(mcast_server)); return -1; } + /* we only use one link to send events, but all to receive them */ + mcast_set_current_link(STATE_SYNC(mcast_client), + CONFIG(mcast_default_link)); - dlog(LOG_NOTICE, "multicast client socket sender queue " - "has been set to %d bytes", CONFIG(mcast).sndbuf); - - if (mcast_buffered_init(CONFIG(mcast).mtu) == -1) { + if (mcast_buffered_init(STATE_SYNC(mcast_client)->max_mtu) == -1) { dlog(LOG_ERR, "can't init tx buffer!"); - mcast_server_destroy(STATE_SYNC(mcast_server)); - mcast_client_destroy(STATE_SYNC(mcast_client)); + mcast_server_destroy_multi(STATE_SYNC(mcast_server)); + mcast_client_destroy_multi(STATE_SYNC(mcast_client)); + return -1; + } + + STATE_SYNC(mcast_iface) = nl_init_interface_handler(); + if (!STATE_SYNC(mcast_iface)) { + dlog(LOG_ERR, "can't open interface watcher"); return -1; } @@ -257,7 +301,14 @@ static int init_sync(void) static int register_fds_sync(struct fds *fds) { - if (register_fd(STATE_SYNC(mcast_server->fd), fds) == -1) + int i; + + for (i=0; inum_links; i++) { + int fd = mcast_get_fd(STATE_SYNC(mcast_server)->multi[i]); + if (register_fd(fd, fds) == -1) + return -1; + } + if (register_fd(nlif_fd(STATE_SYNC(mcast_iface)), fds) == -1) return -1; if (register_fd(queue_get_eventfd(STATE_SYNC(tx_queue)), fds) == -1) @@ -268,13 +319,20 @@ static int register_fds_sync(struct fds *fds) static void run_sync(fd_set *readfds) { - /* multicast packet has been received */ - if (FD_ISSET(STATE_SYNC(mcast_server->fd), readfds)) - mcast_handler(); + int i; + + for (i=0; inum_links; i++) { + int fd = mcast_get_fd(STATE_SYNC(mcast_server)->multi[i]); + if (FD_ISSET(fd, readfds)) + mcast_handler(STATE_SYNC(mcast_server)->multi[i], i); + } if (FD_ISSET(queue_get_eventfd(STATE_SYNC(tx_queue)), readfds)) STATE_SYNC(sync)->xmit(); + if (FD_ISSET(nlif_fd(STATE_SYNC(mcast_iface)), readfds)) + mcast_iface_handler(); + /* flush pending messages */ mcast_buffered_pending_netmsg(STATE_SYNC(mcast_client)); } @@ -284,8 +342,10 @@ static void kill_sync(void) cache_destroy(STATE_SYNC(internal)); cache_destroy(STATE_SYNC(external)); - mcast_server_destroy(STATE_SYNC(mcast_server)); - mcast_client_destroy(STATE_SYNC(mcast_client)); + mcast_server_destroy_multi(STATE_SYNC(mcast_server)); + mcast_client_destroy_multi(STATE_SYNC(mcast_client)); + + nlif_close(STATE_SYNC(mcast_iface)); mcast_buffered_destroy(); queue_destroy(STATE_SYNC(tx_queue)); @@ -418,6 +478,11 @@ static int local_handler_sync(int fd, int type, void *data) cache_stats_extended(STATE_SYNC(internal), fd); cache_stats_extended(STATE_SYNC(external), fd); break; + case STATS_MULTICAST: + mcast_dump_stats_extended(fd, STATE_SYNC(mcast_client), + STATE_SYNC(mcast_server), + STATE_SYNC(mcast_iface)); + break; default: if (STATE_SYNC(sync)->local) ret = STATE_SYNC(sync)->local(fd, type, data); -- cgit v1.2.3 From 746f7031f4d1e3bccdd6db3c53835d8b85b73c90 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 17 Jan 2009 18:03:53 +0100 Subject: src: add state polling support (oppossed to current event-driven) This patch adds the clause PollSecs that changes the normal behaviour of conntrackd. With PollSecs set to > 0, conntrackd polls every N seconds the entries. This is the opposed behaviour of an event-driven behaviour but may be useful for those that have really strong limitations in terms of CPU consumption and want to perform a relaxed replication. Signed-off-by: Pablo Neira Ayuso --- doc/stats/conntrackd.conf | 12 ++++++++++++ doc/sync/alarm/conntrackd.conf | 12 ++++++++++++ doc/sync/ftfw/conntrackd.conf | 12 ++++++++++++ doc/sync/notrack/conntrackd.conf | 12 ++++++++++++ include/conntrackd.h | 2 ++ src/read_config_lex.l | 1 + src/read_config_yy.y | 13 ++++++++++++- src/run.c | 41 ++++++++++++++++++++++++++++------------ 8 files changed, 92 insertions(+), 13 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index 1fc21af..889d387 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -91,6 +91,18 @@ Stats { # LogFile on + # + # By default, the daemon receives state updates following an + # event-driven model. You can modify this behaviour by switching to + # polling mode with the PollSecs clause. This clause tells conntrackd + # to dump the states in the kernel every N seconds. With regards to + # synchronization mode, the polling mode can only guarantee that + # long-lifetime states are recovered. The main advantage of this method + # is the reduction in the state replication at the cost of reducing the + # chances of recovering connections. + # + # PollSecs 15 + # # Enable connection logging via Syslog. Default is off. # Syslog: on, off or a facility name (daemon (default) or local0..7) diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 528ff8f..3479a83 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -183,6 +183,18 @@ General { # SocketBufferSizeMaxGrowth 8388608 + # + # By default, the daemon receives state updates following an + # event-driven model. You can modify this behaviour by switching to + # polling mode with the PollSecs clause. This clause tells conntrackd + # to dump the states in the kernel every N seconds. With regards to + # synchronization mode, the polling mode can only guarantee that + # long-lifetime states are recovered. The main advantage of this method + # is the reduction in the state replication at the cost of reducing the + # chances of recovering connections. + # + # PollSecs 15 + # # The daemon prioritizes the handling of state-change events coming # from the core. With this clause, you can set the maximum number of diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 2e60f2c..77ef76c 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -191,6 +191,18 @@ General { # SocketBufferSizeMaxGrowth 8388608 + # + # By default, the daemon receives state updates following an + # event-driven model. You can modify this behaviour by switching to + # polling mode with the PollSecs clause. This clause tells conntrackd + # to dump the states in the kernel every N seconds. With regards to + # synchronization mode, the polling mode can only guarantee that + # long-lifetime states are recovered. The main advantage of this method + # is the reduction in the state replication at the cost of reducing the + # chances of recovering connections. + # + # PollSecs 15 + # # The daemon prioritizes the handling of state-change events coming # from the core. With this clause, you can set the maximum number of diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 7f8c8a3..5abf589 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -173,6 +173,18 @@ General { # SocketBufferSizeMaxGrowth 8388608 + # + # By default, the daemon receives state updates following an + # event-driven model. You can modify this behaviour by switching to + # polling mode with the PollSecs clause. This clause tells conntrackd + # to dump the states in the kernel every N seconds. With regards to + # synchronization mode, the polling mode can only guarantee that + # long-lifetime states are recovered. The main advantage of this method + # is the reduction in the state replication at the cost of reducing the + # chances of recovering connections. + # + # PollSecs 15 + # # The daemon prioritizes the handling of state-change events coming # from the core. With this clause, you can set the maximum number of diff --git a/include/conntrackd.h b/include/conntrackd.h index fbf126a..acf907c 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -48,6 +48,7 @@ #define CTD_SYNC_FTFW (1UL << 2) #define CTD_SYNC_ALARM (1UL << 3) #define CTD_SYNC_NOTRACK (1UL << 4) +#define CTD_POLL (1UL << 5) /* FILENAME_MAX is 4096 on my system, perhaps too much? */ #ifndef FILENAME_MAXLEN @@ -85,6 +86,7 @@ struct ct_conf { int family; /* protocol family */ unsigned int resend_queue_size; /* FTFW protocol */ unsigned int window_size; + int poll_kernel_secs; int cache_write_through; int filter_from_kernelspace; int event_iterations_limit; diff --git a/src/read_config_lex.l b/src/read_config_lex.l index e9e5d43..4953974 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -119,6 +119,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "Kernelspace" { return T_KERNELSPACE; } "EventIterationLimit" { return T_EVENT_ITER_LIMIT; } "Default" { return T_DEFAULT; } +"PollSecs" { return T_POLL_SECS; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index de6cef3..ce604d9 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -58,7 +58,7 @@ static void __max_mcast_dedicated_links_reached(void); %token T_ESTABLISHED T_SYN_SENT T_SYN_RECV T_FIN_WAIT %token T_CLOSE_WAIT T_LAST_ACK T_TIME_WAIT T_CLOSE T_LISTEN %token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT -%token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK +%token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK T_POLL_SECS %token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE %token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT @@ -715,6 +715,7 @@ general_line: hashsize | netlink_buffer_size_max_grown | family | event_iterations_limit + | poll_secs | filter ; @@ -741,6 +742,16 @@ event_iterations_limit : T_EVENT_ITER_LIMIT T_NUMBER CONFIG(event_iterations_limit) = $2; }; +poll_secs: T_POLL_SECS T_NUMBER +{ + conf.flags |= CTD_POLL; + conf.poll_kernel_secs = $2; + if (conf.poll_kernel_secs == 0) { + fprintf(stderr, "ERROR: `PollSecs' clause must be > 0\n"); + exit(EXIT_FAILURE); + } +}; + filter : T_FILTER '{' filter_list '}' { CONFIG(filter_from_kernelspace) = 0; diff --git a/src/run.c b/src/run.c index a6dfe15..a483ab3 100644 --- a/src/run.c +++ b/src/run.c @@ -39,7 +39,8 @@ void killer(int foo) /* no signals while handling signals */ sigprocmask(SIG_BLOCK, &STATE(block), NULL); - nfct_close(STATE(event)); + if (!(CONFIG(flags) & CTD_POLL)) + nfct_close(STATE(event)); nfct_close(STATE(request)); if (STATE(us_filter)) @@ -204,12 +205,18 @@ void local_handler(int fd, void *data) STATE(stats).local_unknown_request++; } -static void do_resync_alarm(struct alarm_block *a, void *data) +static void do_overrun_resync_alarm(struct alarm_block *a, void *data) { nl_send_resync(STATE(resync)); STATE(stats).nl_kernel_table_resync++; } +static void do_poll_resync_alarm(struct alarm_block *a, void *data) +{ + nl_send_resync(STATE(resync)); + add_alarm(&STATE(resync_alarm), CONFIG(poll_kernel_secs), 0); +} + static int event_handler(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) @@ -297,15 +304,18 @@ init(void) } register_fd(STATE(local).fd, STATE(fds)); - STATE(event) = nl_init_event_handler(); - if (STATE(event) == NULL) { - dlog(LOG_ERR, "can't open netlink handler: %s", - strerror(errno)); - dlog(LOG_ERR, "no ctnetlink kernel support?"); - return -1; + if (!(CONFIG(flags) & CTD_POLL)) { + STATE(event) = nl_init_event_handler(); + if (STATE(event) == NULL) { + dlog(LOG_ERR, "can't open netlink handler: %s", + strerror(errno)); + dlog(LOG_ERR, "no ctnetlink kernel support?"); + return -1; + } + nfct_callback_register(STATE(event), NFCT_T_ALL, + event_handler, NULL); + register_fd(nfct_fd(STATE(event)), STATE(fds)); } - nfct_callback_register(STATE(event), NFCT_T_ALL, event_handler, NULL); - register_fd(nfct_fd(STATE(event)), STATE(fds)); STATE(dump) = nl_init_dump_handler(); if (STATE(dump) == NULL) { @@ -343,7 +353,13 @@ init(void) return -1; } - init_alarm(&STATE(resync_alarm), NULL, do_resync_alarm); + if (CONFIG(flags) & CTD_POLL) { + init_alarm(&STATE(resync_alarm), NULL, do_poll_resync_alarm); + add_alarm(&STATE(resync_alarm), CONFIG(poll_kernel_secs), 0); + dlog(LOG_NOTICE, "running in polling mode"); + } else { + init_alarm(&STATE(resync_alarm), NULL, do_overrun_resync_alarm); + } /* Signals handling */ sigemptyset(&STATE(block)); @@ -397,7 +413,8 @@ static void __run(struct timeval *next_alarm) do_local_server_step(&STATE(local), NULL, local_handler); /* conntrack event has happened */ - if (FD_ISSET(nfct_fd(STATE(event)), &readfds)) { + if (!(CONFIG(flags) & CTD_POLL) && + FD_ISSET(nfct_fd(STATE(event)), &readfds)) { ret = nfct_catch(STATE(event)); if (ret == -1) { switch(errno) { -- cgit v1.2.3 From cced587d766b9194b698a156d241766d5bad8a9d Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 25 Jan 2009 17:53:14 +0100 Subject: src: increase default PurgeTimeout value This patch increases the default PurgeTimeout value to 60 seconds. The former 15 seconds provides good real-time reaction in terms of user-side expected behaviour, but it is too small if you trigger random failure in a firewall cluster. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 11 +++++------ doc/sync/ftfw/conntrackd.conf | 11 +++++------ doc/sync/notrack/conntrackd.conf | 11 +++++------ src/read_config_yy.y | 4 ++-- 4 files changed, 17 insertions(+), 20 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 3479a83..db7d99e 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -27,13 +27,12 @@ Sync { # # If the firewall replica goes from primary to backup, # the conntrackd -t command is invoked in the script. - # This command resets the timers of the conntracks that - # live in the kernel to this new value. This is useful - # to purge the connection tracking table of zombie entries - # and avoid clashes with old entries if you trigger - # several consecutive hand-overs. + # This command schedules a flush of the table in N seconds. + # This is useful to purge the connection tracking table of + # zombie entries and avoid clashes with old entries if you + # trigger several consecutive hand-overs. Default is 60 seconds # - PurgeTimeout 15 + # PurgeTimeout 60 } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 4fd86d7..69572cf 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -24,13 +24,12 @@ Sync { # # If the firewall replica goes from primary to backup, # the conntrackd -t command is invoked in the script. - # This command resets the timers of the conntracks that - # live in the kernel to this new value. This is useful - # to purge the connection tracking table of zombie entries - # and avoid clashes with old entries if you trigger - # several consecutive hand-overs. + # This command schedules a flush of the table in N seconds. + # This is useful to purge the connection tracking table of + # zombie entries and avoid clashes with old entries if you + # trigger several consecutive hand-overs. Default is 60 seconds. # - PurgeTimeout 15 + # PurgeTimeout 60 # Set the acknowledgement window size. If you decrease this # value, the number of acknowlegdments increases. More diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 5abf589..1df79a1 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -13,13 +13,12 @@ Sync { # # If the firewall replica goes from primary to backup, # the conntrackd -t command is invoked in the script. - # This command resets the timers of the conntracks that - # live in the kernel to this new value. This is useful - # to purge the connection tracking table of zombie entries - # and avoid clashes with old entries if you trigger - # several consecutive hand-overs. + # This command schedules a flush of the table in N seconds. + # This is useful to purge the connection tracking table of + # zombie entries and avoid clashes with old entries if you + # trigger several consecutive hand-overs. Default is 60 seconds. # - PurgeTimeout 15 + # PurgeTimeout 60 } # diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 766d543..049896e 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -1141,9 +1141,9 @@ init_config(char *filename) if (CONFIG(cache_timeout) == 0) CONFIG(cache_timeout) = 180; - /* default to 15 seconds: purge kernel entries */ + /* default to 60 seconds: purge kernel entries */ if (CONFIG(purge_timeout) == 0) - CONFIG(purge_timeout) = 15; + CONFIG(purge_timeout) = 60; /* default to 60 seconds of refresh time */ if (CONFIG(refresh) == 0) -- cgit v1.2.3 From 2aeebebf6d6a48d57023e3c7953ddd9088284f99 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 25 Jan 2009 18:21:26 +0100 Subject: doc: unset CommitTimeout by default This patch disables CommitTimeout by default. The daemon now uses the approximate timeout calculation by default. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 14 ++++++++++---- doc/sync/ftfw/conntrackd.conf | 14 ++++++++++---- doc/sync/notrack/conntrackd.conf | 14 ++++++++++---- 3 files changed, 30 insertions(+), 12 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index db7d99e..39741b3 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -18,11 +18,17 @@ Sync { CacheTimeout 180 # - # Entries committed to the connection tracking table - # starts with a limited timeout of N seconds until the - # takeover process is completed. + # This parameter allows you to set an initial fixed timeout + # for the committed entries when this node goes from backup + # to primary. This mechanism provides a way to purge entries + # that were not recovered appropriately after the specified + # fixed timeout. If you set a low value, TCP entries in + # Established states with no traffic may hang. For example, + # an SSH connection without KeepAlive enabled. If not set, + # the daemon uses an approximate timeout value calculation + # mechanism. By default, this option is not set. # - CommitTimeout 180 + # CommitTimeout 180 # # If the firewall replica goes from primary to backup, diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 69572cf..93f7a44 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -15,11 +15,17 @@ Sync { # ResendQueueSize 131072 # - # Entries committed to the connection tracking table - # starts with a limited timeout of N seconds until the - # takeover process is completed. + # This parameter allows you to set an initial fixed timeout + # for the committed entries when this node goes from backup + # to primary. This mechanism provides a way to purge entries + # that were not recovered appropriately after the specified + # fixed timeout. If you set a low value, TCP entries in + # Established states with no traffic may hang. For example, + # an SSH connection without KeepAlive enabled. If not set, + # the daemon uses an approximate timeout value calculation + # mechanism. By default, this option is not set. # - CommitTimeout 180 + # CommitTimeout 180 # # If the firewall replica goes from primary to backup, diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 1df79a1..39a5faa 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -4,11 +4,17 @@ Sync { Mode NOTRACK { # - # Entries committed to the connection tracking table - # starts with a limited timeout of N seconds until the - # takeover process is completed. + # This parameter allows you to set an initial fixed timeout + # for the committed entries when this node goes from backup + # to primary. This mechanism provides a way to purge entries + # that were not recovered appropriately after the specified + # fixed timeout. If you set a low value, TCP entries in + # Established states with no traffic may hang. For example, + # an SSH connection without KeepAlive enabled. If not set, + # the daemon uses an approximate timeout value calculation + # mechanism. By default, this option is not set. # - CommitTimeout 180 + # CommitTimeout 180 # # If the firewall replica goes from primary to backup, -- cgit v1.2.3 From afb9b7f9ee21df97754648d832fcee2b778b277a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 25 Jan 2009 18:50:43 +0100 Subject: doc: use 'From' instead of 'from' in the example configfiles This patch fixes a wrong use of 'from' instead of 'From' in the example configuration files. Reported-by: Yoann Juet Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 2 +- doc/sync/ftfw/conntrackd.conf | 2 +- doc/sync/notrack/conntrackd.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 39741b3..da11887 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -226,7 +226,7 @@ General { # event filtering, use the keyword 'Kernelspace' instead of # 'Userspace'. # - Filter from Userspace { + Filter From Userspace { # # Accept only certain protocols: You may want to replicate # the state of flows depending on their layer 4 protocol. diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 93f7a44..3c39291 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -235,7 +235,7 @@ General { # event filtering, use the keyword 'Kernelspace' instead of # 'Userspace'. # - Filter from Userspace { + Filter From Userspace { # # Accept only certain protocols: You may want to replicate # the state of flows depending on their layer 4 protocol. diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 39a5faa..f86d17b 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -216,7 +216,7 @@ General { # event filtering, use the keyword 'Kernelspace' instead of # 'Userspace'. # - Filter from Userspace { + Filter From Userspace { # # Accept only certain protocols: You may want to replicate # the state of flows depending on their layer 4 protocol. -- cgit v1.2.3 From 8b7937e8a3864d84992e931ace69172ba171d875 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 25 Jan 2009 19:15:01 +0100 Subject: doc: increase hashtable bucket size and limits in example files This patch details a bit more the hashtable parameters. Moreover, it increases the default size of the hashtable. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 14 +++++++++----- doc/sync/ftfw/conntrackd.conf | 14 +++++++++----- doc/sync/notrack/conntrackd.conf | 14 +++++++++----- 3 files changed, 27 insertions(+), 15 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index da11887..ad9bcd9 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -135,15 +135,19 @@ Sync { # General { # - # Number of buckets in the caches: hash table. + # Number of buckets in the cache hashtable. The bigger it is, + # the closer it gets to O(1) at the cost of consuming more memory. + # Read some documents about tuning hashtables for further reference. # - HashSize 16384 + HashSize 32768 # - # Maximum number of conntracks: - # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max + # Maximum number of conntracks, it should be double of: + # $ cat /proc/sys/net/netfilter/nf_conntrack_max + # since the daemon may keep some dead entries cached for possible + # retransmission during state synchronization. # - HashLimit 65536 + HashLimit 131072 # # Logfile: on (/var/log/conntrackd.log), off, or a filename diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 3c39291..0021ea8 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -144,15 +144,19 @@ Sync { # General { # - # Number of buckets in the caches: hash table. + # Number of buckets in the cache hashtable. The bigger it is, + # the closer it gets to O(1) at the cost of consuming more memory. + # Read some documents about tuning hashtables for further reference. # - HashSize 16384 + HashSize 32768 # - # Maximum number of conntracks: - # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max + # Maximum number of conntracks, it should be double of: + # $ cat /proc/sys/net/netfilter/nf_conntrack_max + # since the daemon may keep some dead entries cached for possible + # retransmission during state synchronization. # - HashLimit 65536 + HashLimit 131072 # # Logfile: on (/var/log/conntrackd.log), off, or a filename diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index f86d17b..b77d589 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -125,15 +125,19 @@ Sync { # General { # - # Number of buckets in the caches: hash table. + # Number of buckets in the cache hashtable. The bigger it is, + # the closer it gets to O(1) at the cost of consuming more memory. + # Read some documents about tuning hashtables for further reference. # - HashSize 16384 + HashSize 32768 # - # Maximum number of conntracks: - # it must be >= $ cat /proc/sys/net/ipv4/netfilter/ip_conntrack_max + # Maximum number of conntracks, it should be double of: + # $ cat /proc/sys/net/netfilter/nf_conntrack_max + # since the daemon may keep some dead entries cached for possible + # retransmission during state synchronization. # - HashLimit 65536 + HashLimit 131072 # # Logfile: on (/var/log/conntrackd.log), off, or a filename -- cgit v1.2.3 From f3464ea99081fbe4f429f030ea99c60e2338c047 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 8 Feb 2009 19:13:22 +0100 Subject: netlink: add new option NetlinkOverrunResync This patch adds NetlinkOverrunResync. This option can be used to set the amount of time after which the daemon resynchronizes itself with the kernel state-table if it detects a Netlink overrun. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 13 +++++++++++++ doc/sync/ftfw/conntrackd.conf | 13 +++++++++++++ doc/sync/notrack/conntrackd.conf | 13 +++++++++++++ include/conntrackd.h | 1 + src/read_config_lex.l | 1 + src/read_config_yy.y | 23 ++++++++++++++++++++++- src/run.c | 8 ++++---- 7 files changed, 67 insertions(+), 5 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index ad9bcd9..5e44d0d 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -192,6 +192,19 @@ General { # SocketBufferSizeMaxGrowth 8388608 + # + # If the daemon detects that Netlink is dropping state-change events, + # it automatically schedules a resynchronization against the Kernel + # after 30 seconds (default value). Resynchronizations are expensive + # in terms of CPU consumption since the daemon has to get the full + # kernel state-table and purge state-entries that do not exist anymore. + # Be careful of setting a very small value here. You have the following + # choices: On (enabled, use default 30 seconds value), Off (disabled) + # or Value (in seconds, to set a specific amount of time). If not + # specified, the daemon assumes that this option is enabled. + # + # NetlinkOverrunResync On + # # By default, the daemon receives state updates following an # event-driven model. You can modify this behaviour by switching to diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 0021ea8..92cd9d1 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -201,6 +201,19 @@ General { # SocketBufferSizeMaxGrowth 8388608 + # + # If the daemon detects that Netlink is dropping state-change events, + # it automatically schedules a resynchronization against the Kernel + # after 30 seconds (default value). Resynchronizations are expensive + # in terms of CPU consumption since the daemon has to get the full + # kernel state-table and purge state-entries that do not exist anymore. + # Be careful of setting a very small value here. You have the following + # choices: On (enabled, use default 30 seconds value), Off (disabled) + # or Value (in seconds, to set a specific amount of time). If not + # specified, the daemon assumes that this option is enabled. + # + # NetlinkOverrunResync On + # # By default, the daemon receives state updates following an # event-driven model. You can modify this behaviour by switching to diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index b77d589..c64291b 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -182,6 +182,19 @@ General { # SocketBufferSizeMaxGrowth 8388608 + # + # If the daemon detects that Netlink is dropping state-change events, + # it automatically schedules a resynchronization against the Kernel + # after 30 seconds (default value). Resynchronizations are expensive + # in terms of CPU consumption since the daemon has to get the full + # kernel state-table and purge state-entries that do not exist anymore. + # Be careful of setting a very small value here. You have the following + # choices: On (enabled, use default 30 seconds value), Off (disabled) + # or Value (in seconds, to set a specific amount of time). If not + # specified, the daemon assumes that this option is enabled. + # + # NetlinkOverrunResync On + # # By default, the daemon receives state updates following an # event-driven model. You can modify this behaviour by switching to diff --git a/include/conntrackd.h b/include/conntrackd.h index 34c7629..4051e94 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -80,6 +80,7 @@ struct ct_conf { unsigned int purge_timeout; /* purge kernel entries timeout */ unsigned int netlink_buffer_size; unsigned int netlink_buffer_size_max_grown; + unsigned int nl_overrun_resync; union inet_address *listen_to; unsigned int listen_to_len; unsigned int flags; diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 9bc4c18..26c6124 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -121,6 +121,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "EventIterationLimit" { return T_EVENT_ITER_LIMIT; } "Default" { return T_DEFAULT; } "PollSecs" { return T_POLL_SECS; } +"NetlinkOverrunResync" { return T_NETLINK_OVERRUN_RESYNC; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 049896e..1bea865 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -1,6 +1,6 @@ %{ /* - * (C) 2006-2007 by Pablo Neira Ayuso + * (C) 2006-2009 by Pablo Neira Ayuso * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -61,6 +61,7 @@ static void __max_mcast_dedicated_links_reached(void); %token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK T_POLL_SECS %token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE %token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT +%token T_NETLINK_OVERRUN_RESYNC %token T_IP T_PATH_VAL %token T_NUMBER @@ -725,6 +726,7 @@ general_line: hashsize | event_iterations_limit | poll_secs | filter + | netlink_overrun_resync ; netlink_buffer_size: T_BUFFER_SIZE T_NUMBER @@ -737,6 +739,21 @@ netlink_buffer_size_max_grown : T_BUFFER_SIZE_MAX_GROWN T_NUMBER conf.netlink_buffer_size_max_grown = $2; }; +netlink_overrun_resync : T_NETLINK_OVERRUN_RESYNC T_ON +{ + conf.nl_overrun_resync = 30; +}; + +netlink_overrun_resync : T_NETLINK_OVERRUN_RESYNC T_OFF +{ + conf.nl_overrun_resync = -1; +}; + +netlink_overrun_resync : T_NETLINK_OVERRUN_RESYNC T_NUMBER +{ + conf.nl_overrun_resync = $2; +} + family : T_FAMILY T_STRING { if (strncmp($2, "IPv6", strlen("IPv6")) == 0) @@ -1159,5 +1176,9 @@ init_config(char *filename) if (CONFIG(event_iterations_limit) == 0) CONFIG(event_iterations_limit) = 100; + /* if overrun, automatically resync with kernel after 30 seconds */ + if (CONFIG(nl_overrun_resync) == 0) + CONFIG(nl_overrun_resync) = 30; + return 0; } diff --git a/src/run.c b/src/run.c index 81f2590..5c2a3e7 100644 --- a/src/run.c +++ b/src/run.c @@ -417,9 +417,6 @@ init(void) return 0; } -/* interval of 30s. for between two overrun */ -#define OVRUN_INT 30 - static void __run(struct timeval *next_alarm) { int ret; @@ -475,7 +472,10 @@ static void __run(struct timeval *next_alarm) * we resync ourselves. */ nl_resize_socket_buffer(STATE(event)); - add_alarm(&STATE(resync_alarm), OVRUN_INT, 0); + if (CONFIG(nl_overrun_resync) > 0) { + add_alarm(&STATE(resync_alarm), + CONFIG(nl_overrun_resync),0); + } STATE(stats).nl_catch_event_failed++; STATE(stats).nl_overrun++; break; -- cgit v1.2.3 From 7f902c8419c891ec3ec83d40fb30afccb2a150c6 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sun, 8 Feb 2009 20:55:34 +0100 Subject: src: add Nice clause to set the nice value Signed-off-by: Pablo Neira Ayuso --- doc/stats/conntrackd.conf | 8 ++++++++ doc/sync/alarm/conntrackd.conf | 8 ++++++++ doc/sync/ftfw/conntrackd.conf | 8 ++++++++ doc/sync/notrack/conntrackd.conf | 8 ++++++++ include/conntrackd.h | 1 + src/main.c | 1 + src/read_config_lex.l | 3 +++ src/read_config_yy.y | 11 +++++++++-- 8 files changed, 46 insertions(+), 2 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index 889d387..54e2322 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -2,6 +2,14 @@ # General settings # General { + # + # Set the nice value of the daemon. This value goes from -20 + # (most favorable scheduling) to 19 (least favorable). Using a + # negative value reduces the chances to lose state-change events. + # Default is 0. See man nice(1) for more information. + # + Nice -1 + # # Number of buckets in the caches: hash table # diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 5e44d0d..aa87541 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -134,6 +134,14 @@ Sync { # General settings # General { + # + # Set the nice value of the daemon, this value goes from -20 + # (most favorable scheduling) to 19 (least favorable). Using a + # negative value reduces the chances to lose state-change events. + # Default is 0. See man nice(1) for more information. + # + Nice -1 + # # Number of buckets in the cache hashtable. The bigger it is, # the closer it gets to O(1) at the cost of consuming more memory. diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 92cd9d1..a3f42a2 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -143,6 +143,14 @@ Sync { # General settings # General { + # + # Set the nice value of the daemon, this value goes from -20 + # (most favorable scheduling) to 19 (least favorable). Using a + # negative value reduces the chances to lose state-change events. + # Default is 0. See man nice(1) for more information. + # + Nice -1 + # # Number of buckets in the cache hashtable. The bigger it is, # the closer it gets to O(1) at the cost of consuming more memory. diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index c64291b..755b08b 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -124,6 +124,14 @@ Sync { # General settings # General { + # + # Set the nice value of the daemon, this value goes from -20 + # (most favorable scheduling) to 19 (least favorable). Using a + # negative value reduces the chances to lose state-change events. + # Default is 0. See man nice(1) for more information. + # + Nice -1 + # # Number of buckets in the cache hashtable. The bigger it is, # the closer it gets to O(1) at the cost of consuming more memory. diff --git a/include/conntrackd.h b/include/conntrackd.h index 4051e94..2aaa6e6 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -73,6 +73,7 @@ struct ct_conf { int mcast_default_link; struct mcast_conf mcast[MCAST_LINKS_MAX]; struct local_conf local; /* unix socket facilities */ + int nice; int limit; int refresh; int cache_timeout; /* cache entries timeout */ diff --git a/src/main.c b/src/main.c index c3271fe..8f75904 100644 --- a/src/main.c +++ b/src/main.c @@ -279,6 +279,7 @@ int main(int argc, char *argv[]) chdir("/"); close(STDIN_FILENO); + nice(CONFIG(nice)); /* Daemonize conntrackd */ if (type == DAEMON) { diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 26c6124..a1830fd 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -35,6 +35,7 @@ nl [\n\r] is_on [o|O][n|N] is_off [o|O][f|F][f|F] integer [0-9]+ +signed_integer [\-\+][0-9]+ path \/[^\"\n ]* ip4_cidr \/[0-2]*[0-9]+ ip4_end [0-9]*[0-9]+ @@ -122,10 +123,12 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "Default" { return T_DEFAULT; } "PollSecs" { return T_POLL_SECS; } "NetlinkOverrunResync" { return T_NETLINK_OVERRUN_RESYNC; } +"Nice" { return T_NICE; } {is_on} { return T_ON; } {is_off} { return T_OFF; } {integer} { yylval.val = atoi(yytext); return T_NUMBER; } +{signed_integer} { yylval.val = atoi(yytext); return T_SIGNED_NUMBER; } {ip4} { yylval.string = strdup(yytext); return T_IP; } {ip6} { yylval.string = strdup(yytext); return T_IP; } {path} { yylval.string = strdup(yytext); return T_PATH_VAL; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 1bea865..b9a37f7 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -61,10 +61,11 @@ static void __max_mcast_dedicated_links_reached(void); %token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK T_POLL_SECS %token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE %token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT -%token T_NETLINK_OVERRUN_RESYNC +%token T_NETLINK_OVERRUN_RESYNC T_NICE %token T_IP T_PATH_VAL %token T_NUMBER +%token T_SIGNED_NUMBER %token T_STRING %% @@ -727,6 +728,7 @@ general_line: hashsize | poll_secs | filter | netlink_overrun_resync + | nice ; netlink_buffer_size: T_BUFFER_SIZE T_NUMBER @@ -752,7 +754,12 @@ netlink_overrun_resync : T_NETLINK_OVERRUN_RESYNC T_OFF netlink_overrun_resync : T_NETLINK_OVERRUN_RESYNC T_NUMBER { conf.nl_overrun_resync = $2; -} +}; + +nice : T_NICE T_SIGNED_NUMBER +{ + conf.nice = $2; +}; family : T_FAMILY T_STRING { -- cgit v1.2.3 From ae94864dee8596fcaf19ffe5670d192a0efd5fd6 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 21 Feb 2009 14:18:56 +0100 Subject: config: add NetlinkBufferSize and NetlinkBufferSizeMaxGrowth This patch adds two alias that removes an inconsistency in the configuration file names. Now, the clauses that refers to Netlink starts by the prefix "Netlink". Signed-off-by: Pablo Neira Ayuso --- doc/stats/conntrackd.conf | 4 ++-- doc/sync/alarm/conntrackd.conf | 4 ++-- doc/sync/ftfw/conntrackd.conf | 4 ++-- doc/sync/notrack/conntrackd.conf | 4 ++-- src/read_config_lex.l | 8 +++++--- 5 files changed, 13 insertions(+), 11 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index 54e2322..1f1a697 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -49,12 +49,12 @@ General { # # Netlink socket buffer size # - SocketBufferSize 262142 + NetlinkBufferSize 262142 # # Increase the socket buffer up to maximun if required # - SocketBufferSizeMaxGrown 655355 + NetlinkBufferSizeMaxGrowth 655355 # # Event filtering: This clause allows you to filter certain traffic, diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index aa87541..cefda00 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -190,7 +190,7 @@ General { # and high CPU consumption. This example configuration file sets the # size to 2 MBytes to avoid this sort of problems. # - SocketBufferSize 2097152 + NetlinkBufferSize 2097152 # # The daemon doubles the size of the netlink event socket buffer size @@ -198,7 +198,7 @@ General { # maximum buffer size growth that can be reached. This example file # sets the size to 8 MBytes. # - SocketBufferSizeMaxGrowth 8388608 + NetlinkBufferSizeMaxGrowth 8388608 # # If the daemon detects that Netlink is dropping state-change events, diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 790026b..d7e4123 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -199,7 +199,7 @@ General { # and high CPU consumption. This example configuration file sets the # size to 2 MBytes to avoid this sort of problems. # - SocketBufferSize 2097152 + NetlinkBufferSize 2097152 # # The daemon doubles the size of the netlink event socket buffer size @@ -207,7 +207,7 @@ General { # maximum buffer size growth that can be reached. This example file # sets the size to 8 MBytes. # - SocketBufferSizeMaxGrowth 8388608 + NetlinkBufferSizeMaxGrowth 8388608 # # If the daemon detects that Netlink is dropping state-change events, diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 755b08b..884d536 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -180,7 +180,7 @@ General { # and high CPU consumption. This example configuration file sets the # size to 2 MBytes to avoid this sort of problems. # - SocketBufferSize 2097152 + NetlinkBufferSize 2097152 # # The daemon doubles the size of the netlink event socket buffer size @@ -188,7 +188,7 @@ General { # maximum buffer size growth that can be reached. This example file # sets the size to 8 MBytes. # - SocketBufferSizeMaxGrowth 8388608 + NetlinkBufferSizeMaxGrowth 8388608 # # If the daemon detects that Netlink is dropping state-change events, diff --git a/src/read_config_lex.l b/src/read_config_lex.l index a1830fd..d75e299 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -82,9 +82,11 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "Sync" { return T_SYNC; } "Stats" { return T_STATS; } "RelaxTransitions" { return T_RELAX_TRANSITIONS; } -"SocketBufferSize" { return T_BUFFER_SIZE; } -"SocketBufferSizeMaxGrown" { return T_BUFFER_SIZE_MAX_GROWN; } -"SocketBufferSizeMaxGrowth" { return T_BUFFER_SIZE_MAX_GROWN; } +"SocketBufferSize" { return T_BUFFER_SIZE; /* alias */ } +"SocketBufferSizeMaxGrown" { return T_BUFFER_SIZE_MAX_GROWN; /* alias */ } +"SocketBufferSizeMaxGrowth" { return T_BUFFER_SIZE_MAX_GROWN; /* alias */ } +"NetlinkBufferSize" { return T_BUFFER_SIZE; } +"NetlinkBufferSizeMaxGrowth" { return T_BUFFER_SIZE_MAX_GROWN; } "Mode" { return T_SYNC_MODE; } "ListenTo" { return T_LISTEN_TO; } "Family" { return T_FAMILY; } -- cgit v1.2.3 From 41e8560ea7c09533d03f523380c1cb5c62d87261 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 13 Mar 2009 14:00:59 +0100 Subject: sync-mode: add unicast UDP support to propagate state-changes This patch adds support for unicast UDP to the channel infrastructure. With this patch, you can select UDP unicast to propagate state-changes instead of multicast. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 52 +++++++- doc/sync/ftfw/conntrackd.conf | 52 +++++++- doc/sync/notrack/conntrackd.conf | 52 +++++++- include/Makefile.am | 2 +- include/channel.h | 9 ++ include/conntrackd.h | 1 + include/udp.h | 58 +++++++++ src/Makefile.am | 4 +- src/channel.c | 2 + src/channel_udp.c | 123 ++++++++++++++++++ src/read_config_lex.l | 10 +- src/read_config_yy.y | 170 ++++++++++++++++++++++--- src/udp.c | 261 +++++++++++++++++++++++++++++++++++++++ 13 files changed, 764 insertions(+), 32 deletions(-) create mode 100644 include/udp.h create mode 100644 src/channel_udp.c create mode 100644 src/udp.c (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index cefda00..9197db3 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -88,7 +88,7 @@ Sync { # of the sender buffer. The default size is usually around # ~100 KBytes which is fairly small for busy firewalls. # - McastSndSocketBuffer 1249280 + SndSocketBuffer 1249280 # The multicast receiver uses a buffer to enqueue the packets # that the socket is pending to handle. The default size of this @@ -100,7 +100,7 @@ Sync { # the receiver buffer. The default size is usually around # ~100 KBytes which is fairly small for busy firewalls. # - McastRcvSocketBuffer 1249280 + RcvSocketBuffer 1249280 # # Enable/Disable message checksumming. This is a good @@ -124,10 +124,54 @@ Sync { # Group 3781 # IPv4_interface 192.168.100.101 # Interface eth3 - # # McastSndSocketBuffer 1249280 - # # McastRcvSocketBuffer 1249280 + # # SndSocketBuffer 1249280 + # # RcvSocketBuffer 1249280 # Checksum on # } + + # + # You can use Unicast UDP instead of Multicast to propagate events. + # Note that you cannot use unicast UDP and Multicast at the same + # time, you can only select one. + # + # UDP { + # + # UDP address that this firewall uses to listen to events. + # + # IPv4_address 192.168.2.100 + + # + # Destination UDP address that receives events, ie. the other + # firewall's dedicated link address. + # + # IPv4_Destination_Address 192.168.2.101 + + # + # UDP port used + # + # Port 3780 + + # + # The name of the interface that you are going to use to + # send the synchronization messages. + # + # Interface eth2 + + # + # The sender socket buffer size + # + # SndSocketBuffer 1249280 + + # + # The receiver socket buffer size + # + # RcvSocketBuffer 1249280 + + # + # Enable/Disable message checksumming. + # + # Checksum on + # } } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index d7e4123..be78850 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -97,7 +97,7 @@ Sync { # of the sender buffer. The default size is usually around # ~100 KBytes which is fairly small for busy firewalls. # - McastSndSocketBuffer 1249280 + SndSocketBuffer 1249280 # The multicast receiver uses a buffer to enqueue the packets # that the socket is pending to handle. The default size of this @@ -109,7 +109,7 @@ Sync { # the receiver buffer. The default size is usually around # ~100 KBytes which is fairly small for busy firewalls. # - McastRcvSocketBuffer 1249280 + RcvSocketBuffer 1249280 # # Enable/Disable message checksumming. This is a good @@ -133,10 +133,54 @@ Sync { # Group 3781 # IPv4_interface 192.168.100.101 # Interface eth3 - # # McastSndSocketBuffer 1249280 - # # McastRcvSocketBuffer 1249280 + # # SndSocketBuffer 1249280 + # # RcvSocketBuffer 1249280 # Checksum on # } + + # + # You can use Unicast UDP instead of Multicast to propagate events. + # Note that you cannot use unicast UDP and Multicast at the same + # time, you can only select one. + # + # UDP { + # + # UDP address that this firewall uses to listen to events. + # + # IPv4_address 192.168.2.100 + + # + # Destination UDP address that receives events, ie. the other + # firewall's dedicated link address. + # + # IPv4_Destination_Address 192.168.2.101 + + # + # UDP port used + # + # Port 3780 + + # + # The name of the interface that you are going to use to + # send the synchronization messages. + # + # Interface eth2 + + # + # The sender socket buffer size + # + # SndSocketBuffer 1249280 + + # + # The receiver socket buffer size + # + # RcvSocketBuffer 1249280 + + # + # Enable/Disable message checksumming. + # + # Checksum on + # } } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 884d536..173eab5 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -76,7 +76,7 @@ Sync { # Note: This protocol is best effort, it is really recommended # to increase the buffer size. # - McastSndSocketBuffer 1249280 + SndSocketBuffer 1249280 # The multicast receiver uses a buffer to enqueue the packets # that the socket is pending to handle. The default size of this @@ -90,7 +90,7 @@ Sync { # Note: This protocol is best effort, it is really recommended # to increase the buffer size. # - McastRcvSocketBuffer 1249280 + RcvSocketBuffer 1249280 # # Enable/Disable message checksumming. This is a good @@ -114,10 +114,54 @@ Sync { # Group 3781 # IPv4_interface 192.168.100.101 # Interface eth3 - # # McastSndSocketBuffer 1249280 - # # McastRcvSocketBuffer 1249280 + # # SndSocketBuffer 1249280 + # # RcvSocketBuffer 1249280 # Checksum on # } + + # + # You can use Unicast UDP instead of Multicast to propagate events. + # Note that you cannot use unicast UDP and Multicast at the same + # time, you can only select one. + # + # UDP { + # + # UDP address that this firewall uses to listen to events. + # + # IPv4_address 192.168.2.100 + + # + # Destination UDP address that receives events, ie. the other + # firewall's dedicated link address. + # + # IPv4_Destination_Address 192.168.2.101 + + # + # UDP port used + # + # Port 3780 + + # + # The name of the interface that you are going to use to + # send the synchronization messages. + # + # Interface eth2 + + # + # The sender socket buffer size + # + # SndSocketBuffer 1249280 + + # + # The receiver socket buffer size + # + # RcvSocketBuffer 1249280 + + # + # Enable/Disable message checksumming. + # + # Checksum on + # } } # diff --git a/include/Makefile.am b/include/Makefile.am index 0265620..f02ce89 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,6 +1,6 @@ noinst_HEADERS = alarm.h jhash.h cache.h linux_list.h linux_rbtree.h \ - sync.h conntrackd.h local.h \ + sync.h conntrackd.h local.h udp.h \ debug.h log.h hash.h mcast.h conntrack.h \ network.h filter.h queue.h vector.h cidr.h \ traffic_stats.h netlink.h fds.h event.h bitops.h channel.h diff --git a/include/channel.h b/include/channel.h index ac1a93c..42534e0 100644 --- a/include/channel.h +++ b/include/channel.h @@ -2,12 +2,15 @@ #define _CHANNEL_H_ #include "mcast.h" +#include "udp.h" struct channel; struct nethdr; enum { + CHANNEL_NONE, CHANNEL_MCAST, + CHANNEL_UDP, CHANNEL_MAX, }; @@ -16,12 +19,18 @@ struct mcast_channel { struct mcast_sock *server; }; +struct udp_channel { + struct udp_sock *client; + struct udp_sock *server; +}; + #define CHANNEL_F_DEFAULT (1 << 0) #define CHANNEL_F_BUFFERED (1 << 1) #define CHANNEL_F_MAX (1 << 2) union channel_type_conf { struct mcast_conf mcast; + struct udp_conf udp; }; struct channel_conf { diff --git a/include/conntrackd.h b/include/conntrackd.h index cfb1ac5..f30a094 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -74,6 +74,7 @@ struct ct_conf { int hashsize; /* hashtable size */ int channel_num; int channel_default; + int channel_type_global; struct channel_conf channel[MULTICHANNEL_MAX]; struct local_conf local; /* unix socket facilities */ int nice; diff --git a/include/udp.h b/include/udp.h new file mode 100644 index 0000000..02b8af1 --- /dev/null +++ b/include/udp.h @@ -0,0 +1,58 @@ +#ifndef _UDP_H_ +#define _UDP_H_ + +#include +#include + +struct udp_conf { + int ipproto; + int reuseaddr; + int checksum; + unsigned short port; + union { + struct in_addr inet_addr; + struct in6_addr inet_addr6; + } server; + union { + struct in_addr inet_addr; + struct in6_addr inet_addr6; + } client; + int sndbuf; + int rcvbuf; +}; + +struct udp_stats { + uint64_t bytes; + uint64_t messages; + uint64_t error; +}; + +struct udp_sock { + int fd; + union { + struct sockaddr_in ipv4; + struct sockaddr_in6 ipv6; + } addr; + socklen_t sockaddr_len; + struct udp_stats stats; +}; + +struct udp_sock *udp_server_create(struct udp_conf *conf); +void udp_server_destroy(struct udp_sock *m); + +struct udp_sock *udp_client_create(struct udp_conf *conf); +void udp_client_destroy(struct udp_sock *m); + +ssize_t udp_send(struct udp_sock *m, const void *data, int size); +ssize_t udp_recv(struct udp_sock *m, void *data, int size); + +int udp_get_fd(struct udp_sock *m); + +int udp_snprintf_stats(char *buf, size_t buflen, char *ifname, + struct udp_stats *s, struct udp_stats *r); + +int udp_snprintf_stats2(char *buf, size_t buflen, const char *ifname, + const char *status, int active, + struct udp_stats *s, struct udp_stats *r); + +#endif diff --git a/src/Makefile.am b/src/Makefile.am index 54cfda4..667040c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,7 +11,7 @@ conntrack_LDADD = ../extensions/libct_proto_tcp.la ../extensions/libct_proto_udp conntrack_LDFLAGS = $(all_libraries) @LIBNETFILTER_CONNTRACK_LIBS@ conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \ - local.c log.c mcast.c netlink.c vector.c \ + local.c log.c mcast.c udp.c netlink.c vector.c \ filter.c fds.c event.c \ cache.c cache_iterators.c \ cache_timer.c cache_wt.c \ @@ -19,7 +19,7 @@ conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \ traffic_stats.c stats-mode.c \ network.c cidr.c \ build.c parse.c \ - channel.c multichannel.c channel_mcast.c \ + channel.c multichannel.c channel_mcast.c channel_udp.c \ read_config_yy.y read_config_lex.l # yacc and lex generate dirty code diff --git a/src/channel.c b/src/channel.c index 733fd03..255026a 100644 --- a/src/channel.c +++ b/src/channel.c @@ -19,10 +19,12 @@ static struct channel_ops *ops[CHANNEL_MAX]; extern struct channel_ops channel_mcast; +extern struct channel_ops channel_udp; void channel_init(void) { ops[CHANNEL_MCAST] = &channel_mcast; + ops[CHANNEL_UDP] = &channel_udp; } #define HEADERSIZ 28 /* IP header (20 bytes) + UDP header 8 (bytes) */ diff --git a/src/channel_udp.c b/src/channel_udp.c new file mode 100644 index 0000000..1c15b47 --- /dev/null +++ b/src/channel_udp.c @@ -0,0 +1,123 @@ +/* + * (C) 2009 by Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include + +#include "channel.h" +#include "udp.h" + +static void +*channel_udp_open(void *conf) +{ + struct udp_channel *m; + struct udp_conf *c = conf; + + m = calloc(sizeof(struct udp_channel), 1); + if (m == NULL) + return NULL; + + m->client = udp_client_create(c); + if (m->client == NULL) { + free(m); + return NULL; + } + + m->server = udp_server_create(c); + if (m->server == NULL) { + udp_client_destroy(m->client); + free(m); + return NULL; + } + return m; +} + +static int +channel_udp_send(void *channel, const void *data, int len) +{ + struct udp_channel *m = channel; + return udp_send(m->client, data, len); +} + +static int +channel_udp_recv(void *channel, char *buf, int size) +{ + struct udp_channel *m = channel; + return udp_recv(m->server, buf, size); +} + +static void +channel_udp_close(void *channel) +{ + struct udp_channel *m = channel; + udp_client_destroy(m->client); + udp_server_destroy(m->server); + free(m); +} + +static int +channel_udp_get_fd(void *channel) +{ + struct udp_channel *m = channel; + return udp_get_fd(m->server); +} + +static void +channel_udp_stats(struct channel *c, int fd) +{ + struct udp_channel *m = c->data; + char ifname[IFNAMSIZ], buf[512]; + int size; + + if_indextoname(c->channel_ifindex, ifname); + size = udp_snprintf_stats(buf, sizeof(buf), ifname, + &m->client->stats, &m->server->stats); + send(fd, buf, size, 0); +} + +static void +channel_udp_stats_extended(struct channel *c, int active, + struct nlif_handle *h, int fd) +{ + struct udp_channel *m = c->data; + char ifname[IFNAMSIZ], buf[512]; + const char *status; + unsigned int flags; + int size; + + if_indextoname(c->channel_ifindex, ifname); + nlif_get_ifflags(h, c->channel_ifindex, &flags); + /* + * IFF_UP shows administrative status + * IFF_RUNNING shows carrier status + */ + if (flags & IFF_UP) { + if (!(flags & IFF_RUNNING)) + status = "NO-CARRIER"; + else + status = "RUNNING"; + } else { + status = "DOWN"; + } + size = udp_snprintf_stats2(buf, sizeof(buf), + ifname, status, active, + &m->client->stats, + &m->server->stats); + send(fd, buf, size, 0); +} + +struct channel_ops channel_udp = { + .open = channel_udp_open, + .close = channel_udp_close, + .send = channel_udp_send, + .recv = channel_udp_recv, + .get_fd = channel_udp_get_fd, + .stats = channel_udp_stats, + .stats_extended = channel_udp_stats_extended, +}; diff --git a/src/read_config_lex.l b/src/read_config_lex.l index d75e299..44ccf0b 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -58,11 +58,14 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "UNIX" { return T_UNIX; } "IPv4_address" { return T_IPV4_ADDR; } "IPv6_address" { return T_IPV6_ADDR; } +"IPv4_Destination_Address" { return T_IPV4_DEST_ADDR; } +"IPv6_Destination_Address" { return T_IPV6_DEST_ADDR; } "IPv4_interface" { return T_IPV4_IFACE; } "IPv6_interface" { return T_IPV6_IFACE; } "Interface" { return T_IFACE; } "Port" { return T_PORT; } "Multicast" { return T_MULTICAST; } +"UDP" { return T_UDP; } "HashSize" { return T_HASHSIZE; } "RefreshTime" { return T_REFRESH; } "CacheTimeout" { return T_EXPIRE; } @@ -75,6 +78,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "StripNAT" { return T_STRIP_NAT; } "Backlog" { return T_BACKLOG; } "Group" { return T_GROUP; } +"Port" { return T_PORT; } "LogFile" { return T_LOG; } "Syslog" { return T_SYSLOG; } "LockFile" { return T_LOCK; } @@ -109,8 +113,10 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "LISTEN" { return T_LISTEN; } "LogFileBufferSize" { return T_STAT_BUFFER_SIZE; } "DestroyTimeout" { return T_DESTROY_TIMEOUT; } -"McastSndSocketBuffer" { return T_MCAST_SNDBUFF; } -"McastRcvSocketBuffer" { return T_MCAST_RCVBUFF; } +"McastSndSocketBuffer" { return T_SNDBUFF; /* deprecated */ } +"McastRcvSocketBuffer" { return T_RCVBUFF; /* deprecated */ } +"SndSocketBuffer" { return T_SNDBUFF; } +"RcvSocketBuffer" { return T_RCVBUFF; } "Filter" { return T_FILTER; } "Protocol" { return T_PROTOCOL; } "Address" { return T_ADDRESS; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index b3a2640..cfcd574 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -38,7 +38,7 @@ struct ct_conf conf; static void __kernel_filter_start(void); static void __kernel_filter_add_state(int value); -static void __max_mcast_dedicated_links_reached(void); +static void __max_dedicated_links_reached(void); %} %union { @@ -58,10 +58,10 @@ static void __max_mcast_dedicated_links_reached(void); %token T_ESTABLISHED T_SYN_SENT T_SYN_RECV T_FIN_WAIT %token T_CLOSE_WAIT T_LAST_ACK T_TIME_WAIT T_CLOSE T_LISTEN %token T_SYSLOG T_WRITE_THROUGH T_STAT_BUFFER_SIZE T_DESTROY_TIMEOUT -%token T_MCAST_RCVBUFF T_MCAST_SNDBUFF T_NOTRACK T_POLL_SECS +%token T_RCVBUFF T_SNDBUFF T_NOTRACK T_POLL_SECS %token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE %token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT -%token T_NETLINK_OVERRUN_RESYNC T_NICE +%token T_NETLINK_OVERRUN_RESYNC T_NICE T_IPV4_DEST_ADDR T_IPV6_DEST_ADDR %token T_IP T_PATH_VAL %token T_NUMBER @@ -256,6 +256,13 @@ ignore_traffic_option : T_IPV6_ADDR T_IP multicast_line : T_MULTICAST '{' multicast_options '}' { + if (conf.channel_type_global != CHANNEL_NONE && + conf.channel_type_global != CHANNEL_MCAST) { + fprintf(stderr, "ERROR: Cannot use `Multicast' with other " + "dedicated link protocols!\n"); + exit(EXIT_FAILURE); + } + conf.channel_type_global = CHANNEL_MCAST; conf.channel[conf.channel_num].channel_type = CHANNEL_MCAST; conf.channel[conf.channel_num].channel_flags = CHANNEL_F_BUFFERED; conf.channel_num++; @@ -263,6 +270,13 @@ multicast_line : T_MULTICAST '{' multicast_options '}' multicast_line : T_MULTICAST T_DEFAULT '{' multicast_options '}' { + if (conf.channel_type_global != CHANNEL_NONE && + conf.channel_type_global != CHANNEL_MCAST) { + fprintf(stderr, "ERROR: Cannot use `Multicast' with other " + "dedicated link protocols!\n"); + exit(EXIT_FAILURE); + } + conf.channel_type_global = CHANNEL_MCAST; conf.channel[conf.channel_num].channel_type = CHANNEL_MCAST; conf.channel[conf.channel_num].channel_flags = CHANNEL_F_DEFAULT | CHANNEL_F_BUFFERED; @@ -275,7 +289,7 @@ multicast_options : multicast_option : T_IPV4_ADDR T_IP { - __max_mcast_dedicated_links_reached(); + __max_dedicated_links_reached(); if (!inet_aton($2, &conf.channel[conf.channel_num].u.mcast.in)) { fprintf(stderr, "%s is not a valid IPv4 address\n", $2); @@ -294,7 +308,7 @@ multicast_option : T_IPV4_ADDR T_IP multicast_option : T_IPV6_ADDR T_IP { - __max_mcast_dedicated_links_reached(); + __max_dedicated_links_reached(); #ifdef HAVE_INET_PTON_IPV6 if (inet_pton(AF_INET6, $2, @@ -333,7 +347,7 @@ multicast_option : T_IPV6_ADDR T_IP multicast_option : T_IPV4_IFACE T_IP { - __max_mcast_dedicated_links_reached(); + __max_dedicated_links_reached(); if (!inet_aton($2, &conf.channel[conf.channel_num].u.mcast.ifa)) { fprintf(stderr, "%s is not a valid IPv4 address\n", $2); @@ -359,7 +373,7 @@ multicast_option : T_IFACE T_STRING { unsigned int idx; - __max_mcast_dedicated_links_reached(); + __max_dedicated_links_reached(); strncpy(conf.channel[conf.channel_num].channel_ifname, $2, IFNAMSIZ); strncpy(conf.channel[conf.channel_num].u.mcast.iface, $2, IFNAMSIZ); @@ -385,34 +399,159 @@ multicast_option : T_BACKLOG T_NUMBER multicast_option : T_GROUP T_NUMBER { - __max_mcast_dedicated_links_reached(); + __max_dedicated_links_reached(); conf.channel[conf.channel_num].u.mcast.port = $2; }; -multicast_option: T_MCAST_SNDBUFF T_NUMBER +multicast_option: T_SNDBUFF T_NUMBER { - __max_mcast_dedicated_links_reached(); + __max_dedicated_links_reached(); conf.channel[conf.channel_num].u.mcast.sndbuf = $2; }; -multicast_option: T_MCAST_RCVBUFF T_NUMBER +multicast_option: T_RCVBUFF T_NUMBER { - __max_mcast_dedicated_links_reached(); + __max_dedicated_links_reached(); conf.channel[conf.channel_num].u.mcast.rcvbuf = $2; }; multicast_option: T_CHECKSUM T_ON { - __max_mcast_dedicated_links_reached(); + __max_dedicated_links_reached(); conf.channel[conf.channel_num].u.mcast.checksum = 0; }; multicast_option: T_CHECKSUM T_OFF { - __max_mcast_dedicated_links_reached(); + __max_dedicated_links_reached(); conf.channel[conf.channel_num].u.mcast.checksum = 1; }; +udp_line : T_UDP '{' udp_options '}' +{ + if (conf.channel_type_global != CHANNEL_NONE && + conf.channel_type_global != CHANNEL_UDP) { + fprintf(stderr, "ERROR: Cannot use `UDP' with other " + "dedicated link protocols!\n"); + exit(EXIT_FAILURE); + } + conf.channel_type_global = CHANNEL_UDP; + conf.channel[conf.channel_num].channel_type = CHANNEL_UDP; + conf.channel[conf.channel_num].channel_flags = CHANNEL_F_BUFFERED; + conf.channel_num++; +}; + +udp_line : T_UDP T_DEFAULT '{' udp_options '}' +{ + if (conf.channel_type_global != CHANNEL_NONE && + conf.channel_type_global != CHANNEL_UDP) { + fprintf(stderr, "ERROR: Cannot use `UDP' with other " + "dedicated link protocols!\n"); + exit(EXIT_FAILURE); + } + conf.channel_type_global = CHANNEL_UDP; + conf.channel[conf.channel_num].channel_type = CHANNEL_UDP; + conf.channel[conf.channel_num].channel_flags = CHANNEL_F_DEFAULT | + CHANNEL_F_BUFFERED; + conf.channel_default = conf.channel_num; + conf.channel_num++; +}; + +udp_options : + | udp_options udp_option; + +udp_option : T_IPV4_ADDR T_IP +{ + __max_dedicated_links_reached(); + + if (!inet_aton($2, &conf.channel[conf.channel_num].u.udp.server)) { + fprintf(stderr, "%s is not a valid IPv4 address\n", $2); + break; + } + conf.channel[conf.channel_num].u.udp.ipproto = AF_INET; +}; + +udp_option : T_IPV6_ADDR T_IP +{ + __max_dedicated_links_reached(); + +#ifdef HAVE_INET_PTON_IPV6 + if (inet_pton(AF_INET6, $2, + &conf.channel[conf.channel_num].u.udp.server) <= 0) { + fprintf(stderr, "%s is not a valid IPv6 address\n", $2); + break; + } +#else + fprintf(stderr, "Cannot find inet_pton(), IPv6 unsupported!"); + break; +#endif + conf.channel[conf.channel_num].u.udp.ipproto = AF_INET6; +}; + +udp_option : T_IPV4_DEST_ADDR T_IP +{ + __max_dedicated_links_reached(); + + if (!inet_aton($2, &conf.channel[conf.channel_num].u.udp.client)) { + fprintf(stderr, "%s is not a valid IPv4 address\n", $2); + break; + } + conf.channel[conf.channel_num].u.udp.ipproto = AF_INET; +}; + +udp_option : T_IPV6_DEST_ADDR T_IP +{ + __max_dedicated_links_reached(); + +#ifdef HAVE_INET_PTON_IPV6 + if (inet_pton(AF_INET6, $2, + &conf.channel[conf.channel_num].u.udp.client) <= 0) { + fprintf(stderr, "%s is not a valid IPv6 address\n", $2); + break; + } +#else + fprintf(stderr, "Cannot find inet_pton(), IPv6 unsupported!"); + break; +#endif + conf.channel[conf.channel_num].u.udp.ipproto = AF_INET6; +}; + +udp_option : T_IFACE T_STRING +{ + __max_dedicated_links_reached(); + strncpy(conf.channel[conf.channel_num].channel_ifname, $2, IFNAMSIZ); +}; + +udp_option : T_PORT T_NUMBER +{ + __max_dedicated_links_reached(); + conf.channel[conf.channel_num].u.udp.port = $2; +}; + +udp_option: T_SNDBUFF T_NUMBER +{ + __max_dedicated_links_reached(); + conf.channel[conf.channel_num].u.udp.sndbuf = $2; +}; + +udp_option: T_RCVBUFF T_NUMBER +{ + __max_dedicated_links_reached(); + conf.channel[conf.channel_num].u.udp.rcvbuf = $2; +}; + +udp_option: T_CHECKSUM T_ON +{ + __max_dedicated_links_reached(); + conf.channel[conf.channel_num].u.udp.checksum = 0; +}; + +udp_option: T_CHECKSUM T_OFF +{ + __max_dedicated_links_reached(); + conf.channel[conf.channel_num].u.udp.checksum = 1; +}; + hashsize : T_HASHSIZE T_NUMBER { conf.hashsize = $2; @@ -493,6 +632,7 @@ sync_line: refreshtime | purge | checksum | multicast_line + | udp_line | relax_transitions | delay_destroy_msgs | sync_mode_alarm @@ -1133,7 +1273,7 @@ static void __kernel_filter_add_state(int value) &filter_proto); } -static void __max_mcast_dedicated_links_reached(void) +static void __max_dedicated_links_reached(void) { if (conf.channel_num >= MULTICHANNEL_MAX) { fprintf(stderr, "ERROR: too many dedicated links in " diff --git a/src/udp.c b/src/udp.c new file mode 100644 index 0000000..bad8db8 --- /dev/null +++ b/src/udp.c @@ -0,0 +1,261 @@ +/* + * (C) 2009 by Pablo Neira Ayuso + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include "udp.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct udp_sock *udp_server_create(struct udp_conf *conf) +{ + int yes = 1; + struct udp_sock *m; + socklen_t socklen = sizeof(int); + + m = calloc(sizeof(struct udp_sock), 1); + if (m == NULL) + return NULL; + + switch(conf->ipproto) { + case AF_INET: + m->addr.ipv4.sin_family = AF_INET; + m->addr.ipv4.sin_port = htons(conf->port); + m->addr.ipv4.sin_addr.s_addr = conf->server.inet_addr.s_addr; + m->sockaddr_len = sizeof(struct sockaddr_in); + break; + + case AF_INET6: + m->addr.ipv6.sin6_family = AF_INET6; + m->addr.ipv6.sin6_port = htons(conf->port); + m->addr.ipv6.sin6_addr = conf->server.inet_addr6; + m->sockaddr_len = sizeof(struct sockaddr_in6); + break; + } + + m->fd = socket(conf->ipproto, SOCK_DGRAM, 0); + if (m->fd == -1) { + free(m); + return NULL; + } + + if (setsockopt(m->fd, SOL_SOCKET, SO_REUSEADDR, &yes, + sizeof(int)) == -1) { + close(m->fd); + free(m); + return NULL; + } + +#ifndef SO_RCVBUFFORCE +#define SO_RCVBUFFORCE 33 +#endif + + if (conf->rcvbuf && + setsockopt(m->fd, SOL_SOCKET, SO_RCVBUFFORCE, &conf->rcvbuf, + sizeof(int)) == -1) { + /* not supported in linux kernel < 2.6.14 */ + if (errno != ENOPROTOOPT) { + close(m->fd); + free(m); + return NULL; + } + } + + getsockopt(m->fd, SOL_SOCKET, SO_RCVBUF, &conf->rcvbuf, &socklen); + + if (bind(m->fd, (struct sockaddr *) &m->addr, m->sockaddr_len) == -1) { + close(m->fd); + free(m); + return NULL; + } + + return m; +} + +void udp_server_destroy(struct udp_sock *m) +{ + close(m->fd); + free(m); +} + +struct udp_sock *udp_client_create(struct udp_conf *conf) +{ + int ret = 0; + struct udp_sock *m; + socklen_t socklen = sizeof(int); + + m = calloc(sizeof(struct udp_sock), 1); + if (m == NULL) + return NULL; + + m->fd = socket(conf->ipproto, SOCK_DGRAM, 0); + if (m->fd == -1) { + free(m); + return NULL; + } + + if (setsockopt(m->fd, SOL_SOCKET, SO_NO_CHECK, &conf->checksum, + sizeof(int)) == -1) { + close(m->fd); + free(m); + return NULL; + } + +#ifndef SO_SNDBUFFORCE +#define SO_SNDBUFFORCE 32 +#endif + + if (conf->sndbuf && + setsockopt(m->fd, SOL_SOCKET, SO_SNDBUFFORCE, &conf->sndbuf, + sizeof(int)) == -1) { + /* not supported in linux kernel < 2.6.14 */ + if (errno != ENOPROTOOPT) { + close(m->fd); + free(m); + return NULL; + } + } + + getsockopt(m->fd, SOL_SOCKET, SO_SNDBUF, &conf->sndbuf, &socklen); + + switch(conf->ipproto) { + case AF_INET: + m->addr.ipv4.sin_family = AF_INET; + m->addr.ipv4.sin_port = htons(conf->port); + m->addr.ipv4.sin_addr = conf->client.inet_addr; + m->sockaddr_len = sizeof(struct sockaddr_in); + break; + case AF_INET6: + m->addr.ipv6.sin6_family = AF_INET6; + m->addr.ipv6.sin6_port = htons(conf->port); + memcpy(&m->addr.ipv6.sin6_addr, &conf->client.inet_addr6, + sizeof(struct in6_addr)); + m->sockaddr_len = sizeof(struct sockaddr_in6); + break; + default: + ret = -1; + break; + } + + if (ret == -1) { + close(m->fd); + free(m); + m = NULL; + } + + return m; +} + +void udp_client_destroy(struct udp_sock *m) +{ + close(m->fd); + free(m); +} + +ssize_t udp_send(struct udp_sock *m, const void *data, int size) +{ + ssize_t ret; + + ret = sendto(m->fd, + data, + size, + 0, + (struct sockaddr *) &m->addr, + m->sockaddr_len); + if (ret == -1) { + m->stats.error++; + return ret; + } + + m->stats.bytes += ret; + m->stats.messages++; + + return ret; +} + +ssize_t udp_recv(struct udp_sock *m, void *data, int size) +{ + ssize_t ret; + socklen_t sin_size = sizeof(struct sockaddr_in); + + ret = recvfrom(m->fd, + data, + size, + 0, + (struct sockaddr *)&m->addr, + &sin_size); + if (ret == -1) { + m->stats.error++; + return ret; + } + + m->stats.bytes += ret; + m->stats.messages++; + + return ret; +} + +int udp_get_fd(struct udp_sock *m) +{ + return m->fd; +} + +int +udp_snprintf_stats(char *buf, size_t buflen, char *ifname, + struct udp_stats *s, struct udp_stats *r) +{ + size_t size; + + size = snprintf(buf, buflen, "UDP traffic (active device=%s):\n" + "%20llu Bytes sent " + "%20llu Bytes recv\n" + "%20llu Pckts sent " + "%20llu Pckts recv\n" + "%20llu Error send " + "%20llu Error recv\n\n", + ifname, + (unsigned long long)s->bytes, + (unsigned long long)r->bytes, + (unsigned long long)s->messages, + (unsigned long long)r->messages, + (unsigned long long)s->error, + (unsigned long long)r->error); + return size; +} + +int +udp_snprintf_stats2(char *buf, size_t buflen, const char *ifname, + const char *status, int active, + struct udp_stats *s, struct udp_stats *r) +{ + size_t size; + + size = snprintf(buf, buflen, + "UDP traffic device=%s status=%s role=%s:\n" + "%20llu Bytes sent " + "%20llu Bytes recv\n" + "%20llu Pckts sent " + "%20llu Pckts recv\n" + "%20llu Error send " + "%20llu Error recv\n\n", + ifname, status, active ? "ACTIVE" : "BACKUP", + (unsigned long long)s->bytes, + (unsigned long long)r->bytes, + (unsigned long long)s->messages, + (unsigned long long)r->messages, + (unsigned long long)s->error, + (unsigned long long)r->error); + return size; +} -- cgit v1.2.3 From f7b4b7bd19b16d11491f18891942f6d48c2fcf7e Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 20 Mar 2009 14:05:31 +0100 Subject: udp: fix missing scope_id in the socket creation This patch fixes an EINVAL error returned by bind() when opening an UDP server socket to propagate state-changes over the dedicated link. This patch also includes the change of the example configuration files in case that you want to use UDP over IPv6. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 8 ++++++++ doc/sync/ftfw/conntrackd.conf | 8 ++++++++ doc/sync/notrack/conntrackd.conf | 8 ++++++++ include/udp.h | 9 +++++++-- src/read_config_yy.y | 13 +++++++++++-- src/udp.c | 5 +++-- 6 files changed, 45 insertions(+), 6 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 9197db3..8eb22dd 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -139,12 +139,20 @@ Sync { # UDP address that this firewall uses to listen to events. # # IPv4_address 192.168.2.100 + # + # or you may want to use an IPv6 address: + # + # IPv6_address fe80::215:58ff:fe28:5a27 # # Destination UDP address that receives events, ie. the other # firewall's dedicated link address. # # IPv4_Destination_Address 192.168.2.101 + # + # or you may want to use an IPv6 address: + # + # IPv6_Destination_Address fe80::2d0:59ff:fe2a:775c # # UDP port used diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index be78850..059f7b3 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -148,12 +148,20 @@ Sync { # UDP address that this firewall uses to listen to events. # # IPv4_address 192.168.2.100 + # + # or you may want to use an IPv6 address: + # + # IPv6_address fe80::215:58ff:fe28:5a27 # # Destination UDP address that receives events, ie. the other # firewall's dedicated link address. # # IPv4_Destination_Address 192.168.2.101 + # + # or you may want to use an IPv6 address: + # + # IPv6_Destination_Address fe80::2d0:59ff:fe2a:775c # # UDP port used diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 173eab5..96ef547 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -129,12 +129,20 @@ Sync { # UDP address that this firewall uses to listen to events. # # IPv4_address 192.168.2.100 + # + # or you may want to use an IPv6 address: + # + # IPv6_address fe80::215:58ff:fe28:5a27 # # Destination UDP address that receives events, ie. the other # firewall's dedicated link address. # # IPv4_Destination_Address 192.168.2.101 + # + # or you may want to use an IPv6 address: + # + # IPv6_Destination_Address fe80::2d0:59ff:fe2a:775c # # UDP port used diff --git a/include/udp.h b/include/udp.h index 02b8af1..6c659b9 100644 --- a/include/udp.h +++ b/include/udp.h @@ -10,8 +10,13 @@ struct udp_conf { int checksum; unsigned short port; union { - struct in_addr inet_addr; - struct in6_addr inet_addr6; + struct { + struct in_addr inet_addr; + } ipv4; + struct { + struct in6_addr inet_addr6; + int scope_id; + } ipv6; } server; union { struct in_addr inet_addr; diff --git a/src/read_config_yy.y b/src/read_config_yy.y index cfcd574..7b62cf3 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -464,7 +464,7 @@ udp_option : T_IPV4_ADDR T_IP { __max_dedicated_links_reached(); - if (!inet_aton($2, &conf.channel[conf.channel_num].u.udp.server)) { + if (!inet_aton($2, &conf.channel[conf.channel_num].u.udp.server.ipv4)) { fprintf(stderr, "%s is not a valid IPv4 address\n", $2); break; } @@ -477,7 +477,7 @@ udp_option : T_IPV6_ADDR T_IP #ifdef HAVE_INET_PTON_IPV6 if (inet_pton(AF_INET6, $2, - &conf.channel[conf.channel_num].u.udp.server) <= 0) { + &conf.channel[conf.channel_num].u.udp.server.ipv6) <= 0) { fprintf(stderr, "%s is not a valid IPv6 address\n", $2); break; } @@ -518,8 +518,17 @@ udp_option : T_IPV6_DEST_ADDR T_IP udp_option : T_IFACE T_STRING { + int idx; + __max_dedicated_links_reached(); strncpy(conf.channel[conf.channel_num].channel_ifname, $2, IFNAMSIZ); + + idx = if_nametoindex($2); + if (!idx) { + fprintf(stderr, "%s is an invalid interface.\n", $2); + break; + } + conf.channel[conf.channel_num].u.udp.server.ipv6.scope_id = idx; }; udp_option : T_PORT T_NUMBER diff --git a/src/udp.c b/src/udp.c index bad8db8..d9943a0 100644 --- a/src/udp.c +++ b/src/udp.c @@ -33,14 +33,15 @@ struct udp_sock *udp_server_create(struct udp_conf *conf) case AF_INET: m->addr.ipv4.sin_family = AF_INET; m->addr.ipv4.sin_port = htons(conf->port); - m->addr.ipv4.sin_addr.s_addr = conf->server.inet_addr.s_addr; + m->addr.ipv4.sin_addr = conf->server.ipv4.inet_addr; m->sockaddr_len = sizeof(struct sockaddr_in); break; case AF_INET6: m->addr.ipv6.sin6_family = AF_INET6; m->addr.ipv6.sin6_port = htons(conf->port); - m->addr.ipv6.sin6_addr = conf->server.inet_addr6; + m->addr.ipv6.sin6_addr = conf->server.ipv6.inet_addr6; + m->addr.ipv6.sin6_scope_id = conf->server.ipv6.scope_id; m->sockaddr_len = sizeof(struct sockaddr_in6); break; } -- cgit v1.2.3 From c2b5b2dff2eb181044575082d78f0a46bb5986f5 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 31 Mar 2009 21:09:26 +0200 Subject: doc: set nice to -20 in example config files This patch sets the most favourable nice value for conntrackd in the default configuration files. This is generally a good idea to reduce the chances to hit ENOBUFS. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 8 +++++--- doc/sync/ftfw/conntrackd.conf | 8 +++++--- doc/sync/notrack/conntrackd.conf | 8 +++++--- 3 files changed, 15 insertions(+), 9 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 8eb22dd..ca6e661 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -189,10 +189,12 @@ General { # # Set the nice value of the daemon, this value goes from -20 # (most favorable scheduling) to 19 (least favorable). Using a - # negative value reduces the chances to lose state-change events. - # Default is 0. See man nice(1) for more information. + # very low value reduces the chances to lose state-change events. + # Default is 0 but this example file sets it to most favourable + # scheduling as this is generally a good idea. See man nice(1) for + # more information. # - Nice -1 + Nice -20 # # Number of buckets in the cache hashtable. The bigger it is, diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 059f7b3..33c6fce 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -198,10 +198,12 @@ General { # # Set the nice value of the daemon, this value goes from -20 # (most favorable scheduling) to 19 (least favorable). Using a - # negative value reduces the chances to lose state-change events. - # Default is 0. See man nice(1) for more information. + # very low value reduces the chances to lose state-change events. + # Default is 0 but this example file sets it to most favourable + # scheduling as this is generally a good idea. See man nice(1) for + # more information. # - Nice -1 + Nice -20 # # Number of buckets in the cache hashtable. The bigger it is, diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 96ef547..6175284 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -179,10 +179,12 @@ General { # # Set the nice value of the daemon, this value goes from -20 # (most favorable scheduling) to 19 (least favorable). Using a - # negative value reduces the chances to lose state-change events. - # Default is 0. See man nice(1) for more information. + # very low value reduces the chances to lose state-change events. + # Default is 0 but this example file sets it to most favourable + # scheduling as this is generally a good idea. See man nice(1) for + # more information. # - Nice -1 + Nice -20 # # Number of buckets in the cache hashtable. The bigger it is, -- cgit v1.2.3 From dfb88dae65fbdc37d72483ddff23171ef4070dae Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 14 Apr 2009 10:43:16 +0200 Subject: conntrackd: change scheduler and priority via configuration file With this patch, you can change the scheduler policy and priority for conntrackd. Using a RT scheduler policy reduces the chances to hit ENOBUFS in Netlink. Signed-off-by: Pablo Neira Ayuso --- doc/stats/conntrackd.conf | 11 +++++++++++ doc/sync/alarm/conntrackd.conf | 11 +++++++++++ doc/sync/ftfw/conntrackd.conf | 11 +++++++++++ doc/sync/notrack/conntrackd.conf | 11 +++++++++++ include/conntrackd.h | 4 ++++ src/main.c | 19 ++++++++++++++++++- src/read_config_lex.l | 3 +++ src/read_config_yy.y | 30 ++++++++++++++++++++++++++++++ 8 files changed, 99 insertions(+), 1 deletion(-) (limited to 'doc/sync/alarm') diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index 1f1a697..8945293 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -10,6 +10,17 @@ General { # Nice -1 + # + # Select a different scheduler for the daemon, you can select between + # RR and FIFO and the process priority (minimum is 0, maximum is 99). + # See man sched_setscheduler(2) for more information. Using a RT + # scheduler reduces the chances to overrun the Netlink buffer. + # + # Scheduler { + # Type FIFO + # Priority 99 + # } + # # Number of buckets in the caches: hash table # diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index ca6e661..793e953 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -196,6 +196,17 @@ General { # Nice -20 + # + # Select a different scheduler for the daemon, you can select between + # RR and FIFO and the process priority (minimum is 0, maximum is 99). + # See man sched_setscheduler(2) for more information. Using a RT + # scheduler reduces the chances to overrun the Netlink buffer. + # + # Scheduler { + # Type FIFO + # Priority 99 + # } + # # Number of buckets in the cache hashtable. The bigger it is, # the closer it gets to O(1) at the cost of consuming more memory. diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 33c6fce..6eb4475 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -205,6 +205,17 @@ General { # Nice -20 + # + # Select a different scheduler for the daemon, you can select between + # RR and FIFO and the process priority (minimum is 0, maximum is 99). + # See man sched_setscheduler(2) for more information. Using a RT + # scheduler reduces the chances to overrun the Netlink buffer. + # + # Scheduler { + # Type FIFO + # Priority 99 + # } + # # Number of buckets in the cache hashtable. The bigger it is, # the closer it gets to O(1) at the cost of consuming more memory. diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 6175284..e2085f7 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -186,6 +186,17 @@ General { # Nice -20 + # + # Select a different scheduler for the daemon, you can select between + # RR and FIFO and the process priority (minimum is 0, maximum is 99). + # See man sched_setscheduler(2) for more information. Using a RT + # scheduler reduces the chances to overrun the Netlink buffer. + # + # Scheduler { + # Type FIFO + # Priority 99 + # } + # # Number of buckets in the cache hashtable. The bigger it is, # the closer it gets to O(1) at the cost of consuming more memory. diff --git a/include/conntrackd.h b/include/conntrackd.h index 737c7fd..013ec4f 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -94,6 +94,10 @@ struct ct_conf { int cache_write_through; int filter_from_kernelspace; int event_iterations_limit; + struct { + int type; + int prio; + } sched; struct { char logfile[FILENAME_MAXLEN]; int syslog_facility; diff --git a/src/main.c b/src/main.c index 62ae599..7507ae5 100644 --- a/src/main.c +++ b/src/main.c @@ -26,6 +26,7 @@ #include #include #include +#include #include struct ct_general_state st; @@ -295,6 +296,23 @@ int main(int argc, char *argv[]) } close(ret); + /* + * Setting process priority and scheduler + */ + nice(CONFIG(nice)); + + if (CONFIG(sched).type != SCHED_OTHER) { + struct sched_param schedparam = { + .sched_priority = CONFIG(sched).prio, + }; + + ret = sched_setscheduler(0, CONFIG(sched).type, &schedparam); + if (ret == -1) { + perror("sched"); + exit(EXIT_FAILURE); + } + } + /* * initialization process */ @@ -309,7 +327,6 @@ int main(int argc, char *argv[]) chdir("/"); close(STDIN_FILENO); - nice(CONFIG(nice)); /* Daemonize conntrackd */ if (type == DAEMON) { diff --git a/src/read_config_lex.l b/src/read_config_lex.l index 44ccf0b..3d5913e 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -132,6 +132,9 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "PollSecs" { return T_POLL_SECS; } "NetlinkOverrunResync" { return T_NETLINK_OVERRUN_RESYNC; } "Nice" { return T_NICE; } +"Scheduler" { return T_SCHEDULER; } +"Type" { return T_TYPE; } +"Priority" { return T_PRIO; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 152f33e..56fd2f8 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -29,6 +29,7 @@ #include "bitops.h" #include "cidr.h" #include +#include #include #include @@ -70,6 +71,7 @@ static void __max_dedicated_links_reached(void); %token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE %token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT %token T_NETLINK_OVERRUN_RESYNC T_NICE T_IPV4_DEST_ADDR T_IPV6_DEST_ADDR +%token T_SCHEDULER T_TYPE T_PRIO %token T_IP T_PATH_VAL %token T_NUMBER @@ -870,6 +872,7 @@ general_line: hashsize | filter | netlink_overrun_resync | nice + | scheduler ; netlink_buffer_size: T_BUFFER_SIZE T_NUMBER @@ -902,6 +905,33 @@ nice : T_NICE T_SIGNED_NUMBER conf.nice = $2; }; +scheduler : T_SCHEDULER '{' scheduler_options '}'; + +scheduler_options : + | scheduler_options scheduler_line + ; + +scheduler_line : T_TYPE T_STRING +{ + if (strcasecmp($2, "rr") == 0) { + conf.sched.type = SCHED_RR; + } else if (strcasecmp($2, "fifo") == 0) { + conf.sched.type = SCHED_FIFO; + } else { + print_err(CTD_CFG_ERROR, "unknown scheduler `%s'", $2); + exit(EXIT_FAILURE); + } +}; + +scheduler_line : T_PRIO T_NUMBER +{ + conf.sched.prio = $2; + if (conf.sched.prio < 0 || conf.sched.prio > 99) { + print_err(CTD_CFG_ERROR, "`Priority' must be [0, 99]\n", $2); + exit(EXIT_FAILURE); + } +}; + family : T_FAMILY T_STRING { if (strncmp($2, "IPv6", strlen("IPv6")) == 0) -- cgit v1.2.3 From 400ae54438c4b85126f9fab0ae1dc067823b70f7 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Sat, 18 Apr 2009 19:36:38 +0200 Subject: sync: add support for SCTP state replication This patch adds initial support for SCTP state replication. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 1 + doc/sync/ftfw/conntrackd.conf | 1 + doc/sync/notrack/conntrackd.conf | 1 + include/network.h | 8 +++++++- src/build.c | 16 +++++++++++++++- src/parse.c | 16 +++++++++++++++- 6 files changed, 40 insertions(+), 3 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 793e953..4607ad1 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -323,6 +323,7 @@ General { # Protocol Accept { TCP + SCTP } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 6eb4475..3135c6c 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -332,6 +332,7 @@ General { # Protocol Accept { TCP + SCTP } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index e2085f7..ff8a8a2 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -313,6 +313,7 @@ General { # Protocol Accept { TCP + SCTP } # diff --git a/include/network.h b/include/network.h index b182339..06c0463 100644 --- a/include/network.h +++ b/include/network.h @@ -199,7 +199,7 @@ enum nta_attr { NTA_IPV6, /* struct nfct_attr_grp_ipv6 */ NTA_L4PROTO, /* uint8_t */ NTA_PORT, /* struct nfct_attr_grp_port */ - NTA_STATE = 4, /* uint8_t */ + NTA_STATE_TCP = 4, /* uint8_t */ NTA_STATUS, /* uint32_t */ NTA_TIMEOUT, /* uint32_t */ NTA_MARK, /* uint32_t */ @@ -212,6 +212,7 @@ enum nta_attr { NTA_SPAT_PORT, /* uint16_t */ NTA_DPAT_PORT, /* uint16_t */ NTA_NAT_SEQ_ADJ = 16, /* struct nta_attr_natseqadj */ + NTA_STATE_SCTP, /* struct nta_attr_sctp */ NTA_MAX }; @@ -224,6 +225,11 @@ struct nta_attr_natseqadj { uint32_t repl_seq_offset_after; }; +struct nta_attr_sctp { + uint8_t state; + uint32_t vtag_orig, vtag_repl; +}; + void build_payload(const struct nf_conntrack *ct, struct nethdr *n); int parse_payload(struct nf_conntrack *ct, struct nethdr *n, size_t remain); diff --git a/src/build.c b/src/build.c index 63a85db..6b0fad7 100644 --- a/src/build.c +++ b/src/build.c @@ -92,6 +92,17 @@ __build_natseqadj(const struct nf_conntrack *ct, struct nethdr *n) addattr(n, NTA_NAT_SEQ_ADJ, &data, sizeof(struct nta_attr_natseqadj)); } +static inline void +__build_sctp(const struct nf_conntrack *ct, struct nethdr *n) +{ + struct nta_attr_sctp data = { + .state = nfct_get_attr_u8(ct, ATTR_SCTP_STATE), + .vtag_orig = htonl(nfct_get_attr_u32(ct, ATTR_SCTP_VTAG_ORIG)), + .vtag_repl = htonl(nfct_get_attr_u32(ct, ATTR_SCTP_VTAG_REPL)), + }; + addattr(n, NTA_STATE_SCTP, &data, sizeof(struct nta_attr_sctp)); +} + static enum nf_conntrack_attr nat_type[] = { ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ATTR_REPL_NAT_SEQ_CORRECTION_POS, @@ -117,7 +128,10 @@ void build_payload(const struct nf_conntrack *ct, struct nethdr *n) __build_u32(ct, ATTR_STATUS, n, NTA_STATUS); if (nfct_attr_is_set(ct, ATTR_TCP_STATE)) - __build_u8(ct, ATTR_TCP_STATE, n, NTA_STATE); + __build_u8(ct, ATTR_TCP_STATE, n, NTA_STATE_TCP); + else if (nfct_attr_is_set(ct, ATTR_SCTP_STATE)) + __build_sctp(ct, n); + if (!CONFIG(commit_timeout) && nfct_attr_is_set(ct, ATTR_TIMEOUT)) __build_u32(ct, ATTR_TIMEOUT, n, NTA_TIMEOUT); if (nfct_attr_is_set(ct, ATTR_MARK)) diff --git a/src/parse.c b/src/parse.c index 76287fd..d14910a 100644 --- a/src/parse.c +++ b/src/parse.c @@ -29,6 +29,7 @@ static void parse_u16(struct nf_conntrack *ct, int attr, void *data); static void parse_u32(struct nf_conntrack *ct, int attr, void *data); static void parse_group(struct nf_conntrack *ct, int attr, void *data); static void parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data); +static void parse_sctp(struct nf_conntrack *ct, int attr, void *data); struct parser { void (*parse)(struct nf_conntrack *ct, int attr, void *data); @@ -57,7 +58,7 @@ static struct parser h[NTA_MAX] = { .attr = ATTR_L4PROTO, .size = NTA_SIZE(sizeof(uint8_t)), }, - [NTA_STATE] = { + [NTA_STATE_TCP] = { .parse = parse_u8, .attr = ATTR_TCP_STATE, .size = NTA_SIZE(sizeof(uint8_t)), @@ -121,6 +122,10 @@ static struct parser h[NTA_MAX] = { .parse = parse_nat_seq_adj, .size = NTA_SIZE(sizeof(struct nta_attr_natseqadj)), }, + [NTA_STATE_SCTP] = { + .parse = parse_sctp, + .size = NTA_SIZE(sizeof(struct nta_attr_sctp)), + }, }; static void @@ -168,6 +173,15 @@ parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data) ntohl(this->orig_seq_correction_pos)); } +static void +parse_sctp(struct nf_conntrack *ct, int attr, void *data) +{ + struct nta_attr_sctp *this = data; + nfct_set_attr_u8(ct, ATTR_SCTP_STATE, this->state); + nfct_set_attr_u32(ct, ATTR_SCTP_VTAG_ORIG, ntohl(this->vtag_orig)); + nfct_set_attr_u32(ct, ATTR_SCTP_VTAG_REPL, ntohl(this->vtag_repl)); +} + int parse_payload(struct nf_conntrack *ct, struct nethdr *net, size_t remain) { int len; -- cgit v1.2.3 From b808645ec71b7cc22cf5106b3d79625d07e6077c Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Fri, 24 Apr 2009 12:23:03 +0200 Subject: sync: add support for DCCP state replication This patch adds initial support for DCCP state replication. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 1 + doc/sync/ftfw/conntrackd.conf | 1 + doc/sync/notrack/conntrackd.conf | 1 + include/network.h | 5 +++++ src/build.c | 12 ++++++++++++ src/parse.c | 13 +++++++++++++ 6 files changed, 33 insertions(+) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 4607ad1..a108569 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -324,6 +324,7 @@ General { Protocol Accept { TCP SCTP + DCCP } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 3135c6c..c1208f9 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -333,6 +333,7 @@ General { Protocol Accept { TCP SCTP + DCCP } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index ff8a8a2..b528fab 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -314,6 +314,7 @@ General { Protocol Accept { TCP SCTP + DCCP } # diff --git a/include/network.h b/include/network.h index 06c0463..2786585 100644 --- a/include/network.h +++ b/include/network.h @@ -213,6 +213,7 @@ enum nta_attr { NTA_DPAT_PORT, /* uint16_t */ NTA_NAT_SEQ_ADJ = 16, /* struct nta_attr_natseqadj */ NTA_STATE_SCTP, /* struct nta_attr_sctp */ + NTA_STATE_DCCP, /* struct nta_attr_dccp */ NTA_MAX }; @@ -230,6 +231,10 @@ struct nta_attr_sctp { uint32_t vtag_orig, vtag_repl; }; +struct nta_attr_dccp { + uint8_t state, role; +}; + void build_payload(const struct nf_conntrack *ct, struct nethdr *n); int parse_payload(struct nf_conntrack *ct, struct nethdr *n, size_t remain); diff --git a/src/build.c b/src/build.c index 6b0fad7..a02a912 100644 --- a/src/build.c +++ b/src/build.c @@ -103,6 +103,16 @@ __build_sctp(const struct nf_conntrack *ct, struct nethdr *n) addattr(n, NTA_STATE_SCTP, &data, sizeof(struct nta_attr_sctp)); } +static inline void +__build_dccp(const struct nf_conntrack *ct, struct nethdr *n) +{ + struct nta_attr_dccp data = { + .state = nfct_get_attr_u8(ct, ATTR_DCCP_STATE), + .role = nfct_get_attr_u8(ct, ATTR_DCCP_ROLE), + }; + addattr(n, NTA_STATE_DCCP, &data, sizeof(struct nta_attr_dccp)); +} + static enum nf_conntrack_attr nat_type[] = { ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ATTR_REPL_NAT_SEQ_CORRECTION_POS, @@ -131,6 +141,8 @@ void build_payload(const struct nf_conntrack *ct, struct nethdr *n) __build_u8(ct, ATTR_TCP_STATE, n, NTA_STATE_TCP); else if (nfct_attr_is_set(ct, ATTR_SCTP_STATE)) __build_sctp(ct, n); + else if (nfct_attr_is_set(ct, ATTR_DCCP_STATE)) + __build_dccp(ct, n); if (!CONFIG(commit_timeout) && nfct_attr_is_set(ct, ATTR_TIMEOUT)) __build_u32(ct, ATTR_TIMEOUT, n, NTA_TIMEOUT); diff --git a/src/parse.c b/src/parse.c index d14910a..100177b 100644 --- a/src/parse.c +++ b/src/parse.c @@ -30,6 +30,7 @@ static void parse_u32(struct nf_conntrack *ct, int attr, void *data); static void parse_group(struct nf_conntrack *ct, int attr, void *data); static void parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data); static void parse_sctp(struct nf_conntrack *ct, int attr, void *data); +static void parse_dccp(struct nf_conntrack *ct, int attr, void *data); struct parser { void (*parse)(struct nf_conntrack *ct, int attr, void *data); @@ -126,6 +127,10 @@ static struct parser h[NTA_MAX] = { .parse = parse_sctp, .size = NTA_SIZE(sizeof(struct nta_attr_sctp)), }, + [NTA_STATE_DCCP] = { + .parse = parse_dccp, + .size = NTA_SIZE(sizeof(struct nta_attr_dccp)), + }, }; static void @@ -182,6 +187,14 @@ parse_sctp(struct nf_conntrack *ct, int attr, void *data) nfct_set_attr_u32(ct, ATTR_SCTP_VTAG_REPL, ntohl(this->vtag_repl)); } +static void +parse_dccp(struct nf_conntrack *ct, int attr, void *data) +{ + struct nta_attr_dccp *this = data; + nfct_set_attr_u8(ct, ATTR_DCCP_STATE, this->state); + nfct_set_attr_u8(ct, ATTR_DCCP_ROLE, this->role); +} + int parse_payload(struct nf_conntrack *ct, struct nethdr *net, size_t remain) { int len; -- cgit v1.2.3 From 0521db731c0daa417a3dfb67fba7c6f80596e553 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 21 Jul 2009 14:36:18 +0200 Subject: conntrackd: add clause to enable ctnetlink reliable event delivery This patch adds the NetlinkEventsReliable clause, this is useful to turn on reliable Netlink event delivery. This features requires a Linux kernel >= 2.6.31. Signed-off-by: Pablo Neira Ayuso --- doc/stats/conntrackd.conf | 7 +++++++ doc/sync/alarm/conntrackd.conf | 7 +++++++ doc/sync/ftfw/conntrackd.conf | 8 ++++++++ doc/sync/notrack/conntrackd.conf | 7 +++++++ include/conntrackd.h | 3 +++ src/netlink.c | 12 ++++++++++++ src/read_config_lex.l | 1 + src/read_config_yy.y | 13 ++++++++++++- 8 files changed, 57 insertions(+), 1 deletion(-) (limited to 'doc/sync/alarm') diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index 8945293..ef6a698 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -110,6 +110,13 @@ Stats { # LogFile on + # If you want reliable event reporting over Netlink, set on this + # option. If you set on this clause, it is a good idea to set off + # NetlinkOverrunResync. This option is off by default and you need + # a Linux kernel >= 2.6.31. + # + # NetlinkEventsReliable Off + # # By default, the daemon receives state updates following an # event-driven model. You can modify this behaviour by switching to diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index a108569..805a531 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -278,6 +278,13 @@ General { # # NetlinkOverrunResync On + # If you want reliable event reporting over Netlink, set on this + # option. If you set on this clause, it is a good idea to set off + # NetlinkOverrunResync. This option is off by default and you need + # a Linux kernel >= 2.6.31. + # + # NetlinkEventsReliable Off + # # By default, the daemon receives state updates following an # event-driven model. You can modify this behaviour by switching to diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index c1208f9..ceca224 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -287,6 +287,14 @@ General { # # NetlinkOverrunResync On + # + # If you want reliable event reporting over Netlink, set on this + # option. If you set on this clause, it is a good idea to set off + # NetlinkOverrunResync. This option is off by default and you need + # a Linux kernel >= 2.6.31. + # + # NetlinkEventsReliable Off + # # By default, the daemon receives state updates following an # event-driven model. You can modify this behaviour by switching to diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index b528fab..1efeb81 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -268,6 +268,13 @@ General { # # NetlinkOverrunResync On + # If you want reliable event reporting over Netlink, set on this + # option. If you set on this clause, it is a good idea to set off + # NetlinkOverrunResync. This option is off by default and you need + # a Linux kernel >= 2.6.31. + # + # NetlinkEventsReliable Off + # # By default, the daemon receives state updates following an # event-driven model. You can modify this behaviour by switching to diff --git a/include/conntrackd.h b/include/conntrackd.h index 12fd17f..907ce33 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -95,6 +95,9 @@ struct ct_conf { int poll_kernel_secs; int filter_from_kernelspace; int event_iterations_limit; + struct { + int events_reliable; + } netlink; struct { int commit_steps; } general; diff --git a/src/netlink.c b/src/netlink.c index 5c07201..a43f782 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -75,6 +75,18 @@ struct nfct_handle *nl_init_event_handler(void) CONFIG(netlink_buffer_size_max_grown) = CONFIG(netlink_buffer_size); + if (CONFIG(netlink).events_reliable) { + int on = 1; + + setsockopt(nfct_fd(h), SOL_NETLINK, + NETLINK_BROADCAST_SEND_ERROR, &on, sizeof(int)); + + setsockopt(nfct_fd(h), SOL_NETLINK, + NETLINK_NO_ENOBUFS, &on, sizeof(int)); + + dlog(LOG_NOTICE, "reliable ctnetlink event delivery " + "is ENABLED."); + } return h; } diff --git a/src/read_config_lex.l b/src/read_config_lex.l index cd03ad4..dad7555 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -134,6 +134,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "Scheduler" { return T_SCHEDULER; } "Type" { return T_TYPE; } "Priority" { return T_PRIO; } +"NetlinkEventsReliable" { return T_NETLINK_EVENTS_RELIABLE; } {is_on} { return T_ON; } {is_off} { return T_OFF; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 0e9b99b..87f99b6 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -71,7 +71,7 @@ static void __max_dedicated_links_reached(void); %token T_FILTER T_ADDRESS T_PROTOCOL T_STATE T_ACCEPT T_IGNORE %token T_FROM T_USERSPACE T_KERNELSPACE T_EVENT_ITER_LIMIT T_DEFAULT %token T_NETLINK_OVERRUN_RESYNC T_NICE T_IPV4_DEST_ADDR T_IPV6_DEST_ADDR -%token T_SCHEDULER T_TYPE T_PRIO +%token T_SCHEDULER T_TYPE T_PRIO T_NETLINK_EVENTS_RELIABLE %token T_IP T_PATH_VAL %token T_NUMBER @@ -873,6 +873,7 @@ general_line: hashsize | poll_secs | filter | netlink_overrun_resync + | netlink_events_reliable | nice | scheduler ; @@ -902,6 +903,16 @@ netlink_overrun_resync : T_NETLINK_OVERRUN_RESYNC T_NUMBER conf.nl_overrun_resync = $2; }; +netlink_events_reliable : T_NETLINK_EVENTS_RELIABLE T_ON +{ + conf.netlink.events_reliable = 1; +}; + +netlink_events_reliable : T_NETLINK_EVENTS_RELIABLE T_OFF +{ + conf.netlink.events_reliable = 0; +}; + nice : T_NICE T_SIGNED_NUMBER { conf.nice = $2; -- cgit v1.2.3 From e55321739fa5e04920feeb2a25b02073d8eb9e10 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 21 Jul 2009 16:57:54 +0200 Subject: conntrackd: add support for IPv6 kernel-space filtering via BSF This patch adds the missing support to filter IPv6 from kernel-space by means of the BSF API that libnetfilter_conntrack provides. Signed-off-by: Pablo Neira Ayuso --- doc/stats/conntrackd.conf | 1 + doc/sync/alarm/conntrackd.conf | 3 +++ doc/sync/ftfw/conntrackd.conf | 3 +++ doc/sync/notrack/conntrackd.conf | 3 +++ include/cidr.h | 1 + src/cidr.c | 11 +++++++++++ src/read_config_yy.y | 17 ++++++++++++++++- 7 files changed, 38 insertions(+), 1 deletion(-) (limited to 'doc/sync/alarm') diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index ef6a698..0941f64 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -88,6 +88,7 @@ General { # Address Ignore { IPv4_address 127.0.0.1 # loopback + # IPv6_address ::1 } # diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 805a531..800012f 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -351,6 +351,9 @@ General { # # You can also specify networks in format IP/cidr. # IPv4_address 192.168.0.0/24 + # + # You can also specify an IPv6 address + # IPv6_address ::1 } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index ceca224..602c3d1 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -361,6 +361,9 @@ General { # # You can also specify networks in format IP/cidr. # IPv4_address 192.168.0.0/24 + # + # You can also specify an IPv6 address + # IPv6_address ::1 } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 1efeb81..6968025 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -341,6 +341,9 @@ General { # # You can also specify networks in format IP/cidr. # IPv4_address 192.168.0.0/24 + # + # You can also specify an IPv6 address + # IPv6_address ::1 } # diff --git a/include/cidr.h b/include/cidr.h index f8a4e2a..413c321 100644 --- a/include/cidr.h +++ b/include/cidr.h @@ -4,5 +4,6 @@ uint32_t ipv4_cidr2mask_host(uint8_t cidr); uint32_t ipv4_cidr2mask_net(uint8_t cidr); void ipv6_cidr2mask_host(uint8_t cidr, uint32_t *res); void ipv6_cidr2mask_net(uint8_t cidr, uint32_t *res); +void ipv6_addr2addr_host(uint32_t *addr, uint32_t *res); #endif diff --git a/src/cidr.c b/src/cidr.c index d43dabc..91025b6 100644 --- a/src/cidr.c +++ b/src/cidr.c @@ -57,3 +57,14 @@ void ipv6_cidr2mask_net(uint8_t cidr, uint32_t *res) res[i] = htonl(res[i]); } +/* I need this function because I initially defined an IPv6 address as + * uint32 u[4]. Using char u[16] instead would allow to remove this. */ +void ipv6_addr2addr_host(uint32_t *addr, uint32_t *res) +{ + int i; + + memset(res, 0, sizeof(uint32_t)*4); + for (i = 0; i < 4; i++) { + res[i] = ntohl(addr[i]); + } +} diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 87f99b6..f3f4730 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -1053,6 +1053,12 @@ filter_item : T_ADDRESS T_IGNORE '{' filter_address_list '}' nfct_filter_set_logic(STATE(filter), NFCT_FILTER_DST_IPV4, NFCT_FILTER_LOGIC_NEGATIVE); + nfct_filter_set_logic(STATE(filter), + NFCT_FILTER_SRC_IPV6, + NFCT_FILTER_LOGIC_NEGATIVE); + nfct_filter_set_logic(STATE(filter), + NFCT_FILTER_DST_IPV6, + NFCT_FILTER_LOGIC_NEGATIVE); }; filter_address_list : @@ -1121,7 +1127,8 @@ filter_address_item : T_IPV6_ADDR T_IP { union inet_address ip; char *slash; - int cidr; + int cidr = 128; + struct nfct_filter_ipv6 filter_ipv6; memset(&ip, 0, sizeof(union inet_address)); @@ -1166,6 +1173,14 @@ filter_address_item : T_IPV6_ADDR T_IP "ignore pool!"); } } + __kernel_filter_start(); + + /* host byte order */ + ipv6_addr2addr_host(ip.ipv6, filter_ipv6.addr); + ipv6_cidr2mask_host(cidr, filter_ipv6.mask); + + nfct_filter_add_attr(STATE(filter), NFCT_FILTER_SRC_IPV6, &filter_ipv6); + nfct_filter_add_attr(STATE(filter), NFCT_FILTER_DST_IPV6, &filter_ipv6); }; filter_item : T_STATE T_ACCEPT '{' filter_state_list '}' -- cgit v1.2.3 From 65645763ebe870fa01b5c1a5dbe810feb9397ff2 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 6 Oct 2009 11:19:28 +0200 Subject: conntrackd: add ICMP support for state-synchronization This patch adds state-synchronization for ICMP. You SHOULD use a Linux kernel >= 2.6.31, otherwise this patch can result in tons of state-updates. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 1 + doc/sync/ftfw/conntrackd.conf | 1 + doc/sync/notrack/conntrackd.conf | 1 + include/network.h | 3 +++ src/build.c | 9 ++++++++- src/parse.c | 15 +++++++++++++++ 6 files changed, 29 insertions(+), 1 deletion(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 800012f..3424e39 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -332,6 +332,7 @@ General { TCP SCTP DCCP + # ICMP # This requires a Linux kernel >= 2.6.31 } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 81f2de1..df10aca 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -357,6 +357,7 @@ General { TCP SCTP DCCP + # ICMP # This requires a Linux kernel >= 2.6.31 } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 529fbd9..5b9ebbb 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -338,6 +338,7 @@ General { TCP SCTP DCCP + # ICMP # This requires a Linux kernel >= 2.6.31 } # diff --git a/include/network.h b/include/network.h index dfc3015..70812b1 100644 --- a/include/network.h +++ b/include/network.h @@ -217,6 +217,9 @@ enum nta_attr { NTA_SCTP_VTAG_REPL, /* uint32_t */ NTA_DCCP_STATE = 20, /* uint8_t */ NTA_DCCP_ROLE, /* uint8_t */ + NTA_ICMP_TYPE, /* uint8_t */ + NTA_ICMP_CODE, /* uint8_t */ + NTA_ICMP_ID, /* uint16_t */ NTA_MAX }; diff --git a/src/build.c b/src/build.c index defb2ec..6d8b12e 100644 --- a/src/build.c +++ b/src/build.c @@ -124,6 +124,13 @@ static void build_l4proto_dccp(const struct nf_conntrack *ct, struct nethdr *n) __build_u8(ct, ATTR_DCCP_ROLE, n, NTA_DCCP_ROLE); } +static void build_l4proto_icmp(const struct nf_conntrack *ct, struct nethdr *n) +{ + __build_u8(ct, ATTR_ICMP_TYPE, n, NTA_ICMP_TYPE); + __build_u8(ct, ATTR_ICMP_CODE, n, NTA_ICMP_CODE); + __build_u16(ct, ATTR_ICMP_ID, n, NTA_ICMP_ID); +} + #ifndef IPPROTO_DCCP #define IPPROTO_DCCP 33 #endif @@ -134,9 +141,9 @@ static struct build_l4proto { [IPPROTO_TCP] = { .build = build_l4proto_tcp }, [IPPROTO_SCTP] = { .build = build_l4proto_sctp }, [IPPROTO_DCCP] = { .build = build_l4proto_dccp }, + [IPPROTO_ICMP] = { .build = build_l4proto_icmp }, }; -/* XXX: ICMP not supported */ void build_payload(const struct nf_conntrack *ct, struct nethdr *n) { uint8_t l4proto = nfct_get_attr_u8(ct, ATTR_L4PROTO); diff --git a/src/parse.c b/src/parse.c index b5f257c..e6eefe4 100644 --- a/src/parse.c +++ b/src/parse.c @@ -146,6 +146,21 @@ static struct parser h[NTA_MAX] = { .attr = ATTR_DCCP_ROLE, .size = NTA_SIZE(sizeof(uint8_t)), }, + [NTA_ICMP_TYPE] = { + .parse = parse_u8, + .attr = ATTR_ICMP_TYPE, + .size = NTA_SIZE(sizeof(uint8_t)), + }, + [NTA_ICMP_CODE] = { + .parse = parse_u8, + .attr = ATTR_ICMP_CODE, + .size = NTA_SIZE(sizeof(uint8_t)), + }, + [NTA_ICMP_ID] = { + .parse = parse_u16, + .attr = ATTR_ICMP_ID, + .size = NTA_SIZE(sizeof(uint16_t)), + }, }; static void -- cgit v1.2.3 From 73da80df0c3cf4175662b3da4dfbd3574d34f96a Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 11 Feb 2010 11:56:37 +0100 Subject: conntrackd: fix UDP filtering in configuration file UDP filtering was broken during the addition of the UDP-based synchronization protocol that was introduced in 0.9.14. This patch fixes the problem. Signed-off-by: Pablo Neira Ayuso --- doc/stats/conntrackd.conf | 1 + doc/sync/alarm/conntrackd.conf | 1 + doc/sync/ftfw/conntrackd.conf | 1 + doc/sync/notrack/conntrackd.conf | 1 + src/read_config_yy.y | 19 +++++++++++++++++++ 5 files changed, 23 insertions(+) (limited to 'doc/sync/alarm') diff --git a/doc/stats/conntrackd.conf b/doc/stats/conntrackd.conf index 0941f64..22556a0 100644 --- a/doc/stats/conntrackd.conf +++ b/doc/stats/conntrackd.conf @@ -81,6 +81,7 @@ General { # Protocol Accept { TCP + # UDP } # diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 3424e39..9b7d8c6 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -332,6 +332,7 @@ General { TCP SCTP DCCP + # UDP # ICMP # This requires a Linux kernel >= 2.6.31 } diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index df10aca..877ed68 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -357,6 +357,7 @@ General { TCP SCTP DCCP + # UDP # ICMP # This requires a Linux kernel >= 2.6.31 } diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index f8bccc4..693209a 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -394,6 +394,7 @@ General { TCP SCTP DCCP + # UDP # ICMP # This requires a Linux kernel >= 2.6.31 } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 6dfca98..5f4e6be 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -1221,6 +1221,25 @@ filter_protocol_item : T_TCP pent->p_proto); }; +filter_protocol_item : T_UDP +{ + struct protoent *pent; + + pent = getprotobyname("udp"); + if (pent == NULL) { + print_err(CTD_CFG_WARN, "getprotobyname() cannot find " + "protocol `udp' in /etc/protocols"); + break; + } + ct_filter_add_proto(STATE(us_filter), pent->p_proto); + + __kernel_filter_start(); + + nfct_filter_add_attr_u32(STATE(filter), + NFCT_FILTER_L4PROTO, + pent->p_proto); +}; + filter_item : T_ADDRESS T_ACCEPT '{' filter_address_list '}' { ct_filter_set_logic(STATE(us_filter), -- cgit v1.2.3 From 56817d1c0cc30bcd65c56c2f73634b256603cc4d Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Tue, 29 Dec 2009 20:02:55 +0100 Subject: conntrackd: add support for TCP window scale factor synchronization This patch adds a new option TCPWindowTracking that allows not to disable TCP window tracking as it occurs by default. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 11 +++++++++++ doc/sync/ftfw/conntrackd.conf | 10 ++++++++++ doc/sync/notrack/conntrackd.conf | 11 +++++++++++ include/conntrackd.h | 1 + include/network.h | 2 ++ src/build.c | 4 ++++ src/netlink.c | 20 ++++++++++---------- src/parse.c | 10 ++++++++++ src/read_config_lex.l | 2 ++ src/read_config_yy.y | 18 ++++++++++++++++++ 10 files changed, 79 insertions(+), 10 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 9b7d8c6..65c8715 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -180,6 +180,17 @@ Sync { # # Checksum on # } + + # + # Other unsorted options that are related to the synchronization. + # + # Options { + # + # TCP state-entries have window tracking disabled by default, + # you can enable it with this option. As said, default is off. + # + # TCPWindowTracking Off + # } } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 877ed68..481fe8b 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -204,6 +204,16 @@ Sync { # Checksum on # } + # + # Other unsorted options that are related to the synchronization. + # + # Options { + # + # TCP state-entries have window tracking disabled by default, + # you can enable it with this option. As said, default is off. + # + # TCPWindowTracking Off + # } } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 693209a..430ca25 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -242,6 +242,17 @@ Sync { # # Checksum on # } + + # + # Other unsorted options that are related to the synchronization. + # + # Options { + # + # TCP state-entries have window tracking disabled by default, + # you can enable it with this option. As said, default is off. + # + # TCPWindowTracking Off + # } } # diff --git a/include/conntrackd.h b/include/conntrackd.h index c7f33f0..b35c95d 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -102,6 +102,7 @@ struct ct_conf { struct { int internal_cache_disable; int external_cache_disable; + int tcp_window_tracking; } sync; struct { int events_reliable; diff --git a/include/network.h b/include/network.h index 70812b1..567317b 100644 --- a/include/network.h +++ b/include/network.h @@ -220,6 +220,8 @@ enum nta_attr { NTA_ICMP_TYPE, /* uint8_t */ NTA_ICMP_CODE, /* uint8_t */ NTA_ICMP_ID, /* uint16_t */ + NTA_TCP_WSCALE_ORIG, /* uint8_t */ + NTA_TCP_WSCALE_REPL, /* uint8_t */ NTA_MAX }; diff --git a/src/build.c b/src/build.c index 6d8b12e..0bfe8c1 100644 --- a/src/build.c +++ b/src/build.c @@ -103,6 +103,10 @@ static void build_l4proto_tcp(const struct nf_conntrack *ct, struct nethdr *n) return; __build_u8(ct, ATTR_TCP_STATE, n, NTA_TCP_STATE); + if (CONFIG(sync).tcp_window_tracking) { + __build_u8(ct, ATTR_TCP_WSCALE_ORIG, n, NTA_TCP_WSCALE_ORIG); + __build_u8(ct, ATTR_TCP_WSCALE_REPL, n, NTA_TCP_WSCALE_REPL); + } } static void build_l4proto_sctp(const struct nf_conntrack *ct, struct nethdr *n) diff --git a/src/netlink.c b/src/netlink.c index a43f782..5b6452a 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -196,12 +196,12 @@ int nl_create_conntrack(struct nfct_handle *h, nfct_setobjopt(ct, NFCT_SOPT_SETUP_REPLY); - /* - * TCP flags to overpass window tracking for recovered connections - */ + /* disable TCP window tracking for recovered connections if required */ if (nfct_attr_is_set(ct, ATTR_TCP_STATE)) { - uint8_t flags = IP_CT_TCP_FLAG_BE_LIBERAL | - IP_CT_TCP_FLAG_SACK_PERM; + uint8_t flags = IP_CT_TCP_FLAG_SACK_PERM; + + if (!CONFIG(sync).tcp_window_tracking) + flags |= IP_CT_TCP_FLAG_BE_LIBERAL; /* FIXME: workaround, we should send TCP flags in updates */ if (nfct_get_attr_u8(ct, ATTR_TCP_STATE) >= @@ -261,12 +261,12 @@ int nl_update_conntrack(struct nfct_handle *h, nfct_attr_unset(ct, ATTR_MASTER_PORT_DST); } - /* - * TCP flags to overpass window tracking for recovered connections - */ + /* disable TCP window tracking for recovered connections if required */ if (nfct_attr_is_set(ct, ATTR_TCP_STATE)) { - uint8_t flags = IP_CT_TCP_FLAG_BE_LIBERAL | - IP_CT_TCP_FLAG_SACK_PERM; + uint8_t flags = IP_CT_TCP_FLAG_SACK_PERM; + + if (!CONFIG(sync).tcp_window_tracking) + flags |= IP_CT_TCP_FLAG_BE_LIBERAL; /* FIXME: workaround, we should send TCP flags in updates */ if (nfct_get_attr_u8(ct, ATTR_TCP_STATE) >= diff --git a/src/parse.c b/src/parse.c index e6eefe4..3eb7f44 100644 --- a/src/parse.c +++ b/src/parse.c @@ -161,6 +161,16 @@ static struct parser h[NTA_MAX] = { .attr = ATTR_ICMP_ID, .size = NTA_SIZE(sizeof(uint16_t)), }, + [NTA_TCP_WSCALE_ORIG] = { + .parse = parse_u8, + .attr = ATTR_TCP_WSCALE_ORIG, + .size = NTA_SIZE(sizeof(uint8_t)), + }, + [NTA_TCP_WSCALE_REPL] = { + .parse = parse_u8, + .attr = ATTR_TCP_WSCALE_REPL, + .size = NTA_SIZE(sizeof(uint8_t)), + }, }; static void diff --git a/src/read_config_lex.l b/src/read_config_lex.l index b2d4bdb..f005099 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -138,6 +138,8 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "NetlinkEventsReliable" { return T_NETLINK_EVENTS_RELIABLE; } "DisableInternalCache" { return T_DISABLE_INTERNAL_CACHE; } "DisableExternalCache" { return T_DISABLE_EXTERNAL_CACHE; } +"Options" { return T_OPTIONS; } +"TCPWindowTracking" { return T_TCP_WINDOW_TRACKING; } "ErrorQueueLength" { return T_ERROR_QUEUE_LENGTH; } {is_on} { return T_ON; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 5f4e6be..bc76e92 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -73,6 +73,7 @@ static void __max_dedicated_links_reached(void); %token T_NETLINK_OVERRUN_RESYNC T_NICE T_IPV4_DEST_ADDR T_IPV6_DEST_ADDR %token T_SCHEDULER T_TYPE T_PRIO T_NETLINK_EVENTS_RELIABLE %token T_DISABLE_INTERNAL_CACHE T_DISABLE_EXTERNAL_CACHE T_ERROR_QUEUE_LENGTH +%token T_OPTIONS T_TCP_WINDOW_TRACKING %token T_IP T_PATH_VAL %token T_NUMBER @@ -808,8 +809,25 @@ sync_line: refreshtime | state_replication | cache_writethrough | destroy_timeout + | option_line ; +option_line: T_OPTIONS '{' options '}'; + +options: + | options option + ; + +option: T_TCP_WINDOW_TRACKING T_ON +{ + CONFIG(sync).tcp_window_tracking = 1; +}; + +option: T_TCP_WINDOW_TRACKING T_OFF +{ + CONFIG(sync).tcp_window_tracking = 0; +}; + sync_mode_alarm: T_SYNC_MODE T_ALARM '{' sync_mode_alarm_list '}' { conf.flags |= CTD_SYNC_ALARM; -- cgit v1.2.3 From c93ff79c70e1595af94abbadce685087f702c39b Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 1 Jul 2010 17:38:07 +0200 Subject: conntrackd: fix ICMPv6 support This patch fixes several minor nitpicks to support IPv6 failover: * ICMPv6 type/code/id were missing in synchronization messages. * The use of '-' as string in the configuration file was not allowed. * Include example in configuration file under doc/. Reported-by: Mohit Mehta Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 1 + doc/sync/ftfw/conntrackd.conf | 1 + doc/sync/notrack/conntrackd.conf | 1 + src/build.c | 1 + src/read_config_lex.l | 2 +- 5 files changed, 5 insertions(+), 1 deletion(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 65c8715..ed36c32 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -345,6 +345,7 @@ General { DCCP # UDP # ICMP # This requires a Linux kernel >= 2.6.31 + # IPv6-ICMP # This requires a Linux kernel >= 2.6.31 } # diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 481fe8b..103f9eb 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -369,6 +369,7 @@ General { DCCP # UDP # ICMP # This requires a Linux kernel >= 2.6.31 + # IPv6-ICMP # This requires a Linux kernel >= 2.6.31 } # diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 430ca25..cc17fe5 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -407,6 +407,7 @@ General { DCCP # UDP # ICMP # This requires a Linux kernel >= 2.6.31 + # IPv6-ICMP # This requires a Linux kernel >= 2.6.31 } # diff --git a/src/build.c b/src/build.c index a73476a..a495872 100644 --- a/src/build.c +++ b/src/build.c @@ -161,6 +161,7 @@ static struct build_l4proto { [IPPROTO_SCTP] = { .build = build_l4proto_sctp }, [IPPROTO_DCCP] = { .build = build_l4proto_dccp }, [IPPROTO_ICMP] = { .build = build_l4proto_icmp }, + [IPPROTO_ICMPV6] = { .build = build_l4proto_icmp }, [IPPROTO_UDP] = { .build = build_l4proto_udp }, }; diff --git a/src/read_config_lex.l b/src/read_config_lex.l index f005099..be6bf8b 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -47,7 +47,7 @@ ip6_part {hex_255}":"? ip6_form1 {ip6_part}{0,16}"::"{ip6_part}{0,16} ip6_form2 ({hex_255}":"){16}{hex_255} ip6 {ip6_form1}{ip6_cidr}?|{ip6_form2}{ip6_cidr}? -string [a-zA-Z][a-zA-Z0-9\.]* +string [a-zA-Z][a-zA-Z0-9\.\-]* persistent [P|p][E|e][R|r][S|s][I|i][S|s][T|t][E|e][N|n][T|T] nack [N|n][A|a][C|c][K|k] alarm [A|a][L|l][A|a][R|r][M|m] -- cgit v1.2.3 From c06742539805717a02c6bc5088843d4fd59b6ded Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Thu, 15 Jul 2010 20:15:16 +0200 Subject: conntrackd: warn on TCPWindowTracking option (it requires kernel >= 2.6.35) This patch adds a comment on the TCPWindowTracking option to warn that this will be supported since the Linux kernel 2.6.35. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 1 + doc/sync/ftfw/conntrackd.conf | 1 + doc/sync/notrack/conntrackd.conf | 1 + 3 files changed, 3 insertions(+) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index ed36c32..1ec0633 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -188,6 +188,7 @@ Sync { # # TCP state-entries have window tracking disabled by default, # you can enable it with this option. As said, default is off. + # This feature requires a Linux kernel >= 2.6.35. # # TCPWindowTracking Off # } diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 103f9eb..450ac1e 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -211,6 +211,7 @@ Sync { # # TCP state-entries have window tracking disabled by default, # you can enable it with this option. As said, default is off. + # This feature requires a Linux kernel >= 2.6.35. # # TCPWindowTracking Off # } diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index cc17fe5..50eaaa9 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -250,6 +250,7 @@ Sync { # # TCP state-entries have window tracking disabled by default, # you can enable it with this option. As said, default is off. + # This feature requires a Linux kernel >= 2.6.35. # # TCPWindowTracking Off # } -- cgit v1.2.3 From 023735ca0eab6681804036bb55416b4fc9720b74 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Wed, 4 Aug 2010 19:02:58 +0200 Subject: conntrackd: fix wrong kernel requirements for TCPWindowTracking in example files This patch fixes wrong Linux kernel requirements in the example configuration files. We require a Linux kernel >= 2.6.36 instead of >= 2.6.35 as the files suggest. Signed-off-by: Pablo Neira Ayuso --- doc/sync/alarm/conntrackd.conf | 2 +- doc/sync/ftfw/conntrackd.conf | 2 +- doc/sync/notrack/conntrackd.conf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'doc/sync/alarm') diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index 1ec0633..d05b499 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -188,7 +188,7 @@ Sync { # # TCP state-entries have window tracking disabled by default, # you can enable it with this option. As said, default is off. - # This feature requires a Linux kernel >= 2.6.35. + # This feature requires a Linux kernel >= 2.6.36. # # TCPWindowTracking Off # } diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index 450ac1e..c52f214 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -211,7 +211,7 @@ Sync { # # TCP state-entries have window tracking disabled by default, # you can enable it with this option. As said, default is off. - # This feature requires a Linux kernel >= 2.6.35. + # This feature requires a Linux kernel >= 2.6.36. # # TCPWindowTracking Off # } diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 50eaaa9..4d77266 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -250,7 +250,7 @@ Sync { # # TCP state-entries have window tracking disabled by default, # you can enable it with this option. As said, default is off. - # This feature requires a Linux kernel >= 2.6.35. + # This feature requires a Linux kernel >= 2.6.36. # # TCPWindowTracking Off # } -- cgit v1.2.3 From 79a777c60cfe02197c135adcc4edb2f63ae9a695 Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso Date: Mon, 19 Dec 2011 17:13:25 +0100 Subject: conntrackd: support for expectation synchronization This patch adds support to synchronize expectations between firewalls. This addition aims to re-use as much as possible of the existing infrastructure for stability reasons. The expectation support has been tested with the FTP helper. This extension requires libnetfilter_conntrack 1.0.0. If this is the first time you're playing with conntrackd, I *strongly* recommend you to get working setup of conntrackd without expectation support before as described in the documentation. Then, enabling expectation support is rather easy. To know more about expectations, if you're not familiar with them, I suggest you to read: "Netfilter's Connection Tracking System" http://people.netfilter.org/pablo/docs/login.pdf Reprinted from ;login: The Magazine of USENIX, vol. 31, no. 3 (Berkeley, CA: USENIX Association, 2006, pp40-45.) In short, expectations allow one Linux firewall to filter multi-flow traffic like FTP, SIP and H.323. In my testbed, there are two firewalls in a primary-backup configuration running keepalived. The use a couple of floating cluster IP address (192.168.0.100 and 192.168.1.100) that are used by the client. These firewalls protect one FTP server (192.168.1.2) that will be accessed by one client. In ASCII art, it looks like this: 192.168.0.100 192.168.1.100 eth1 eth2 fw-1 / \ FTP -- client ------ ------ server -- 192.168.0.2 \ / 192.168.1.2 fw-2 This is the rule-set for the firewalls: -A POSTROUTING -t nat -s 192.168.0.2/32 -d 192.168.1.2/32 -j SNAT --to-source 192.168.1.100 -A INPUT -p tcp -m tcp --dport 22 -j ACCEPT -A INPUT -m state --state INVALID -j DROP -A FORWARD -m state --state RELATED -j ACCEPT -A FORWARD -i eth2 -m state --state ESTABLISHED -j ACCEPT -A FORWARD -i eth1 -p tcp -m tcp --dport 21 --tcp-flags FIN,SYN,RST,ACK SYN -m state --state NEW -j ACCEPT -A FORWARD -i eth1 -p tcp -m state --state ESTABLISHED -j ACCEPT -A FORWARD -m state --state INVALID -j LOG --log-prefix "invalid: " The following steps detail how to check that the expectation support works fine for conntrackd: 1) You have to enable the expectation support in the configuration file with the following option: Sync { ... Options { ExpectationSync { ftp sip h323 } } } This enables expectation synchronization for the FTP, SIP and H.323 helpers. You can alternatively use: Sync { ... Options { ExpectationSync On } } To enable expectation synchronization for all helpers. 2) Make sure you have loaded the FTP helper in both firewalls. root@fw1# modprobe nf_conntrack_ftp root@fw2# modprobe nf_conntrack_ftp 3) Switch to the client. Start one FTP control connection to one server that is protected by the firewalls, enter passive mode: (term-1) user@client$ nc 192.168.1.2 21 220 dummy FTP server USER anonymous 331 Please specify the password. PASS nothing 230 Login successful. PASV 227 Entering Passive Mode (192,168,1,2,163,11). This means that port 163*256+11=41739 will be used for the data traffic. Read this if you are not familiar with the FTP protocol: http://www.freefire.org/articles/ftpexample.php 3) Switch to fw-1 (primary) to check that the expectation is in the internal cache. root@fw1# conntrackd -i exp proto=6 src=192.168.0.2 dst=192.168.1.2 sport=0 dport=41739 mask-src=255.255.255.255 mask-dst=255.255.255.255 sport=0 dport=65535 master-src=192.168.0.2 master-dst=192.168.1.2 sport=36390 dport=21 [active since 5s] 4) Switch to fw-2 (backup) to check that the expectation has been successfully replicated. root@fw2# conntrackd -e exp proto=6 src=192.168.0.2 dst=192.168.1.2 sport=0 dport=41739 mask-src=255.255.255.255 mask-dst=255.255.255.255 sport=0 dport=65535 master-src=192.168.0.2 master-dst=192.168.1.2 sport=36390 dport=21 [active since 8s] 5) Make the primary firewall fw-1 fail. Now fw-2 becomes primary. 6) Switch to fw-2 (primary) to commit the external cache into the kernel. root@fw2# conntrackd -c exp The logs should display that the commit was successful: root@fw2# tail -100f /var/log/conntrackd.log [Wed Dec 7 22:16:31 2011] (pid=19195) [notice] committing external cache: expectations [Wed Dec 7 22:16:31 2011] (pid=19195) [notice] Committed 1 new entries [Wed Dec 7 22:16:31 2011] (pid=19195) [notice] commit has taken 0.000366 seconds 7) Switch to the client. Open a new terminal and connect to the port that has been announced by the server: (term-2) user@client$ nc -vvv 192.168.1.2 41739 (UNKNOWN) [192.168.1.2] 41739 (?) open 8) Switch to term-1 and ask for the file listing: [...] 227 Entering Passive Mode (192,168,1,2,163,11). LIST 9) Switch to term-2, it should display the listing. That means everything has worked fine. You may want to try disabling the expectation support and repeating the steps to check that *it does not work* without the state-synchronization. You can also display expectation statistics by means of: root@fwX# conntrackd -s exp This update requires no changes in the primary-backup.sh script that is used by the HA manager to interact with conntrackd. Thus, we provide a backward compatible command line interface. Regarding the Filter clause and expectations, we use the master conntrack to filter expectation events. The filtering is performed in user-space. No kernel-space filtering support for expectations yet (this support should go in libnetfilter_conntrack at some point). This patch also includes support to disable caching and to allow direct injection of expectations. Signed-off-by: Pablo Neira Ayuso --- configure.ac | 2 +- conntrackd.8 | 12 +- doc/sync/alarm/conntrackd.conf | 16 ++ doc/sync/ftfw/conntrackd.conf | 16 ++ doc/sync/notrack/conntrackd.conf | 16 ++ include/cache.h | 4 + include/conntrackd.h | 19 +++ include/external.h | 11 ++ include/filter.h | 7 + include/internal.h | 17 +++ include/log.h | 2 + include/netlink.h | 7 + include/network.h | 40 ++++- src/Makefile.am | 2 +- src/build.c | 99 +++++++++++++ src/cache-ct.c | 6 +- src/cache-exp.c | 308 +++++++++++++++++++++++++++++++++++++++ src/external_cache.c | 85 +++++++++++ src/external_inject.c | 95 +++++++++++- src/filter.c | 76 ++++++++++ src/internal_bypass.c | 146 ++++++++++++++++++- src/internal_cache.c | 173 ++++++++++++++++++++++ src/log.c | 37 +++++ src/main.c | 69 +++++++-- src/netlink.c | 63 +++++++- src/network.c | 5 + src/parse.c | 192 ++++++++++++++++++++++++ src/read_config_lex.l | 1 + src/read_config_yy.y | 50 ++++++- src/run.c | 206 +++++++++++++++++++++++--- src/sync-ftfw.c | 7 +- src/sync-mode.c | 165 ++++++++++++++++++--- src/sync-notrack.c | 6 +- 33 files changed, 1889 insertions(+), 71 deletions(-) create mode 100644 src/cache-exp.c (limited to 'doc/sync/alarm') diff --git a/configure.ac b/configure.ac index 0481e23..26a7e02 100644 --- a/configure.ac +++ b/configure.ac @@ -52,7 +52,7 @@ else fi PKG_CHECK_MODULES([LIBNFNETLINK], [libnfnetlink >= 1.0.0]) -PKG_CHECK_MODULES([LIBNETFILTER_CONNTRACK], [libnetfilter_conntrack >= 0.9.1]) +PKG_CHECK_MODULES([LIBNETFILTER_CONNTRACK], [libnetfilter_conntrack >= 1.0.0]) AC_CHECK_HEADERS([linux/capability.h],, [AC_MSG_ERROR([Cannot find linux/capabibility.h])]) diff --git a/conntrackd.8 b/conntrackd.8 index 0c9054e..f07ad7a 100644 --- a/conntrackd.8 +++ b/conntrackd.8 @@ -24,10 +24,10 @@ Run conntrackd in daemon mode. .B conntrackd can be used in client mode to request several information and operations to a running daemon .TP -.BI "-i " +.BI "-i "[ct|expect]" Dump the internal cache, i.e. show local states .TP -.BI "-e " +.BI "-e "[ct|expect]" Dump the external cache, i.e. show foreign states .TP .BI "-x " @@ -37,7 +37,7 @@ with "-i" and "-e" parameters. .BI "-f " "[|internal|external]" Flush the internal and/or external cache .TP -.BI "-F " +.BI "-F [ct|expect]" Flush the kernel conntrack table (if you use a Linux kernel >= 2.6.29, this option will not flush your internal and external cache). .TP @@ -48,15 +48,17 @@ ask conntrackd to send the state-entries that it owns to others. .BI "-k " Kill the daemon .TP -.BI "-s " "[|network|cache|runtime|link|rsqueue|process|queue]" +.BI "-s " "[|network|cache|runtime|link|rsqueue|process|queue|ct|expect]" Dump statistics. If no parameter is passed, it displays the general statistics. If "network" is passed as parameter it displays the networking statistics. If "cache" is passed as parameter, it shows the extended cache statistics. If "runtime" is passed as parameter, it shows the run-time statistics. If "process" is passed as parameter, it shows existing child processes (if any). If "queue" is passed as parameter, it shows queue statistics. +If "ct" is passed, it displays the general statistics. +If "expect" is passed as parameter, it shows expectation statistics. .TP -.BI "-R " +.BI "-R " "[ct|expect]" Force a resync against the kernel connection tracking table .TP .BI "-t " diff --git a/doc/sync/alarm/conntrackd.conf b/doc/sync/alarm/conntrackd.conf index d05b499..deed291 100644 --- a/doc/sync/alarm/conntrackd.conf +++ b/doc/sync/alarm/conntrackd.conf @@ -191,6 +191,22 @@ Sync { # This feature requires a Linux kernel >= 2.6.36. # # TCPWindowTracking Off + + # Set this option on if you want to enable the synchronization + # of expectations. You have to specify the list of helpers that + # you want to enable. Default is off. + # + # ExpectationSync { + # ftp + # h323 + # sip + # } + # + # You can use this alternatively: + # + # ExpectationSync On + # + # If you want to synchronize expectations of all helpers. # } } diff --git a/doc/sync/ftfw/conntrackd.conf b/doc/sync/ftfw/conntrackd.conf index c52f214..0304f0f 100644 --- a/doc/sync/ftfw/conntrackd.conf +++ b/doc/sync/ftfw/conntrackd.conf @@ -214,6 +214,22 @@ Sync { # This feature requires a Linux kernel >= 2.6.36. # # TCPWindowTracking Off + + # Set this option on if you want to enable the synchronization + # of expectations. You have to specify the list of helpers that + # you want to enable. Default is off. + # + # ExpectationSync { + # ftp + # h323 + # sip + # } + # + # You can use this alternatively: + # + # ExpectationSync On + # + # If you want to synchronize expectations of all helpers. # } } diff --git a/doc/sync/notrack/conntrackd.conf b/doc/sync/notrack/conntrackd.conf index 4d77266..34e7b32 100644 --- a/doc/sync/notrack/conntrackd.conf +++ b/doc/sync/notrack/conntrackd.conf @@ -253,6 +253,22 @@ Sync { # This feature requires a Linux kernel >= 2.6.36. # # TCPWindowTracking Off + + # Set this option on if you want to enable the synchronization + # of expectations. You have to specify the list of helpers that + # you want to enable. Default is off. + # + # ExpectationSync { + # ftp + # h323 + # sip + # } + # + # You can use this alternatively: + # + # ExpectationSync On + # + # If you want to synchronize expectations of all helpers. # } } diff --git a/include/cache.h b/include/cache.h index abebb97..3af2741 100644 --- a/include/cache.h +++ b/include/cache.h @@ -52,6 +52,7 @@ extern struct cache_feature timer_feature; enum cache_type { CACHE_T_NONE = 0, CACHE_T_CT, + CACHE_T_EXP, CACHE_T_MAX }; @@ -128,6 +129,9 @@ struct cache_ops { extern struct cache_ops cache_sync_internal_ct_ops; extern struct cache_ops cache_sync_external_ct_ops; extern struct cache_ops cache_stats_ct_ops; +/* templates to configure expectation caching. */ +extern struct cache_ops cache_sync_internal_exp_ops; +extern struct cache_ops cache_sync_external_exp_ops; struct nf_conntrack; diff --git a/include/conntrackd.h b/include/conntrackd.h index 697d3d7..8baa088 100644 --- a/include/conntrackd.h +++ b/include/conntrackd.h @@ -37,6 +37,16 @@ #define CT_FLUSH_EXT_CACHE 34 /* flush external cache */ #define STATS_PROCESS 35 /* child process stats */ #define STATS_QUEUE 36 /* queue stats */ +#define EXP_STATS 37 /* dump statistics */ +#define EXP_FLUSH_MASTER 38 /* flush kernel expect table */ +#define EXP_RESYNC_MASTER 39 /* resync with kernel exp table */ +#define EXP_DUMP_INTERNAL 40 /* dump internal expect cache */ +#define EXP_DUMP_EXTERNAL 41 /* dump external expect cache */ +#define EXP_COMMIT 42 /* commit expectations */ +#define ALL_FLUSH_MASTER 43 /* flush all kernel tables */ +#define ALL_RESYNC_MASTER 44 /* resync w/all kernel tables */ +#define ALL_FLUSH_CACHE 45 /* flush all caches */ +#define ALL_COMMIT 46 /* commit all tables */ #define DEFAULT_CONFIGFILE "/etc/conntrackd/conntrackd.conf" #define DEFAULT_LOCKFILE "/var/lock/conntrackd.lock" @@ -56,6 +66,7 @@ #define CTD_SYNC_ALARM (1UL << 3) #define CTD_SYNC_NOTRACK (1UL << 4) #define CTD_POLL (1UL << 5) +#define CTD_EXPECT (1UL << 6) /* FILENAME_MAX is 4096 on my system, perhaps too much? */ #ifndef FILENAME_MAXLEN @@ -105,6 +116,8 @@ struct ct_conf { int tcp_window_tracking; } sync; struct { + int subsys_id; + int groups; int events_reliable; } netlink; struct { @@ -130,6 +143,7 @@ struct ct_general_state { struct local_server local; struct ct_mode *mode; struct ct_filter *us_filter; + struct exp_filter *exp_filter; struct nfct_handle *event; /* event handler */ struct nfct_filter *filter; /* event filter */ @@ -177,6 +191,10 @@ struct ct_general_state { } stats; }; +struct commit_runqueue { + int (*cb)(struct nfct_handle *h, int step); +}; + #define STATE_SYNC(x) state.sync->x struct ct_sync_state { @@ -196,6 +214,7 @@ struct ct_sync_state { struct nfct_handle *h; struct evfd *evfd; int current; + struct commit_runqueue rq[2]; struct { int ok; int fail; diff --git a/include/external.h b/include/external.h index eef0e42..70f0c5c 100644 --- a/include/external.h +++ b/include/external.h @@ -18,6 +18,17 @@ struct external_handler { void (*stats)(int fd); void (*stats_ext)(int fd); } ct; + struct { + void (*new)(struct nf_expect *exp); + void (*upd)(struct nf_expect *exp); + void (*del)(struct nf_expect *exp); + + void (*dump)(int fd, int type); + void (*flush)(void); + int (*commit)(struct nfct_handle *h, int fd); + void (*stats)(int fd); + void (*stats_ext)(int fd); + } exp; }; extern struct external_handler external_cache; diff --git a/include/filter.h b/include/filter.h index f19b18b..3c7c8cc 100644 --- a/include/filter.h +++ b/include/filter.h @@ -52,4 +52,11 @@ void ct_filter_set_logic(struct ct_filter *f, enum ct_filter_logic logic); int ct_filter_conntrack(const struct nf_conntrack *ct, int userspace); +struct exp_filter; +struct nf_expect; + +struct exp_filter *exp_filter_create(void); +int exp_filter_add(struct exp_filter *f, const char *helper_name); +int exp_filter_find(struct exp_filter *f, const struct nf_expect *exp); + #endif diff --git a/include/internal.h b/include/internal.h index f50eb79..2ba9714 100644 --- a/include/internal.h +++ b/include/internal.h @@ -34,6 +34,23 @@ struct internal_handler { void (*stats)(int fd); void (*stats_ext)(int fd); } ct; + struct { + void *data; + + void (*new)(struct nf_expect *exp, int origin_type); + void (*upd)(struct nf_expect *exp, int origin_type); + int (*del)(struct nf_expect *exp, int origin_type); + + void (*dump)(int fd, int type); + void (*populate)(struct nf_expect *exp); + void (*purge)(void); + int (*resync)(enum nf_conntrack_msg_type type, + struct nf_expect *exp, void *data); + void (*flush)(void); + + void (*stats)(int fd); + void (*stats_ext)(int fd); + } exp; }; extern struct internal_handler internal_cache; diff --git a/include/log.h b/include/log.h index f5c5b4f..ae58e79 100644 --- a/include/log.h +++ b/include/log.h @@ -4,10 +4,12 @@ #include struct nf_conntrack; +struct nf_expect; int init_log(void); void dlog(int priority, const char *format, ...); void dlog_ct(FILE *fd, struct nf_conntrack *ct, unsigned int type); +void dlog_exp(FILE *fd, struct nf_expect *exp, unsigned int type); void close_log(void); #endif diff --git a/include/netlink.h b/include/netlink.h index 0df0cbb..3bde30c 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -30,4 +30,11 @@ static inline int ct_is_related(const struct nf_conntrack *ct) nfct_attr_is_set(ct, ATTR_MASTER_PORT_DST)); } +int nl_create_expect(struct nfct_handle *h, const struct nf_expect *orig, int timeout); +int nl_destroy_expect(struct nfct_handle *h, const struct nf_expect *exp); +int nl_get_expect(struct nfct_handle *h, const struct nf_expect *exp); +int nl_dump_expect_table(struct nfct_handle *h); +int nl_flush_expect_table(struct nfct_handle *h); +int nl_send_expect_resync(struct nfct_handle *h); + #endif diff --git a/include/network.h b/include/network.h index d0531b9..ab95499 100644 --- a/include/network.h +++ b/include/network.h @@ -4,9 +4,10 @@ #include #include -#define CONNTRACKD_PROTOCOL_VERSION 0 +#define CONNTRACKD_PROTOCOL_VERSION 1 struct nf_conntrack; +struct nf_expect; struct nethdr { #if __BYTE_ORDER == __LITTLE_ENDIAN @@ -28,7 +29,10 @@ enum nethdr_type { NET_T_STATE_CT_NEW = 0, NET_T_STATE_CT_UPD, NET_T_STATE_CT_DEL, - NET_T_STATE_MAX = NET_T_STATE_CT_DEL, + NET_T_STATE_EXP_NEW = 3, + NET_T_STATE_EXP_UPD, + NET_T_STATE_EXP_DEL, + NET_T_STATE_MAX = NET_T_STATE_EXP_DEL, NET_T_CTL = 10, }; @@ -92,6 +96,17 @@ enum { __hdr; \ }) +#define BUILD_NETMSG_FROM_EXP(exp, query) \ +({ \ + static char __net[4096]; \ + struct nethdr *__hdr = (struct nethdr *) __net; \ + memset(__hdr, 0, NETHDR_SIZ); \ + nethdr_set(__hdr, query); \ + exp2msg(exp, __hdr); \ + HDR_HOST2NETWORK(__hdr); \ + __hdr; \ +}) + struct mcast_sock_multi; enum { @@ -239,4 +254,25 @@ struct nta_attr_natseqadj { void ct2msg(const struct nf_conntrack *ct, struct nethdr *n); int msg2ct(struct nf_conntrack *ct, struct nethdr *n, size_t remain); +enum nta_exp_attr { + NTA_EXP_MASTER_IPV4 = 0, /* struct nfct_attr_grp_ipv4 */ + NTA_EXP_MASTER_IPV6, /* struct nfct_attr_grp_ipv6 */ + NTA_EXP_MASTER_L4PROTO, /* uint8_t */ + NTA_EXP_MASTER_PORT, /* struct nfct_attr_grp_port */ + NTA_EXP_EXPECT_IPV4 = 4, /* struct nfct_attr_grp_ipv4 */ + NTA_EXP_EXPECT_IPV6, /* struct nfct_attr_grp_ipv6 */ + NTA_EXP_EXPECT_L4PROTO, /* uint8_t */ + NTA_EXP_EXPECT_PORT, /* struct nfct_attr_grp_port */ + NTA_EXP_MASK_IPV4 = 8, /* struct nfct_attr_grp_ipv4 */ + NTA_EXP_MASK_IPV6, /* struct nfct_attr_grp_ipv6 */ + NTA_EXP_MASK_L4PROTO, /* uint8_t */ + NTA_EXP_MASK_PORT, /* struct nfct_attr_grp_port */ + NTA_EXP_TIMEOUT, /* uint32_t */ + NTA_EXP_FLAGS, /* uint32_t */ + NTA_EXP_MAX +}; + +void exp2msg(const struct nf_expect *exp, struct nethdr *n); +int msg2exp(struct nf_expect *exp, struct nethdr *n, size_t remain); + #endif diff --git a/src/Makefile.am b/src/Makefile.am index a0abeee..7d7b2ac 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,7 +12,7 @@ conntrack_LDADD = ../extensions/libct_proto_tcp.la ../extensions/libct_proto_udp conntrackd_SOURCES = alarm.c main.c run.c hash.c queue.c rbtree.c \ local.c log.c mcast.c udp.c netlink.c vector.c \ filter.c fds.c event.c process.c origin.c date.c \ - cache.c cache-ct.c \ + cache.c cache-ct.c cache-exp.c \ cache_timer.c \ sync-mode.c sync-alarm.c sync-ftfw.c sync-notrack.c \ traffic_stats.c stats-mode.c \ diff --git a/src/build.c b/src/build.c index 9c3687c..3193884 100644 --- a/src/build.c +++ b/src/build.c @@ -224,3 +224,102 @@ void ct2msg(const struct nf_conntrack *ct, struct nethdr *n) if (nfct_attr_is_set_array(ct, nat_type, 6)) ct_build_natseqadj(ct, n); } + +static void +exp_build_l4proto_tcp(const struct nf_conntrack *ct, struct nethdr *n, int a) +{ + ct_build_group(ct, ATTR_GRP_ORIG_PORT, n, a, + sizeof(struct nfct_attr_grp_port)); +} + +static void +exp_build_l4proto_sctp(const struct nf_conntrack *ct, struct nethdr *n, int a) +{ + ct_build_group(ct, ATTR_GRP_ORIG_PORT, n, a, + sizeof(struct nfct_attr_grp_port)); +} + +static void +exp_build_l4proto_dccp(const struct nf_conntrack *ct, struct nethdr *n, int a) +{ + ct_build_group(ct, ATTR_GRP_ORIG_PORT, n, a, + sizeof(struct nfct_attr_grp_port)); +} + +static void +exp_build_l4proto_udp(const struct nf_conntrack *ct, struct nethdr *n, int a) +{ + ct_build_group(ct, ATTR_GRP_ORIG_PORT, n, a, + sizeof(struct nfct_attr_grp_port)); +} + +static struct exp_build_l4proto { + void (*build)(const struct nf_conntrack *, struct nethdr *n, int a); +} exp_l4proto_fcn[IPPROTO_MAX] = { + [IPPROTO_TCP] = { .build = exp_build_l4proto_tcp }, + [IPPROTO_SCTP] = { .build = exp_build_l4proto_sctp }, + [IPPROTO_DCCP] = { .build = exp_build_l4proto_dccp }, + [IPPROTO_UDP] = { .build = exp_build_l4proto_udp }, +}; + +static inline void +exp_build_u32(const struct nf_expect *exp, int a, struct nethdr *n, int b) +{ + uint32_t data = nfexp_get_attr_u32(exp, a); + data = htonl(data); + addattr(n, b, &data, sizeof(uint32_t)); +} + +void exp2msg(const struct nf_expect *exp, struct nethdr *n) +{ + const struct nf_conntrack *ct = nfexp_get_attr(exp, ATTR_EXP_MASTER); + uint8_t l4proto = nfct_get_attr_u8(ct, ATTR_L4PROTO); + + /* master conntrack for this expectation. */ + if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV4)) { + ct_build_group(ct, ATTR_GRP_ORIG_IPV4, n, NTA_EXP_MASTER_IPV4, + sizeof(struct nfct_attr_grp_ipv4)); + } else if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV6)) { + ct_build_group(ct, ATTR_GRP_ORIG_IPV6, n, NTA_EXP_MASTER_IPV6, + sizeof(struct nfct_attr_grp_ipv6)); + } + ct_build_u8(ct, ATTR_L4PROTO, n, NTA_EXP_MASTER_L4PROTO); + + if (exp_l4proto_fcn[l4proto].build) + exp_l4proto_fcn[l4proto].build(ct, n, NTA_EXP_MASTER_PORT); + + /* the expectation itself. */ + ct = nfexp_get_attr(exp, ATTR_EXP_EXPECTED); + + if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV4)) { + ct_build_group(ct, ATTR_GRP_ORIG_IPV4, n, NTA_EXP_EXPECT_IPV4, + sizeof(struct nfct_attr_grp_ipv4)); + } else if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV6)) { + ct_build_group(ct, ATTR_GRP_ORIG_IPV6, n, NTA_EXP_EXPECT_IPV6, + sizeof(struct nfct_attr_grp_ipv6)); + } + ct_build_u8(ct, ATTR_L4PROTO, n, NTA_EXP_EXPECT_L4PROTO); + + if (exp_l4proto_fcn[l4proto].build) + exp_l4proto_fcn[l4proto].build(ct, n, NTA_EXP_EXPECT_PORT); + + /* mask for the expectation. */ + ct = nfexp_get_attr(exp, ATTR_EXP_MASK); + + if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV4)) { + ct_build_group(ct, ATTR_GRP_ORIG_IPV4, n, NTA_EXP_MASK_IPV4, + sizeof(struct nfct_attr_grp_ipv4)); + } else if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV6)) { + ct_build_group(ct, ATTR_GRP_ORIG_IPV6, n, NTA_EXP_MASK_IPV6, + sizeof(struct nfct_attr_grp_ipv6)); + } + ct_build_u8(ct, ATTR_L4PROTO, n, NTA_EXP_MASK_L4PROTO); + + if (exp_l4proto_fcn[l4proto].build) + exp_l4proto_fcn[l4proto].build(ct, n, NTA_EXP_MASK_PORT); + + if (!CONFIG(commit_timeout) && nfexp_attr_is_set(exp, ATTR_EXP_TIMEOUT)) + exp_build_u32(exp, ATTR_EXP_TIMEOUT, n, NTA_EXP_TIMEOUT); + + exp_build_u32(exp, ATTR_EXP_FLAGS, n, NTA_EXP_FLAGS); +} diff --git a/src/cache-ct.c b/src/cache-ct.c index 2c6fd4e..0ad8d2a 100644 --- a/src/cache-ct.c +++ b/src/cache-ct.c @@ -251,7 +251,7 @@ static int cache_ct_commit(struct cache *c, struct nfct_handle *h, int clientfd) /* we already have one commit in progress, skip this. The clientfd * descriptor has to be closed by the caller. */ if (clientfd && STATE_SYNC(commit).clientfd != -1) - return 0; + return -1; switch(STATE_SYNC(commit).state) { case COMMIT_STATE_INACTIVE: @@ -308,9 +308,7 @@ static int cache_ct_commit(struct cache *c, struct nfct_handle *h, int clientfd) STATE_SYNC(commit).current = 0; STATE_SYNC(commit).state = COMMIT_STATE_INACTIVE; - /* Close the client socket now that we're done. */ - close(STATE_SYNC(commit).clientfd); - STATE_SYNC(commit).clientfd = -1; + return 0; } return 1; } diff --git a/src/cache-exp.c b/src/cache-exp.c new file mode 100644 index 0000000..e88877a --- /dev/null +++ b/src/cache-exp.c @@ -0,0 +1,308 @@ +/* + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "cache.h" +#include "hash.h" +#include "log.h" +#include "conntrackd.h" +#include "netlink.h" +#include "event.h" +#include "jhash.h" +#include "network.h" + +#include +#include +#include +#include + +static uint32_t +cache_hash4_exp(const struct nf_conntrack *ct, const struct hashtable *table) +{ + uint32_t a[4] = { + [0] = nfct_get_attr_u32(ct, ATTR_IPV4_SRC), + [1] = nfct_get_attr_u32(ct, ATTR_IPV4_DST), + [2] = nfct_get_attr_u8(ct, ATTR_L3PROTO) << 16 | + nfct_get_attr_u8(ct, ATTR_L4PROTO), + [3] = nfct_get_attr_u16(ct, ATTR_PORT_SRC) << 16 | + nfct_get_attr_u16(ct, ATTR_PORT_DST), + }; + + /* + * Instead of returning hash % table->hashsize (implying a divide) + * we return the high 32 bits of the (hash * table->hashsize) that will + * give results between [0 and hashsize-1] and same hash distribution, + * but using a multiply, less expensive than a divide. See: + * http://www.mail-archive.com/netdev@vger.kernel.org/msg56623.html + */ + return ((uint64_t)jhash2(a, 4, 0) * table->hashsize) >> 32; +} + +static uint32_t +cache_hash6_exp(const struct nf_conntrack *ct, const struct hashtable *table) +{ + uint32_t a[10]; + + memcpy(&a[0], nfct_get_attr(ct, ATTR_IPV6_SRC), sizeof(uint32_t)*4); + memcpy(&a[4], nfct_get_attr(ct, ATTR_IPV6_SRC), sizeof(uint32_t)*4); + a[8] = nfct_get_attr_u8(ct, ATTR_ORIG_L3PROTO) << 16 | + nfct_get_attr_u8(ct, ATTR_ORIG_L4PROTO); + a[9] = nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC) << 16 | + nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST); + + return ((uint64_t)jhash2(a, 10, 0) * table->hashsize) >> 32; +} + +static uint32_t +cache_exp_hash(const void *data, const struct hashtable *table) +{ + int ret = 0; + const struct nf_expect *exp = data; + const struct nf_conntrack *ct = nfexp_get_attr(exp, ATTR_EXP_MASTER); + + switch(nfct_get_attr_u8(ct, ATTR_L3PROTO)) { + case AF_INET: + ret = cache_hash4_exp(ct, table); + break; + case AF_INET6: + ret = cache_hash6_exp(ct, table); + break; + default: + dlog(LOG_ERR, "unknown layer 3 proto in hash"); + break; + } + return ret; +} + +static int cache_exp_cmp(const void *data1, const void *data2) +{ + const struct cache_object *obj = data1; + const struct nf_expect *exp = data2; + + return nfexp_cmp(obj->ptr, exp, 0); +} + +static void *cache_exp_alloc(void) +{ + return nfexp_new(); +} + +static void cache_exp_free(void *ptr) +{ + nfexp_destroy(ptr); +} + +static void cache_exp_copy(void *dst, void *src, unsigned int flags) +{ + /* XXX: add nfexp_copy(...) to libnetfilter_conntrack. */ + memcpy(dst, src, nfexp_maxsize()); +} + +static int cache_exp_dump_step(void *data1, void *n) +{ + char buf[1024]; + int size; + struct __dump_container *container = data1; + struct cache_object *obj = n; + char *data = obj->data; + unsigned i; + + /* + * XXX: Do not dump the entries that are scheduled to expire. + * These entries talk about already destroyed connections + * that we keep for some time just in case that we have to + * resent some lost messages. We do not show them to the + * user as he may think that the firewall replicas are not + * in sync. The branch below is a hack as it is quite + * specific and it breaks conntrackd modularity. Probably + * there's a nicer way to do this but until I come up with it... + */ + if (CONFIG(flags) & CTD_SYNC_FTFW && obj->status == C_OBJ_DEAD) + return 0; + + /* do not show cached timeout, this may confuse users */ + if (nfexp_attr_is_set(obj->ptr, ATTR_EXP_TIMEOUT)) + nfexp_attr_unset(obj->ptr, ATTR_EXP_TIMEOUT); + + memset(buf, 0, sizeof(buf)); + size = nfexp_snprintf(buf, sizeof(buf),obj->ptr, + NFCT_T_UNKNOWN, container->type, 0); + + for (i = 0; i < obj->cache->num_features; i++) { + if (obj->cache->features[i]->dump) { + size += obj->cache->features[i]->dump(obj, data, + buf+size, + container->type); + data += obj->cache->features[i]->size; + } + } + if (container->type != NFCT_O_XML) { + long tm = time(NULL); + size += sprintf(buf+size, " [active since %lds]", + tm - obj->lifetime); + } + size += sprintf(buf+size, "\n"); + if (send(container->fd, buf, size, 0) == -1) { + if (errno != EPIPE) + return -1; + } + + return 0; +} + +static int cache_exp_commit_step(void *data, void *n) +{ + struct cache_object *obj = n; + struct __commit_container *tmp = data; + int ret, retry = 1, timeout; + struct nf_expect *exp = obj->ptr; + + if (CONFIG(commit_timeout)) { + timeout = CONFIG(commit_timeout); + } else { + timeout = time(NULL) - obj->lastupdate; + if (timeout < 0) { + /* XXX: Arbitrarily set the timer to one minute, how + * can this happen? For example, an adjustment due to + * daylight-saving. Probably other situations can + * trigger this. */ + timeout = 60; + } + /* calculate an estimation of the current timeout */ + timeout = nfexp_get_attr_u32(exp, ATTR_EXP_TIMEOUT) - timeout; + if (timeout < 0) { + timeout = 60; + } + } + +retry: + if (nl_create_expect(tmp->h, exp, timeout) == -1) { + if (errno == EEXIST && retry == 1) { + ret = nl_destroy_expect(tmp->h, exp); + if (ret == 0 || (ret == -1 && errno == ENOENT)) { + if (retry) { + retry = 0; + goto retry; + } + } + dlog(LOG_ERR, "commit-destroy: %s", strerror(errno)); + dlog_exp(STATE(log), exp, NFCT_O_PLAIN); + tmp->c->stats.commit_fail++; + } else { + dlog(LOG_ERR, "commit-create: %s", strerror(errno)); + dlog_exp(STATE(log), exp, NFCT_O_PLAIN); + tmp->c->stats.commit_fail++; + } + } else { + tmp->c->stats.commit_ok++; + } + /* keep iterating even if we have found errors */ + return 0; +} + +static int +cache_exp_commit(struct cache *c, struct nfct_handle *h, int clientfd) +{ + unsigned int commit_ok, commit_fail; + struct timeval commit_stop, res; + struct __commit_container tmp = { + .h = h, + .c = c, + }; + + /* we already have one commit in progress, skip this. The clientfd + * descriptor has to be closed by the caller. */ + if (clientfd && STATE_SYNC(commit).clientfd != -1) + return -1; + + switch(STATE_SYNC(commit).state) { + case COMMIT_STATE_INACTIVE: + gettimeofday(&STATE_SYNC(commit).stats.start, NULL); + STATE_SYNC(commit).stats.ok = c->stats.commit_ok; + STATE_SYNC(commit).stats.fail = c->stats.commit_fail; + STATE_SYNC(commit).clientfd = clientfd; + case COMMIT_STATE_MASTER: + STATE_SYNC(commit).current = + hashtable_iterate_limit(c->h, &tmp, + STATE_SYNC(commit).current, + CONFIG(general).commit_steps, + cache_exp_commit_step); + if (STATE_SYNC(commit).current < CONFIG(hashsize)) { + STATE_SYNC(commit).state = COMMIT_STATE_MASTER; + /* give it another step as soon as possible */ + write_evfd(STATE_SYNC(commit).evfd); + return 1; + } + + /* calculate the time that commit has taken */ + gettimeofday(&commit_stop, NULL); + timersub(&commit_stop, &STATE_SYNC(commit).stats.start, &res); + + /* calculate new entries committed */ + commit_ok = c->stats.commit_ok - STATE_SYNC(commit).stats.ok; + commit_fail = + c->stats.commit_fail - STATE_SYNC(commit).stats.fail; + + /* log results */ + dlog(LOG_NOTICE, "Committed %u new expectations", commit_ok); + + if (commit_fail) + dlog(LOG_NOTICE, "%u expectations can't be " + "committed", commit_fail); + + dlog(LOG_NOTICE, "commit has taken %lu.%06lu seconds", + res.tv_sec, res.tv_usec); + + /* prepare the state machine for new commits */ + STATE_SYNC(commit).current = 0; + STATE_SYNC(commit).state = COMMIT_STATE_INACTIVE; + + return 0; + } + return 1; +} + +static struct nethdr * +cache_exp_build_msg(const struct cache_object *obj, int type) +{ + return BUILD_NETMSG_FROM_EXP(obj->ptr, type); +} + +/* template to cache expectations coming from the kernel. */ +struct cache_ops cache_sync_internal_exp_ops = { + .hash = cache_exp_hash, + .cmp = cache_exp_cmp, + .alloc = cache_exp_alloc, + .free = cache_exp_free, + .copy = cache_exp_copy, + .dump_step = cache_exp_dump_step, + .commit = NULL, + .build_msg = cache_exp_build_msg, +}; + +/* template to cache expectations coming from the network. */ +struct cache_ops cache_sync_external_exp_ops = { + .hash = cache_exp_hash, + .cmp = cache_exp_cmp, + .alloc = cache_exp_alloc, + .free = cache_exp_free, + .copy = cache_exp_copy, + .dump_step = cache_exp_dump_step, + .commit = cache_exp_commit, + .build_msg = NULL, +}; diff --git a/src/external_cache.c b/src/external_cache.c index 3f896a0..e290249 100644 --- a/src/external_cache.c +++ b/src/external_cache.c @@ -26,6 +26,7 @@ #include static struct cache *external; +static struct cache *external_exp; static int external_cache_init(void) { @@ -36,12 +37,21 @@ static int external_cache_init(void) dlog(LOG_ERR, "can't allocate memory for the external cache"); return -1; } + external_exp = cache_create("external", CACHE_T_EXP, + STATE_SYNC(sync)->external_cache_flags, + NULL, &cache_sync_external_exp_ops); + if (external_exp == NULL) { + dlog(LOG_ERR, "can't allocate memory for the external cache"); + return -1; + } + return 0; } static void external_cache_close(void) { cache_destroy(external); + cache_destroy(external_exp); } static void external_cache_ct_new(struct nf_conntrack *ct) @@ -109,6 +119,71 @@ static void external_cache_ct_stats_ext(int fd) cache_stats_extended(external, fd); } +static void external_cache_exp_new(struct nf_expect *exp) +{ + struct cache_object *obj; + int id; + + obj = cache_find(external_exp, exp, &id); + if (obj == NULL) { +retry: + obj = cache_object_new(external_exp, exp); + if (obj == NULL) + return; + + if (cache_add(external_exp, obj, id) == -1) { + cache_object_free(obj); + return; + } + } else { + cache_del(external_exp, obj); + cache_object_free(obj); + goto retry; + } +} + +static void external_cache_exp_upd(struct nf_expect *exp) +{ + cache_update_force(external_exp, exp); +} + +static void external_cache_exp_del(struct nf_expect *exp) +{ + struct cache_object *obj; + int id; + + obj = cache_find(external_exp, exp, &id); + if (obj) { + cache_del(external_exp, obj); + cache_object_free(obj); + } +} + +static void external_cache_exp_dump(int fd, int type) +{ + cache_dump(external_exp, fd, type); +} + +static int external_cache_exp_commit(struct nfct_handle *h, int fd) +{ + return cache_commit(external_exp, h, fd); +} + +static void external_cache_exp_flush(void) +{ + cache_flush(external_exp); +} + +static void external_cache_exp_stats(int fd) +{ + cache_stats(external_exp, fd); +} + +static void external_cache_exp_stats_ext(int fd) +{ + cache_stats_extended(external_exp, fd); +} + struct external_handler external_cache = { .init = external_cache_init, .close = external_cache_close, @@ -122,4 +197,14 @@ struct external_handler external_cache = { .stats = external_cache_ct_stats, .stats_ext = external_cache_ct_stats_ext, }, + .exp = { + .new = external_cache_exp_new, + .upd = external_cache_exp_upd, + .del = external_cache_exp_del, + .dump = external_cache_exp_dump, + .commit = external_cache_exp_commit, + .flush = external_cache_exp_flush, + .stats = external_cache_exp_stats, + .stats_ext = external_cache_exp_stats_ext, + }, }; diff --git a/src/external_inject.c b/src/external_inject.c index ba5f3d1..0ad3478 100644 --- a/src/external_inject.c +++ b/src/external_inject.c @@ -42,7 +42,7 @@ struct { static int external_inject_init(void) { /* handler to directly inject conntracks into kernel-space */ - inject = nfct_open(CONNTRACK, 0); + inject = nfct_open(CONFIG(netlink).subsys_id, 0); if (inject == NULL) { dlog(LOG_ERR, "can't open netlink handler: %s", strerror(errno)); @@ -175,6 +175,89 @@ static void external_inject_ct_stats(int fd) send(fd, buf, size, 0); } +struct { + uint32_t add_ok; + uint32_t add_fail; + uint32_t upd_ok; + uint32_t upd_fail; + uint32_t del_ok; + uint32_t del_fail; +} exp_external_inject_stat; + +static void external_inject_exp_new(struct nf_expect *exp) +{ + int ret, retry = 1; + +retry: + if (nl_create_expect(inject, exp, 0) == -1) { + /* if the state entry exists, we delete and try again */ + if (errno == EEXIST && retry == 1) { + ret = nl_destroy_expect(inject, exp); + if (ret == 0 || (ret == -1 && errno == ENOENT)) { + if (retry) { + retry = 0; + goto retry; + } + } + exp_external_inject_stat.add_fail++; + dlog(LOG_ERR, "inject-add1: %s", strerror(errno)); + dlog_exp(STATE(log), exp, NFCT_O_PLAIN); + return; + } + exp_external_inject_stat.add_fail++; + dlog(LOG_ERR, "inject-add2: %s", strerror(errno)); + dlog_exp(STATE(log), exp, NFCT_O_PLAIN); + } else { + exp_external_inject_stat.add_ok++; + } +} + +static void external_inject_exp_del(struct nf_expect *exp) +{ + if (nl_destroy_expect(inject, exp) == -1) { + if (errno != ENOENT) { + exp_external_inject_stat.del_fail++; + dlog(LOG_ERR, "inject-del: %s", strerror(errno)); + dlog_exp(STATE(log), exp, NFCT_O_PLAIN); + } + } else { + exp_external_inject_stat.del_ok++; + } +} + +static void external_inject_exp_dump(int fd, int type) +{ +} + +static int external_inject_exp_commit(struct nfct_handle *h, int fd) +{ + /* close the commit socket. */ + return LOCAL_RET_OK; +} + +static void external_inject_exp_flush(void) +{ +} + +static void external_inject_exp_stats(int fd) +{ + char buf[512]; + int size; + + size = sprintf(buf, "external inject:\n" + "connections created:\t\t%12u\tfailed:\t%12u\n" + "connections updated:\t\t%12u\tfailed:\t%12u\n" + "connections destroyed:\t\t%12u\tfailed:\t%12u\n\n", + exp_external_inject_stat.add_ok, + exp_external_inject_stat.add_fail, + exp_external_inject_stat.upd_ok, + exp_external_inject_stat.upd_fail, + exp_external_inject_stat.del_ok, + exp_external_inject_stat.del_fail); + + send(fd, buf, size, 0); +} + struct external_handler external_inject = { .init = external_inject_init, .close = external_inject_close, @@ -188,4 +271,14 @@ struct external_handler external_inject = { .stats = external_inject_ct_stats, .stats_ext = external_inject_ct_stats, }, + .exp = { + .new = external_inject_exp_new, + .upd = external_inject_exp_new, + .del = external_inject_exp_del, + .dump = external_inject_exp_dump, + .commit = external_inject_exp_commit, + .flush = external_inject_exp_flush, + .stats = external_inject_exp_stats, + .stats_ext = external_inject_exp_stats, + }, }; diff --git a/src/filter.c b/src/filter.c index 746a9bb..e8515d6 100644 --- a/src/filter.c +++ b/src/filter.c @@ -405,3 +405,79 @@ int ct_filter_conntrack(const struct nf_conntrack *ct, int userspace) return 0; } + +struct exp_filter { + struct list_head list; +}; + +struct exp_filter *exp_filter_create(void) +{ + struct exp_filter *f; + + f = calloc(1, sizeof(struct exp_filter)); + if (f == NULL) + return NULL; + + INIT_LIST_HEAD(&f->list); + return f; +} + +struct exp_filter_item { + struct list_head head; + char helper_name[NFCT_HELPER_NAME_MAX]; +}; + +/* this is ugly, but it simplifies read_config_yy.y */ +static struct exp_filter *exp_filter_alloc(void) +{ + if (STATE(exp_filter) == NULL) { + STATE(exp_filter) = exp_filter_create(); + if (STATE(exp_filter) == NULL) { + fprintf(stderr, "Can't init expectation filtering!\n"); + return NULL; + } + } + return STATE(exp_filter);; +} + +int exp_filter_add(struct exp_filter *f, const char *helper_name) +{ + struct exp_filter_item *item; + + f = exp_filter_alloc(); + if (f == NULL) + return -1; + + list_for_each_entry(item, &f->list, head) { + if (strncmp(item->helper_name, helper_name, + NFCT_HELPER_NAME_MAX) == 0) { + return -1; + } + } + item = calloc(1, sizeof(struct exp_filter_item)); + if (item == NULL) + return -1; + + strncpy(item->helper_name, helper_name, NFCT_HELPER_NAME_MAX); + list_add(&item->head, &f->list); + return 0; +} + +int exp_filter_find(struct exp_filter *f, const struct nf_expect *exp) +{ + struct exp_filter_item *item; + + if (f == NULL) + return 0; + + list_for_each_entry(item, &f->list, head) { + const char *name = nfexp_get_attr(exp, ATTR_EXP_HELPER_NAME); + + /* we allow partial matching to support things like sip-PORT. */ + if (strncmp(item->helper_name, name, + strlen(item->helper_name)) == 0) { + return 1; + } + } + return 0; +} diff --git a/src/internal_bypass.c b/src/internal_bypass.c index 98717f3..5c83c21 100644 --- a/src/internal_bypass.c +++ b/src/internal_bypass.c @@ -52,7 +52,7 @@ static void internal_bypass_ct_dump(int fd, int type) u_int32_t family = AF_UNSPEC; int ret; - h = nfct_open(CONNTRACK, 0); + h = nfct_open(CONFIG(netlink).subsys_id, 0); if (h == NULL) { dlog(LOG_ERR, "can't allocate memory for the internal cache"); return; @@ -151,6 +151,138 @@ static int internal_bypass_ct_event_del(struct nf_conntrack *ct, int origin) return 1; } +static int +internal_bypass_exp_dump_cb(enum nf_conntrack_msg_type type, + struct nf_expect *exp, void *data) +{ + char buf[1024]; + int size, *fd = data; + const struct nf_conntrack *master = + nfexp_get_attr(exp, ATTR_EXP_MASTER); + + if (!exp_filter_find(STATE(exp_filter), exp)) + return NFCT_CB_CONTINUE; + + if (ct_filter_conntrack(master, 1)) + return NFCT_CB_CONTINUE; + + size = nfexp_snprintf(buf, 1024, exp, + NFCT_T_UNKNOWN, NFCT_O_DEFAULT, 0); + if (size < 1024) { + buf[size] = '\n'; + size++; + } + send(*fd, buf, size, 0); + + return NFCT_CB_CONTINUE; +} + +static void internal_bypass_exp_dump(int fd, int type) +{ + struct nfct_handle *h; + u_int32_t family = AF_UNSPEC; + int ret; + + h = nfct_open(CONFIG(netlink).subsys_id, 0); + if (h == NULL) { + dlog(LOG_ERR, "can't allocate memory for the internal cache"); + return; + } + nfexp_callback_register(h, NFCT_T_ALL, + internal_bypass_exp_dump_cb, &fd); + ret = nfexp_query(h, NFCT_Q_DUMP, &family); + if (ret == -1) { + dlog(LOG_ERR, "can't dump kernel table"); + } + nfct_close(h); +} + +static void internal_bypass_exp_flush(void) +{ + nl_flush_expect_table(STATE(flush)); +} + +struct { + uint32_t new; + uint32_t upd; + uint32_t del; +} exp_internal_bypass_stats; + +static void internal_bypass_exp_stats(int fd) +{ + char buf[512]; + int size; + + size = sprintf(buf, "internal bypass:\n" + "connections new:\t\t%12u\n" + "connections updated:\t\t%12u\n" + "connections destroyed:\t\t%12u\n\n", + exp_internal_bypass_stats.new, + exp_internal_bypass_stats.upd, + exp_internal_bypass_stats.del); + + send(fd, buf, size, 0); +} + +/* unused, INTERNAL_F_POPULATE is unset. No cache, nothing to populate. */ +static void internal_bypass_exp_populate(struct nf_expect *exp) +{ +} + +/* unused, INTERNAL_F_RESYNC is unset. */ +static void internal_bypass_exp_purge(void) +{ +} + +/* unused, INTERNAL_F_RESYNC is unset. Nothing to resync, we have no cache. */ +static int +internal_bypass_exp_resync(enum nf_conntrack_msg_type type, + struct nf_expect *exp, void *data) +{ + return NFCT_CB_CONTINUE; +} + +static void internal_bypass_exp_event_new(struct nf_expect *exp, int origin) +{ + struct nethdr *net; + + /* this event has been triggered by me, skip */ + if (origin != CTD_ORIGIN_NOT_ME) + return; + + net = BUILD_NETMSG_FROM_EXP(exp, NET_T_STATE_EXP_NEW); + multichannel_send(STATE_SYNC(channel), net); + exp_internal_bypass_stats.new++; +} + +static void internal_bypass_exp_event_upd(struct nf_expect *exp, int origin) +{ + struct nethdr *net; + + /* this event has been triggered by me, skip */ + if (origin != CTD_ORIGIN_NOT_ME) + return; + + net = BUILD_NETMSG_FROM_EXP(exp, NET_T_STATE_EXP_UPD); + multichannel_send(STATE_SYNC(channel), net); + exp_internal_bypass_stats.upd++; +} + +static int internal_bypass_exp_event_del(struct nf_expect *exp, int origin) +{ + struct nethdr *net; + + /* this event has been triggered by me, skip */ + if (origin != CTD_ORIGIN_NOT_ME) + return 1; + + net = BUILD_NETMSG_FROM_EXP(exp, NET_T_STATE_EXP_DEL); + multichannel_send(STATE_SYNC(channel), net); + exp_internal_bypass_stats.del++; + + return 1; +} + struct internal_handler internal_bypass = { .init = internal_bypass_init, .close = internal_bypass_close, @@ -166,4 +298,16 @@ struct internal_handler internal_bypass = { .upd = internal_bypass_ct_event_upd, .del = internal_bypass_ct_event_del, }, + .exp = { + .dump = internal_bypass_exp_dump, + .flush = internal_bypass_exp_flush, + .stats = internal_bypass_exp_stats, + .stats_ext = internal_bypass_exp_stats, + .populate = internal_bypass_exp_populate, + .purge = internal_bypass_exp_purge, + .resync = internal_bypass_exp_resync, + .new = internal_bypass_exp_event_new, + .upd = internal_bypass_exp_event_upd, + .del = internal_bypass_exp_event_del, + }, }; diff --git a/src/internal_cache.c b/src/internal_cache.c index 952327d..ba2d74b 100644 --- a/src/internal_cache.c +++ b/src/internal_cache.c @@ -32,12 +32,25 @@ static int internal_cache_init(void) dlog(LOG_ERR, "can't allocate memory for the internal cache"); return -1; } + + STATE(mode)->internal->exp.data = + cache_create("internal", CACHE_T_EXP, + STATE_SYNC(sync)->internal_cache_flags, + STATE_SYNC(sync)->internal_cache_extra, + &cache_sync_internal_exp_ops); + + if (!STATE(mode)->internal->exp.data) { + dlog(LOG_ERR, "can't allocate memory for the internal cache"); + return -1; + } + return 0; } static void internal_cache_close(void) { cache_destroy(STATE(mode)->internal->ct.data); + cache_destroy(STATE(mode)->internal->exp.data); } static void internal_cache_ct_dump(int fd, int type) @@ -203,6 +216,154 @@ static int internal_cache_ct_event_del(struct nf_conntrack *ct, int origin) return 1; } +static void internal_cache_exp_dump(int fd, int type) +{ + cache_dump(STATE(mode)->internal->exp.data, fd, type); +} + +static void internal_cache_exp_flush(void) +{ + cache_flush(STATE(mode)->internal->exp.data); +} + +static void internal_cache_exp_stats(int fd) +{ + cache_stats(STATE(mode)->internal->exp.data, fd); +} + +static void internal_cache_exp_stats_ext(int fd) +{ + cache_stats_extended(STATE(mode)->internal->exp.data, fd); +} + +static void internal_cache_exp_populate(struct nf_expect *exp) +{ + cache_update_force(STATE(mode)->internal->exp.data, exp); +} + +static int internal_cache_exp_purge_step(void *data1, void *data2) +{ + struct cache_object *obj = data2; + + STATE(get_retval) = 0; + nl_get_expect(STATE(get), obj->ptr); /* modifies STATE(get_reval) */ + if (!STATE(get_retval)) { + if (obj->status != C_OBJ_DEAD) { + cache_object_set_status(obj, C_OBJ_DEAD); + sync_send(obj, NET_T_STATE_EXP_DEL); + cache_object_put(obj); + } + } + + return 0; +} + +static void internal_cache_exp_purge(void) +{ + cache_iterate(STATE(mode)->internal->exp.data, NULL, + internal_cache_exp_purge_step); +} + +static int +internal_cache_exp_resync(enum nf_conntrack_msg_type type, + struct nf_expect *exp, void *data) +{ + struct cache_object *obj; + const struct nf_conntrack *master = + nfexp_get_attr(exp, ATTR_EXP_MASTER); + + if (!exp_filter_find(STATE(exp_filter), exp)) + return NFCT_CB_CONTINUE; + + if (ct_filter_conntrack(master, 1)) + return NFCT_CB_CONTINUE; + + obj = cache_update_force(STATE(mode)->internal->exp.data, exp); + if (obj == NULL) + return NFCT_CB_CONTINUE; + + switch (obj->status) { + case C_OBJ_NEW: + sync_send(obj, NET_T_STATE_EXP_NEW); + break; + case C_OBJ_ALIVE: + sync_send(obj, NET_T_STATE_EXP_UPD); + break; + } + return NFCT_CB_CONTINUE; +} + +static void internal_cache_exp_event_new(struct nf_expect *exp, int origin) +{ + struct cache_object *obj; + int id; + + /* this event has been triggered by a direct inject, skip */ + if (origin == CTD_ORIGIN_INJECT) + return; + + obj = cache_find(STATE(mode)->internal->exp.data, exp, &id); + if (obj == NULL) { +retry: + obj = cache_object_new(STATE(mode)->internal->exp.data, exp); + if (obj == NULL) + return; + if (cache_add(STATE(mode)->internal->exp.data, obj, id) == -1) { + cache_object_free(obj); + return; + } + /* only synchronize events that have been triggered by other + * processes or the kernel, but don't propagate events that + * have been triggered by conntrackd itself, eg. commits. */ + if (origin == CTD_ORIGIN_NOT_ME) + sync_send(obj, NET_T_STATE_EXP_NEW); + } else { + cache_del(STATE(mode)->internal->exp.data, obj); + cache_object_free(obj); + goto retry; + } +} + +static void internal_cache_exp_event_upd(struct nf_expect *exp, int origin) +{ + struct cache_object *obj; + + /* this event has been triggered by a direct inject, skip */ + if (origin == CTD_ORIGIN_INJECT) + return; + + obj = cache_update_force(STATE(mode)->internal->exp.data, exp); + if (obj == NULL) + return; + + if (origin == CTD_ORIGIN_NOT_ME) + sync_send(obj, NET_T_STATE_EXP_UPD); +} + +static int internal_cache_exp_event_del(struct nf_expect *exp, int origin) +{ + struct cache_object *obj; + int id; + + /* this event has been triggered by a direct inject, skip */ + if (origin == CTD_ORIGIN_INJECT) + return 0; + + /* we don't synchronize events for objects that are not in the cache */ + obj = cache_find(STATE(mode)->internal->exp.data, exp, &id); + if (obj == NULL) + return 0; + + if (obj->status != C_OBJ_DEAD) { + cache_object_set_status(obj, C_OBJ_DEAD); + if (origin == CTD_ORIGIN_NOT_ME) { + sync_send(obj, NET_T_STATE_EXP_DEL); + } + cache_object_put(obj); + } + return 1; +} + struct internal_handler internal_cache = { .flags = INTERNAL_F_POPULATE | INTERNAL_F_RESYNC, .init = internal_cache_init, @@ -219,4 +380,16 @@ struct internal_handler internal_cache = { .upd = internal_cache_ct_event_upd, .del = internal_cache_ct_event_del, }, + .exp = { + .dump = internal_cache_exp_dump, + .flush = internal_cache_exp_flush, + .stats = internal_cache_exp_stats, + .stats_ext = internal_cache_exp_stats_ext, + .populate = internal_cache_exp_populate, + .purge = internal_cache_exp_purge, + .resync = internal_cache_exp_resync, + .new = internal_cache_exp_event_new, + .upd = internal_cache_exp_event_upd, + .del = internal_cache_exp_event_del, + }, }; diff --git a/src/log.c b/src/log.c index 9fe5119..d4de111 100644 --- a/src/log.c +++ b/src/log.c @@ -145,6 +145,43 @@ void dlog_ct(FILE *fd, struct nf_conntrack *ct, unsigned int type) } } +void dlog_exp(FILE *fd, struct nf_expect *exp, unsigned int type) +{ + time_t t; + char buf[1024]; + char *tmp; + unsigned int flags = 0; + + buf[0]='\0'; + + switch(type) { + case NFCT_O_PLAIN: + t = time(NULL); + ctime_r(&t, buf); + tmp = buf + strlen(buf); + buf[strlen(buf)-1]='\t'; + break; + default: + return; + } + nfexp_snprintf(buf+strlen(buf), 1024-strlen(buf), exp, 0, type, flags); + + if (fd) { + snprintf(buf+strlen(buf), 1024-strlen(buf), "\n"); + fputs(buf, fd); + } + + if (fd == STATE(log)) { + /* error reporting */ + if (CONFIG(syslog_facility) != -1) + syslog(LOG_ERR, "%s", tmp); + } else if (fd == STATE(stats_log)) { + /* connection logging */ + if (CONFIG(stats).syslog_facility != -1) + syslog(LOG_INFO, "%s", tmp); + } +} + void close_log(void) { if (STATE(log) != NULL) diff --git a/src/main.c b/src/main.c index ebfc8b9..342ed45 100644 --- a/src/main.c +++ b/src/main.c @@ -1,5 +1,6 @@ /* - * (C) 2006-2007 by Pablo Neira Ayuso + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,14 +39,15 @@ static const char usage_daemon_commands[] = static const char usage_client_commands[] = "Client mode commands:\n" - " -c, commit external cache to conntrack table\n" + " -c [ct|expect], commit external cache to conntrack table\n" " -f [|internal|external], flush internal and external cache\n" - " -F, flush kernel conntrack table\n" - " -i, display content of the internal cache\n" - " -e, display the content of the external cache\n" + " -F [ct|expect], flush kernel conntrack table\n" + " -i [ct|expect], display content of the internal cache\n" + " -e [ct|expect], display the content of the external cache\n" " -k, kill conntrack daemon\n" - " -s [|network|cache|runtime|link|rsqueue|queue], dump statistics\n" - " -R, resync with kernel conntrack table\n" + " -s [|network|cache|runtime|link|rsqueue|queue|ct|expect], " + "dump statistics\n" + " -R [ct|expect], resync with kernel conntrack table\n" " -n, request resync with other node (only FT-FW and NOTRACK modes)\n" " -x, dump cache in XML format (requires -i or -e)\n" " -t, reset the kernel timeout (see PurgeTimeout clause)\n" @@ -89,6 +91,25 @@ set_operation_mode(int *current, int want, char *argv[]) } } +static int +set_action_by_table(int i, int argc, char *argv[], + int ct_action, int exp_action, int dfl_action, int *action) +{ + if (i+1 < argc && argv[i+1][0] != '-') { + if (strncmp(argv[i+1], "ct", strlen(argv[i+1])) == 0) { + *action = ct_action; + i++; + } else if (strncmp(argv[i+1], "expect", + strlen(argv[i+1])) == 0) { + *action = exp_action; + i++; + } + } else + *action = dfl_action; + + return i; +} + int main(int argc, char *argv[]) { int ret, i, action = -1; @@ -115,15 +136,23 @@ int main(int argc, char *argv[]) break; case 'c': set_operation_mode(&type, REQUEST, argv); - action = CT_COMMIT; + i = set_action_by_table(i, argc, argv, + CT_COMMIT, EXP_COMMIT, + ALL_COMMIT, &action); break; case 'i': set_operation_mode(&type, REQUEST, argv); - action = CT_DUMP_INTERNAL; + i = set_action_by_table(i, argc, argv, + CT_DUMP_INTERNAL, + EXP_DUMP_INTERNAL, + CT_DUMP_INTERNAL, &action); break; case 'e': set_operation_mode(&type, REQUEST, argv); - action = CT_DUMP_EXTERNAL; + i = set_action_by_table(i, argc, argv, + CT_DUMP_EXTERNAL, + EXP_DUMP_EXTERNAL, + CT_DUMP_EXTERNAL, &action); break; case 'C': if (++i < argc) { @@ -142,7 +171,10 @@ int main(int argc, char *argv[]) break; case 'F': set_operation_mode(&type, REQUEST, argv); - action = CT_FLUSH_MASTER; + i = set_action_by_table(i, argc, argv, + CT_FLUSH_MASTER, + EXP_FLUSH_MASTER, + ALL_FLUSH_MASTER, &action); break; case 'f': set_operation_mode(&type, REQUEST, argv); @@ -164,12 +196,15 @@ int main(int argc, char *argv[]) } } else { /* default to general flushing */ - action = CT_FLUSH_CACHE; + action = ALL_FLUSH_CACHE; } break; case 'R': set_operation_mode(&type, REQUEST, argv); - action = CT_RESYNC_MASTER; + i = set_action_by_table(i, argc, argv, + CT_RESYNC_MASTER, + EXP_RESYNC_MASTER, + ALL_RESYNC_MASTER, &action); break; case 'B': set_operation_mode(&type, REQUEST, argv); @@ -222,6 +257,14 @@ int main(int argc, char *argv[]) strlen(argv[i+1])) == 0) { action = STATS_QUEUE; i++; + } else if (strncmp(argv[i+1], "ct", + strlen(argv[i+1])) == 0) { + action = STATS; + i++; + } else if (strncmp(argv[i+1], "expect", + strlen(argv[i+1])) == 0) { + action = EXP_STATS; + i++; } else { fprintf(stderr, "ERROR: unknown " "parameter `%s' for " diff --git a/src/netlink.c b/src/netlink.c index 60274f3..fe979e3 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1,5 +1,6 @@ /* - * (C) 2006 by Pablo Neira Ayuso + * (C) 2006-2011 by Pablo Neira Ayuso + * (C) 2011 by Vyatta Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,7 +33,7 @@ struct nfct_handle *nl_init_event_handler(void) { struct nfct_handle *h; - h = nfct_open(CONNTRACK, NFCT_ALL_CT_GROUPS); + h = nfct_open(CONFIG(netlink).subsys_id, CONFIG(netlink).groups); if (h == NULL) return NULL; @@ -301,3 +302,61 @@ int nl_destroy_conntrack(struct nfct_handle *h, const struct nf_conntrack *ct) { return nfct_query(h, NFCT_Q_DESTROY, ct); } + +int nl_create_expect(struct nfct_handle *h, const struct nf_expect *orig, + int timeout) +{ + int ret; + struct nf_expect *exp; + + exp = nfexp_clone(orig); + if (exp == NULL) + return -1; + + if (timeout > 0) + nfexp_set_attr_u32(exp, ATTR_EXP_TIMEOUT, timeout); + + ret = nfexp_query(h, NFCT_Q_CREATE, exp); + nfexp_destroy(exp); + + return ret; +} + +int nl_destroy_expect(struct nfct_handle *h, const struct nf_expect *exp) +{ + return nfexp_query(h, NFCT_Q_DESTROY, exp); +} + +/* if the handle has no callback, check for existence, otherwise, update */ +int nl_get_expect(struct nfct_handle *h, const struct nf_expect *exp) +{ + int ret = 1; + struct nf_expect *tmp; + + /* XXX: we only need the expectation, not the mask and the master. */ + tmp = nfexp_clone(exp); + if (tmp == NULL) + return -1; + + if (nfexp_query(h, NFCT_Q_GET, tmp) == -1) + ret = (errno == ENOENT) ? 0 : -1; + + nfexp_destroy(tmp); + return ret; +} + +int nl_dump_expect_table(struct nfct_handle *h) +{ + return nfexp_query(h, NFCT_Q_DUMP, &CONFIG(family)); +} + +int nl_flush_expect_table(struct nfct_handle *h) +{ + return nfexp_query(h, NFCT_Q_FLUSH, &CONFIG(family)); +} + +int nl_send_expect_resync(struct nfct_handle *h) +{ + int family = CONFIG(family); + return nfexp_send(h, NFCT_Q_DUMP, &family); +} diff --git a/src/network.c b/src/network.c index cadc466..13db37c 100644 --- a/src/network.c +++ b/src/network.c @@ -126,6 +126,11 @@ static int status2type[CACHE_T_MAX][C_OBJ_MAX] = { [C_OBJ_ALIVE] = NET_T_STATE_CT_UPD, [C_OBJ_DEAD] = NET_T_STATE_CT_DEL, }, + [CACHE_T_EXP] = { + [C_OBJ_NEW] = NET_T_STATE_EXP_NEW, + [C_OBJ_ALIVE] = NET_T_STATE_EXP_UPD, + [C_OBJ_DEAD] = NET_T_STATE_EXP_DEL, + }, }; int object_status_to_network_type(struct cache_object *obj) diff --git a/src/parse.c b/src/parse.c index 0718128..81e9c6b 100644 --- a/src/parse.c +++ b/src/parse.c @@ -248,3 +248,195 @@ int msg2ct(struct nf_conntrack *ct, struct nethdr *net, size_t remain) return 0; } + +static void exp_parse_ct_group(void *ct, int attr, void *data); +static void exp_parse_ct_u8(void *ct, int attr, void *data); +static void exp_parse_u32(void *exp, int attr, void *data); + +static struct exp_parser { + void (*parse)(void *obj, int attr, void *data); + int exp_attr; + int ct_attr; + int size; +} exp_h[NTA_EXP_MAX] = { + [NTA_EXP_MASTER_IPV4] = { + .parse = exp_parse_ct_group, + .exp_attr = ATTR_EXP_MASTER, + .ct_attr = ATTR_GRP_ORIG_IPV4, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv4)), + }, + [NTA_EXP_MASTER_IPV6] = { + .parse = exp_parse_ct_group, + .exp_attr = ATTR_EXP_MASTER, + .ct_attr = ATTR_GRP_ORIG_IPV6, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv6)), + }, + [NTA_EXP_MASTER_L4PROTO] = { + .parse = exp_parse_ct_u8, + .exp_attr = ATTR_EXP_MASTER, + .ct_attr = ATTR_L4PROTO, + .size = NTA_SIZE(sizeof(uint8_t)), + }, + [NTA_EXP_MASTER_PORT] = { + .parse = exp_parse_ct_group, + .exp_attr = ATTR_EXP_MASTER, + .ct_attr = ATTR_GRP_ORIG_PORT, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_port)), + }, + [NTA_EXP_EXPECT_IPV4] = { + .parse = exp_parse_ct_group, + .exp_attr = ATTR_EXP_EXPECTED, + .ct_attr = ATTR_GRP_ORIG_IPV4, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv4)), + }, + [NTA_EXP_EXPECT_IPV6] = { + .parse = exp_parse_ct_group, + .exp_attr = ATTR_EXP_EXPECTED, + .ct_attr = ATTR_GRP_ORIG_IPV6, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv6)), + }, + [NTA_EXP_EXPECT_L4PROTO] = { + .parse = exp_parse_ct_u8, + .exp_attr = ATTR_EXP_EXPECTED, + .ct_attr = ATTR_L4PROTO, + .size = NTA_SIZE(sizeof(uint8_t)), + }, + [NTA_EXP_EXPECT_PORT] = { + .parse = exp_parse_ct_group, + .exp_attr = ATTR_EXP_EXPECTED, + .ct_attr = ATTR_GRP_ORIG_PORT, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_port)), + }, + [NTA_EXP_MASK_IPV4] = { + .parse = exp_parse_ct_group, + .exp_attr = ATTR_EXP_MASK, + .ct_attr = ATTR_GRP_ORIG_IPV4, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv4)), + }, + [NTA_EXP_MASK_IPV6] = { + .parse = exp_parse_ct_group, + .exp_attr = ATTR_EXP_MASK, + .ct_attr = ATTR_GRP_ORIG_IPV6, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv6)), + }, + [NTA_EXP_MASK_L4PROTO] = { + .parse = exp_parse_ct_u8, + .exp_attr = ATTR_EXP_MASK, + .ct_attr = ATTR_L4PROTO, + .size = NTA_SIZE(sizeof(uint8_t)), + }, + [NTA_EXP_MASK_PORT] = { + .parse = exp_parse_ct_group, + .exp_attr = ATTR_EXP_MASK, + .ct_attr = ATTR_GRP_ORIG_PORT, + .size = NTA_SIZE(sizeof(struct nfct_attr_grp_port)), + }, + [NTA_EXP_TIMEOUT] = { + .parse = exp_parse_u32, + .exp_attr = ATTR_EXP_TIMEOUT, + .size = NTA_SIZE(sizeof(uint32_t)), + }, + [NTA_EXP_FLAGS] = { + .parse = exp_parse_u32, + .exp_attr = ATTR_EXP_FLAGS, + .size = NTA_SIZE(sizeof(uint32_t)), + }, +}; + +static void exp_parse_ct_group(void *ct, int attr, void *data) +{ + nfct_set_attr_grp(ct, exp_h[attr].ct_attr, data); +} + +static void exp_parse_ct_u8(void *ct, int attr, void *data) +{ + uint8_t *value = (uint8_t *) data; + nfct_set_attr_u8(ct, exp_h[attr].ct_attr, *value); +} + +static void exp_parse_u32(void *exp, int attr, void *data) +{ + uint32_t *value = (uint32_t *) data; + nfexp_set_attr_u32(exp, exp_h[attr].exp_attr, ntohl(*value)); +} + +int msg2exp(struct nf_expect *exp, struct nethdr *net, size_t remain) +{ + int len; + struct netattr *attr; + struct nf_conntrack *master, *expected, *mask; + + if (remain < net->len) + return -1; + + len = net->len - NETHDR_SIZ; + attr = NETHDR_DATA(net); + + master = nfct_new(); + if (master == NULL) + goto err_master; + + expected = nfct_new(); + if (expected == NULL) + goto err_expected; + + mask = nfct_new(); + if (mask == NULL) + goto err_mask; + + while (len > ssizeof(struct netattr)) { + ATTR_NETWORK2HOST(attr); + if (attr->nta_len > len) + goto err; + if (attr->nta_attr > NTA_MAX) + goto err; + if (attr->nta_len != exp_h[attr->nta_attr].size) + goto err; + if (exp_h[attr->nta_attr].parse == NULL) { + attr = NTA_NEXT(attr, len); + continue; + } + switch(exp_h[attr->nta_attr].exp_attr) { + case ATTR_EXP_MASTER: + exp_h[attr->nta_attr].parse(master, attr->nta_attr, + NTA_DATA(attr)); + case ATTR_EXP_EXPECTED: + exp_h[attr->nta_attr].parse(expected, attr->nta_attr, + NTA_DATA(attr)); + case ATTR_EXP_MASK: + exp_h[attr->nta_attr].parse(mask, attr->nta_attr, + NTA_DATA(attr)); + break; + case ATTR_EXP_TIMEOUT: + case ATTR_EXP_FLAGS: + exp_h[attr->nta_attr].parse(exp, attr->nta_attr, + NTA_DATA(attr)); + break; + } + attr = NTA_NEXT(attr, len); + } + + nfexp_set_attr(exp, ATTR_EXP_MASTER, master); + nfexp_set_attr(exp, ATTR_EXP_EXPECTED, expected); + nfexp_set_attr(exp, ATTR_EXP_MASK, mask); + + /* We can release the conntrack objects at this point because the + * setter makes a copy of them. This is not efficient, it would be + * better to save that extra copy but this is how the library works. + * I'm sorry, I cannot change it without breaking backward + * compatibility. Probably it is a good idea to think of adding new + * interfaces in the near future to get it better. */ + nfct_destroy(mask); + nfct_destroy(expected); + nfct_destroy(master); + + return 0; +err: + nfct_destroy(mask); +err_mask: + nfct_destroy(expected); +err_expected: + nfct_destroy(master); +err_master: + return -1; +} diff --git a/src/read_config_lex.l b/src/read_config_lex.l index be6bf8b..01fe4fc 100644 --- a/src/read_config_lex.l +++ b/src/read_config_lex.l @@ -140,6 +140,7 @@ notrack [N|n][O|o][T|t][R|r][A|a][C|c][K|k] "DisableExternalCache" { return T_DISABLE_EXTERNAL_CACHE; } "Options" { return T_OPTIONS; } "TCPWindowTracking" { return T_TCP_WINDOW_TRACKING; } +"ExpectationSync" { return T_EXPECT_SYNC; } "ErrorQueueLength" { return T_ERROR_QUEUE_LENGTH; } {is_on} { return T_ON; } diff --git a/src/read_config_yy.y b/src/read_config_yy.y index 68a83f7..b22784c 100644 --- a/src/read_config_yy.y +++ b/src/read_config_yy.y @@ -73,7 +73,7 @@ static void __max_dedicated_links_reached(void); %token T_NETLINK_OVERRUN_RESYNC T_NICE T_IPV4_DEST_ADDR T_IPV6_DEST_ADDR %token T_SCHEDULER T_TYPE T_PRIO T_NETLINK_EVENTS_RELIABLE %token T_DISABLE_INTERNAL_CACHE T_DISABLE_EXTERNAL_CACHE T_ERROR_QUEUE_LENGTH -%token T_OPTIONS T_TCP_WINDOW_TRACKING +%token T_OPTIONS T_TCP_WINDOW_TRACKING T_EXPECT_SYNC %token T_IP T_PATH_VAL %token T_NUMBER @@ -828,6 +828,46 @@ option: T_TCP_WINDOW_TRACKING T_OFF CONFIG(sync).tcp_window_tracking = 0; }; +option: T_EXPECT_SYNC T_ON +{ + CONFIG(flags) |= CTD_EXPECT; + CONFIG(netlink).subsys_id = NFNL_SUBSYS_NONE; + CONFIG(netlink).groups = NF_NETLINK_CONNTRACK_NEW | + NF_NETLINK_CONNTRACK_UPDATE | + NF_NETLINK_CONNTRACK_DESTROY | + NF_NETLINK_CONNTRACK_EXP_NEW | + NF_NETLINK_CONNTRACK_EXP_UPDATE | + NF_NETLINK_CONNTRACK_EXP_DESTROY; +}; + +option: T_EXPECT_SYNC T_OFF +{ + CONFIG(netlink).subsys_id = NFNL_SUBSYS_CTNETLINK; + CONFIG(netlink).groups = NF_NETLINK_CONNTRACK_NEW | + NF_NETLINK_CONNTRACK_UPDATE | + NF_NETLINK_CONNTRACK_DESTROY; +}; + +option: T_EXPECT_SYNC '{' expect_list '}' +{ + CONFIG(flags) |= CTD_EXPECT; + CONFIG(netlink).subsys_id = NFNL_SUBSYS_NONE; + CONFIG(netlink).groups = NF_NETLINK_CONNTRACK_NEW | + NF_NETLINK_CONNTRACK_UPDATE | + NF_NETLINK_CONNTRACK_DESTROY | + NF_NETLINK_CONNTRACK_EXP_NEW | + NF_NETLINK_CONNTRACK_EXP_UPDATE | + NF_NETLINK_CONNTRACK_EXP_DESTROY; +}; + +expect_list: + | expect_list expect_item ; + +expect_item: T_STRING +{ + exp_filter_add(STATE(exp_filter), $1); +} + sync_mode_alarm: T_SYNC_MODE T_ALARM '{' sync_mode_alarm_list '}' { conf.flags |= CTD_SYNC_ALARM; @@ -1598,6 +1638,7 @@ init_config(char *filename) /* Zero may be a valid facility */ CONFIG(syslog_facility) = -1; CONFIG(stats).syslog_facility = -1; + CONFIG(netlink).subsys_id = -1; yyrestart(fp); yyparse(); @@ -1646,5 +1687,12 @@ init_config(char *filename) if (CONFIG(channelc).error_queue_length == 0) CONFIG(channelc).error_queue_length = 128; + if (CONFIG(netlink).subsys_id == -1) { + CONFIG(netlink).subsys_id = NFNL_SUBSYS_CTNETLINK; + CONFIG(netlink).groups = NF_NETLINK_CONNTRACK_NEW | + NF_NETLINK_CONNTRACK_UPDATE | + NF_NETLINK_CONNTRACK_DESTROY; + } + return 0; } diff --git a/src/run.c b/src/run.c index c21db2e..26c1783 100644 --- a/src/run.c +++ b/src/run.c @@ -187,6 +187,62 @@ static void dump_stats_runtime(int fd) send(fd, buf, size, 0); } +static void local_flush_master(void) +{ + STATE(stats).nl_kernel_table_flush++; + dlog(LOG_NOTICE, "flushing kernel conntrack table"); + + /* fork a child process that performs the flush operation, + * meanwhile the parent process handles events. */ + if (fork_process_new(CTD_PROC_FLUSH, CTD_PROC_F_EXCL, + NULL, NULL) == 0) { + nl_flush_conntrack_table(STATE(flush)); + exit(EXIT_SUCCESS); + } +} + +static void local_resync_master(void) +{ + if (STATE(mode)->internal->flags & INTERNAL_F_POPULATE) { + STATE(stats).nl_kernel_table_resync++; + dlog(LOG_NOTICE, "resync with master conntrack table"); + nl_dump_conntrack_table(STATE(dump)); + } else { + dlog(LOG_NOTICE, "resync is unsupported in this mode"); + } +} + +static void local_exp_flush_master(void) +{ + if (!(CONFIG(flags) & CTD_EXPECT)) + return; + + STATE(stats).nl_kernel_table_flush++; + dlog(LOG_NOTICE, "flushing kernel expect table"); + + /* fork a child process that performs the flush operation, + * meanwhile the parent process handles events. */ + if (fork_process_new(CTD_PROC_FLUSH, CTD_PROC_F_EXCL, + NULL, NULL) == 0) { + nl_flush_expect_table(STATE(flush)); + exit(EXIT_SUCCESS); + } +} + +static void local_exp_resync_master(void) +{ + if (!(CONFIG(flags) & CTD_EXPECT)) + return; + + if (STATE(mode)->internal->flags & INTERNAL_F_POPULATE) { + STATE(stats).nl_kernel_table_resync++; + dlog(LOG_NOTICE, "resync with master expect table"); + nl_dump_expect_table(STATE(dump)); + } else { + dlog(LOG_NOTICE, "resync is unsupported in this mode"); + } +} + static int local_handler(int fd, void *data) { int ret = LOCAL_RET_OK; @@ -198,25 +254,24 @@ static int local_handler(int fd, void *data) } switch(type) { case CT_FLUSH_MASTER: - STATE(stats).nl_kernel_table_flush++; - dlog(LOG_NOTICE, "flushing kernel conntrack table"); - - /* fork a child process that performs the flush operation, - * meanwhile the parent process handles events. */ - if (fork_process_new(CTD_PROC_FLUSH, CTD_PROC_F_EXCL, - NULL, NULL) == 0) { - nl_flush_conntrack_table(STATE(flush)); - exit(EXIT_SUCCESS); - } + local_flush_master(); break; case CT_RESYNC_MASTER: - if (STATE(mode)->internal->flags & INTERNAL_F_POPULATE) { - STATE(stats).nl_kernel_table_resync++; - dlog(LOG_NOTICE, "resync with master table"); - nl_dump_conntrack_table(STATE(dump)); - } else { - dlog(LOG_NOTICE, "resync is unsupported in this mode"); - } + local_resync_master(); + break; + case EXP_FLUSH_MASTER: + local_exp_flush_master(); + break; + case EXP_RESYNC_MASTER: + local_exp_resync_master(); + break; + case ALL_FLUSH_MASTER: + local_flush_master(); + local_exp_flush_master(); + break; + case ALL_RESYNC_MASTER: + local_resync_master(); + local_exp_resync_master(); break; case STATS_RUNTIME: dump_stats_runtime(fd); @@ -245,7 +300,11 @@ static void do_polling_alarm(struct alarm_block *a, void *data) if (STATE(mode)->internal->ct.purge) STATE(mode)->internal->ct.purge(); + if (STATE(mode)->internal->exp.purge) + STATE(mode)->internal->exp.purge(); + nl_send_resync(STATE(resync)); + nl_send_expect_resync(STATE(resync)); add_alarm(&STATE(polling_alarm), CONFIG(poll_kernel_secs), 0); } @@ -290,6 +349,49 @@ out: return NFCT_CB_CONTINUE; } +static int exp_event_handler(const struct nlmsghdr *nlh, + enum nf_conntrack_msg_type type, + struct nf_expect *exp, + void *data) +{ + int origin_type; + const struct nf_conntrack *master = + nfexp_get_attr(exp, ATTR_EXP_MASTER); + + STATE(stats).nl_events_received++; + + if (!exp_filter_find(STATE(exp_filter), exp)) { + STATE(stats).nl_events_filtered++; + goto out; + } + if (ct_filter_conntrack(master, 1)) + return NFCT_CB_CONTINUE; + + origin_type = origin_find(nlh); + + switch(type) { + case NFCT_T_NEW: + STATE(mode)->internal->exp.new(exp, origin_type); + break; + case NFCT_T_UPDATE: + STATE(mode)->internal->exp.upd(exp, origin_type); + break; + case NFCT_T_DESTROY: + STATE(mode)->internal->exp.del(exp, origin_type); + break; + default: + STATE(stats).nl_events_unknown_type++; + break; + } + +out: + /* we reset the iteration limiter in the main select loop. */ + if (STATE(event_iterations_limit)-- <= 0) + return NFCT_CB_STOP; + else + return NFCT_CB_CONTINUE; +} + static int dump_handler(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) @@ -308,6 +410,29 @@ static int dump_handler(enum nf_conntrack_msg_type type, return NFCT_CB_CONTINUE; } +static int exp_dump_handler(enum nf_conntrack_msg_type type, + struct nf_expect *exp, void *data) +{ + const struct nf_conntrack *master = + nfexp_get_attr(exp, ATTR_EXP_MASTER); + + if (!exp_filter_find(STATE(exp_filter), exp)) + return NFCT_CB_CONTINUE; + + if (ct_filter_conntrack(master, 1)) + return NFCT_CB_CONTINUE; + + switch(type) { + case NFCT_T_UPDATE: + STATE(mode)->internal->exp.populate(exp); + break; + default: + STATE(stats).nl_dump_unknown_type++; + break; + } + return NFCT_CB_CONTINUE; +} + static int get_handler(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data) @@ -319,6 +444,22 @@ static int get_handler(enum nf_conntrack_msg_type type, return NFCT_CB_CONTINUE; } +static int exp_get_handler(enum nf_conntrack_msg_type type, + struct nf_expect *exp, void *data) +{ + const struct nf_conntrack *master = + nfexp_get_attr(exp, ATTR_EXP_MASTER); + + if (!exp_filter_find(STATE(exp_filter), exp)) + return NFCT_CB_CONTINUE; + + if (ct_filter_conntrack(master, 1)) + return NFCT_CB_CONTINUE; + + STATE(get_retval) = 1; + return NFCT_CB_CONTINUE; +} + int init(void) { @@ -355,7 +496,7 @@ init(void) register_fd(STATE(local).fd, STATE(fds)); /* resynchronize (like 'dump' socket) but it also purges old entries */ - STATE(resync) = nfct_open(CONNTRACK, 0); + STATE(resync) = nfct_open(CONFIG(netlink).subsys_id, 0); if (STATE(resync)== NULL) { dlog(LOG_ERR, "can't open netlink handler: %s", strerror(errno)); @@ -370,7 +511,7 @@ init(void) fcntl(nfct_fd(STATE(resync)), F_SETFL, O_NONBLOCK); if (STATE(mode)->internal->flags & INTERNAL_F_POPULATE) { - STATE(dump) = nfct_open(CONNTRACK, 0); + STATE(dump) = nfct_open(CONFIG(netlink).subsys_id, 0); if (STATE(dump) == NULL) { dlog(LOG_ERR, "can't open netlink handler: %s", strerror(errno)); @@ -380,13 +521,26 @@ init(void) nfct_callback_register(STATE(dump), NFCT_T_ALL, dump_handler, NULL); + if (CONFIG(flags) & CTD_EXPECT) { + nfexp_callback_register(STATE(dump), NFCT_T_ALL, + exp_dump_handler, NULL); + } + if (nl_dump_conntrack_table(STATE(dump)) == -1) { dlog(LOG_ERR, "can't get kernel conntrack table"); return -1; } + + if (CONFIG(flags) & CTD_EXPECT) { + if (nl_dump_expect_table(STATE(dump)) == -1) { + dlog(LOG_ERR, "can't get kernel " + "expect table"); + return -1; + } + } } - STATE(get) = nfct_open(CONNTRACK, 0); + STATE(get) = nfct_open(CONFIG(netlink).subsys_id, 0); if (STATE(get) == NULL) { dlog(LOG_ERR, "can't open netlink handler: %s", strerror(errno)); @@ -395,7 +549,12 @@ init(void) } nfct_callback_register(STATE(get), NFCT_T_ALL, get_handler, NULL); - STATE(flush) = nfct_open(CONNTRACK, 0); + if (CONFIG(flags) & CTD_EXPECT) { + nfexp_callback_register(STATE(get), NFCT_T_ALL, + exp_get_handler, NULL); + } + + STATE(flush) = nfct_open(CONFIG(netlink).subsys_id, 0); if (STATE(flush) == NULL) { dlog(LOG_ERR, "cannot open flusher handler"); return -1; @@ -426,6 +585,11 @@ init(void) } nfct_callback_register2(STATE(event), NFCT_T_ALL, event_handler, NULL); + + if (CONFIG(flags) & CTD_EXPECT) { + nfexp_callback_register2(STATE(event), NFCT_T_ALL, + exp_event_handler, NULL); + } register_fd(nfct_fd(STATE(event)), STATE(fds)); } diff --git a/src/sync-ftfw.c b/src/sync-ftfw.c index fa76c0c..1bc2d9f 100644 --- a/src/sync-ftfw.c +++ b/src/sync-ftfw.c @@ -231,6 +231,8 @@ static int ftfw_local(int fd, int type, void *data) dlog(LOG_NOTICE, "sending bulk update"); cache_iterate(STATE(mode)->internal->ct.data, NULL, do_cache_to_tx); + cache_iterate(STATE(mode)->internal->exp.data, + NULL, do_cache_to_tx); break; case STATS_RSQUEUE: ftfw_local_queue(fd); @@ -350,7 +352,10 @@ static int digest_msg(const struct nethdr *net) } else if (IS_RESYNC(net)) { dp("RESYNC ALL\n"); - cache_iterate(STATE(mode)->internal->ct.data, NULL, do_cache_to_tx); + cache_iterate(STATE(mode)->internal->ct.data, NULL, + do_cache_to_tx); + cache_iterate(STATE(mode)->internal->exp.data, NULL, + do_cache_to_tx); return MSG_CTL; } else if (IS_ALIVE(net)) diff --git a/src/sync-mode.c b/src/sync-mode.c index fa522c7..2505631 100644 --- a/src/sync-mode.c +++ b/src/sync-mode.c @@ -59,10 +59,29 @@ static struct nf_conntrack *msg2ct_alloc(struct nethdr *net, size_t remain) return ct; } +static struct nf_expect *msg2exp_alloc(struct nethdr *net, size_t remain) +{ + struct nf_expect *exp; + + /* TODO: add stats on ENOMEM errors in the future. */ + exp = nfexp_new(); + if (exp == NULL) + return NULL; + + if (msg2exp(exp, net, remain) == -1) { + STATE_SYNC(error).msg_rcv_malformed++; + STATE_SYNC(error).msg_rcv_bad_payload++; + nfexp_destroy(exp); + return NULL; + } + return exp; +} + static void do_channel_handler_step(int i, struct nethdr *net, size_t remain) { - struct nf_conntrack *ct; + struct nf_conntrack *ct = NULL; + struct nf_expect *exp = NULL; if (net->version != CONNTRACKD_PROTOCOL_VERSION) { STATE_SYNC(error).msg_rcv_malformed++; @@ -112,12 +131,33 @@ do_channel_handler_step(int i, struct nethdr *net, size_t remain) return; STATE_SYNC(external)->ct.del(ct); break; + case NET_T_STATE_EXP_NEW: + exp = msg2exp_alloc(net, remain); + if (exp == NULL) + return; + STATE_SYNC(external)->exp.new(exp); + break; + case NET_T_STATE_EXP_UPD: + exp = msg2exp_alloc(net, remain); + if (exp == NULL) + return; + STATE_SYNC(external)->exp.upd(exp); + break; + case NET_T_STATE_EXP_DEL: + exp = msg2exp_alloc(net, remain); + if (exp == NULL) + return; + STATE_SYNC(external)->exp.del(exp); + break; default: STATE_SYNC(error).msg_rcv_malformed++; STATE_SYNC(error).msg_rcv_bad_type++; break; } - nfct_destroy(ct); + if (ct != NULL) + nfct_destroy(ct); + if (exp != NULL) + nfexp_destroy(exp); } static char __net[65536]; /* XXX: maximum MTU for IPv4 */ @@ -351,7 +391,7 @@ static int init_sync(void) STATE(fds)) == -1) return -1; - STATE_SYNC(commit).h = nfct_open(CONNTRACK, 0); + STATE_SYNC(commit).h = nfct_open(CONFIG(netlink).subsys_id, 0); if (STATE_SYNC(commit).h == NULL) { dlog(LOG_ERR, "can't create handler to commit"); return -1; @@ -402,8 +442,30 @@ static void run_sync(fd_set *readfds) interface_handler(); if (FD_ISSET(get_read_evfd(STATE_SYNC(commit).evfd), readfds)) { + int ret; + read_evfd(STATE_SYNC(commit).evfd); - STATE_SYNC(external)->ct.commit(STATE_SYNC(commit).h, 0); + + ret = STATE_SYNC(commit).rq[0].cb(STATE_SYNC(commit).h, 0); + if (ret == 0) { + /* we still have things in the callback queue. */ + if (STATE_SYNC(commit).rq[1].cb) { + int fd = STATE_SYNC(commit).clientfd; + + STATE_SYNC(commit).rq[0].cb = + STATE_SYNC(commit).rq[1].cb; + + STATE_SYNC(commit).rq[1].cb = NULL; + + STATE_SYNC(commit).clientfd = -1; + STATE_SYNC(commit).rq[0].cb( + STATE_SYNC(commit).h, fd); + } else { + /* Close the client socket now, we're done. */ + close(STATE_SYNC(commit).clientfd); + STATE_SYNC(commit).clientfd = -1; + } + } } /* flush pending messages */ @@ -480,6 +542,27 @@ static void dump_stats_sync_extended(int fd) send(fd, buf, size, 0); } +static int local_commit(int fd) +{ + int ret; + + /* delete the reset alarm if any before committing */ + del_alarm(&STATE_SYNC(reset_cache_alarm)); + + ret = STATE_SYNC(commit).rq[0].cb(STATE_SYNC(commit).h, fd); + if (ret == -1) { + dlog(LOG_NOTICE, "commit already in progress, skipping"); + ret = LOCAL_RET_OK; + } else if (ret == 0) { + /* we've finished the commit. */ + ret = LOCAL_RET_OK; + } else { + /* Keep open the client, we want synchronous commit. */ + ret = LOCAL_RET_STOLEN; + } + return ret; +} + /* handler for requests coming via UNIX socket */ static int local_handler_sync(int fd, int type, void *data) { @@ -511,19 +594,10 @@ static int local_handler_sync(int fd, int type, void *data) } break; case CT_COMMIT: - /* delete the reset alarm if any before committing */ - del_alarm(&STATE_SYNC(reset_cache_alarm)); - - dlog(LOG_NOTICE, "committing external cache"); - ret = STATE_SYNC(external)->ct.commit(STATE_SYNC(commit).h, fd); - if (ret == 0) { - dlog(LOG_NOTICE, "commit already in progress, " - "skipping"); - ret = LOCAL_RET_OK; - } else { - /* Keep open the client, we want synchronous commit. */ - ret = LOCAL_RET_STOLEN; - } + dlog(LOG_NOTICE, "committing conntrack cache"); + STATE_SYNC(commit).rq[0].cb = STATE_SYNC(external)->ct.commit; + STATE_SYNC(commit).rq[1].cb = NULL; + ret = local_commit(fd); break; case RESET_TIMERS: if (!alarm_pending(&STATE_SYNC(reset_cache_alarm))) { @@ -575,6 +649,63 @@ static int local_handler_sync(int fd, int type, void *data) case STATS_QUEUE: queue_stats_show(fd); break; + case EXP_STATS: + if (!(CONFIG(flags) & CTD_EXPECT)) + break; + + STATE(mode)->internal->exp.stats(fd); + STATE_SYNC(external)->exp.stats(fd); + dump_traffic_stats(fd); + multichannel_stats(STATE_SYNC(channel), fd); + dump_stats_sync(fd); + break; + case EXP_DUMP_INTERNAL: + if (!(CONFIG(flags) & CTD_EXPECT)) + break; + + if (fork_process_new(CTD_PROC_ANY, 0, NULL, NULL) == 0) { + STATE(mode)->internal->exp.dump(fd, NFCT_O_PLAIN); + exit(EXIT_SUCCESS); + } + break; + case EXP_DUMP_EXTERNAL: + if (!(CONFIG(flags) & CTD_EXPECT)) + break; + + if (fork_process_new(CTD_PROC_ANY, 0, NULL, NULL) == 0) { + STATE_SYNC(external)->exp.dump(fd, NFCT_O_PLAIN); + exit(EXIT_SUCCESS); + } + break; + case EXP_COMMIT: + if (!(CONFIG(flags) & CTD_EXPECT)) + break; + + dlog(LOG_NOTICE, "committing expectation cache"); + STATE_SYNC(commit).rq[0].cb = STATE_SYNC(external)->exp.commit; + STATE_SYNC(commit).rq[1].cb = NULL; + local_commit(fd); + break; + case ALL_FLUSH_CACHE: + dlog(LOG_NOTICE, "flushing caches"); + STATE(mode)->internal->ct.flush(); + STATE_SYNC(external)->ct.flush(); + if (CONFIG(flags) & CTD_EXPECT) { + STATE(mode)->internal->exp.flush(); + STATE_SYNC(external)->exp.flush(); + } + break; + case ALL_COMMIT: + dlog(LOG_NOTICE, "committing all external caches"); + STATE_SYNC(commit).rq[0].cb = STATE_SYNC(external)->ct.commit; + if (CONFIG(flags) & CTD_EXPECT) { + STATE_SYNC(commit).rq[1].cb = + STATE_SYNC(external)->exp.commit; + } else { + STATE_SYNC(commit).rq[1].cb = NULL; + } + local_commit(fd); + break; default: if (STATE_SYNC(sync)->local) ret = STATE_SYNC(sync)->local(fd, type, data); diff --git a/src/sync-notrack.c b/src/sync-notrack.c index 06ad1f0..a7df4e7 100644 --- a/src/sync-notrack.c +++ b/src/sync-notrack.c @@ -102,7 +102,7 @@ static void kernel_resync(void) u_int32_t family = AF_UNSPEC; int ret; - h = nfct_open(CONNTRACK, 0); + h = nfct_open(CONFIG(netlink).subsys_id, 0); if (h == NULL) { dlog(LOG_ERR, "can't allocate memory for the internal cache"); return; @@ -131,6 +131,8 @@ static int notrack_local(int fd, int type, void *data) } else { cache_iterate(STATE(mode)->internal->ct.data, NULL, do_cache_to_tx); + cache_iterate(STATE(mode)->internal->exp.data, + NULL, do_cache_to_tx); } break; default: @@ -152,6 +154,8 @@ static int digest_msg(const struct nethdr *net) } else { cache_iterate(STATE(mode)->internal->ct.data, NULL, do_cache_to_tx); + cache_iterate(STATE(mode)->internal->exp.data, + NULL, do_cache_to_tx); } return MSG_CTL; } -- cgit v1.2.3