On Wednesday 26 May 2010, Stefan Berger wrote:
+static int
+doPortProfileOpSetLink(bool nltarget_kernel,
+ int ifindex,
+ const char *profileId,
+ struct ifla_port_vsi *portVsi,
+ const unsigned char *instanceId,
+ const unsigned char *hostUUID,
+ int32_t vf,
+ uint8_t op)
+{
+ int rc = 0;
+ char nlmsgbuf[NLMSGBUF_SIZE];
+ struct nlmsghdr *nlm = (struct nlmsghdr *)nlmsgbuf, *resp;
+ struct nlmsgerr *err;
+ char rtattbuf[RATTBUF_SIZE];
+ struct rtattr *rta, *vfports = NULL, *vfport;
+ struct ifinfomsg ifinfo = {
+ .ifi_family = AF_UNSPEC,
+ .ifi_index = ifindex,
+ };
+ char *recvbuf = NULL;
+ unsigned int recvbuflen = 0;
+
+ memset(&nlmsgbuf, 0, sizeof(nlmsgbuf));
+
+ nlInit(nlm, NLM_F_REQUEST, RTM_SETLINK);
+
+ if (!nlAppend(nlm, sizeof(nlmsgbuf), &ifinfo, sizeof(ifinfo)))
+ goto buffer_too_small;
+
+ if (vf == PORT_SELF_VF) {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_PORT_SELF, NULL, 0);
+ } else {
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_VF_PORTS, NULL, 0);
+ if (!rta ||
+ !(vfports = nlAppend(nlm, sizeof(nlmsgbuf),
+ rtattbuf, rta->rta_len)))
+ goto buffer_too_small;
+
+ /* begin nesting vfports */
+ rta = rtattrCreate(rtattbuf, sizeof(rtattbuf), IFLA_VF_PORT, NULL, 0);
+ }
I think we need to distinguish three cases here, not two: PORT_SELF_VF
(configuring an enic static function), a specific VF (configuring an
enic dynamic function) and no VF at all (using lldpad). We cannot use
IFLA_PORT_SELF in lldpad because that would imply that we do the
communication on the macvtap link itself, which is not allowed to talk
VDP to the switch.
We also need a way to communicate the MAC and VLAN address to lldpad
in this case.
I would suggest leaving out the IFLA_PORT_VF attribute in that case,
and transmitting IFLA_VF_MAC and IFLA_VF_VLAN attributes with their
vf field set to zero or maybe (__u32)-1. lldpad would then choose
a vf number for its internal housekeeping which gets returned when
querying the device, so you have an identifier to refer to.
+ int op = PORT_REQUEST_ASSOCIATE;
+ struct ifla_port_vsi portVsi = {
+ .vsi_mgr_id = virtPort->u.virtPort8021Qbg.managerID,
+ .vsi_type_version = virtPort->u.virtPort8021Qbg.typeIDVersion,
+ };
+ bool nltarget_kernel = false;
Right, "nltarget_kernel = false" is probably a reasonable setting for
now, we can always extend this if we should need more options.
+ int ifindex;
+
+ if (ifaceGetIndex(true, ifname, &ifindex) != 0) {
+ rc = 1;
+ goto err_exit;
+ }
What is ifname here, the macvtap interface or the underlying
interface that lldpad talks to?
I guess we need to have access to both here, the underlying
device to pass as ifindex, and the macvlan device so we
can figure out the vlan and mac address settings. I did not
follow the discussion on the libvir-list so far, maybe you
have already discussed this in depth.
+ rc = doPortProfileOpCommon(nltarget_kernel, ifindex,
+ NULL,
+ &portVsi,
+ virtPort->u.virtPort8021Qbg.instanceID,
+ NULL,
+ PORT_SELF_VF,
+ op);
Maybe just pass vf=0 here?
Arnd