Bug 209427

Summary: [PATCH] if_vtnet(4) is not sending LINK_(UP|DOWN) events
Product: Base System Reporter: Roman Bogorodskiy <novel>
Component: kernAssignee: freebsd-virtualization (Nobody) <virtualization>
Status: New ---    
Severity: Affects Only Me CC: bryanv
Priority: --- Keywords: patch
Version: CURRENT   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
dirty fix
none
proposed fix, v2 none

Description Roman Bogorodskiy freebsd_committer 2016-05-10 15:08:17 UTC
if_vtnet(4) is not sending devd notifications. 

Steps to reproduce:

1. Run "cat /var/run/devd.seqpacket.pipe"
2. Run "ifconfig vtnet0 down && ifconfig vtnet0 up"

Expected result:

 First command outputting something like:

!system=IFNET subsystem=vtnet0 type=LINK_DOWN
!system=IFNET subsystem=vtnet0 type=LINK_UP

This does not happen with if_vtnet(4). It does happen with e.g. re(4) though.
Comment 1 Roman Bogorodskiy freebsd_committer 2016-05-10 15:52:06 UTC
Created attachment 170183 [details]
dirty fix

Attaching a dirty fix that changes vtnet_is_link_up() just to check the IFF_DRV_RUNNING flag and also calling vtnet_update_link_status() instead of setting sc->vtnet_link_active to 0 in vtnet_stop().

This is most likely wrong and breaks something, though at fixes the original issue:

# fg
cat /var/run/devd.seqpacket.pipe (wd: ~)
^Z
Suspended
(wd now: /usr/src/sys/dev/virtio/network)
# ifconfig vtnet0 down; ifconfig vtnet0 up
# fg
cat /var/run/devd.seqpacket.pipe (wd: ~)
!system=IFNET subsystem=vtnet0 type=LINK_DOWN
!system=IFNET subsystem=vtnet0 type=LINK_UP
Comment 2 Roman Bogorodskiy freebsd_committer 2016-05-17 15:14:49 UTC
Created attachment 170409 [details]
proposed fix, v2

Attaching a new patch that's slightly less dirty than the previous one.

Specifically, it does not change vtnet_is_link_up() behavior, but extends vtnet_update_link_status() event triggering.

Specifically, if link is here and IFF_DRV_RUNNING is set, but interface was not active, we mark it active and trigger notification. If there is no link or IFF_DRV_RUNNING, then we consider interface down.

Also, add a call to vtnet_update_link_status() on mtu change to trigger events as well like other if drivers usually do.

So, a pair of ifconfig vtnet0 down/up followed by ifconfig vtnet0 mtu 1496 look like this in devd:

!system=IFNET subsystem=vtnet0 type=LINK_DOWN
!system=IFNET subsystem=vtnet0 type=LINK_UP
!system=IFNET subsystem=vtnet0 type=LINK_DOWN
!system=IFNET subsystem=vtnet0 type=LINK_UP
!system=IFNET subsystem=vtnet0 type=LINK_DOWN
!system=IFNET subsystem=vtnet0 type=LINK_UP

I'm yet to figure out how I can test link status change in bhyve so vtnet_is_link_up() returned something other that 1.
Comment 3 Bryan Venteicher freebsd_committer 2016-05-28 18:04:21 UTC
(In reply to Roman Bogorodskiy from comment #2)

I think is still a bit dirty: are you using a host that does not advertise the VIRTIO_NET_F_STATUS feature?
Comment 4 Roman Bogorodskiy freebsd_committer 2016-05-28 18:14:35 UTC
(In reply to Bryan Venteicher from comment #3)

I'm using it with bhyve.

Looks like it does advertise the VIRTIO_NET_F_STATUS feature:

https://svnweb.freebsd.org/base/head/usr.sbin/bhyve/pci_virtio_net.c?view=markup#l90

However, it looks like it's set to 1 if it successfully opens a tap device and doesn't change after that:

https://svnweb.freebsd.org/base/head/usr.sbin/bhyve/pci_virtio_net.c?view=markup#l891

(I could be wrong in my interpretation though).