void CW80211ManagementFrameEvent(struct nl_handle **handleMgmt, cw_sock_handler handler, void * cb, struct WTPBSSInfo * BSSInfo)
{
	//Set file descriptor of socket to non-blocking state
	nl_socket_set_nonblocking(*handleMgmt);
	int nlSocketFDmgmt = nl_socket_get_fd(*handleMgmt);
	CWBool exitThread=CW_FALSE;
	
	while(1)
	{
		//On delete BSS
		CWThreadMutexLock(&(BSSInfo->bssMutex));
		exitThread = BSSInfo->destroyBSS;
		CWThreadMutexUnlock(&(BSSInfo->bssMutex));
		if(exitThread == CW_TRUE)
			CWExitThread();
			
		int result;
		fd_set readset;
		do {
		   FD_ZERO(&readset);
		   FD_SET(nlSocketFDmgmt, &readset);
		   result = select(nlSocketFDmgmt + 1, &readset, NULL, NULL, NULL);
		} while (result == -1 && errno == EINTR);
		
		if (result > 0) {
		   if (FD_ISSET(nlSocketFDmgmt, &readset)) {
			 handler(cb, (*handleMgmt));
		   }   
		}
		else if (result < 0) {
		   CWLog("Error on select(): %s", strerror(errno));
		}
	}			     
}
Exemple #2
0
/**
 * Allocate new cache manager
 * @arg sk		Netlink socket or NULL to auto allocate
 * @arg protocol	Netlink protocol this manager is used for
 * @arg flags		Flags (\c NL_AUTO_PROVIDE)
 * @arg result		Result pointer
 *
 * Allocates a new cache manager for the specified netlink protocol.
 *
 * 1. If sk is not specified (\c NULL) a netlink socket matching the
 *    specified protocol will be automatically allocated.
 *
 * 2. The socket will be put in non-blocking mode and sequence checking
 *    will be disabled regardless of whether the socket was provided by
 *    the caller or automatically allocated.
 *
 * 3. The socket will be connected.
 *
 * If the flag \c NL_AUTO_PROVIDE is specified, any cache added to the
 * manager will automatically be made available to other users using
 * nl_cache_mngt_provide().
 *
 * @note If the socket is provided by the caller, it is NOT recommended
 *       to use the socket for anything else besides receiving netlink
 *       notifications.
 *
 * @return 0 on success or a negative error code.
 */
int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags,
			struct nl_cache_mngr **result)
{
	struct nl_cache_mngr *mngr;
	int err = -NLE_NOMEM;

	/* Catch abuse of flags */
	if (flags & NL_ALLOCATED_SOCK)
		BUG();

	mngr = calloc(1, sizeof(*mngr));
	if (!mngr)
		return -NLE_NOMEM;

	if (!sk) {
		if (!(sk = nl_socket_alloc()))
			goto errout;

		flags |= NL_ALLOCATED_SOCK;
	}

	mngr->cm_sock = sk;
	mngr->cm_nassocs = NASSOC_INIT;
	mngr->cm_protocol = protocol;
	mngr->cm_flags = flags;
	mngr->cm_assocs = calloc(mngr->cm_nassocs,
				 sizeof(struct nl_cache_assoc));
	if (!mngr->cm_assocs)
		goto errout;

	/* Required to receive async event notifications */
	nl_socket_disable_seq_check(mngr->cm_sock);

	if ((err = nl_connect(mngr->cm_sock, protocol)) < 0)
		goto errout;

	if ((err = nl_socket_set_nonblocking(mngr->cm_sock)) < 0)
		goto errout;

	/* Create and allocate socket for sync cache fills */
	mngr->cm_sync_sock = nl_socket_alloc();
	if (!mngr->cm_sync_sock) {
		err = -NLE_NOMEM;
		goto errout;
	}
	if ((err = nl_connect(mngr->cm_sync_sock, protocol)) < 0)
		goto errout_free_sync_sock;

	NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n",
	       mngr, protocol, mngr->cm_nassocs);

	*result = mngr;
	return 0;

errout_free_sync_sock:
	nl_socket_free(mngr->cm_sync_sock);
errout:
	nl_cache_mngr_free(mngr);
	return err;
}
Exemple #3
0
/**
 * Allocate new cache manager
 * @arg sk		Netlink socket.
 * @arg protocol	Netlink Protocol this manager is used for
 * @arg flags		Flags
 * @arg result		Result pointer
 *
 * @return 0 on success or a negative error code.
 */
