int main(void)
{
	int ret;
	u_int8_t family = AF_INET;
	struct nfct_handle *h;

	h = nfct_open(EXPECT, 0);
	if (!h) {
		perror("nfct_open");
		return -1;
	}

	nfexp_callback_register(h, NFCT_T_ALL, cb, NULL);
	ret = nfexp_query(h, NFCT_Q_DUMP, &family);

	printf("TEST: dumo expectation ");
	if (ret == -1)
		printf("(%d)(%s)\n", ret, strerror(errno));
	else
		printf("(OK)\n");

	nfct_close(h);

	ret == -1 ? exit(EXIT_FAILURE) : exit(EXIT_SUCCESS);
}
int main(void)
{
	int ret;
	uint32_t family = AF_INET;
	struct nfct_handle *h;

	h = nfct_open(CONNTRACK, 0);
	if (!h) {
		perror("nfct_open");
		return -1;
	}

	nfct_callback_register(h, NFCT_T_ALL, cb, NULL);
	ret = nfct_query(h, NFCT_Q_DUMP, &family);

	printf("TEST: get conntrack ");
	if (ret == -1)
		printf("(%d)(%s)\n", ret, strerror(errno));
	else
		printf("(OK)\n");

	nfct_close(h);

	ret == -1 ? exit(EXIT_FAILURE) : exit(EXIT_SUCCESS);
}
Beispiel #3
0
int main()
{
	int ret;
	struct nfct_handle *h;

	h = nfct_open(EXPECT, NF_NETLINK_CONNTRACK_EXP_NEW);
	if (!h) {
		perror("nfct_open");
		return -1;
	}

	nfexp_callback_register(h, NFCT_T_ALL, event_cb, NULL);

	printf("TEST: waiting for 10 expectation events...\n");

	ret = nfexp_catch(h);

	printf("TEST: OK (%d)(%s)\n", ret, strerror(errno));

	nfct_close(h);

	if (ret == -1)
		exit(EXIT_FAILURE);

	exit(EXIT_SUCCESS);
}
Beispiel #4
0
int main()
{
	int ret;
	struct nfct_handle *h;
	struct nf_conntrack *ct;

	ct = nfct_new();
	if (!ct) {
		perror("nfct_new");
		return 0;
	}

	nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
	nfct_set_attr_u32(ct, ATTR_IPV4_SRC, inet_addr("1.1.1.1"));
	nfct_set_attr_u32(ct, ATTR_IPV4_DST, inet_addr("2.2.2.2"));
	
	nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_TCP);
	nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(20));
	nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(10));

	h = nfct_open(CONNTRACK, 0);
	if (!h) {
		perror("nfct_open");
		return -1;
	}

	ret = nfct_query(h, NFCT_Q_DESTROY, ct);

	printf("TEST: delete conntrack (%d)(%s)\n", ret, strerror(errno));

	if (ret == -1)
		exit(EXIT_FAILURE);

	nfct_close(h);
}
Beispiel #5
0
int nl_init_event_handler(void)
{
	STATE(event) = nfct_open(CONNTRACK, NFCT_ALL_CT_GROUPS);
	if (!STATE(event))
		return -1;

	fcntl(nfct_fd(STATE(event)), F_SETFL, O_NONBLOCK);

	/* set up socket buffer size */
	if (CONFIG(netlink_buffer_size))
		nfnl_rcvbufsiz(nfct_nfnlh(STATE(event)), 
			       CONFIG(netlink_buffer_size));
	else {
		socklen_t socklen = sizeof(unsigned int);
		unsigned int read_size;

		/* get current buffer size */
		getsockopt(nfct_fd(STATE(event)), SOL_SOCKET,
			   SO_RCVBUF, &read_size, &socklen);

		CONFIG(netlink_buffer_size) = read_size;
	}

	/* ensure that maximum grown size is >= than maximum size */
	if (CONFIG(netlink_buffer_size_max_grown) < CONFIG(netlink_buffer_size))
		CONFIG(netlink_buffer_size_max_grown) = 
					CONFIG(netlink_buffer_size);

	/* register callback for events */
	nfct_callback_register(STATE(event), NFCT_T_ALL, event_handler, NULL);

	return 0;
}
Beispiel #6
0
/*-
-- cthandle = nfct.open(subsys, [subscription...])

subsys is "track" or "expect"

subscription is the groups for which notifications are requested, zero or more of
"none", "new", "update", "destroy", or "all" (default is "none").

Returns a conntrack handle on success, or nil,emsg,errno on failure.

There is no garbage collection, nfct.fini() must be called on the handle to
release it's resources.
*/
static int hopen(lua_State *L)
{
    static const char* subsys_opts[] = {
        "track", "expect", NULL
    };
    static u_int8_t subsys_vals[] = {
        NFNL_SUBSYS_CTNETLINK, NFNL_SUBSYS_CTNETLINK_EXP,
    };
    int subsys_opt = luaL_checkoption(L, 1, NULL, subsys_opts);
    u_int8_t subsys_val = subsys_vals[subsys_opt];
    static const char*  subscription_opts[] = {
        "none", "new", "update", "destroy", "all", NULL
    };
    unsigned subscription_vals[2][5] = {
        {   /* [0] == "track" */
            0,
            NF_NETLINK_CONNTRACK_NEW,
            NF_NETLINK_CONNTRACK_UPDATE,
            NF_NETLINK_CONNTRACK_DESTROY,
            NFCT_ALL_CT_GROUPS
        },
        {   /* [1] == "expect" */
            0,
            NF_NETLINK_CONNTRACK_EXP_NEW,
            NF_NETLINK_CONNTRACK_EXP_UPDATE,
            NF_NETLINK_CONNTRACK_EXP_DESTROY,
            NF_NETLINK_CONNTRACK_EXP_NEW
            |NF_NETLINK_CONNTRACK_EXP_UPDATE
            |NF_NETLINK_CONNTRACK_EXP_DESTROY
        }
    };
    unsigned subscription_val = 0;
    int narg = 0;
    struct nfct_handle* ct = NULL;

    /* the check option should have ensured that the opt index is 0 or 1,
     * so we can safely use it to index into the watfor vals
     */
    assert(subsys_opt == 0 || subsys_opt == 1);

    for(narg = 2; narg <= lua_gettop(L); narg++) {
        int subscription_opt = luaL_checkoption(L, narg, NULL, subscription_opts);
        subscription_val |= subscription_vals[subsys_opt][subscription_opt];
    }

    ct = nfct_open(subsys_val, subscription_val);

    if(!ct) {
        push_error(L);
        return 3;
    }

    lua_pushlightuserdata(L, ct);

    return 1;
}
int main(void)
{
	int ret;
	struct nfct_handle *h;
	struct nf_conntrack *expected;
	struct nf_expect *exp;

	expected = nfct_new();
	if (!expected) {
		perror("nfct_new");
		exit(EXIT_FAILURE);
	}

	nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET);
	nfct_set_attr_u32(expected, ATTR_IPV4_SRC, inet_addr("1.1.1.1"));
	nfct_set_attr_u32(expected, ATTR_IPV4_DST, inet_addr("2.2.2.2"));

	nfct_set_attr_u8(expected, ATTR_L4PROTO, IPPROTO_TCP);
	nfct_set_attr_u16(expected, ATTR_PORT_SRC, 0);
	nfct_set_attr_u16(expected, ATTR_PORT_DST, htons(10241));

	exp = nfexp_new();
	if (!exp) {
		perror("nfexp_new");
		nfct_destroy(expected);
		exit(EXIT_FAILURE);
	}

	nfexp_set_attr(exp, ATTR_EXP_EXPECTED, expected);

	h = nfct_open(EXPECT, 0);
	if (!h) {
		perror("nfct_open");
		nfct_destroy(expected);
		return -1;
	}

	ret = nfexp_query(h, NFCT_Q_DESTROY, exp);

	printf("TEST: delete expectation ");
	if (ret == -1)
		printf("(%d)(%s)\n", ret, strerror(errno));
	else
		printf("(OK)\n");

	nfct_close(h);

	nfct_destroy(expected);

	ret == -1 ? exit(EXIT_FAILURE) : exit(EXIT_SUCCESS);
}
static int external_inject_init(void)
{
	/* handler to directly inject conntracks into kernel-space */
	inject = nfct_open(CONFIG(netlink).subsys_id, 0);
	if (inject == NULL) {
		dlog(LOG_ERR, "can't open netlink handler: %s",
		     strerror(errno));
		dlog(LOG_ERR, "no ctnetlink kernel support?");
		return -1;
	}
	/* we are directly injecting the entries into the kernel */
	origin_register(inject, CTD_ORIGIN_INJECT);
	return 0;
}
Beispiel #9
0
int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr, int istcp, unsigned int *markp)
{
  struct nf_conntrack *ct;
  struct nfct_handle *h;
  
  gotit = 0;
  
  if ((ct = nfct_new())) 
    {
      nfct_set_attr_u8(ct, ATTR_L4PROTO, istcp ? IPPROTO_TCP : IPPROTO_UDP);
      nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(daemon->port));
      
#ifdef HAVE_IPV6
      if (peer_addr->sa.sa_family == AF_INET6)
	{
	  nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET6);
	  nfct_set_attr(ct, ATTR_IPV6_SRC, peer_addr->in6.sin6_addr.s6_addr);
	  nfct_set_attr_u16(ct, ATTR_PORT_SRC, peer_addr->in6.sin6_port);
	  nfct_set_attr(ct, ATTR_IPV6_DST, local_addr->addr.addr6.s6_addr);
	}
      else
