void ind_ovs_port_init(void) { int nlerr; route_cache_sock = nl_socket_alloc(); if (route_cache_sock == NULL) { LOG_ERROR("nl_socket_alloc failed"); abort(); } if ((nlerr = nl_cache_mngr_alloc(route_cache_sock, NETLINK_ROUTE, 0, &route_cache_mngr)) < 0) { LOG_ERROR("nl_cache_mngr_alloc failed: %s", nl_geterror(nlerr)); abort(); } if ((nlerr = nl_cache_mngr_add(route_cache_mngr, "route/link", link_change_cb, NULL, &link_cache)) < 0) { LOG_ERROR("nl_cache_mngr_add failed: %s", nl_geterror(nlerr)); abort(); } if (ind_soc_socket_register(nl_cache_mngr_get_fd(route_cache_mngr), (ind_soc_socket_ready_callback_f)route_cache_mngr_socket_cb, NULL) < 0) { LOG_ERROR("failed to register socket"); abort(); } netlink_callbacks = nl_cb_alloc(NL_CB_DEFAULT); if (netlink_callbacks == NULL) { LOG_ERROR("failed to allocate netlink callbacks"); abort(); } }
/** * Print a libnl error message * @arg s error message prefix * * Prints the error message of the call that failed last. * * If s is not NULL and *s is not a null byte the argument * string is printed, followed by a colon and a blank. Then * the error message and a new-line. */ void nl_perror(const char *s) { if (s && *s) fprintf(stderr, "%s: %s\n", s, nl_geterror()); else fprintf(stderr, "%s\n", nl_geterror()); }
static gboolean nlh_setup (struct nl_sock *nlh, nl_recvmsg_msg_cb_t valid_func, gpointer cb_data, GError **error) { int err; nl_socket_modify_cb (nlh, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, cb_data); if (valid_func) nl_socket_modify_cb (nlh, NL_CB_VALID, NL_CB_CUSTOM, valid_func, cb_data); err = nl_connect (nlh, NETLINK_ROUTE); if (err < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT, _("unable to connect to netlink for monitoring link status: %s"), nl_geterror (err)); return FALSE; } /* Enable unix socket peer credentials which we use for verifying that the * sender of the message is actually the kernel. */ if (nl_socket_set_passcred (nlh, 1) < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT, _("unable to enable netlink handle credential passing: %s"), nl_geterror (err)); return FALSE; } return TRUE; }
static gboolean sync_connection_setup (NMNetlinkMonitor *self, GError **error) { NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); #ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND struct nl_cache *addr_cache; #endif int err; /* Set up the event listener connection */ priv->nlh_sync = nl_socket_alloc (); if (!priv->nlh_sync) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_HANDLE, _("unable to allocate netlink handle for monitoring link status: %s"), nl_geterror (ENOMEM)); goto error; } if (!nlh_setup (priv->nlh_sync, NULL, self, error)) goto error; #ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND /* Work around apparent libnl bug; rtnl_addr requires that all * addresses have the "peer" attribute set in order to be compared * for equality, but this attribute is not normally set. As a * result, most addresses will not compare as equal even to * themselves, busting caching. */ rtnl_addr_alloc_cache (priv->nlh_sync, &addr_cache); g_warn_if_fail (addr_cache != NULL); nl_cache_get_ops (addr_cache)->co_obj_ops->oo_id_attrs &= ~0x80; nl_cache_free (addr_cache); #endif err = rtnl_link_alloc_cache (priv->nlh_sync, AF_UNSPEC, &priv->link_cache); if (err < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_LINK_CACHE, _("unable to allocate netlink link cache for monitoring link status: %s"), nl_geterror (err)); goto error; } nl_cache_mngt_provide (priv->link_cache); return TRUE; error: if (priv->link_cache) { nl_cache_free (priv->link_cache); priv->link_cache = NULL; } if (priv->nlh_sync) { nl_socket_free (priv->nlh_sync); priv->nlh_sync = NULL; } return FALSE; }
bool TaskstatsSocket::Open() { std::unique_ptr<nl_sock, decltype(&nl_socket_free)> nl( nl_socket_alloc(), nl_socket_free); if (!nl.get()) { LOG(ERROR) << "Failed to allocate netlink socket"; return false; } int ret = genl_connect(nl.get()); if (ret < 0) { LOG(ERROR) << nl_geterror(ret) << std::endl << "Unable to open netlink socket (are you root?)"; return false; } int family_id = genl_ctrl_resolve(nl.get(), TASKSTATS_GENL_NAME); if (family_id < 0) { LOG(ERROR) << nl_geterror(family_id) << std::endl << "Unable to determine taskstats family id (does your kernel support taskstats?)"; return false; } nl_ = std::move(nl); family_id_ = family_id; return true; }
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; }
TError TNlCgFilter::Remove(const TNlLink &link) { TError error = TError::Success(); struct rtnl_cls *cls; int ret; cls = rtnl_cls_alloc(); if (!cls) return TError(EError::Unknown, std::string("Unable to allocate filter object")); rtnl_tc_set_ifindex(TC_CAST(cls), link.GetIndex()); ret = rtnl_tc_set_kind(TC_CAST(cls), FilterType); if (ret < 0) { error = TError(EError::Unknown, std::string("Unable to set filter type: ") + nl_geterror(ret)); goto free_cls; } rtnl_cls_set_prio(cls, FilterPrio); rtnl_cls_set_protocol(cls, 0); rtnl_tc_set_parent(TC_CAST(cls), Parent); link.Dump("remove", cls); ret = rtnl_cls_delete(link.GetSock(), cls, 0); if (ret < 0) error = TError(EError::Unknown, std::string("Unable to remove filter: ") + nl_geterror(ret)); free_cls: rtnl_cls_put(cls); return error; }
int main(int argc, char *argv[]) { struct nl_cache_mngr *mngr; struct nl_cache *cache; int err, i; dp.dp_fd = stdout; signal(SIGINT, sigint); err = nl_cache_mngr_alloc(NULL, NETLINK_ROUTE, NL_AUTO_PROVIDE, &mngr); if (err < 0) nl_cli_fatal(err, "Unable to allocate cache manager: %s", nl_geterror(err)); for (i = 1; i < argc; i++) { err = nl_cache_mngr_add(mngr, argv[i], &change_cb, NULL, &cache); if (err < 0) nl_cli_fatal(err, "Unable to add cache %s: %s", argv[i], nl_geterror(err)); } while (!quit) { int err = nl_cache_mngr_poll(mngr, 1000); if (err < 0 && err != -NLE_INTR) nl_cli_fatal(err, "Polling failed: %s", nl_geterror(err)); nl_cache_mngr_info(mngr, &dp); } nl_cache_mngr_free(mngr); return 0; }
TError TNlHtb::Create(const TNlLink &link, uint32_t defaultClass) { TError error = TError::Success(); int ret; struct rtnl_qdisc *qdisc; qdisc = rtnl_qdisc_alloc(); if (!qdisc) return TError(EError::Unknown, std::string("Unable to allocate qdisc object")); rtnl_tc_set_ifindex(TC_CAST(qdisc), link.GetIndex()); rtnl_tc_set_parent(TC_CAST(qdisc), Parent); rtnl_tc_set_handle(TC_CAST(qdisc), Handle); ret = rtnl_tc_set_kind(TC_CAST(qdisc), "htb"); if (ret < 0) { error = TError(EError::Unknown, std::string("Unable to set qdisc type: ") + nl_geterror(ret)); goto free_qdisc; } rtnl_htb_set_defcls(qdisc, TC_H_MIN(defaultClass)); rtnl_htb_set_rate2quantum(qdisc, 10); link.Dump("add", qdisc); ret = rtnl_qdisc_add(link.GetSock(), qdisc, NLM_F_CREATE); if (ret < 0) error = TError(EError::Unknown, std::string("Unable to add qdisc: ") + nl_geterror(ret)); free_qdisc: rtnl_qdisc_put(qdisc); return error; }
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 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; }
int netem_set_params(const char *iface, struct netem_params *params) { struct rtnl_link *link; struct rtnl_qdisc *qdisc; int err; pthread_mutex_lock(&nl_sock_mutex); /* filter link by name */ if ((link = rtnl_link_get_by_name(link_cache, iface)) == NULL) { fprintf(stderr, "unknown interface/link name.\n"); pthread_mutex_unlock(&nl_sock_mutex); return -1; } if (!(qdisc = rtnl_qdisc_alloc())) { /* OOM error */ fprintf(stderr, "couldn't alloc qdisc\n"); pthread_mutex_unlock(&nl_sock_mutex); return -1; } rtnl_tc_set_link(TC_CAST(qdisc), link); rtnl_tc_set_parent(TC_CAST(qdisc), TC_H_ROOT); rtnl_tc_set_kind(TC_CAST(qdisc), "netem"); rtnl_netem_set_delay(qdisc, params->delay * 1000); /* expects microseconds */ rtnl_netem_set_jitter(qdisc, params->jitter * 1000); /* params->loss is given in 10ths of a percent */ rtnl_netem_set_loss(qdisc, (params->loss * (UINT_MAX / 1000))); /* Submit request to kernel and wait for response */ err = rtnl_qdisc_add(sock, qdisc, NLM_F_CREATE | NLM_F_REPLACE); /* Return the qdisc object to free memory resources */ rtnl_qdisc_put(qdisc); if (err < 0) { fprintf(stderr, "Unable to add qdisc: %s\n", nl_geterror(err)); pthread_mutex_unlock(&nl_sock_mutex); return err; } if ((err = nl_cache_refill(sock, link_cache)) < 0) { fprintf(stderr, "Unable to resync link cache: %s\n", nl_geterror(err)); pthread_mutex_unlock(&nl_sock_mutex); return -1; } pthread_mutex_unlock(&nl_sock_mutex); return 0; }
TError TNlCgFilter::Create(const TNlLink &link) { TError error = TError::Success(); struct nl_msg *msg; int ret; struct tcmsg tchdr; tchdr.tcm_family = AF_UNSPEC; tchdr.tcm_ifindex = link.GetIndex(); tchdr.tcm_handle = Handle; tchdr.tcm_parent = Parent; tchdr.tcm_info = TC_H_MAKE(FilterPrio << 16, htons(ETH_P_ALL)); msg = nlmsg_alloc_simple(RTM_NEWTFILTER, NLM_F_EXCL|NLM_F_CREATE); if (!msg) return TError(EError::Unknown, "Unable to add filter: no memory"); ret = nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO); if (ret < 0) { error = TError(EError::Unknown, std::string("Unable to add filter: ") + nl_geterror(ret)); goto free_msg; } ret = nla_put(msg, TCA_KIND, strlen(FilterType) + 1, FilterType); if (ret < 0) { error = TError(EError::Unknown, std::string("Unable to add filter: ") + nl_geterror(ret)); goto free_msg; } ret = nla_put(msg, TCA_OPTIONS, 0, NULL); if (ret < 0) { error = TError(EError::Unknown, std::string("Unable to add filter: ") + nl_geterror(ret)); goto free_msg; } L() << "netlink " << link.GetDesc() << ": add tfilter id 0x" << std::hex << Handle << " parent 0x" << Parent << std::dec << std::endl; ret = nl_send_sync(link.GetSock(), msg); if (ret) error = TError(EError::Unknown, std::string("Unable to add filter: ") + nl_geterror(ret)); if (!Exists(link)) error = TError(EError::Unknown, "BUG: created filter doesn't exist"); return error; free_msg: nlmsg_free(msg); return error; }
static bool nl_new(struct dionaea *d) { g_debug("%s", __PRETTY_FUNCTION__); nl_runtime.sock = nl_socket_alloc(); struct nl_sock *sock = nl_runtime.sock; nl_socket_disable_seq_check(sock); nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, nl_event_input, NULL); nl_join_groups(sock, RTMGRP_LINK); int err; if ( (err = nl_connect(sock, NETLINK_ROUTE)) < 0) { g_error("Could not connect netlink (%s)", nl_geterror(err)); } nl_socket_add_membership(sock, RTNLGRP_LINK); nl_socket_add_membership(sock, RTNLGRP_NEIGH); nl_socket_add_membership(sock, RTNLGRP_IPV4_IFADDR); nl_socket_add_membership(sock, RTNLGRP_IPV6_IFADDR); if( (err=rtnl_neigh_alloc_cache(sock, &nl_runtime.neigh_cache)) != 0 ) { g_error("Could not allocate neigh cache! (%s)", nl_geterror(err)); } #if LIBNL_RTNL_LINK_ALLOC_CACHE_ARGC == 3 if( (err=rtnl_link_alloc_cache(sock, AF_UNSPEC, &nl_runtime.link_cache)) != 0 ) #elif LIBNL_RTNL_LINK_ALLOC_CACHE_ARGC == 2 if( (err=rtnl_link_alloc_cache(sock, &nl_runtime.link_cache)) != 0 ) #endif { g_error("Could not allocate link cache! (%s)", nl_geterror(err)); } if( (err=rtnl_addr_alloc_cache(sock, &nl_runtime.addr_cache)) != 0 ) { g_error("Could not allocate addr cache! (%s)", nl_geterror(err)); } nl_cache_mngt_provide(nl_runtime.neigh_cache); nl_cache_mngt_provide(nl_runtime.link_cache); nl_cache_mngt_provide(nl_runtime.addr_cache); nl_runtime.ihandler = ihandler_new("dionaea.connection.*.accept", nl_ihandler_cb, NULL); ev_io_init(&nl_runtime.io_in, nl_io_in_cb, nl_socket_get_fd(sock), EV_READ); ev_io_start(g_dionaea->loop, &nl_runtime.io_in); nl_runtime.link_addr_cache = g_hash_table_new(g_int_hash, g_int_equal); nl_cache_foreach(nl_runtime.link_cache, nl_obj_input, NULL); nl_cache_foreach(nl_runtime.addr_cache, nl_obj_input, NULL); return true; }
bool devEthernet::hasLink() { if ( ! _netlinkSocket ) { MOD_ERROR("hasLink() called on uninitialized netlink socket."); return false; } nl_cache* cache; if ( rtnl_link_alloc_cache (_netlinkSocket, AF_UNSPEC, &cache) ) { MOD_ERROR("hasLink() rtnl_link_alloc_cache error: %s", nl_geterror(errno)); return false; } rtnl_link* link = rtnl_link_get(cache, index()); if ( ! link ) { MOD_ERROR("hasLink() rtnl_link_get error: %s", nl_geterror(errno)); nl_cache_free(cache); return false; } // First, check that interface is able to send uint8_t operState = rtnl_link_get_operstate(link); #ifdef DEFINE_DEBUG char buf[100]; rtnl_link_operstate2str (operState, buf, 100); MOD_DEBUG("operState is 0x%x (%s).", operState, buf); #endif bool ret = false; // Next make sure there's a carrier #ifndef IFF_LOWER_UP const int IFF_LOWER_UP = 0x10000; #endif #ifndef IFF_DORMANT const int IFF_DORMANT = 0x20000; #endif if ( operState == OperUp) { unsigned int flags = rtnl_link_get_flags (link); ret = ( ((flags & IFF_LOWER_UP) == IFF_LOWER_UP) && ((flags & IFF_DORMANT) != IFF_DORMANT) ); } rtnl_link_put(link); nl_cache_free(cache); return ret; }
static int parse_prio_opts(struct rtnl_qdisc *qdisc, char *argv[], int argc) { int i, err, bands; uint8_t map[] = QDISC_PRIO_DEFAULT_PRIOMAP; if (argc > 0) { if (argc < 2 || strcasecmp(argv[0], "bands")) goto usage; bands = strtoul(argv[1], NULL, 0); err = rtnl_qdisc_prio_set_bands(qdisc, bands); if (err < 0) { fprintf(stderr, "%s\n", nl_geterror()); return -1; } } if (argc > 2) { if (argc < 5 || strcasecmp(argv[2], "map")) goto usage; for (i = 3; i < (argc & ~1U); i += 2) { int prio, band; prio = rtnl_str2prio(argv[i]); if (prio < 0 || prio > sizeof(map)/sizeof(map[0])) { fprintf(stderr, "Invalid priority \"%s\"\n", argv[i]); return -1; } band = strtoul(argv[i+1], NULL, 0); map[prio] = band; } } err = rtnl_qdisc_prio_set_priomap(qdisc, map, sizeof(map)); if (err < 0) { fprintf(stderr, "%s\n", nl_geterror()); return -1; } return 0; usage: fprintf(stderr, "Usage: ... prio bands <nbands> map MAP\n" "MAP := <prio> <band>\n"); return -1; }
static void basic_parse_argv(struct rtnl_cls *cls, int argc, char **argv) { uint32_t classid; for (;;) { int c, optidx = 0, err; static struct option long_opts[] = { { "help", 0, 0, 'h' }, { "ematch", 1, 0, 'e' }, { "classid", 1, 0, 'c' }, { 0, 0, 0, 0 } }; c = getopt_long(argc, argv, "he:c:", long_opts, &optidx); if (c == -1) break; switch (c) { case '?': exit(NLE_INVAL); case 'h': print_usage(); case 'e': #if 0 if ((err = parse_ematch_syntax(optarg, &tree)) < 0) fatal(err, "Error while parsing ematch: %s", nl_geterror(err)); if ((err = rtnl_basic_set_ematch(cls, tree)) < 0) fatal(err, "Unable to set ematch: %s", nl_geterror(err)); #endif break; case 'c': if ((err = rtnl_tc_str2handle(optarg, &classid)) < 0) fatal(err, "Invalid classid \"%s\": %s", optarg, nl_geterror(err)); if ((err = rtnl_basic_set_classid(cls, classid)) < 0) fatal(err, "Unable to set classid: %s", nl_geterror(err)); break; } } }
/* * Receive netlink message and trigger processing by callback */ static void __ni_rtevent_receive(ni_socket_t *sock) { ni_rtevent_handle_t *handle = sock->user_data; int ret; if (handle && handle->nlsock) { do { ret = nl_recvmsgs_default(handle->nlsock); } while (ret == NLE_SUCCESS || ret == -NLE_INTR); switch (ret) { case NLE_SUCCESS: case -NLE_AGAIN: break; default: ni_error("rtnetlink event receive error: %s (%m)", nl_geterror(ret)); if (__ni_rtevent_restart(sock)) { ni_note("restarted rtnetlink event listener"); } else { ni_error("unable to restart rtnetlink event listener"); } break; } } }
static int parse_bfifo_opts(struct rtnl_qdisc *qdisc, char *argv[], int argc) { int err, limit; if (argc > 0) { if (argc != 2 || strcasecmp(argv[0], "limit")) { fprintf(stderr, "Usage: ... bfifo limit <limit>\n"); return -1; } limit = nl_size2int(argv[1]); if (limit < 0) { fprintf(stderr, "Invalid value for limit.\n"); return -1; } err = rtnl_qdisc_fifo_set_limit(qdisc, limit); if (err < 0) { fprintf(stderr, "%s\n", nl_geterror()); return -1; } } return 0; }
Try<vector<Info> > infos(int family, int states) { Try<Netlink<struct nl_sock> > sock = routing::socket(NETLINK_INET_DIAG); if (sock.isError()) { return Error(sock.error()); } struct nl_cache* c = NULL; int err = idiagnl_msg_alloc_cache(sock.get().get(), family, states, &c); if (err != 0) { return Error(nl_geterror(err)); } Netlink<struct nl_cache> cache(c); vector<Info> results; for (struct nl_object* o = nl_cache_get_first(cache.get()); o != NULL; o = nl_cache_get_next(o)) { struct idiagnl_msg* msg = (struct idiagnl_msg*)o; // For 'state', libnl-idiag only returns the number of left // shifts. Convert it back to power-of-2 number. results.push_back(Info( idiagnl_msg_get_family(msg), 1 << idiagnl_msg_get_state(msg), idiagnl_msg_get_sport(msg), idiagnl_msg_get_dport(msg), IP(idiagnl_msg_get_src(msg)), IP(idiagnl_msg_get_dst(msg)), idiagnl_msg_get_tcpinfo(msg))); } return results; }
/* * Get the first AF_INET address on 'link'. Returns 0 if successful. Caller * must release reference to *addr. */ static int get_link_inet_addr(struct nl_sock *sk, struct rtnl_link *link, struct nl_addr **addr) { struct nl_cache *addr_cache; int err; err = rtnl_addr_alloc_cache(sk, &addr_cache); if (err < 0) { warnx("rtnl_addr_alloc_cache() failed: %s", nl_geterror(err)); return 1; } /* Retrieve the first AF_INET address on the requested interface. */ struct rtnl_addr *filter; filter = rtnl_addr_alloc(); assert(filter); rtnl_addr_set_ifindex(filter, rtnl_link_get_ifindex(link)); rtnl_addr_set_family(filter, AF_INET); *addr = NULL; nl_cache_foreach_filter(addr_cache, (struct nl_object *)filter, match_first_addr, addr); if (*addr == NULL) { warnx("No AF_INET address found on veth"); rtnl_addr_put(filter); nl_cache_free(addr_cache); return 1; } rtnl_addr_put(filter); nl_cache_free(addr_cache); return 0; }
static void delete_cb(struct nl_object *obj, void *arg) { struct rtnl_qdisc *qdisc = nl_object_priv(obj); struct nl_dump_params params = { .dp_type = NL_DUMP_LINE, .dp_fd = stdout, }; int err; /* Ignore default qdiscs, unable to delete */ if (rtnl_tc_get_handle((struct rtnl_tc *) qdisc) == 0) return; if (interactive && !nl_cli_confirm(obj, ¶ms, default_yes)) return; if ((err = rtnl_qdisc_delete(sock, qdisc)) < 0) nl_cli_fatal(err, "Unable to delete qdisc: %s\n", nl_geterror(err)); if (!quiet) { printf("Deleted "); nl_object_dump(obj, ¶ms); } deleted++; }
static gboolean sync_connection_setup (NMNetlinkMonitor *self, GError **error) { NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); /* Set up the event listener connection */ priv->nlh_sync = nl_socket_alloc (); if (!priv->nlh_sync) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_HANDLE, _("unable to allocate netlink handle for monitoring link status: %s"), nl_geterror (ENOMEM)); goto error; } if (!nlh_setup (priv->nlh_sync, NULL, self, error)) goto error; return TRUE; error: if (priv->nlh_sync) { nl_socket_free (priv->nlh_sync); priv->nlh_sync = NULL; } return FALSE; }
static gboolean nm_netlink_listener_event_handler (GIOChannel *channel, GIOCondition io_condition, gpointer user_data) { NMNetlinkListener *listener = (NMNetlinkListener *) user_data; NMNetlinkListenerPrivate *priv; GError *error = NULL; g_return_val_if_fail (NM_IS_NETLINK_LISTENER (listener), TRUE); priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener); g_return_val_if_fail (priv->event_id > 0, TRUE); if (io_condition & NM_NETLINK_LISTENER_ERROR_CONDITIONS) return nm_netlink_listener_error_handler (channel, io_condition, listener); else if (io_condition & NM_NETLINK_LISTENER_DISCONNECT_CONDITIONS) return nm_netlink_listener_disconnect_handler (channel, io_condition, listener); g_return_val_if_fail (!(io_condition & ~(NM_NETLINK_LISTENER_EVENT_CONDITIONS)), FALSE); if (nl_recvmsgs_default (priv->nlh) < 0) { error = g_error_new (NM_NETLINK_LISTENER_ERROR, NM_NETLINK_LISTENER_ERROR_PROCESSING_MESSAGE, _("error processing netlink message: %s"), nl_geterror ()); g_signal_emit (G_OBJECT (listener), signals[ERROR], 0, error); g_error_free (error); } return TRUE; }
/* * Heads up: * Netlink wants this function to return either a negative error code or an enum * nl_cb_action. * Because NL_SKIP == EPERM and NL_STOP == ENOENT, you should mind the sign of * the result HARD. */ static int response_handler(struct nl_msg *msg, void *void_arg) { struct jool_response response; struct nlattr *attrs[__ATTR_MAX + 1]; struct response_cb *arg; int error; error = genlmsg_parse(nlmsg_hdr(msg), 0, attrs, __ATTR_MAX, NULL); if (error) { log_err("%s (error code %d)", nl_geterror(error), error); return -abs(error); } if (!attrs[ATTR_DATA]) { log_err("The module's response seems to be empty."); return -EINVAL; } error = netlink_parse_response(nla_data(attrs[ATTR_DATA]), nla_len(attrs[ATTR_DATA]), &response); if (error) return -abs(error); arg = void_arg; return (arg && arg->cb) ? (-abs(arg->cb(&response, arg->arg))) : 0; }
static int remus_netbuf_op(libxl__remus_device_nic *remus_nic, libxl__checkpoint_devices_state *cds, int buffer_op) { int rc, ret; libxl__remus_state *rs = cds->concrete_data; STATE_AO_GC(cds->ao); if (buffer_op == tc_buffer_start) ret = rtnl_qdisc_plug_buffer(remus_nic->qdisc); else ret = rtnl_qdisc_plug_release_one(remus_nic->qdisc); if (ret) { rc = ERROR_FAIL; goto out; } ret = rtnl_qdisc_add(rs->nlsock, remus_nic->qdisc, NLM_F_REQUEST); if (ret) { rc = ERROR_FAIL; goto out; } rc = 0; out: if (rc) LOGD(ERROR, cds-> domid, "Remus: cannot do netbuf op %s on %s:%s", ((buffer_op == tc_buffer_start) ? "start_new_epoch" : "release_prev_epoch"), remus_nic->ifb, nl_geterror(ret)); return rc; }
static gboolean event_connection_setup (NMNetlinkMonitor *self, GError **error) { NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); GError *channel_error = NULL; GIOFlags channel_flags; int fd; g_return_val_if_fail (priv->io_channel == NULL, FALSE); /* Set up the event listener connection */ priv->nlh_event = nl_socket_alloc (); if (!priv->nlh_event) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_HANDLE, _("unable to allocate netlink handle for monitoring link status: %s"), nl_geterror (ENOMEM)); goto error; } if (!nlh_setup (priv->nlh_event, event_msg_ready, self, error)) goto error; nl_socket_disable_seq_check (priv->nlh_event); /* Subscribe to the LINK group for internal carrier signals */ if (!nm_netlink_monitor_subscribe (self, RTNLGRP_LINK, error)) goto error; fd = nl_socket_get_fd (priv->nlh_event); priv->io_channel = g_io_channel_unix_new (fd); g_io_channel_set_encoding (priv->io_channel, NULL, &channel_error); /* Encoding is NULL, so no conversion error can possibly occur */ g_assert (channel_error == NULL); g_io_channel_set_close_on_unref (priv->io_channel, TRUE); channel_flags = g_io_channel_get_flags (priv->io_channel); channel_error = NULL; g_io_channel_set_flags (priv->io_channel, channel_flags | G_IO_FLAG_NONBLOCK, &channel_error); if (channel_error != NULL) { g_propagate_error (error, channel_error); goto error; } return TRUE; error: if (priv->io_channel) nm_netlink_monitor_close_connection (self); if (priv->nlh_event) { nl_socket_free (priv->nlh_event); priv->nlh_event = NULL; } return FALSE; }
bool TNlCgFilter::Exists(const TNlLink &link) { int ret; struct nl_cache *clsCache; ret = rtnl_cls_alloc_cache(link.GetSock(), link.GetIndex(), Parent, &clsCache); if (ret < 0) { L_ERR() << "Can't allocate filter cache: " << nl_geterror(ret) << std::endl; return false; } link.LogCache(clsCache); struct CgFilterIter { uint32_t parent; uint32_t handle; bool exists; } data = { Parent, Handle, false }; nl_cache_foreach(clsCache, [](struct nl_object *obj, void *data) { CgFilterIter *p = (CgFilterIter *)data; if (rtnl_tc_get_handle(TC_CAST(obj)) == p->handle && rtnl_tc_get_parent(TC_CAST(obj)) == p->parent) p->exists = true; }, &data); nl_cache_free(clsCache); return data.exists; }
gboolean nm_netlink_monitor_subscribe (NMNetlinkMonitor *self, int group, GError **error) { NMNetlinkMonitorPrivate *priv; int subs, err; g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), FALSE); priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); if (!priv->nlh_event) { if (!nm_netlink_monitor_open_connection (self, error)) return FALSE; } subs = get_subs (self, group) + 1; if (subs == 1) { err = nl_socket_add_membership (priv->nlh_event, group); if (err < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_JOIN_GROUP, _("unable to join netlink group: %s"), nl_geterror (err)); return FALSE; } } /* Update # of subscriptions for this group */ set_subs (self, group, subs); return TRUE; }
gboolean nm_netlink_listener_subscribe (NMNetlinkListener *listener, int group, GError **error) { NMNetlinkListenerPrivate *priv; g_return_val_if_fail (NM_IS_NETLINK_LISTENER (listener), FALSE); priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener); if (!priv->nlh) { if (!open_connection (listener, error)) return FALSE; } if (nl_socket_add_membership (priv->nlh, group) < 0) { g_set_error (error, NM_NETLINK_LISTENER_ERROR, NM_NETLINK_LISTENER_ERROR_NETLINK_JOIN_GROUP, _("unable to join netlink group: %s"), nl_geterror ()); return FALSE; } return TRUE; }