int nl_cache_mngr_alloc(struct nl_sock *sk, int protocol, int flags,
			struct nl_cache_mngr **result)
{
	struct nl_cache_mngr *mngr;
	int err = -NLE_NOMEM;

	if (sk == NULL)
		BUG();

	mngr = calloc(1, sizeof(*mngr));
	if (!mngr)
		goto errout;

	mngr->cm_handle = sk;
	mngr->cm_nassocs = 32;
	mngr->cm_protocol = protocol;
	mngr->cm_flags = flags;
	mngr->cm_assocs = calloc(mngr->cm_nassocs,
				 sizeof(struct nl_cache_assoc));
	if (!mngr->cm_assocs)
		goto errout;

	nl_socket_modify_cb(mngr->cm_handle, NL_CB_VALID, NL_CB_CUSTOM,
			    event_input, mngr);

	/* Required to receive async event notifications */
	nl_socket_disable_seq_check(mngr->cm_handle);

	if ((err = nl_connect(mngr->cm_handle, protocol) < 0))
		goto errout;

	if ((err = nl_socket_set_nonblocking(mngr->cm_handle) < 0))
		goto errout;

	NL_DBG(1, "Allocated cache manager %p, protocol %d, %d caches\n",
	       mngr, protocol, mngr->cm_nassocs);

	*result = mngr;
	return 0;

errout:
	nl_cache_mngr_free(mngr);
	return err;
}
Exemple #4
0
GWaterNlSource *
g_water_nl_source_new_for_sock(GMainContext *context, struct nl_sock *sock)
{
    g_return_val_if_fail(sock != NULL, NULL);

    GSource *source;
    GWaterNlSource *self;

    source = g_source_new(&_g_water_nl_source_funcs, sizeof(GWaterNlSource));
    self = (GWaterNlSource *)source;
    self->sock = sock;

    nl_socket_set_nonblocking(self->sock);

    self->fd = g_source_add_unix_fd(source, nl_socket_get_fd(self->sock), G_IO_IN | G_IO_ERR | G_IO_HUP);

    g_source_attach(source, context);

    return self;
}
Exemple #5
0
/* Set netlink socket channel as non-blocking */
static int
netlink_set_nonblock(nl_handle_t *nl, int *flags)
{
#ifdef _HAVE_LIBNL3_
	int ret;

	if ((ret = nl_socket_set_nonblocking(nl->sk)) < 0 ) {
		log_message(LOG_INFO, "Netlink: Cannot set nonblocking : (%s)",
			strerror(ret));
		return -1;
	}
#else
	*flags |= O_NONBLOCK;
	if (fcntl(nl->fd, F_SETFL, *flags) < 0) {
		log_message(LOG_INFO, "Netlink: Cannot F_SETFL socket : (%s)",
		       strerror(errno));
		return -1;
	}
#endif
	return 0;
}
Exemple #6
0
static ni_socket_t *
__ni_rtevent_sock_open(void)
{
	unsigned int recv_buff_len = __ni_rtevent_config_recv_buff_len();
	unsigned int mesg_buff_len = __ni_rtevent_config_mesg_buff_len();
	ni_rtevent_handle_t *handle;
	ni_socket_t *sock;
	int fd, ret;

	if (!(handle = __ni_rtevent_handle_new())) {
		ni_error("Unable to allocate rtnetlink event handle: %m");
		return NULL;
	}

	if (!(handle->nlsock = nl_socket_alloc())) {
		ni_error("Cannot allocate rtnetlink event socket: %m");
		__ni_rtevent_handle_free(handle);
		return NULL;
	}

	/*
	 * Modify the callback for processing valid messages...
	 * We may pass some kind of data (event filter?) too...
	 */
	nl_socket_modify_cb(handle->nlsock, NL_CB_VALID, NL_CB_CUSTOM,
				__ni_rtevent_process_cb, NULL);

	/* Required to receive async event notifications */
	nl_socket_disable_seq_check(handle->nlsock);

	if ((ret = nl_connect(handle->nlsock, NETLINK_ROUTE)) < 0) {
		ni_error("Cannot open rtnetlink: %s", nl_geterror(ret));
		__ni_rtevent_handle_free(handle);
		return NULL;
	}

	/* Enable non-blocking processing */
	nl_socket_set_nonblocking(handle->nlsock);

	fd = nl_socket_get_fd(handle->nlsock);
	if (!(sock = ni_socket_wrap(fd, SOCK_DGRAM))) {
		ni_error("Cannot wrap rtnetlink event socket: %m");
		__ni_rtevent_handle_free(handle);
		return NULL;
	}

	if (recv_buff_len) {
		if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE,
				(char *)&recv_buff_len, sizeof(recv_buff_len)) &&
		    setsockopt(fd, SOL_SOCKET, SO_RCVBUF,
				(char *)&recv_buff_len, sizeof(recv_buff_len))) {
			ni_warn("Unable to set netlink event receive buffer to %u bytes: %m",
					recv_buff_len);
		} else {
			ni_info("Using netlink event receive buffer of %u bytes",
					recv_buff_len);
		}
	}
	if (mesg_buff_len) {
		if (nl_socket_set_msg_buf_size(handle->nlsock, mesg_buff_len)) {
			ni_warn("Unable to set netlink event message buffer to %u bytes",
					mesg_buff_len);
		} else {
			ni_info("Using netlink event message buffer of %u bytes",
					mesg_buff_len);
		}
	}

	sock->user_data	= handle;
	sock->receive	= __ni_rtevent_receive;
	sock->close	= __ni_rtevent_close;
	sock->handle_error  = __ni_rtevent_sock_error_handler;
	sock->release_user_data = __ni_rtevent_sock_release_data;
	return sock;
}
Exemple #7
0
/**
 * virNetlinkEventServiceStart:
 *
 * start a monitor to receive netlink messages for libvirtd.
 * This registers a netlink socket with the event interface.
 *
 * Returns -1 if the monitor cannot be registered, 0 upon success
 */