#endif
	{
	  nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
	  nfct_set_attr_u32(ct, ATTR_IPV4_SRC, peer_addr->in.sin_addr.s_addr);
	  nfct_set_attr_u16(ct, ATTR_PORT_SRC, peer_addr->in.sin_port);
	  nfct_set_attr_u32(ct, ATTR_IPV4_DST, local_addr->addr.addr4.s_addr);
	}
      
      
      if ((h = nfct_open(CONNTRACK, 0))) 
	{
	  nfct_callback_register(h, NFCT_T_ALL, callback, (void *)markp);  
	  if (nfct_query(h, NFCT_Q_GET, ct) == -1)
	    {
	      static int warned = 0;
	      if (!warned)
		{
		  my_syslog(LOG_ERR, _("Conntrack connection mark retrieval failed: %s"), strerror(errno));
		  warned = 1;
		}
	    }
	  nfct_close(h);  
	}
      nfct_destroy(ct);
    }

  return gotit;
}
Beispiel #10
0
int nl_init_dump_handler(void)
{
	/* open dump netlink socket */
	STATE(dump) = nfct_open(CONNTRACK, 0);
	if (!STATE(dump))
		return -1;

	/* register callback for dumped entries */
	nfct_callback_register(STATE(dump), NFCT_T_ALL, dump_handler, NULL);

	if (nl_dump_conntrack_table() == -1)
		return -1;

	return 0;
}
Beispiel #11
0
int nl_flush_conntrack_table_selective(void)
{
	struct nfct_handle *h;
	int ret;

	h = nfct_open(CONNTRACK, 0);
	if (h == NULL) {
		dlog(LOG_ERR, "cannot open handle");
		return -1;
	}
	nfct_callback_register(h, NFCT_T_ALL, nl_flush_selective_cb, NULL);

	ret = nfct_query(h, NFCT_Q_DUMP, &family);

	nfct_close(h);

	return ret;
}
static void internal_bypass_ct_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;
	}
	nfct_callback_register(h, NFCT_T_ALL, internal_bypass_ct_dump_cb, &fd);
	ret = nfct_query(h, NFCT_Q_DUMP, &family);
	if (ret == -1) {
		dlog(LOG_ERR, "can't dump kernel table");
	}
	nfct_close(h);
}
Beispiel #13
0
static void
ForwardingRule_dealloc(ForwardingRule *self)
{
    struct nfct_handle *ct_handle;

    PyObject_GC_UnTrack(self);
    ForwardingRule_clear(self);

    if (self->is_active) {
        forwarding_rules[ntohs(nfct_get_attr_u16(self->conntrack, ATTR_ORIG_PORT_DST))] = NULL;

        Py_BEGIN_ALLOW_THREADS
        ct_handle = nfct_open(CONNTRACK, 0);
        if (ct_handle != NULL) {
            nfct_query(ct_handle, NFCT_Q_DESTROY, self->conntrack);
            nfct_close(ct_handle);
        }
        Py_END_ALLOW_THREADS
    }
Beispiel #14
0
int main()
{
	int ret;
	struct nfct_handle *h;
	struct nf_conntrack *ct;

	ct = nfct_new();
	if (!ct) {
		perror("nfct_new");
		return 0;
	}

	nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET);
	nfct_set_attr_u32(ct, ATTR_IPV4_SRC, inet_addr("1.1.1.1"));
	nfct_set_attr_u32(ct, ATTR_IPV4_DST, inet_addr("2.2.2.2"));
	
	nfct_set_attr_u8(ct, ATTR_L4PROTO, IPPROTO_TCP);
	nfct_set_attr_u16(ct, ATTR_PORT_SRC, htons(20));
	nfct_set_attr_u16(ct, ATTR_PORT_DST, htons(10));

	nfct_setobjopt(ct, NFCT_SOPT_SETUP_REPLY);

	nfct_set_attr_u8(ct, ATTR_TCP_STATE, TCP_CONNTRACK_LISTEN);
	nfct_set_attr_u32(ct, ATTR_TIMEOUT, 100);

	nfct_set_attr_u32(ct, ATTR_SNAT_IPV4, inet_addr("8.8.8.8"));

	h = nfct_open(CONNTRACK, 0);
	if (!h) {
		perror("nfct_open");
		return -1;
	}

	ret = nfct_query(h, NFCT_Q_CREATE, ct);

	printf("TEST: create conntrack (%d)(%s)\n", ret, strerror(errno));

	if (ret == -1)
		exit(EXIT_FAILURE);

	nfct_close(h);
}
Beispiel #15
0
int main()
{
	int ret;
	u_int8_t family = AF_INET;
	struct nfct_handle *h;
	char buf[1024];

	h = nfct_open(CONNTRACK, 0);
	if (!h) {
		perror("nfct_open");
		return -1;
	}

	nfct_callback_register(h, NFCT_T_ALL, cb, NULL);
	ret = nfct_query(h, NFCT_Q_DUMP, &family);

	printf("TEST: dump conntrack (%d)(%s)\n", ret, strerror(errno));

	if (ret == -1)
		exit(EXIT_FAILURE);

	nfct_close(h);
}
int main(void)
{
	int ret;
	struct nfct_handle *h;
	struct nf_conntrack *master, *expected, *mask, *nat;
	struct nf_expect *exp;

	/*
	 * Step 1: Setup master conntrack
	 */

	master = nfct_new();
	if (!master) {
		perror("nfct_new");
		exit(EXIT_FAILURE);
	}

	nfct_set_attr_u8(master, ATTR_L3PROTO, AF_INET);
	nfct_set_attr_u32(master, ATTR_IPV4_SRC, inet_addr("1.1.1.1"));
	nfct_set_attr_u32(master, ATTR_IPV4_DST, inet_addr("2.2.2.2"));

	nfct_set_attr_u8(master, ATTR_L4PROTO, IPPROTO_TCP);
	nfct_set_attr_u16(master, ATTR_PORT_SRC, htons(1025));
	nfct_set_attr_u16(master, ATTR_PORT_DST, htons(21));

	nfct_setobjopt(master, NFCT_SOPT_SETUP_REPLY);

	nfct_set_attr_u8(master, ATTR_TCP_STATE, TCP_CONNTRACK_ESTABLISHED);
	nfct_set_attr_u32(master, ATTR_TIMEOUT, 200);
	nfct_set_attr(master, ATTR_HELPER_NAME, "ftp");

	h = nfct_open(CONNTRACK, 0);
	if (!h) {
		perror("nfct_open");
		nfct_destroy(master);
		return -1;
	}

	ret = nfct_query(h, NFCT_Q_CREATE, master);

	printf("TEST: add master conntrack ");
	if (ret == -1)
		printf("(%d)(%s)\n", ret, strerror(errno));
	else
		printf("(OK)\n");

	nfct_close(h);

	expected = nfct_new();
	if (!expected) {
		perror("nfct_new");
		exit(EXIT_FAILURE);
	}

	nfct_set_attr_u8(expected, ATTR_L3PROTO, AF_INET);
	nfct_set_attr_u32(expected, ATTR_IPV4_SRC, inet_addr("1.1.1.1"));
	nfct_set_attr_u32(expected, ATTR_IPV4_DST, inet_addr("2.2.2.2"));

	nfct_set_attr_u8(expected, ATTR_L4PROTO, IPPROTO_TCP);
	nfct_set_attr_u16(expected, ATTR_PORT_SRC, 0);
	nfct_set_attr_u16(expected, ATTR_PORT_DST, htons(10241));

	mask = nfct_new();
	if (!mask) {
		perror("nfct_new");
		nfct_destroy(master);
		nfct_destroy(expected);
		exit(EXIT_FAILURE);
	}

	nfct_set_attr_u8(mask, ATTR_L3PROTO, AF_INET);
	nfct_set_attr_u32(mask, ATTR_IPV4_SRC, 0xffffffff);
	nfct_set_attr_u32(mask, ATTR_IPV4_DST, 0xffffffff);

	nfct_set_attr_u8(mask, ATTR_L4PROTO, IPPROTO_TCP);
	nfct_set_attr_u16(mask, ATTR_PORT_SRC, 0x0000);
	nfct_set_attr_u16(mask, ATTR_PORT_DST, 0xffff);

	nat = nfct_new();
	if (!nat) {
		perror("nfct_new");
		nfct_destroy(mask);
		nfct_destroy(master);
		nfct_destroy(expected);
		exit(EXIT_FAILURE);
	}

	nfct_set_attr_u8(nat, ATTR_L3PROTO, AF_INET);
	nfct_set_attr_u32(nat, ATTR_IPV4_SRC, inet_addr("3.3.3.3"));
	nfct_set_attr_u32(nat, ATTR_IPV4_DST, 0);

	nfct_set_attr_u8(nat, ATTR_L4PROTO, IPPROTO_TCP);
	nfct_set_attr_u16(nat, ATTR_PORT_SRC, 12345);
	nfct_set_attr_u16(nat, ATTR_PORT_DST, 0);

	/*
	 * Step 2: Setup expectation
	 */

	exp = nfexp_new();
	if (!exp) {
		perror("nfexp_new");
		nfct_destroy(master);
		nfct_destroy(expected);
		nfct_destroy(mask);
		exit(EXIT_FAILURE);
	}

	nfexp_set_attr(exp, ATTR_EXP_MASTER, master);
	nfexp_set_attr(exp, ATTR_EXP_EXPECTED, expected);
	nfexp_set_attr(exp, ATTR_EXP_MASK, mask);
	nfexp_set_attr(exp, ATTR_EXP_NAT_TUPLE, nat);
	nfexp_set_attr_u32(exp, ATTR_EXP_NAT_DIR, 0);
	nfexp_set_attr_u32(exp, ATTR_EXP_TIMEOUT, 200);

	nfct_destroy(master);
	nfct_destroy(expected);
	nfct_destroy(mask);
	nfct_destroy(nat);

	h = nfct_open(EXPECT, 0);
	if (!h) {
		perror("nfct_open");
		return -1;
	}

	ret = nfexp_query(h, NFCT_Q_CREATE, exp);

	printf("TEST: create expectation ");
	if (ret == -1)
		printf("(%d)(%s)\n", ret, strerror(errno));
	else
		printf("(OK)\n");

	nfct_close(h);

	ret == -1 ? exit(EXIT_FAILURE) : exit(EXIT_SUCCESS);
}
Beispiel #17
0
int main(int argc, char *argv[]) {
   pid_t pid, sid;
   int c, ret;
   char buf[BUF_LEN];
   int syslog_facility = LOG_LOCAL4;

   while (1) {
      static struct option long_options[] = {
         /* Flags */
         {"verbose",   no_argument,       0, 'v'},
         {"daemon",  no_argument,       0, 'd'},
         {"help",    no_argument,       0, 'h'},
         {"facility",required_argument, 0, 'f'},
         {0, 0, 0, 0}
      };
      /* getopt_long stores the option index here. */
      int option_index = 0;
      
      c = getopt_long (argc, argv, "vdhf:",long_options, &option_index);

      if (c == -1)
         break;

      switch(c) {
         case 'v':
            verbose_flag = 1;
            break;
         case 'd':
            daemon_flag = 1;
            break;
         case 'h':
            usage();
            exit(EXIT_SUCCESS);
            break;
         case 'f':
            syslog_facility = __str2facility(optarg);
            if (syslog_facility == -1) {
               ret = snprintf(buf,BUF_LEN-1,
                     "Invalid syslog facility parameter: %s", optarg);
               buf[ret] = '\0';
               write_msg(LOG_ERR,buf);
               usage();
               exit(EXIT_FAILURE);
            }
            break;
         case '?':
         default:
            usage();
            exit(EXIT_FAILURE);
            break;
      }

   }
 
   if (daemon_flag) {
       setlogmask(LOG_UPTO(LOG_INFO));
       openlog(PROGNAME, LOG_CONS, syslog_facility);

       /* Fork off the parent process */
       pid = fork();
       if (pid < 0) {
           exit(EXIT_FAILURE);
       }
       /* If we got a good PID, then
          we can exit the parent process. */
       if (pid > 0) {
           exit(EXIT_SUCCESS);
       }

       /* Create a new SID for the child process */
       sid = setsid();
       if (sid < 0) {
           /* Log the failure */
           exit(EXIT_FAILURE);
       }

       /* Change the current working directory */
       if ((chdir("/")) < 0) {
           /* Log the failure */
           exit(EXIT_FAILURE);
       }

       /* Close out the standard file descriptors */
       close(STDIN_FILENO);
       close(STDOUT_FILENO);
       close(STDERR_FILENO);
   }

   cth = nfct_open(CONNTRACK,
         NF_NETLINK_CONNTRACK_NEW|NF_NETLINK_CONNTRACK_DESTROY);
   
   if (!cth) {
      ret = snprintf(buf, BUF_LEN-1, "Can't open a ctnetlink handler (%s)", 
            strerror(errno));
      buf[ret] = '\0';
      write_msg(LOG_ERR, buf);
      exit(EXIT_FAILURE);
   }

   signal(SIGINT, event_sighandler);
	signal(SIGTERM, event_sighandler);
	
   nfct_callback_register(cth, NFCT_T_NEW|NFCT_T_DESTROY, event_cb, NULL);

   if (nfct_catch(cth) == -1) {
      ret = snprintf(buf, BUF_LEN-1, "Can't catch events (%s)", 
            strerror(errno));
      buf[ret] = '\0';
      write_msg(LOG_ERR, buf);
   }

   nfct_close(cth);

   return EXIT_SUCCESS;
}
Beispiel #18
0
struct nfct_handle *nl_init_event_handler(void)
{
	struct nfct_handle *h;

