static NMIP6Device *
process_address_change (NMIP6Manager *manager, struct nl_msg *msg)
{
	NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
	NMIP6Device *device;
	struct nlmsghdr *hdr;
	struct rtnl_addr *rtnladdr;
	int old_size;

	hdr = nlmsg_hdr (msg);
	rtnladdr = NULL;
	nl_msg_parse (msg, ref_object, &rtnladdr);
	if (!rtnladdr) {
		nm_log_dbg (LOGD_IP6, "error processing netlink new/del address message");
		return NULL;
	}

	device = nm_ip6_manager_get_device (manager, rtnl_addr_get_ifindex (rtnladdr));

	old_size = nl_cache_nitems (priv->addr_cache);
	nl_cache_include (priv->addr_cache, (struct nl_object *)rtnladdr, NULL, NULL);

	/* The kernel will re-notify us of automatically-added addresses
	 * every time it gets another router advertisement. We only want
	 * to notify higher levels if we actually changed something.
	 */
	nm_log_dbg (LOGD_IP6, "(%s): address cache size: %d -> %d:",
		    device_get_iface (device), old_size, nl_cache_nitems (priv->addr_cache));
	dump_address_change (device, hdr, rtnladdr);
	rtnl_addr_put (rtnladdr);
	if (nl_cache_nitems (priv->addr_cache) == old_size)
		return NULL;

	return device;
}
Example #2
0
/**
 * Print information about cache manager
 * @arg mngr		Cache manager
 * @arg p		Dumping parameters
 *
 * Prints information about the cache manager including all managed caches.
 *
 * @note This is a debugging function.
 */
void nl_cache_mngr_info(struct nl_cache_mngr *mngr, struct nl_dump_params *p)
{
	char buf[128];
	int i;

	nl_dump_line(p, "cache-manager <%p>\n", mngr);
	nl_dump_line(p, "  .protocol = %s\n",
		     nl_nlfamily2str(mngr->cm_protocol, buf, sizeof(buf)));
	nl_dump_line(p, "  .flags    = %#x\n", mngr->cm_flags);
	nl_dump_line(p, "  .nassocs  = %u\n", mngr->cm_nassocs);
	nl_dump_line(p, "  .sock     = <%p>\n", mngr->cm_sock);

	for (i = 0; i < mngr->cm_nassocs; i++) {
		struct nl_cache_assoc *assoc = &mngr->cm_assocs[i];

		if (assoc->ca_cache) {
			nl_dump_line(p, "  .cache[%d] = <%p> {\n", i, assoc->ca_cache);
			nl_dump_line(p, "    .name = %s\n", assoc->ca_cache->c_ops->co_name);
			nl_dump_line(p, "    .change_func = <%p>\n", assoc->ca_change);
			nl_dump_line(p, "    .change_data = <%p>\n", assoc->ca_change_data);
			nl_dump_line(p, "    .nitems = %u\n", nl_cache_nitems(assoc->ca_cache));
			nl_dump_line(p, "    .objects = {\n");

			p->dp_prefix += 6;
			nl_cache_dump(assoc->ca_cache, p);
			p->dp_prefix -= 6;

			nl_dump_line(p, "    }\n");
			nl_dump_line(p, "  }\n");
		}
	}
}
static NMIP6Device *
process_route_change (NMIP6Manager *manager, struct nl_msg *msg)
{
	NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
	NMIP6Device *device;
	struct nlmsghdr *hdr;
	struct rtnl_route *rtnlroute;
	int old_size;

	hdr = nlmsg_hdr (msg);
	rtnlroute = NULL;
	nl_msg_parse (msg, ref_object, &rtnlroute);
	if (!rtnlroute) {
		nm_log_dbg (LOGD_IP6, "error processing netlink new/del route message");
		return NULL;
	}

	/* Cached/cloned routes are created by the kernel for specific operations
	 * and aren't part of the interface's permanent routing configuration.
	 */
	if (rtnl_route_get_flags (rtnlroute) & RTM_F_CLONED) {
		rtnl_route_put (rtnlroute);
		return NULL;
	}

	device = nm_ip6_manager_get_device (manager, rtnl_route_get_oif (rtnlroute));

	old_size = nl_cache_nitems (priv->route_cache);
	nl_cache_include (priv->route_cache, (struct nl_object *)rtnlroute, NULL, NULL);

	/* As above in process_address_change */
	nm_log_dbg (LOGD_IP6, "(%s): route cache size: %d -> %d:",
		    device_get_iface (device), old_size, nl_cache_nitems (priv->route_cache));
	dump_route_change (device, hdr, rtnlroute);
	rtnl_route_put (rtnlroute);
	if (nl_cache_nitems (priv->route_cache) == old_size)
		return NULL;

	return device;
}
Example #4
0
static NMIP6Device *
process_route (NMIP6Manager *manager, struct nl_msg *msg)
{
	NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
	NMIP6Device *device;
	struct rtnl_route *rtnlroute;
	int old_size;

	nm_log_dbg (LOGD_IP6, "processing netlink new/del route message");

	rtnlroute = NULL;
	nl_msg_parse (msg, ref_object, &rtnlroute);
	if (!rtnlroute) {
		nm_log_dbg (LOGD_IP6, "error processing netlink new/del route message");
		return NULL;
	}

	device = nm_ip6_manager_get_device (manager, rtnl_route_get_oif (rtnlroute));
	if (!device) {
		nm_log_dbg (LOGD_IP6, "ignoring message for unknown device");
		rtnl_route_put (rtnlroute);
		return NULL;
	}

	old_size = nl_cache_nitems (priv->route_cache);
	nl_cache_include (priv->route_cache, (struct nl_object *)rtnlroute, NULL, NULL);
	rtnl_route_put (rtnlroute);

	/* As above in process_addr */
	if (nl_cache_nitems (priv->route_cache) == old_size) {
		nm_log_dbg (LOGD_IP6, "(%s): route cache unchanged, ignoring message",
		            device->iface);
		return NULL;
	}

	return device;
}
Example #5
0
/* Given an interface's MAC address, return the name (e.g., eth0) in human
 * readable format.  Return NULL for no match
 */
char *iface_mac2device(char *mac) {
    struct nl_handle *handle = NULL;
    struct nl_cache *cache = NULL;
    struct rtnl_link *link = NULL;
    struct nl_addr *mac_as_nl_addr = NULL;
    char *retval = NULL;
    int i, n;

    if (mac == NULL) {
        return NULL;
    }

    if ((mac_as_nl_addr = nl_addr_parse(mac, AF_LLC)) == NULL) {
        return NULL;
    }

    if ((cache = _iface_get_link_cache(&handle)) == NULL) {
        return NULL;
    }

    n = nl_cache_nitems(cache);
    for (i = 0; i <= n; i++) {
        struct nl_addr *addr;

        if ((link = rtnl_link_get(cache, i)) == NULL) {
            continue;
        }

        addr = rtnl_link_get_addr(link);

        if (!nl_addr_cmp(mac_as_nl_addr, addr)) {
            retval = strdup(rtnl_link_get_name(link));
            rtnl_link_put(link);
            break;
        }

        rtnl_link_put(link);
    }

    nl_close(handle);
    nl_handle_destroy(handle);

    return retval;
}