<div dir="ltr"><pre style="color:rgb(0,0,0)">> On Tue, Jun 30, 2020 at 04:02:05PM +0100, Daniel P. Berrangé wrote:<br>> > On Tue, Jun 30, 2020 at 12:59:03PM +0200, Miguel Duarte de Mora Barroso wrote:<br>> > > On Mon, Apr 6, 2020 at 4:03 PM Laine Stump <lstump redhat com> wrote:<br>> > > ><br>> > > > On 4/6/20 9:54 AM, Daniel P. Berrangé wrote:<br>> > > > > On Mon, Apr 06, 2020 at 03:47:01PM +0200, Miguel Duarte de Mora Barroso wrote:<br>> > > > >> Hi all,<br>> > > > >><br>> > > > >> I'm aware that it is possible to plug pre-created macvtap devices to<br>> > > > >> libvirt guests - tracked in RFE [0].<br>> > > > >><br>> > > > >> My interpretation of the wording in [1] and [2] is that it is also<br>> > > > >> possible to plug pre-created tap devices into libvirt guests - that<br>> > > > >> would be a requirement to allow kubevirt to run with less capabilities<br>> > > > >> in the pods that encapsulate the VMs.<br>> > > > >><br>> > > > >> I took a look at the libvirt code ([3] & [4]), and, from my limited<br>> > > > >> understanding, I got the impression that plugging existing interfaces<br>> > > > >> via `managed='no' ` is only possible for macvtap interfaces.<br>> > > ><br>> > > ><br>> > > > No, it works for standard tap devices as well.<br>> > > ><br>> > > ><br>> > > > The reason the BZs and commit logs talk mostly about macvtap rather than<br>> > > > tap is because 1) that's what kubevirt people had asked for and 2) it<br>> > > > already *mostly* worked for tap devices, so most of the work was related<br>> > > > to macvtap (my memory is already fuzzy, but I think there were a couple<br>> > > > privileged operations we still tried to do for standard tap devices even<br>> > > > if they were precreated (standard disclaimer: I often misremember, so<br>> > > > this memory could be wrong! But definitely precreated tap devices do work).<br>> > > ><br>> > ><br>> > > It's been a while since I've started this thread, but lately I've<br>> > > understood better how tap devices work, and that new insight makes me<br>> > > wonder about a couple of things.<br>> > ><br>> > > Our ultimate goal In kubevirt is to consume a pre-created tap device<br>> > > by a kubernetes pod that doesn't have the NET_ADMIN capability.<br>> > ><br>> > > After looking at the current libvirt code, I don't think that is<br>> > > currently supported, since we'll *always* enter the<br>> > > `virNetDevTapCreate` function in [1] (I'm interested in the *tap*<br>> > > scenario).<br>> > ><br>> > > The tap device is effectively created in that function - [2] - by<br>> > > opening the clone device (/dev/net/tun), and calling `ioctl(fd,<br>> > > TUNSETIFF,...)` in it. AFAIK, both of those operations *require* the<br>> > > NET_ADMIN capability. If I'm correct, this means that the current<br>> > > libvirt implementation makes our goals impossible to achieve.<br>> ><br>> > AFAIK, that is not correct - CAP_NET_ADMIN isn't required to open<br>> > or create a tap device - only to add the tap device to a bridge.<br>> ><br>> > So if you create the tap device & attach it to a bridge ahead of<br>> > time, libvirt should then be able to open it and give it to QEMU<br>><br>> <a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/tun.c#n586">https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/net/tun.c#n586</a><br>><br>>  ((uid_valid(tun->owner) && !uid_eq(cred->euid, tun->owner)) ||<br>>                 (gid_valid(tun->group) && !in_egroup_p(tun->group))) &&<br>>               !ns_capable(net->user_ns, CAP_NET_ADMIN);<br>><br>><br>> This is called by the TUNSETIFF code.<br>><br>> AFAICT, that means if you  fchown(tapfd, uid, gid), to the uid+gid of<br>> libvirtd, it should not require CAP_NET_ADMIN.<br>><br>> Regards,<br>> Daniel

I have no idea if this message will get linked into the thread properly, but
I came across this and wanted to comment on the mystery without having an actual
email to reply to or headers.</pre><pre style="color:rgb(0,0,0)">I recently ran into this issue as well, and found that even *with* NET_ADMIN at
the container level, trying to launch Qemu directly results in:

qemu-system-x86_64: -netdev tap,id=hostnet0,ifname=tap0: could not configure /dev/net/tun (tap0): Permission denied

So as a note I'd say even Libvirt aside, Qemu is trying to do this as well:

<a href="https://github.com/qemu/qemu/blob/0982a56a551556c704dc15752dabf57b4be1c640/net/tap-linux.c#L104">https://github.com/qemu/qemu/blob/0982a56a551556c704dc15752dabf57b4be1c640/net/tap-linux.c#L104</a>

But it's unclear where the EPERM is coming from in the kernel at tun_set_iff().

Of note, if I give Qemu a non-existing tap name, it will create it, but if I give
it an existing tap name, I get EPERM.</pre></div>