Example #1
0
int
netlink_link_add_vmac(vrrp_rt *vrrp)
{
	struct rtattr *linkinfo;
	interface *ifp;
	char ifname[IFNAMSIZ];
	struct {
		struct nlmsghdr n;
		struct ifinfomsg ifi;
		char buf[256];
	} req;

	if (!vrrp->ifp)
		return -1;

	memset(&req, 0, sizeof (req));
	memset(ifname, 0, IFNAMSIZ);
	strncpy(ifname, vrrp->vmac_ifname, IFNAMSIZ - 1);

	req.n.nlmsg_len = NLMSG_LENGTH(sizeof (struct ifinfomsg));
	req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
	req.n.nlmsg_type = RTM_NEWLINK;
	req.ifi.ifi_family = AF_INET;

	/* macvlan settings */
	linkinfo = NLMSG_TAIL(&req.n);
	addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
	addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, (void *)ll_kind, strlen(ll_kind));
	linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
	addattr_l(&req.n, sizeof(req), IFLA_LINK, &IF_INDEX(vrrp->ifp), sizeof(uint32_t));
	addattr_l(&req.n, sizeof(req), IFLA_IFNAME, ifname, strlen(ifname));

	if (netlink_talk(&nl_cmd, &req.n) < 0)
		return -1;

	/*
	 * Update interface queue and vrrp instance interface binding.
	 * bring it UP !
	 */
	netlink_interface_lookup();
	ifp = if_get_by_ifname(ifname);
	if (!ifp)
		return -1;
	vrrp->ifp = ifp;
	vrrp->vmac |= 2;
	netlink_link_setlladdr(vrrp);
	netlink_link_up(vrrp);

	/*
	 * By default MACVLAN interface are in VEPA mode which filters
	 * out received packets whose MAC source address matches that
	 * of the MACVLAN interface. Setting MACVLAN interface in private
	 * mode will not filter based on source MAC address.
	 */
	netlink_link_setmode(vrrp);

	return 1;
}
Example #2
0
int
netlink_link_add_vmac(vrrp_rt *vrrp)
{
    struct rtattr *linkinfo;
    interface *ifp;
    char ifname[IFNAMSIZ];
    struct {
        struct nlmsghdr n;
        struct ifinfomsg ifi;
        char buf[256];
    } req;

    if (!vrrp->ifp)
        return -1;

    memset(&req, 0, sizeof (req));
    memset(ifname, 0, IFNAMSIZ);
    strncpy(ifname, vrrp->vmac_ifname, IFNAMSIZ - 1);

    /*
     * Check to see if this vmac interface was created
     * by a previous instance.
     */
    if (reload && (ifp = if_get_by_ifname(ifname))) {
        vrrp->xmit_ifp = ifp;
        /* Save ifindex for use on delete */
        vrrp->vmac_ifindex = IF_INDEX(vrrp->xmit_ifp);
        vrrp->vmac |= 2;
        return 1;
    }

    req.n.nlmsg_len = NLMSG_LENGTH(sizeof (struct ifinfomsg));
    req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL;
    req.n.nlmsg_type = RTM_NEWLINK;
    req.ifi.ifi_family = AF_INET;

    /* macvlan settings */
    linkinfo = NLMSG_TAIL(&req.n);
    addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
    addattr_l(&req.n, sizeof(req), IFLA_INFO_KIND, (void *)ll_kind, strlen(ll_kind));
    linkinfo->rta_len = (void *)NLMSG_TAIL(&req.n) - (void *)linkinfo;
    addattr_l(&req.n, sizeof(req), IFLA_LINK, &IF_INDEX(vrrp->ifp), sizeof(uint32_t));
    addattr_l(&req.n, sizeof(req), IFLA_IFNAME, ifname, strlen(ifname));

    if (netlink_talk(&nl_cmd, &req.n) < 0)
        return -1;

    /*
     * Update interface queue and vrrp instance interface binding.
     * bring it UP !
     */
    netlink_interface_lookup();
    ifp = if_get_by_ifname(ifname);
    if (!ifp)
        return -1;
    vrrp->xmit_ifp = ifp;
    vrrp->vmac_ifindex = IF_INDEX(vrrp->xmit_ifp); /* For use on delete */
    vrrp->vmac |= 2;
    netlink_link_setlladdr(vrrp);
    vyatta_if_setup(ifname);
    netlink_link_up(vrrp);
    netlink_link_setmode(vrrp);

    return 1;
}