Exemplo n.º 1
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;
}
Exemplo n.º 2
0
void nl_resize_socket_buffer(struct nfct_handle *h)
{
	unsigned int s = CONFIG(netlink_buffer_size) * 2;

	/* already warned that we have reached the maximum buffer size */
	if (warned)
		return;

	if (s > CONFIG(netlink_buffer_size_max_grown)) {
		dlog(STATE(log), "WARNING: maximum netlink socket buffer "
				 "size has been reached. We are likely to "
				 "be losing events, this may lead to "
				 "unsynchronized replicas. Please, consider "
				 "increasing netlink socket buffer size via "
				 "SocketBufferSize and "
				 "SocketBufferSizeMaxGrown clauses in "
				 "conntrackd.conf");
		s = CONFIG(netlink_buffer_size_max_grown);
		warned = 1;
	}

	CONFIG(netlink_buffer_size) = nfnl_rcvbufsiz(nfct_nfnlh(h), s);

	/* notify the sysadmin */
	dlog(STATE(log), "netlink socket buffer size has been set to %u bytes", 
			  CONFIG(netlink_buffer_size));
}
Exemplo n.º 3
0
void nl_resize_socket_buffer(struct nfct_handle *h)
{
	unsigned int s = CONFIG(netlink_buffer_size);

	/* already warned that we have reached the maximum buffer size */
	if (warned)
		return;

	/* since sock_setsockopt in net/core/sock.c doubles the size of socket
	   buffer passed to it using nfnl_rcvbufsiz, only call nfnl_rcvbufsiz
	   if new value is not greater than netlink_buffer_size_max_grown */
	if (s*2 > CONFIG(netlink_buffer_size_max_grown)) {
		dlog(LOG_WARNING,
		     "netlink event socket buffer size cannot "
		     "be doubled further since it will exceed "
		     "NetlinkBufferSizeMaxGrowth. We are likely to "
		     "be losing events, this may lead to "
		     "unsynchronized replicas. Please, consider "
		     "increasing netlink socket buffer size via "
		     "NetlinkBufferSize and "
		     "NetlinkBufferSizeMaxGrowth clauses in "
		     "conntrackd.conf");
		warned = 1;
		return;
	}

	CONFIG(netlink_buffer_size) = nfnl_rcvbufsiz(nfct_nfnlh(h), s);

	/* notify the sysadmin */
	dlog(LOG_NOTICE, "netlink event socket buffer size has been doubled "
			 "to %u bytes", CONFIG(netlink_buffer_size));
}
Exemplo n.º 4
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;
}