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; }
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; }