Hello, I am trying to use conntrackd with connection tracking helpers. As a first step I want to get one of the helpers (tfp) that ship with conntrack-tools running. However, I am getting "[ERROR] unknown layer 3 protocol" when conntrackd parses its configuration file (which is a stripped-down version of doc/helper/conntrackd.conf, containing only the ftp helper (see below)). Here is what I am doing in detail: ~~~~ [root@dev1 conntrack-tools]# uname -a Linux dev1 5.0.7-arch1-1-ARCH #1 SMP PREEMPT Mon Apr 8 10:37:08 UTC 2019 x86_64 GNU/Linux [root@dev1 conntrack-tools]# git log -n1 commit 8ae8c537cd7fd0f2fe18e30046d73c59d3a7fe85 (HEAD -> master, origin/master, origin/HEAD) Author: Brian Haley <bhaley@xxxxxxxxxx> Date: Tue Mar 19 15:56:55 2019 -0400 conntrack: Allow protocol number zero /etc/protocols defines protocol zero as 'ip' for IPv4, and 'hopopt' for IPv6, which can be used with conntrack as '-p ip' or '-p hopopt'. However it's equivalent, '-p 0' is considered unsupported. Change the range check in findproto() to allow zero as well. Signed-off-by: Brian Haley <bhaley@xxxxxxxxxx> Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> [root@dev1 conntrack-tools]# nfct add helper ftp inet tcp [root@dev1 conntrack-tools]# nfct list helper { .name = ftp, .queuenum = 0, .l3protonum = 2, .l4protonum = 6, .priv_data_len = 0, .status = disabled, }; [root@dev1 conntrack-tools]# iptables -t raw -I OUTPUT -p tcp --dport 21 -j CT --helper ftp [root@dev1 conntrack-tools]# iptables -nvL -t raw Chain PREROUTING (policy ACCEPT 36 packets, 2484 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 19 packets, 1768 bytes) pkts bytes target prot opt in out source destination 0 0 CT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:21 CT helper ftp [root@dev1 conntrack-tools]# cat ~/conntrackd.conf # # Helper settings # Helper { # Before this, you have to make sure you have registered the `ftp' # user-space helper stub via: # # nfct add helper ftp inet tcp # Type ftp inet tcp { # # Set NFQUEUE number you want to use to receive traffic from # the kernel. # QueueNum 0 # # Maximum number of packets waiting in the queue to receive # a verdict from user-space. Default is 1024. # # Rise value if you hit the following error message: # "nf_queue: full at X entries, dropping packets(s)" # QueueLen 10240 # # Set the Expectation policy for this helper. This section # is optional; if left unspecified, the defaults from the # ctd_helper struct will be used. # Policy ftp { # # Maximum number of simultaneous expectations # ExpectMax 1 # # Maximum living time for one expectation (in seconds). # ExpectTimeout 300 } } } # # General settings # General { # # 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 /var/run/conntrackd.ctl } } [root@dev1 conntrack-tools]# conntrackd -C ~/conntrackd.conf [Sat Apr 13 12:52:05 2019] (pid=13395) [ERROR] unknown layer 3 protocol [root@dev1 conntrack-tools]# echo $? 1 [root@dev1 conntrack-tools]# ~~~~ The error seems to come from this part of src/read_config_yy.c: ~~~~ #line 1386 "read_config_yy.y" /* yacc.c:1652 */ { struct ctd_helper_instance *helper_inst; struct ctd_helper *helper; struct stack_item *e; uint16_t l3proto; uint8_t l4proto; if (strcmp((yyvsp[-4].string), "inet") == 0) l3proto = AF_INET; else if (strcmp((yyvsp[-4].string), "inet6") == 0) l3proto = AF_INET6; else { dlog(LOG_ERR, "unknown layer 3 protocol"); exit(EXIT_FAILURE); } ~~~~ Modifying src/read_config_yy.y to generate the following src/read_config_yy.c ~~~~ #line 1386 "read_config_yy.y" /* yacc.c:1652 */ { struct ctd_helper_instance *helper_inst; struct ctd_helper *helper; struct stack_item *e; uint16_t l3proto; uint8_t l4proto; printf("[DEBUG] l3proto: >>>%s<<<\n", (yyvsp[-4].string)); if (strcmp((yyvsp[-4].string), "inet") == 0) l3proto = AF_INET; else if (strcmp((yyvsp[-4].string), "inet6") == 0) l3proto = AF_INET6; else { dlog(LOG_ERR, "unknown layer 3 protocol"); exit(EXIT_FAILURE); } ~~~~ yields ~~~~ [root@dev1 conntrack-tools]# conntrackd -C ~/conntrackd.conf [DEBUG] l3proto: >>>inet tcp { # # Set NFQUEUE number you want to use to receive traffic from # the kernel. # QueueNum 0 # # Maximum number of packets waiting in the queue to receive # a verdict from user-space. Default is 1024. # # Rise value if you hit the following error message: # "nf_queue: full at X entries, dropping packets(s)" # QueueLen 10240 # # Set the Expectation policy for this helper. This section # is optional; if left unspecified, the defaults from the # ctd_helper struct will be used. # Policy ftp { # # Maximum number of simultaneous expectations # ExpectMax 1 # # Maximum living time for one expectation (in seconds). # ExpectTimeout 300 } }<<< [Sat Apr 13 12:57:59 2019] (pid=19535) [ERROR] unknown layer 3 protocol [root@dev1 conntrack-tools]# ~~~~ So, on first sight, it appears that the strcmp()s are causing the errors (either by feeding them too much or by not limiting the substring comparison)? Maybe it is a yacc incompatibility? I am using the following version: ~~~~ [root@dev1 conntrack-tools]# yacc --version bison (GNU Bison) 3.3.2 Written by Robert Corbett and Richard Stallman. Copyright (C) 2019 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. [root@dev1 conntrack-tools]# ~~~~ Best regards, Daniel