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; }
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)); }
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)); }
/************************* main *******************************/ int main() { new_packet = (unsigned char *)malloc(MTU); if(new_packet == NULL) { printf("Malloc failed\n"); exit(EXIT_FAILURE); } struct nfq_handle *h = get_handle(); fd_set rfds; // start the downstream code, later move to a thread initializeRabin(powers); int max_fd = 0; int down_fd = createQueue(h, DOWN_MOBILE_QUEUE, &cbDown); if(down_fd > max_fd) max_fd = down_fd; int up_fd = createQueue(h, UP_MOBILE_QUEUE, &cbUp); if(up_fd > max_fd) max_fd = up_fd; printlog(logfile, system_loglevel, LOG_DEBUG, "Queue packet descriptors, down_fd: %d, up_fd: %d\n", down_fd, up_fd); int n = 0, rv = 0; char buf[4096] __attribute__ ((aligned)); nfnl_rcvbufsiz(nfq_nfnlh(h), 4096 * 4096); while(true) { FD_ZERO(&rfds); FD_SET(down_fd, &rfds); FD_SET(up_fd, &rfds); n = select(max_fd + 1, &rfds, NULL, NULL, NULL); if(n == -1) { printlog(logfile, system_loglevel, LOG_CRITICAL, "Select returned error: %s\n", strerror(errno)); } if(FD_ISSET(down_fd, &rfds)) { rv = recv(down_fd, buf, sizeof(buf), 0); if(rv < 0) { printlog(logfile, system_loglevel, LOG_CRITICAL, "recv call failed: %s\n", strerror(errno)); } else { nfq_handle_packet(h, buf, rv); } } if(FD_ISSET(up_fd, &rfds)) { rv = recv(up_fd, buf, sizeof(buf), 0); if(rv < 0) { printlog(logfile, system_loglevel, LOG_CRITICAL, "recv call failed: %s\n", strerror(errno)); } else { nfq_handle_packet(h, buf, rv); } } } // start the upstream code, later move to a thread return 0; }
int divert_open(int port, divert_cb cb) { unsigned int bufsize = 1024 * 1024 * 1; unsigned int rc; char *m; int fd, flags; _h = nfq_open(); if (!_h) err(1, "nfq_open()"); rc = nfnl_rcvbufsiz(nfq_nfnlh(_h), bufsize); if (rc != bufsize) xprintf(XP_DEBUG, "Buffer size %u wanted %u\n", rc, bufsize); /* reset in case of previous crash */ if (nfq_unbind_pf(_h, AF_INET) < 0) err(1, "nfq_unbind_pf()"); if (nfq_bind_pf(_h, AF_INET) < 0) err(1, "nfq_bind_pf()"); _q = nfq_create_queue(_h, port, packet_input, cb); if (!_q) err(1, "nfq_create_queue()"); if (nfq_set_mode(_q, NFQNL_COPY_PACKET, 0xffff) < 0) err(1, "nfq_set_mode()"); if (nfq_set_queue_maxlen(_q, 10000) < 0) err(1, "nfq_set_queue_maxlen()"); xprintf(XP_DEFAULT, "Divert packets using iptables -j NFQUEUE --queue-num %d\n", port); m = driver_param(0); if (m) { _mark = strtoul(m, NULL, 16); xprintf(XP_DEFAULT, "Also, add -m mark --mark 0x0/0x%x\n", _mark); } fd = nfq_fd(_h); flags = fcntl(fd, F_GETFL); if (flags == -1) err(1, "fcntl()"); if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) err(1, "fcntl()"); open_raw(); return fd; }
int tc_nfq_socket_init(struct nfq_handle **h, struct nfq_q_handle **qh, nfq_callback *cb, int max_queue_len) { int fd; tc_log_info(LOG_NOTICE, 0, "opening library handle"); *h = nfq_open(); if (!(*h)) { tc_log_info(LOG_ERR, errno, "error during nfq_open()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "unbinding existing nf_queue handler for AF_INET (if any)"); if (nfq_unbind_pf((*h), AF_INET) < 0) { tc_log_info(LOG_ERR, errno, "error during nfq_unbind_pf()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "binding nfnetlink_queue as nf_queue handler for AF_INET"); if (nfq_bind_pf((*h), AF_INET) < 0) { tc_log_info(LOG_ERR, errno, "error during nfq_bind_pf()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "binding this socket to queue"); *qh = nfq_create_queue((*h), 0, cb, NULL); if (!(*qh)) { tc_log_info(LOG_ERR, errno, "error during nfq_create_queue()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "setting copy_packet mode"); if (nfq_set_mode((*qh), NFQNL_COPY_PACKET, RESP_MAX_USEFUL_SIZE) < 0) { tc_log_info(LOG_ERR, errno, "can't set packet_copy mode"); return TC_INVALID_SOCKET; } if (max_queue_len > 0) { if (nfq_set_queue_maxlen((*qh), (uint32_t) max_queue_len) < 0) { tc_log_info(LOG_ERR, errno, "can't set queue max length:%d", max_queue_len); tc_log_info(LOG_WARN, 0, "unable to set queue maxlen"); tc_log_info(LOG_WARN, 0, "your kernel probably doesn't support it"); } } fd = nfq_fd(*h); nfnl_rcvbufsiz(nfq_nfnlh(*h), 16777216); return fd; }
int tc_nfq_socket_init(struct nfq_handle **h, struct nfq_q_handle **qh, nfq_callback *cb) { int fd; tc_log_info(LOG_NOTICE, 0, "opening library handle"); *h = nfq_open(); if (!(*h)) { tc_log_info(LOG_ERR, errno, "error during nfq_open()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "unbinding existing nf_queue handler for AF_INET (if any)"); if (nfq_unbind_pf((*h), AF_INET) < 0) { tc_log_info(LOG_ERR, errno, "error during nfq_unbind_pf()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "binding nfnetlink_queue as nf_queue handler for AF_INET"); if (nfq_bind_pf((*h), AF_INET) < 0) { tc_log_info(LOG_ERR, errno, "error during nfq_bind_pf()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "binding this socket to queue"); *qh = nfq_create_queue((*h), 0, cb, NULL); if (!(*qh)) { tc_log_info(LOG_ERR, errno, "error during nfq_create_queue()"); return TC_INVALID_SOCKET; } tc_log_info(LOG_NOTICE, 0, "setting copy_packet mode"); if (nfq_set_mode((*qh), NFQNL_COPY_PACKET, RESP_MAX_USEFUL_SIZE) < 0) { tc_log_info(LOG_ERR, errno, "can't set packet_copy mode"); return TC_INVALID_SOCKET; } fd = nfq_fd(*h); nfnl_rcvbufsiz(nfq_nfnlh(*h), 4096*4096); return fd; }
int nflog_set_nlbufsiz(struct nflog_g_handle *gh, u_int32_t nlbufsiz) { char buf[NFNL_HEADER_LEN+NFA_LENGTH(sizeof(u_int32_t))]; struct nlmsghdr *nmh = (struct nlmsghdr *) buf; int status; nfnl_fill_hdr(gh->h->nfnlssh, nmh, 0, AF_UNSPEC, gh->id, NFULNL_MSG_CONFIG, NLM_F_REQUEST|NLM_F_ACK); nfnl_addattr32(nmh, sizeof(buf), NFULA_CFG_NLBUFSIZ, htonl(nlbufsiz)); status = nfnl_talk(gh->h->nfnlh, nmh, 0, 0, NULL, NULL, NULL); /* we try to have space for at least 10 messages in the socket buffer */ if (status >= 0) nfnl_rcvbufsiz(gh->h->nfnlh, 10*nlbufsiz); return status; }
TmEcode NFQInitThread(NFQThreadVars *nfq_t, uint32_t queue_maxlen) { #ifndef OS_WIN32 struct timeval tv; int opt; #endif NFQQueueVars *nfq_q = NFQGetQueue(nfq_t->nfq_index); if (nfq_q == NULL) { SCLogError(SC_ERR_NFQ_OPEN, "no queue for given index"); return TM_ECODE_FAILED; } SCLogDebug("opening library handle"); nfq_q->h = nfq_open(); if (!nfq_q->h) { SCLogError(SC_ERR_NFQ_OPEN, "nfq_open() failed"); return TM_ECODE_FAILED; } if (nfq_g.unbind == 0) { /* VJ: on my Ubuntu Hardy system this fails the first time it's * run. Ignoring the error seems to have no bad effects. */ SCLogDebug("unbinding existing nf_queue handler for AF_INET (if any)"); if (nfq_unbind_pf(nfq_q->h, AF_INET) < 0) { SCLogError(SC_ERR_NFQ_UNBIND, "nfq_unbind_pf() for AF_INET failed"); exit(EXIT_FAILURE); } if (nfq_unbind_pf(nfq_q->h, AF_INET6) < 0) { SCLogError(SC_ERR_NFQ_UNBIND, "nfq_unbind_pf() for AF_INET6 failed"); exit(EXIT_FAILURE); } nfq_g.unbind = 1; SCLogDebug("binding nfnetlink_queue as nf_queue handler for AF_INET and AF_INET6"); if (nfq_bind_pf(nfq_q->h, AF_INET) < 0) { SCLogError(SC_ERR_NFQ_BIND, "nfq_bind_pf() for AF_INET failed"); exit(EXIT_FAILURE); } if (nfq_bind_pf(nfq_q->h, AF_INET6) < 0) { SCLogError(SC_ERR_NFQ_BIND, "nfq_bind_pf() for AF_INET6 failed"); exit(EXIT_FAILURE); } } SCLogInfo("binding this thread %d to queue '%" PRIu32 "'", nfq_t->nfq_index, nfq_q->queue_num); /* pass the thread memory as a void ptr so the * callback function has access to it. */ nfq_q->qh = nfq_create_queue(nfq_q->h, nfq_q->queue_num, &NFQCallBack, (void *)nfq_t); if (nfq_q->qh == NULL) { SCLogError(SC_ERR_NFQ_CREATE_QUEUE, "nfq_create_queue failed"); return TM_ECODE_FAILED; } SCLogDebug("setting copy_packet mode"); /* 05DC = 1500 */ //if (nfq_set_mode(nfq_t->qh, NFQNL_COPY_PACKET, 0x05DC) < 0) { if (nfq_set_mode(nfq_q->qh, NFQNL_COPY_PACKET, 0xFFFF) < 0) { SCLogError(SC_ERR_NFQ_SET_MODE, "can't set packet_copy mode"); return TM_ECODE_FAILED; } #ifdef HAVE_NFQ_MAXLEN if (queue_maxlen > 0) { SCLogInfo("setting queue length to %" PRId32 "", queue_maxlen); /* non-fatal if it fails */ if (nfq_set_queue_maxlen(nfq_q->qh, queue_maxlen) < 0) { SCLogWarning(SC_ERR_NFQ_MAXLEN, "can't set queue maxlen: your kernel probably " "doesn't support setting the queue length"); } } #endif /* HAVE_NFQ_MAXLEN */ #ifndef OS_WIN32 /* set netlink buffer size to a decent value */ nfnl_rcvbufsiz(nfq_nfnlh(nfq_q->h), queue_maxlen * 1500); SCLogInfo("setting nfnl bufsize to %" PRId32 "", queue_maxlen * 1500); nfq_q->nh = nfq_nfnlh(nfq_q->h); nfq_q->fd = nfnl_fd(nfq_q->nh); NFQMutexInit(nfq_q); /* Set some netlink specific option on the socket to increase performance */ opt = 1; #ifdef NETLINK_BROADCAST_SEND_ERROR setsockopt(nfq_q->fd, SOL_NETLINK, NETLINK_BROADCAST_SEND_ERROR, &opt, sizeof(int)); #endif /* Don't send error about no buffer space available but drop the packets instead */ #ifdef NETLINK_NO_ENOBUFS setsockopt(nfq_q->fd, SOL_NETLINK, NETLINK_NO_ENOBUFS, &opt, sizeof(int)); #endif #ifdef HAVE_NFQ_SET_QUEUE_FLAGS if (nfq_config.flags & NFQ_FLAG_FAIL_OPEN) { uint32_t flags = NFQA_CFG_F_FAIL_OPEN; uint32_t mask = NFQA_CFG_F_FAIL_OPEN; int r = nfq_set_queue_flags(nfq_q->qh, mask, flags); if (r == -1) { SCLogWarning(SC_ERR_NFQ_SET_MODE, "can't set fail-open mode: %s", strerror(errno)); } else { SCLogInfo("fail-open mode should be set on queue"); } } #endif /* set a timeout to the socket so we can check for a signal * in case we don't get packets for a longer period. */ tv.tv_sec = 1; tv.tv_usec = 0; if(setsockopt(nfq_q->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) { SCLogWarning(SC_ERR_NFQ_SETSOCKOPT, "can't set socket timeout: %s", strerror(errno)); } SCLogDebug("nfq_q->h %p, nfq_q->nh %p, nfq_q->qh %p, nfq_q->fd %" PRId32 "", nfq_q->h, nfq_q->nh, nfq_q->qh, nfq_q->fd); #else /* OS_WIN32 */ NFQMutexInit(nfq_q); nfq_q->ovr.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); nfq_q->fd = nfq_fd(nfq_q->h); SCLogDebug("nfq_q->h %p, nfq_q->qh %p, nfq_q->fd %p", nfq_q->h, nfq_q->qh, nfq_q->fd); #endif /* OS_WIN32 */ return TM_ECODE_OK; }
static struct packet_module_state *init_state(int thread_id) { static const u_int16_t proto_family[] = { AF_INET, AF_INET6 }; int i; struct packet_module_state *state = malloc(sizeof(struct packet_module_state)); if (!state) { return NULL; } /* Setup nfqueue connection */ state->handle = nfq_open(); if (!state->handle) { message(HAKA_LOG_ERROR, MODULE_NAME, L"unable to open nfqueue handle"); cleanup_state(state); return NULL; } for (i=0; i<sizeof(proto_family)/sizeof(proto_family[0]); ++i) { if (nfq_unbind_pf(state->handle, proto_family[i]) < 0) { message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot unbind queue"); cleanup_state(state); return NULL; } if (nfq_bind_pf(state->handle, proto_family[i]) < 0) { message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot bind queue"); cleanup_state(state); return NULL; } state->send_fd = open_send_socket(false); if (state->send_fd < 0) { cleanup_state(state); return NULL; } state->send_mark_fd = open_send_socket(true); if (state->send_fd < 0) { cleanup_state(state); return NULL; } } state->queue = nfq_create_queue(state->handle, thread_id, &packet_callback, state); if (!state->queue) { message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot create queue"); cleanup_state(state); return NULL; } if (nfq_set_mode(state->queue, NFQNL_COPY_PACKET, PACKET_BUFFER_SIZE) < 0) { message(HAKA_LOG_ERROR, MODULE_NAME, L"cannot set mode to copy packet"); cleanup_state(state); return NULL; } state->fd = nfq_fd(state->handle); /* Change nfq queue len and netfilter receive size */ if (nfq_set_queue_maxlen(state->queue, nfqueue_len) < 0) { message(HAKA_LOG_WARNING, MODULE_NAME, L"cannot change netfilter queue len"); } nfnl_rcvbufsiz(nfq_nfnlh(state->handle), nfqueue_len * 1500); return state; }
/** * Open a netlink connection and returns file descriptor */ int packetsrv_open(void *data) { int ret; log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG, "Opening netfilter queue socket"); log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG, "[!] Don't forget to load kernel modules nfnetlink and nfnetlink_queue (using modprobe command)"); /* opening library handle */ h = nfq_open(); if (!h) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Error during nfq_open()"); return -1; } /* unbinding existing nf_queue handler for AF_INET (if any) */ /* ignoring return, see http://www.spinics.net/lists/netfilter/msg42063.html */ nfq_unbind_pf(h, AF_INET); /* binding nfnetlink_queue as nf_queue handler for AF_INET */ if (nfq_bind_pf(h, AF_INET) < 0) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Error during nfq_bind_pf()"); return -1; } if (!nufw_no_ipv6) { /* unbinding existing nf_queue handler for AF_INET6 (if any) */ nfq_unbind_pf(h, AF_INET6); /* binding nfnetlink_queue as nf_queue handler for AF_INET6 */ if (nfq_bind_pf(h, AF_INET6) < 0) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Error during nfq_bind_pf()"); log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "Maybe you need to compile NF_NETLINK* kernel options as modules (not built in the kernel!)"); return -1; } } ret = nfnl_rcvbufsiz(nfq_nfnlh(h), 10 * 65536); log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "rcv buf size set to %d (%d asked)", ret, 10 * 65536); /* binding this socket to queue number ::nfqueue_num * and install our packet handler */ log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_DEBUG, "[+] Binding to netfilter queue %d", nfqueue_num); hndl = nfq_create_queue(h, nfqueue_num, (nfq_callback *) & treat_packet, data); if (!hndl) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Error during nfq_create_queue() (queue %d busy ?)", nfqueue_num); return -1; } /* setting copy_packet mode */ if (nfq_set_mode(hndl, NFQNL_COPY_PACKET, 0xffff) < 0) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Can't set packet_copy mode"); return -1; } #ifdef HAVE_NFQ_SET_QUEUE_MAXLEN /* setting queue length */ if (queue_maxlen) { if (nfq_set_queue_maxlen(hndl, queue_maxlen) < 0) { if (nufw_set_mark) { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Can't set queue length, and mark will be set, leaving !"); exit(EXIT_FAILURE); } else { log_area_printf(DEBUG_AREA_MAIN, DEBUG_LEVEL_CRITICAL, "[!] Can't set queue length, continuing anyway"); } } } #endif return nfq_fd(h); }
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; }