int
virNetlinkEventServiceStart(void)
{
    virNetlinkEventSrvPrivatePtr srv;
    int fd;
    int ret = -1;

    if (server)
        return 0;

    VIR_INFO("starting netlink event service");

    if (VIR_ALLOC(srv) < 0) {
        virReportOOMError();
        return -1;
    }

    if (virMutexInit(&srv->lock) < 0) {
        VIR_FREE(srv);
        return -1;
    }

    virNetlinkEventServerLock(srv);

    /* Allocate a new socket and get fd */
    srv->netlinknh = virNetlinkAlloc();

    if (!srv->netlinknh) {
        virReportSystemError(errno,
                             "%s", _("cannot allocate nlhandle for virNetlinkEvent server"));
        goto error_locked;
    }

    if (nl_connect(srv->netlinknh, NETLINK_ROUTE) < 0) {
        virReportSystemError(errno,
                             "%s", _("cannot connect to netlink socket"));
        goto error_server;
    }

    fd = nl_socket_get_fd(srv->netlinknh);

    if (fd < 0) {
        virReportSystemError(errno,
                             "%s", _("cannot get netlink socket fd"));
        goto error_server;
    }

    if (nl_socket_set_nonblocking(srv->netlinknh)) {
        virReportSystemError(errno, "%s",
                             _("cannot set netlink socket nonblocking"));
        goto error_server;
    }

    if ((srv->eventwatch = virEventAddHandle(fd,
                                             VIR_EVENT_HANDLE_READABLE,
                                             virNetlinkEventCallback,
                                             srv, NULL)) < 0) {
        netlinkError(VIR_ERR_INTERNAL_ERROR, "%s",
                     _("Failed to add netlink event handle watch"));
        goto error_server;
    }

    srv->netlinkfd = fd;
    VIR_DEBUG("netlink event listener on fd: %i running", fd);

    ret = 0;
    server = srv;

error_server:
    if (ret < 0) {
        nl_close(srv->netlinknh);
        virNetlinkFree(srv->netlinknh);
    }
error_locked:
    virNetlinkEventServerUnlock(srv);
    if (ret < 0) {
        virMutexDestroy(&srv->lock);
        VIR_FREE(srv);
    }
    return ret;
}
Exemple #8
0
/**
 * virNetlinkEventServiceStart:
 *
 * start a monitor to receive netlink messages for libvirtd.
 * This registers a netlink socket with the event interface.
 *
 * @protocol: netlink protocol
 * @groups: broadcast groups to join in
 * Returns -1 if the monitor cannot be registered, 0 upon success
 */
