Example #1
0
/* Netlink interface link lookup filter */
static int
netlink_if_link_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
{
	struct ifinfomsg *ifi;
	struct rtattr *tb[IFLA_MAX + 1];
	interface_t *ifp;
	int len, status;
	char *name;

	ifi = NLMSG_DATA(h);

	if (h->nlmsg_type != RTM_NEWLINK)
		return 0;

	len = h->nlmsg_len - NLMSG_LENGTH(sizeof (struct ifinfomsg));
	if (len < 0)
		return -1;

	/* Interface name lookup */
	memset(tb, 0, sizeof (tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL)
		return -1;
	name = (char *) RTA_DATA(tb[IFLA_IFNAME]);

	/* Return if loopback */
	if (ifi->ifi_type == ARPHRD_LOOPBACK)
		return 0;

	/* Skip it if already exist */
	ifp = if_get_by_ifname(name);
	if (ifp) {
#ifdef _HAVE_VRRP_VMAC_
		if (!ifp->vmac)
#endif
		{
#ifdef _HAVE_VRRP_VMAC_
			if_vmac_reflect_flags(ifi->ifi_index, ifi->ifi_flags);
#endif
			ifp->flags = ifi->ifi_flags;
		}
		return 0;
	}

	/* Fill the interface structure */
	ifp = (interface_t *) MALLOC(sizeof(interface_t));

	status = netlink_if_link_populate(ifp, tb, ifi);
	if (status < 0) {
		FREE(ifp);
		return -1;
	}
	/* Queue this new interface_t */
	if_add_queue(ifp);
	return 0;
}
Example #2
0
/* Netlink interface link lookup filter */
static int
netlink_if_link_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
{
	struct ifinfomsg *ifi;
	struct rtattr *tb[IFLA_MAX + 1];
	interface_t *ifp;
	int i, len;
	char *name;

	ifi = NLMSG_DATA(h);

	if (h->nlmsg_type != RTM_NEWLINK)
		return 0;

	len = h->nlmsg_len - NLMSG_LENGTH(sizeof (struct ifinfomsg));
	if (len < 0)
		return -1;

	/* Interface name lookup */
	memset(tb, 0, sizeof (tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL)
		return -1;
	name = (char *) RTA_DATA(tb[IFLA_IFNAME]);

	/* Return if loopback */
	if (ifi->ifi_type == ARPHRD_LOOPBACK)
		return 0;

	/* Skip it if already exist */
	ifp = if_get_by_ifname(name);
	if (ifp) {
		ifp->flags = ifi->ifi_flags;
		return 0;
	}

	/* Fill the interface structure */
	ifp = (interface_t *) MALLOC(sizeof(interface_t));
	memcpy(ifp->ifname, name, strlen(name));
	ifp->ifindex = ifi->ifi_index;
	ifp->base_ifindex = ifi->ifi_index;
	ifp->flags = ifi->ifi_flags;
	ifp->mtu = *(int *) RTA_DATA(tb[IFLA_MTU]);
	ifp->hw_type = ifi->ifi_type;

	if (tb[IFLA_ADDRESS]) {
		int hw_addr_len = RTA_PAYLOAD(tb[IFLA_ADDRESS]);

		if (hw_addr_len > IF_HWADDR_MAX)
			log_message(LOG_ERR, "MAC address for %s is too large: %d",
			       name, hw_addr_len);
		else {
			ifp->hw_addr_len = hw_addr_len;
			memcpy(ifp->hw_addr, RTA_DATA(tb[IFLA_ADDRESS]),
			       hw_addr_len);
			for (i = 0; i < hw_addr_len; i++)
				if (ifp->hw_addr[i] != 0)
					break;
			if (i == hw_addr_len)
				ifp->hw_addr_len = 0;
			else
				ifp->hw_addr_len = hw_addr_len;
		}
	}

	/* Queue this new interface_t */
	if_add_queue(ifp);
	return 0;
}
Example #3
0
/* Netlink flag Link update */
static int
netlink_reflect_filter(struct sockaddr_nl *snl, struct nlmsghdr *h)
{
	struct ifinfomsg *ifi;
	struct rtattr *tb[IFLA_MAX + 1];
	interface_t *ifp;
	int len, status;

	ifi = NLMSG_DATA(h);
	if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
		return 0;

	len = h->nlmsg_len - NLMSG_LENGTH(sizeof (struct ifinfomsg));
	if (len < 0)
		return -1;

	/* Interface name lookup */
	memset(tb, 0, sizeof (tb));
	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
	if (tb[IFLA_IFNAME] == NULL)
		return -1;

	/* ignore loopback device */
	if (ifi->ifi_type == ARPHRD_LOOPBACK)
		return 0;

	/* find the interface_t. If the interface doesn't exist in the interface
	 * list and this is a new interface add it to the interface list.
	 * If an interface with the same name exists overwrite the older
	 * structure and fill it with the new interface information.
	 */
	ifp = if_get_by_ifindex(ifi->ifi_index);
	if (!ifp) {
		if (h->nlmsg_type == RTM_NEWLINK) {
			char *name;
			name = (char *) RTA_DATA(tb[IFLA_IFNAME]);
			ifp = if_get_by_ifname(name);
			if (!ifp) {
				ifp = (interface_t *) MALLOC(sizeof(interface_t));
				if_add_queue(ifp);
			} else {
				memset(ifp, 0, sizeof(interface_t));
			}
			status = netlink_if_link_populate(ifp, tb, ifi);
			if (status < 0)
				return -1;
		} else {
			if (__test_bit(LOG_DETAIL_BIT, &debug))
				log_message(LOG_INFO, "Unknown interface %s deleted", (char *)tb[IFLA_IFNAME]);
			return 0;
		}
	}

	/*
	 * Update flags.
	 * VMAC interfaces should never update it own flags, only be reflected
	 * by the base interface flags.
	 */
#ifdef _HAVE_VRRP_VMAC_
	if (!ifp->vmac)
#endif
	{
#ifdef _HAVE_VRRP_VMAC_
		if_vmac_reflect_flags(ifi->ifi_index, ifi->ifi_flags);
#endif
		ifp->flags = ifi->ifi_flags;
	}

	return 0;
}