	h = nfct_open(CONFIG(netlink).subsys_id, CONFIG(netlink).groups);
	if (h == NULL)
		return NULL;

	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.");
	}

	if (STATE(filter)) {
		if (CONFIG(filter_from_kernelspace)) {
			if (nfct_filter_attach(nfct_fd(h),
					       STATE(filter)) == -1) {
				dlog(LOG_ERR, "cannot set event filtering: %s",
				     strerror(errno));
			}
			dlog(LOG_NOTICE, "using kernel-space event filtering");
		} else
			dlog(LOG_NOTICE, "using user-space event filtering");

		nfct_filter_destroy(STATE(filter));
	}

	fcntl(nfct_fd(h), F_SETFL, O_NONBLOCK);

	/* set up socket buffer size */
	if (CONFIG(netlink_buffer_size) &&
	    CONFIG(netlink_buffer_size) <=
			CONFIG(netlink_buffer_size_max_grown)) {
		/* we divide netlink_buffer_size by 2 here since value passed
		   to kernel gets doubled in SO_RCVBUF; see net/core/sock.c */
		CONFIG(netlink_buffer_size) =
		  nfnl_rcvbufsiz(nfct_nfnlh(h), CONFIG(netlink_buffer_size)/2);
	} else {
		dlog(LOG_NOTICE, "NetlinkBufferSize is either not set or "
				 "is greater than NetlinkBufferSizeMaxGrowth. "
				 "Using current system buffer size");

		socklen_t socklen = sizeof(unsigned int);
		unsigned int read_size;

		/* get current buffer size */
		getsockopt(nfct_fd(h), SOL_SOCKET,
			   SO_RCVBUF, &read_size, &socklen);

		CONFIG(netlink_buffer_size) = read_size;
	}

	dlog(LOG_NOTICE, "netlink event socket buffer size has been set "
			 "to %u bytes", CONFIG(netlink_buffer_size));

	return h;
}