int
virNetlinkEventServiceStart(unsigned int protocol, unsigned int groups)
{
    virNetlinkEventSrvPrivatePtr srv;
    int fd;
    int ret = -1;

    if (protocol >= MAX_LINKS) {
        virReportSystemError(EINVAL,
                             _("invalid protocol argument: %d"), protocol);
        return -EINVAL;
    }

    if (server[protocol])
        return 0;

    VIR_INFO("starting netlink event service with protocol %d", protocol);

    if (VIR_ALLOC(srv) < 0)
        return -1;

    if (virMutexInit(&srv->lock) < 0) {
        VIR_FREE(srv);
        return -1;
    }

    virNetlinkEventServerLock(srv);

    /* Allocate a new socket and get fd */
    if (!(srv->netlinknh = virNetlinkCreateSocket(protocol)))
        goto error_locked;

    fd = nl_socket_get_fd(srv->netlinknh);
    if (fd < 0) {
        virReportSystemError(errno,
                             "%s", _("cannot get netlink socket fd"));
        goto error_server;
    }

    if (groups && nl_socket_add_membership(srv->netlinknh, groups) < 0) {
        virReportSystemError(errno,
                             "%s", _("cannot add netlink membership"));
        goto error_server;
    }

    if (nl_socket_set_nonblocking(srv->netlinknh)) {
        virReportSystemError(errno, "%s",
                             _("cannot set netlink socket nonblocking"));
        goto error_server;
    }

    if ((srv->eventwatch = virEventAddHandle(fd,
                                             VIR_EVENT_HANDLE_READABLE,
                                             virNetlinkEventCallback,
                                             srv, NULL)) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Failed to add netlink event handle watch"));
        goto error_server;
    }

    srv->netlinkfd = fd;
    VIR_DEBUG("netlink event listener on fd: %i running", fd);

    ret = 0;
    server[protocol] = srv;

 error_server:
    if (ret < 0) {
        nl_close(srv->netlinknh);
        virNetlinkFree(srv->netlinknh);
    }
 error_locked:
    virNetlinkEventServerUnlock(srv);
    if (ret < 0) {
        virMutexDestroy(&srv->lock);
        VIR_FREE(srv);
    }
    return ret;
}
Exemple #9
0
void
ind_ovs_port_added(uint32_t port_no, const char *ifname, of_mac_addr_t mac_addr)
{
    indigo_error_t err;

    if (ind_ovs_ports[port_no]) {
        return;
    }

    struct ind_ovs_port *port = calloc(1, sizeof(*port));
    if (port == NULL) {
        LOG_ERROR("failed to allocate port");
        return;
    }

    strncpy(port->ifname, ifname, sizeof(port->ifname));
    port->dp_port_no = port_no;
    port->mac_addr = mac_addr;
    aim_ratelimiter_init(&port->upcall_log_limiter, 1000*1000, 5, NULL);
    aim_ratelimiter_init(&port->pktin_limiter, PORT_PKTIN_INTERVAL, PORT_PKTIN_BURST_SIZE, NULL);
    pthread_mutex_init(&port->quiesce_lock, NULL);
    pthread_cond_init(&port->quiesce_cvar, NULL);

    port->notify_socket = ind_ovs_create_nlsock();
    if (port->notify_socket == NULL) {
        goto cleanup_port;
    }

    if (nl_socket_set_nonblocking(port->notify_socket) < 0) {
        LOG_ERROR("failed to set netlink socket nonblocking");
        goto cleanup_port;
    }

    struct nl_msg *msg = ind_ovs_create_nlmsg(ovs_vport_family, OVS_VPORT_CMD_SET);
    nla_put_u32(msg, OVS_VPORT_ATTR_PORT_NO, port_no);
    nla_put_u32(msg, OVS_VPORT_ATTR_UPCALL_PID,
                nl_socket_get_local_port(port->notify_socket));
    err = ind_ovs_transact(msg);
    if (err < 0) {
        LOG_ERROR("datapath failed to configure port %s", ifname);
        goto cleanup_port;
    }

    if (!ind_ovs_get_interface_flags(ifname, &port->ifflags)) {
        /* Bring interface up if not already */
        if (!(port->ifflags & IFF_UP)) {
            port->ifflags |= IFF_UP;
            (void) ind_ovs_set_interface_flags(ifname, port->ifflags);
        }
    } else {
        /* Not a netdev, fake the interface flags */
        port->ifflags = IFF_UP;
    }

    /* Ensure port is fully populated before publishing it. */
    __sync_synchronize();

    ind_ovs_ports[port_no] = port;

    if ((err = port_status_notify(port_no, OF_PORT_CHANGE_REASON_ADD)) < 0) {
        LOG_WARN("failed to notify controller of port addition");
        /* Can't cleanup the port because it's already visible to other
         * threads. */
    }

    ind_ovs_upcall_register(port);
    LOG_INFO("Added port %s", port->ifname);
    ind_ovs_kflow_invalidate_all();
    return;

cleanup_port:
    assert(ind_ovs_ports[port_no] == NULL);
    if (port->notify_socket) {
        nl_socket_free(port->notify_socket);
    }
    free(port);
}
Exemple #10
0
/* Create a socket to netlink interface_t */
static int
netlink_socket(nl_handle_t *nl, int flags, int group, ...)
{
	int ret;
	va_list gp;

	memset(nl, 0, sizeof (*nl));

#ifdef _HAVE_LIBNL3_
	/* We need to keep libnl3 in step with our netlink socket creation.  */
	nl->sk = nl_socket_alloc();
	if ( nl->sk == NULL ) {
		log_message(LOG_INFO, "Netlink: Cannot allocate netlink socket" );
		return -1;
	}

	ret = nl_connect(nl->sk, NETLINK_ROUTE);
	if (ret != 0) {
		log_message(LOG_INFO, "Netlink: Cannot open netlink socket : (%d)", ret);
		return -1;
	}

	/* Unfortunately we can't call nl_socket_add_memberships() with variadic arguments
	 * from a variadic argument list passed to us
	 */
	va_start(gp, group);
	while (group != 0) {
		if (group < 0) {
			va_end(gp);
			return -1;
		}

		if ((ret = nl_socket_add_membership(nl->sk, group))) {
			log_message(LOG_INFO, "Netlink: Cannot add socket membership 0x%x : (%d)", group, ret);
			return -1;
		}

		group = va_arg(gp,int);
	}
	va_end(gp);

	if (flags & SOCK_NONBLOCK) {
		if ((ret = nl_socket_set_nonblocking(nl->sk))) {
			log_message(LOG_INFO, "Netlink: Cannot set netlink socket non-blocking : (%d)", ret);
			return -1;
		}
	}

	if ((ret = nl_socket_set_buffer_size(nl->sk, IF_DEFAULT_BUFSIZE, 0))) {
		log_message(LOG_INFO, "Netlink: Cannot set netlink buffer size : (%d)", ret);
		return -1;
	}

	nl->nl_pid = nl_socket_get_local_port(nl->sk);

	nl->fd = nl_socket_get_fd(nl->sk);

	/* Set CLOEXEC */
	fcntl(nl->fd, F_SETFD, fcntl(nl->fd, F_GETFD) | FD_CLOEXEC);
#else
	socklen_t addr_len;
	struct sockaddr_nl snl;
#if !HAVE_DECL_SOCK_NONBLOCK
	int sock_flags = flags;
	flags &= ~SOCK_NONBLOCK;
#endif

	nl->fd = socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC | flags, NETLINK_ROUTE);
	if (nl->fd < 0) {
		log_message(LOG_INFO, "Netlink: Cannot open netlink socket : (%s)",
		       strerror(errno));
		return -1;
	}

