NetLinkManager::NetLinkManager() : _initialized(false), _sock(NULL), _refresh_cache(false) { ibrcommon::MutexLock l(_call_mutex); _handle = nl_handle_alloc(); nl_connect(_handle, NETLINK_ROUTE); _link_cache = rtnl_link_alloc_cache(_handle); if (_link_cache == NULL) { nl_close(_handle); nl_handle_destroy(_handle); throw ibrcommon::vsocket_exception("netlink cache allocation failed"); } _addr_cache = rtnl_addr_alloc_cache(_handle); if (_addr_cache == NULL) { nl_close(_handle); nl_handle_destroy(_handle); nl_cache_free(_link_cache); _link_cache = NULL; throw ibrcommon::vsocket_exception("netlink cache allocation failed"); } _initialized = true; // create a new socket for the netlink interface _sock = new ibrcommon::vsocket(); }
/* ---------------------------------------------------------------------- */ static int nl_open (pid_t *pid) { struct sockaddr_nl nladdr; int sd; sd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sd < 0) return -1; memset (&nladdr, 0, sizeof (nladdr)); nladdr.nl_family = AF_NETLINK; if (bind (sd, (struct sockaddr *) &nladdr, sizeof (nladdr)) < 0) { nl_close (sd); return -1; } if (pid) { socklen_t len = sizeof(nladdr); if (getsockname (sd, (struct sockaddr *) &nladdr, &len) < 0) { nl_close (sd); return -1; } *pid = nladdr.nl_pid; } return sd; }
/** * Free cache manager and all caches. * @arg mngr Cache manager. * * Release all resources held by a cache manager. */ void nl_cache_mngr_free(struct nl_cache_mngr *mngr) { int i; if (!mngr) return; if (mngr->cm_sock) nl_close(mngr->cm_sock); if (mngr->cm_sync_sock) { nl_close(mngr->cm_sync_sock); nl_socket_free(mngr->cm_sync_sock); } if (mngr->cm_flags & NL_ALLOCATED_SOCK) nl_socket_free(mngr->cm_sock); for (i = 0; i < mngr->cm_nassocs; i++) { if (mngr->cm_assocs[i].ca_cache) { nl_cache_mngt_unprovide(mngr->cm_assocs[i].ca_cache); nl_cache_free(mngr->cm_assocs[i].ca_cache); } } free(mngr->cm_assocs); NL_DBG(1, "Cache manager %p freed\n", mngr); free(mngr); }
int netlink_request(void *request, __u16 request_len, int (*cb)(struct nl_msg *, void *), void *cb_arg) { struct nl_sock *sk; enum nl_cb_type callbacks[] = { NL_CB_VALID, NL_CB_FINISH, NL_CB_ACK }; int i; int error; sk = nl_socket_alloc(); if (!sk) { log_err(ERR_ALLOC_FAILED, "Could not allocate a socket; cannot speak to the NAT64."); return -ENOMEM; } for (i = 0; i < (sizeof(callbacks) / sizeof(callbacks[0])); i++) { error = nl_socket_modify_cb(sk, callbacks[i], NL_CB_CUSTOM, cb, cb_arg); if (error < 0) { log_err(ERR_NETLINK, "Could not register response handler. " "I won't be able to parse the NAT64's response, so I won't send the request.\n" "Netlink error message: %s (Code %d)", nl_geterror(error), error); goto fail_free; } } error = nl_connect(sk, NETLINK_USERSOCK); if (error < 0) { log_err(ERR_NETLINK, "Could not bind the socket to the NAT64.\n" "Netlink error message: %s (Code %d)", nl_geterror(error), error); goto fail_free; } error = nl_send_simple(sk, MSG_TYPE_NAT64, 0, request, request_len); if (error < 0) { log_err(ERR_NETLINK, "Could not send the request to the NAT64 (is it really up?).\n" "Netlink error message: %s (Code %d)", nl_geterror(error), error); goto fail_close; } error = nl_recvmsgs_default(sk); if (error < 0) { log_err(ERR_NETLINK, "%s (System error %d)", nl_geterror(error), error); goto fail_close; } nl_close(sk); nl_socket_free(sk); return 0; fail_close: nl_close(sk); /* Fall through. */ fail_free: nl_socket_free(sk); return -EINVAL; }
static void accept_handler(nl_event_t *ev) { nl_socket_t *sock; nl_stream_t *s; int rc; sock = ev->data; log_trace("#%d accept_handler", sock->fd); s = sock->data; s->error = 0; for ( ; ; ) { rc = nl_accept(sock, &s->accepted_sock); if (rc == -1) { if (sock->error) { s->error = 1; nl_stream_close(s); break; } else if (s->accepted_sock.error) { continue; } else { break; } } s->accepted = 0; s->cbs.on_accepted(s); if (!s->accepted) { nl_close(&s->accepted_sock); } } }
int kern_bcache_init() { supsocket_t *sock; nl_bcache = nl_handle_alloc(); nl_disable_sequence_check(nl_bcache); nl_join_groups(nl_bcache, ~0); nl_cb_set(nl_handle_get_cb(nl_bcache), NL_CB_VALID, NL_CB_CUSTOM, nl_bcache_event, NULL); if (nl_connect(nl_bcache, NETLINK_IP6MBLTY) < 0) { debug_log(1, "nl_connect(NETLINK_IP6MBLTY) failed: %s.\n", strerror(errno)); nl_close(nl_bcache); nl_bcache = NULL; return -1; } fcntl(nl_handle_get_fd(nl_bcache), F_SETFL, O_NONBLOCK); sock = support_register_socket(nl_handle_get_fd(nl_bcache), nl_bcache_events_waiting, NULL, NULL); sock->mode = SUPSOCKET_READ; return 0; }
int main(int argc, char *argv[]) { struct nl_sock *sock; struct nl_msg *msg; void *hdr; int err; sock = nlt_alloc_socket(); nlt_connect(sock, NETLINK_GENERIC); msg = nlmsg_alloc(); if (msg == NULL) fatal(NLE_NOMEM, "Unable to allocate netlink message"); hdr = genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, GENL_ID_CTRL, 0, 0, CTRL_CMD_GETFAMILY, 1); if (hdr == NULL) fatal(ENOMEM, "Unable to write genl header"); if ((err = nla_put_u32(msg, CTRL_ATTR_FAMILY_ID, GENL_ID_CTRL)) < 0) fatal(err, "Unable to add attribute: %s", nl_geterror(err)); if ((err = nl_send_auto_complete(sock, msg)) < 0) fatal(err, "Unable to send message: %s", nl_geterror(err)); if ((err = nl_recvmsgs_default(sock)) < 0) fatal(err, "Unable to receive message: %s", nl_geterror(err)); nlmsg_free(msg); nl_close(sock); nl_socket_free(sock); return 0; }
static void nl_stream_destroy(nl_stream_t *s) { struct list_iterator_t it; nl_buf_t *buf; for (it = list_begin(s->tosend); !list_iterator_equal(list_end(s->tosend), it); it = list_iterator_next(it)) { buf = list_iterator_item(it); free(buf->buf); } list_destroy(s->tosend); while (s->encoders != NULL) { nl_stream_encoder_pop_back(s); } while (s->decoders != NULL) { nl_stream_decoder_pop_back(s); } log_trace("#%d destroyed", s->sock.fd); nl_close(&s->sock); if (s->cbs.on_closed != NULL) { s->cbs.on_closed(s); } }
int main(int argc, char *argv[]) { struct rtnl_link *link; struct nl_sock *sk; int err; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } link = rtnl_link_alloc(); rtnl_link_set_name(link, "my_bond"); if ((err = rtnl_link_delete(sk, link)) < 0) { nl_perror(err, "Unable to delete link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; }
int match_nl_table_cmd_to_type(FILE *fp, bool print, int valid, struct nlattr *tb[]) { unsigned int type, ifindex; int err; char iface[IFNAMSIZ]; struct nl_sock *fd = NULL; if (!tb[NET_MAT_IDENTIFIER_TYPE]) { MAT_LOG(ERR, "Warning: received rule msg without identifier type!\n"); return -EINVAL; } if (!tb[NET_MAT_IDENTIFIER]) { MAT_LOG(ERR, "Warning: received rule msg without identifier!\n"); return -EINVAL; } if (valid > 0 && !tb[valid]) { MAT_LOG(ERR, "Warning: received cmd without valid attribute expected %i\n", valid); return -ENOMSG; } if (nla_len(tb[NET_MAT_IDENTIFIER_TYPE]) < (int)sizeof(type)) { MAT_LOG(ERR, "Warning: invalid identifier type len\n"); return -EINVAL; } type = nla_get_u32(tb[NET_MAT_IDENTIFIER_TYPE]); switch (type) { case NET_MAT_IDENTIFIER_IFINDEX: fd = nl_socket_alloc(); err = nl_connect(fd, NETLINK_ROUTE); if (err < 0) { MAT_LOG(ERR,"Warning: Unable to connect socket\n"); break; } err = rtnl_link_alloc_cache(fd, AF_UNSPEC, &link_cache); if (err < 0) { MAT_LOG(ERR,"Warning: Unable to allocate cache\n"); break; } ifindex = nla_get_u32(tb[NET_MAT_IDENTIFIER]); rtnl_link_i2name(link_cache, (int)ifindex, iface, IFNAMSIZ); if (ifindex) pfprintf(fp, print, "%s (%u):\n", iface, ifindex); break; default: MAT_LOG(ERR, "Warning: unknown interface identifier type %i\n", type); break; } if (fd) { nl_close(fd); nl_socket_free(fd); } return 0; }
/** * virNetlinkEventServiceStop: * * stop the monitor to receive netlink messages for libvirtd. * This removes the netlink socket fd from the event handler. * * @protocol: netlink protocol * * Returns -1 if the monitor cannot be unregistered, 0 upon success */ int virNetlinkEventServiceStop(unsigned int protocol) { if (protocol >= MAX_LINKS) return -EINVAL; virNetlinkEventSrvPrivatePtr srv = server[protocol]; size_t i; VIR_INFO("stopping netlink event service"); if (!server[protocol]) return 0; virNetlinkEventServerLock(srv); nl_close(srv->netlinknh); virNetlinkFree(srv->netlinknh); virEventRemoveHandle(srv->eventwatch); /* free any remaining clients on the list */ for (i = 0; i < srv->handlesCount; i++) { if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID) virNetlinkEventRemoveClientPrimitive(i, protocol); } server[protocol] = NULL; virNetlinkEventServerUnlock(srv); virMutexDestroy(&srv->lock); VIR_FREE(srv); return 0; }
/** * virNetlinkEventServiceStop: * * stop the monitor to receive netlink messages for libvirtd. * This removes the netlink socket fd from the event handler. * * Returns -1 if the monitor cannot be unregistered, 0 upon success */ int virNetlinkEventServiceStop(void) { virNetlinkEventSrvPrivatePtr srv = server; int i; VIR_INFO("stopping netlink event service"); if (!server) return 0; virNetlinkEventServerLock(srv); nl_close(srv->netlinknh); virNetlinkFree(srv->netlinknh); virEventRemoveHandle(srv->eventwatch); /* free any remaining clients on the list */ for (i = 0; i < srv->handlesCount; i++) { if (srv->handles[i].deleted == VIR_NETLINK_HANDLE_VALID) virNetlinkEventRemoveClientPrimitive(i); } server = 0; virNetlinkEventServerUnlock(srv); virMutexDestroy(&srv->lock); VIR_FREE(srv); return 0; }
void TNl::Disconnect() { if (Sock) { nl_close(Sock); nl_socket_free(Sock); Sock = nullptr; } }
/** * virNetlinkEventServiceStopAll: * * Stop all the monitors to receive netlink messages for libvirtd. * * Returns -1 if any monitor cannot be unregistered, 0 upon success */ int virNetlinkEventServiceStopAll(void) { size_t i, j; virNetlinkEventSrvPrivatePtr srv = NULL; VIR_INFO("stopping all netlink event services"); for (i = 0; i < MAX_LINKS; i++) { srv = server[i]; if (!srv) continue; virNetlinkEventServerLock(srv); nl_close(srv->netlinknh); virNetlinkFree(srv->netlinknh); virEventRemoveHandle(srv->eventwatch); for (j = 0; j < srv->handlesCount; j++) { if (srv->handles[j].deleted == VIR_NETLINK_HANDLE_VALID) virNetlinkEventRemoveClientPrimitive(j, i); } server[i] = NULL; virNetlinkEventServerUnlock(srv); virMutexDestroy(&srv->lock); VIR_FREE(srv); } return 0; }
void ompi_btl_usnic_rtnl_sk_free(struct usnic_rtnl_sk *unlsk) { if (unlsk != NULL) { nl_close(unlsk->sock); nl_socket_free(unlsk->sock); free(unlsk); } }
void usnic_rtnl_sk_free(struct usnic_rtnl_sk* u_nlsk) { if (u_nlsk != NULL) { nl_close(u_nlsk->nlh); nl_handle_destroy(u_nlsk->nlh); free(u_nlsk); } }
int main(int argc, char *argv[]) { struct nl_handle *nlh; struct rtnl_addr *addr; struct nl_addr *local; int err = 1; if (argc < 3 || !strcmp(argv[1], "-h")) { printf("Usage: nl-addr-delete <addr> <ifindex>\n"); goto errout; } if (nltool_init(argc, argv) < 0) goto errout; nlh = nltool_alloc_handle(); if (!nlh) goto errout; addr = rtnl_addr_alloc(); if (!addr) goto errout_free_handle; if (nltool_connect(nlh, NETLINK_ROUTE) < 0) goto errout_free_addr; local = nltool_addr_parse(argv[1]); if (!local) goto errout_close; if (rtnl_addr_set_local(addr, local) < 0) { fprintf(stderr, "Unable to set local address: %s\n", nl_geterror()); goto errout_addr_put; } rtnl_addr_set_ifindex(addr, strtoul(argv[2], NULL, 0)); if (rtnl_addr_delete(nlh, addr, 0) < 0) { fprintf(stderr, "Unable to delete address: %s\n", nl_geterror()); goto errout_addr_put; } err = 0; errout_addr_put: nl_addr_put(local); errout_close: nl_close(nlh); errout_free_addr: rtnl_addr_put(addr); errout_free_handle: nl_handle_destroy(nlh); errout: return err; }
int main(int argc, char *argv[]) { struct nl_handle *nlh; struct nl_cache *link_cache, *addr_cache; struct rtnl_addr *addr; struct nl_dump_params params = { .dp_fd = stdout, .dp_type = NL_DUMP_BRIEF }; int err = 1; if (nltool_init(argc, argv) < 0) return -1; nlh = nltool_alloc_handle(); if (!nlh) return -1; addr = rtnl_addr_alloc(); if (!addr) goto errout; if (argc < 2 || !strcmp(argv[1], "-h")) print_usage(); if (nltool_connect(nlh, NETLINK_ROUTE) < 0) goto errout_free; link_cache = nltool_alloc_link_cache(nlh); if (!link_cache) goto errout_close; addr_cache = nltool_alloc_addr_cache(nlh); if (!addr_cache) goto errout_link_cache; params.dp_type = nltool_parse_dumptype(argv[1]); if (params.dp_type < 0) goto errout_addr_cache; get_filter(addr, argc, argv, 2, link_cache); nl_cache_dump_filter(addr_cache, ¶ms, (struct nl_object *) addr); err = 0; errout_addr_cache: nl_cache_free(addr_cache); errout_link_cache: nl_cache_free(link_cache); errout_close: nl_close(nlh); errout_free: rtnl_addr_put(addr); errout: return err; }
void kern_bcache_shutdown() { if (nl_bcache) { support_unregister_socket(nl_handle_get_fd(nl_bcache)); nl_close(nl_bcache); nl_handle_destroy(nl_bcache); nl_bcache = NULL; } }
int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link, *link2; struct nl_sock *sk; uint32_t tb_id; int err; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } if (!(link = rtnl_link_vrf_alloc())) { fprintf(stderr, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "vrf-red"); if ((err = rtnl_link_vrf_set_tableid(link, 10)) < 0) { nl_perror(err, "Unable to set VRF table id"); return err; } if ((err = rtnl_link_add(sk, link, NLM_F_CREATE)) < 0) { nl_perror(err, "Unable to add link"); return err; } if ((err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache)) < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if (!(link2 = rtnl_link_get_by_name(link_cache, "vrf-red"))) { fprintf(stderr, "Unable to lookup vrf-red"); return -1; } if ((err = rtnl_link_vrf_get_tableid(link2, &tb_id)) < 0) { nl_perror(err, "Unable to get VRF table id"); return err; } if (tb_id != 10) { fprintf(stderr, "Mismatch with VRF table id\n"); } rtnl_link_put(link); nl_close(sk); return 0; }
static void lib_fini(void) { if (lib_cfg.head == NULL) { #ifdef KNET_LINUX nl_close(lib_cfg.nlsock); nl_socket_free(lib_cfg.nlsock); #endif close(lib_cfg.ioctlfd); lib_init = 0; } }
static void ovs_global_init(void) { struct nl_handle hnd; if (genl_open(&hnd)) { vport_genl_id = 0; return; } vport_genl_id = genl_family_id(&hnd, OVS_VPORT_FAMILY); nl_close(&hnd); return; }
int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link; struct in_addr addr; struct nl_sock *sk; int err, if_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache); if ( err < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if_index = rtnl_link_name2i(link_cache, "eno16777736"); if (!if_index) { fprintf(stderr, "Unable to lookup eno16777736"); return -1; } link = rtnl_link_sit_alloc(); if(!link) { nl_perror(err, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "sit-tun"); rtnl_link_sit_set_link(link, if_index); inet_pton(AF_INET, "192.168.254.12", &addr.s_addr); rtnl_link_sit_set_local(link, addr.s_addr); inet_pton(AF_INET, "192.168.254.13", &addr.s_addr); rtnl_link_sit_set_remote(link, addr.s_addr); rtnl_link_sit_set_ttl(link, 64); err = rtnl_link_add(sk, link, NLM_F_CREATE); if (err < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; }
int main(int argc, char *argv[]) { struct nl_cache *link_cache; struct rtnl_link *link; struct in6_addr addr; struct nl_sock *sk; int err, if_index; sk = nl_socket_alloc(); if ((err = nl_connect(sk, NETLINK_ROUTE)) < 0) { nl_perror(err, "Unable to connect socket"); return err; } err = rtnl_link_alloc_cache(sk, AF_UNSPEC, &link_cache); if ( err < 0) { nl_perror(err, "Unable to allocate cache"); return err; } if_index = rtnl_link_name2i(link_cache, "ens33"); if (!if_index) { fprintf(stderr, "Unable to lookup ens33"); return -1; } link = rtnl_link_ip6_tnl_alloc(); if(!link) { nl_perror(err, "Unable to allocate link"); return -1; } rtnl_link_set_name(link, "ip6tnl-tun"); rtnl_link_ip6_tnl_set_link(link, if_index); inet_pton(AF_INET6, "2607:f0d0:1002:51::4", &addr); rtnl_link_ip6_tnl_set_local(link, &addr); inet_pton(AF_INET6, "2607:f0d0:1002:52::5", &addr); rtnl_link_ip6_tnl_set_remote(link, &addr); err = rtnl_link_add(sk, link, NLM_F_CREATE); if (err < 0) { nl_perror(err, "Unable to add link"); return err; } rtnl_link_put(link); nl_close(sk); return 0; }
void lowpansocket::getAddress(struct ieee802154_addr *ret, const vinterface &iface) { #if defined HAVE_LIBNL || HAVE_LIBNL3 #ifdef HAVE_LIBNL3 struct nl_sock *nl = nl_socket_alloc(); #else struct nl_handle *nl = nl_handle_alloc(); #endif unsigned char *buf = NULL; struct sockaddr_nl nla; struct nlattr *attrs[IEEE802154_ATTR_MAX+1]; struct genlmsghdr *ghdr; struct nlmsghdr *nlh; struct nl_msg *msg; int family; if (!nl) return; genl_connect(nl); /* Build and send message */ msg = nlmsg_alloc(); family = genl_ctrl_resolve(nl, "802.15.4 MAC"); genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_ECHO, IEEE802154_LIST_IFACE, 1); nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, iface.toString().c_str()); nl_send_auto_complete(nl, msg); nlmsg_free(msg); /* Receive and parse answer */ nl_recv(nl, &nla, &buf, NULL); nlh = (struct nlmsghdr*)buf; genlmsg_parse(nlh, 0, attrs, IEEE802154_ATTR_MAX, ieee802154_policy); ghdr = (genlmsghdr*)nlmsg_data(nlh); if (!attrs[IEEE802154_ATTR_SHORT_ADDR] || !attrs[IEEE802154_ATTR_SHORT_ADDR]) return; // We only handle short addresses right now ret->addr_type = IEEE802154_ADDR_SHORT; ret->pan_id = nla_get_u16(attrs[IEEE802154_ATTR_PAN_ID]); ret->short_addr = nla_get_u16(attrs[IEEE802154_ATTR_SHORT_ADDR]); free(buf); nl_close(nl); #ifdef HAVE_LIBNL3 nl_socket_free(nl); #else nl_handle_destroy(nl); #endif #endif }
NetLinkManager::~NetLinkManager() { stop(); join(); // destroy the socket for the netlink interface delete _sock; nl_close(_handle); nl_cache_free(_addr_cache); nl_cache_free(_link_cache); nl_handle_destroy(_handle); }
void NetLinkManager::run() { struct nl_handle *handle = nl_handle_alloc(); nl_connect(handle, NETLINK_ROUTE); // init route messages nl_socket_add_membership(handle, RTNLGRP_IPV4_IFADDR); // IPv6 requires further support in the parsing procedures! // nl_socket_add_membership(handle, RTNLGRP_IPV6_IFADDR); nl_socket_add_membership(handle, RTNLGRP_LINK); // add netlink fd to vsocket _sock->add(nl_socket_get_fd(handle)); try { while (_initialized) { std::list<int> fds; _sock->select(fds, NULL); int fd = fds.front(); // create a new event object NetLinkManagerEvent lme(fd); // ignore if the event is unknown if (lme.getType() == LinkManagerEvent::EVENT_UNKOWN) continue; // ignore if this is an wireless extension event if (lme.isWirelessExtension()) continue; // need to refresh the cache { ibrcommon::MutexLock l(_call_mutex); _refresh_cache = true; } // print out some debugging IBRCOMMON_LOGGER_DEBUG(10) << lme.toString() << IBRCOMMON_LOGGER_ENDL; // notify all subscribers about this event raiseEvent(lme); } } catch (const vsocket_exception&) { // stopped / interrupted IBRCOMMON_LOGGER(error) << "NetLink connection stopped" << IBRCOMMON_LOGGER_ENDL; } nl_close(handle); nl_handle_destroy(handle); }
int main(int argc, char *argv[]) { struct nl_handle *nlh; struct nl_cache *link_cache; int err = 1; if (nltool_init(argc, argv) < 0) return -1; if (argc < 3 || !strcmp(argv[1], "-h")) print_usage(); nlh = nltool_alloc_handle(); if (!nlh) return -1; if (nltool_connect(nlh, NETLINK_ROUTE) < 0) goto errout; link_cache = nltool_alloc_link_cache(nlh); if (!link_cache) goto errout_close; gargv = &argv[2]; gargc = argc - 2; if (!strcasecmp(argv[1], "all")) nl_cache_foreach(link_cache, dump_stats, NULL); else { int ifindex = strtoul(argv[1], NULL, 0); struct rtnl_link *link = rtnl_link_get(link_cache, ifindex); if (!link) { fprintf(stderr, "Could not find ifindex %d\n", ifindex); goto errout_link_cache; } dump_stats((struct nl_object *) link, NULL); rtnl_link_put(link); } err = 0; errout_link_cache: nl_cache_free(link_cache); errout_close: nl_close(nlh); errout: nl_handle_destroy(nlh); return err; }
int main() { struct nl_sock * sk; int cbarg; // nl_debug = 4; // setup netlink socket sk = nl_socket_alloc(); nl_socket_disable_seq_check(sk); // disable sequence number check genl_connect(sk); int id = genl_ctrl_resolve(sk, DEMO_FAMILY_NAME); struct nl_msg * msg; // create a messgae msg = nlmsg_alloc(); genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, id, 0, // hdrlen 0, // flags DEMO_CMD, // numeric command identifier DEMO_VERSION // interface version ); nla_put_string(msg, DEMO_ATTR1_STRING, "hola"); nla_put_u16(msg, DEMO_ATTR2_UINT16, 0xf1); // send it nl_send_auto(sk, msg); // handle reply struct nl_cb * cb = NULL; cb = nl_cb_alloc(NL_CB_CUSTOM); //nl_cb_set_all(cb, NL_CB_DEBUG, NULL, NULL); nl_cb_set_all(cb, NL_CB_CUSTOM, cb_handler, &cbarg); nl_cb_err(cb, NL_CB_DEBUG, NULL, NULL); int nrecv = nl_recvmsgs_report(sk, cb); printf("cbarg %d nrecv %d\n", cbarg, nrecv); // cleanup nlmsg_free(msg); nl_close(sk); nl_socket_free(sk); return 0; }
/* * Return an NETLINK_ROUTE cache. */ static struct nl_cache *_iface_get_link_cache(struct nl_handle **handle) { struct nl_cache *cache = NULL; if ((*handle = _iface_get_handle()) == NULL) { return NULL; } if ((cache = rtnl_link_alloc_cache(*handle)) == NULL) { nl_close(*handle); nl_handle_destroy(*handle); return NULL; } return cache; }