#if !HAVE_DECL_SOCK_NONBLOCK
	if ((sock_flags & SOCK_NONBLOCK) &&
	    set_sock_flags(nl->fd, F_SETFL, O_NONBLOCK))
		return -1;
#endif

	memset(&snl, 0, sizeof (snl));
	snl.nl_family = AF_NETLINK;

	ret = bind(nl->fd, (struct sockaddr *) &snl, sizeof (snl));
	if (ret < 0) {
		log_message(LOG_INFO, "Netlink: Cannot bind netlink socket : (%s)",
		       strerror(errno));
		close(nl->fd);
		return -1;
	}

	/* Join the requested groups */
	va_start(gp, group);
	while (group != 0) {
		if (group < 0) {
			va_end(gp);
			return -1;
		}

		ret = setsockopt(nl->fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &group, sizeof(group));
		if (ret < 0) {
			log_message(LOG_INFO, "Netlink: Cannot add membership on netlink socket : (%s)",
			       strerror(errno));
			va_end(gp);
			return -1;
		}

		group = va_arg(gp,int);
	}
	va_end(gp);

	addr_len = sizeof (snl);
	ret = getsockname(nl->fd, (struct sockaddr *) &snl, &addr_len);
	if (ret < 0 || addr_len != sizeof (snl)) {
		log_message(LOG_INFO, "Netlink: Cannot getsockname : (%s)",
		       strerror(errno));
		close(nl->fd);
		return -1;
	}

	if (snl.nl_family != AF_NETLINK) {
		log_message(LOG_INFO, "Netlink: Wrong address family %d",
		       snl.nl_family);
		close(nl->fd);
		return -1;
	}

	/* Save the port id for checking message source later */
	nl->nl_pid = snl.nl_pid;

	/* Set default rcvbuf size */
	if_setsockopt_rcvbuf(&nl->fd, IF_DEFAULT_BUFSIZE);
#endif

	nl->seq = (uint32_t)time(NULL);

	if (nl->fd < 0)
		return -1;

	return ret;
}
Exemple #11
0
int netlink_wrapper::open_channel()
{
	auto_unlocker lock(m_cache_lock);
	nl_logdbg("opening netlink channel");

	/*
	 // build to subscriptions groups mask for indicating what type of events the kernel will send on channel
	 unsigned subscriptions = ~RTMGRP_TC;
	 if (netlink_route_group_mask & nlgrpLINK) {
	 subscriptions |= (1 << (RTNLGRP_LINK - 1));
	 }
	 if (netlink_route_group_mask & nlgrpADDRESS) {
	 if (!m_preferred_family || m_preferred_family == AF_INET)
	 subscriptions |= (1 << (RTNLGRP_IPV4_IFADDR - 1));
	 if (!m_preferred_family || m_preferred_family == AF_INET6)
	 subscriptions |= (1 << (RTNLGRP_IPV6_IFADDR - 1));
	 }
	 if (netlink_route_group_mask & nlgrpROUTE) {
	 if (!m_preferred_family || m_preferred_family == AF_INET)
	 subscriptions |= (1 << (RTNLGRP_IPV4_ROUTE - 1));
	 if (!m_preferred_family || m_preferred_family == AF_INET6)
	 subscriptions |= (1 << (RTNLGRP_IPV4_ROUTE - 1));
	 }
	 if (netlink_route_group_mask & nlgrpPREFIX) {
	 if (!m_preferred_family || m_preferred_family == AF_INET6)
	 subscriptions |= (1 << (RTNLGRP_IPV6_PREFIX - 1));
	 }
	 if (netlink_route_group_mask & nlgrpNEIGH) {
	 subscriptions |= (1 << (RTNLGRP_NEIGH - 1));
	 }
	 */

	// Allocate a new netlink handle
	m_handle = nl_handle_alloc();

	BULLSEYE_EXCLUDE_BLOCK_START
	if (m_handle == NULL) {
		nl_logerr("failed to allocate netlink handle, nl_errno=%d", nl_get_errno());
		return -1;
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	// set internal structure to pass the handle with callbacks from netlink
	g_nl_rcv_arg.handle = m_handle;

	// if multiple handles being allocated then a unique netlink PID need to be provided
	// If port is 0, a unique port identifier will be generated automatically as a unique PID
	nl_socket_set_local_port(m_handle, 0);


	//Disables checking of sequence numbers on the netlink handle.
	//This is required to allow messages to be processed which were not requested by a preceding request message, e.g. netlink events.
	nl_disable_sequence_check(m_handle);

	//joining group
	//nl_join_groups(m_handle, 0);

	// Allocate a new cache manager for RTNETLINK
	// NL_AUTO_PROVIDE = automatically provide the caches added to the manager.
	m_mngr = nl_cache_mngr_alloc(m_handle, NETLINK_ROUTE, NL_AUTO_PROVIDE);

	BULLSEYE_EXCLUDE_BLOCK_START
	if (!m_mngr) {
		nl_logerr("Fail to allocate cac he manager");
		return -1;
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	nl_logdbg("netlink socket is open");

	m_cache_neigh = nl_cache_mngr_add(m_mngr, "route/neigh", neigh_cache_callback);
	m_cache_link = nl_cache_mngr_add(m_mngr, "route/link", link_cache_callback);
	m_cache_route = nl_cache_mngr_add(m_mngr, "route/route", route_cache_callback);

	// set custom callback for every message to update message
	nl_socket_modify_cb(m_handle, NL_CB_MSG_IN, NL_CB_CUSTOM, nl_msg_rcv_cb ,NULL);

	// set the socket non-blocking
	BULLSEYE_EXCLUDE_BLOCK_START
	if (nl_socket_set_nonblocking(m_handle)) {
		nl_logerr("Failed to set the socket non-blocking");
		return -1;
	}
	BULLSEYE_EXCLUDE_BLOCK_END

	return 0;

}