Solved use a virtual network interface on a host?

tingo

Daemon

Reaction score: 487
Messages: 2,270

Is there a way to use a virtual network interface on a physical FreeBSD host?
TL;DR - yes - use epair(4) interfaces.

Background: I have this new and quite cheap laptop (Lenovo ideapad 530S-14ARR). It was on outlet sale, therefore cheap. It doesn't have a wired ethernet interface, and the wireless interface is Qualcomm Atheros QCA9377 which is not supported by FreeBSD yet.
But that is also the point: I wanted to try an experiment - to see if I could use a virtual machine running Linux as a gateway.
Long story short: I used a usb dongle (usb hub-with-ethernet-port) as a wired network while installing FreeBSD, vm-bhyve and other packages on the machine. Now it runs:
Code:
root@kg-pod530:~ # freebsd-version -ku
12.1-RELEASE-p7
12.1-RELEASE-p7
The virtual machine is installed and working, it runs Debian. The setup is per BridgeNetworkConnectionsProxyArp page on the Debian wiki.
Code:
tingo@kg-core2$ ssh 10.1.161.14
Linux pod530-gw 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2+deb10u1 (2020-06-07) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Jul 31 21:21:28 2020 from 10.1.150.52
and as you can see, I can ssh into it, so wireless is working. On the host side, I have the following network set up in /etc/rc.conf:
Code:
cloned_interfaces="bridge0 tap0"
ifconfig_bridge0="addm tap0"
ifconfig_tap0="DHCP"
One problem I see right away, is that tap0 shows "no carrier":
Code:
root@kg-pod530:~ # ifconfig tap0
tap0: flags=8903<UP,BROADCAST,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=80000<LINKSTATE>
    ether 00:bd:98:db:f6:00
    groups: tap
    media: Ethernet autoselect
    status: no carrier
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
compare to tap1 (the interface for the virtual machine)
Code:
root@kg-pod530:~ # ifconfig tap1
tap1: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
    description: vmnet-gateway-0-glue
    options=80000<LINKSTATE>
    ether 00:bd:a6:f8:f6:01
    inet6 fe80::2bd:a6ff:fef8:f601%tap1 prefixlen 64 tentative scopeid 0x6
    groups: tap vm-port
    media: Ethernet autoselect
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
    Opened by PID 1543
FWIW, both interfaces are members of the same bridge
Code:
root@kg-pod530:~ # ifconfig bridge0
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    description: vm-glue
    ether 02:73:ff:81:33:00
    id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
    maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
    root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
    member: tap1 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
            ifmaxaddr 0 port 6 priority 128 path cost 2000000
    member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
            ifmaxaddr 0 port 3 priority 128 path cost 2000000
    groups: bridge vm-switch viid-1ed4d@
    nd6 options=9<PERFORMNUD,IFDISABLED>
So, what else have I tried?
- using tun0 instead of tap0; doesn't work - I get an error message when I try to add it to a bridge (understandably)
- using lo1 instead of tap0; doesn't work - I get an error message when I try to add it to a bridge (not sure why)
- using epair(4) interfaces, with epair0a on the host, and epair0b connected to the bridge; here I get no error messages, but the host machine also doesn't get an ip adress from the DHCP server
 
Last edited:
OP
T

tingo

Daemon

Reaction score: 487
Messages: 2,270

Hmm, your setup uses two vm's - maybe tap(4) interface don't work on a host at all, maybe it needs a vm.
 

Emrion

Well-Known Member

Reaction score: 107
Messages: 405

I think it would work with only the debian machine. All my VM are managed by iohyve. Here, the interesting parts of the main configuration files, if it can help:

/etc/rc.conf
Code:
kld_list="nmdm /boot/modules/i915kms.ko"                                     

ifconfig_re0="inet 192.168.5.2 netmask 255.255.255.0"
defaultrouter="192.168.5.1"

cloned_interfaces="bridge0 tap0 tap1"
ifconfig_bridge0="addm re0 addm tap0 addm tap1"
# Condition race between pfs start and tap0 up (?)
ifconfig_tap0="up"
ifconfig_tap1="up"
iohyve_enable="YES"
/etc/sysctl.conf
Code:
net.link.tap.up_on_open=1
/etc/loader.conf
Code:
vmm_load="YES"
pptdevs="0/31/6 1/0/0"
Code:
$ iohyve getall wifi
Getting wifi iohyve properties...
bargs          -S_-A_-H_-P
bhyve_path     /usr/sbin/bhyve
boot           1
con            nmdm2
cpu            1
description    Thu Apr  4 17:55:49 CEST 2019
install        no
loader         grub-bhyve
name           wifi
os             default
pcidev:1       passthru,1/0/0
persist        1
ram            1024m
sectorsize     512
size           10g
tap            tap1
In the wifi VM: /etc/network/interfaces
Code:
# The loopback network interface
auto lo br0
iface lo inet loopback

# The primary network interface
allow-hotplug enp0s4
iface enp0s4 inet manual

allow-hotplug wlp0s3
iface wlp0s3 inet manual

iface br0 inet static
    bridge_ports enp0s4 wlp0s3
    address 192.168.5.3
    netmask 255.255.255.0
    gateway 192.168.5.1
The wifi interface is bridged with tap1 into the debian machine. tap1 is bridged inside the FreeBSD host to an ethernet interface (re0) and also to tap0 (from pfSense VM: 192.168.5.1). The DHCP service is provided by the pfSense VM.

And of course:
Code:
$ ifconfig tap1
tap1: flags=8943<UP,BROADCAST,RUNNING,PROMISC,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=80000<LINKSTATE>
        ether 00:bd:7a:e6:f6:01
        groups: tap
        media: Ethernet autoselect
        status: active
        nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
        Opened by PID 1672
$ ps -ax|grep 1672
1672  -  SC      54:58,67 bhyve: ioh-wifi (bhyve)
20918  0  S+       0:00,00 grep 1672
 

rf10

Member

Reaction score: 6
Messages: 29

This is a neat trick, but boy so much trouble. Why not simply run FreeBSD in a VirtualBox on a Linux machine?
 

Emrion

Well-Known Member

Reaction score: 107
Messages: 405

This is a neat trick, but boy so much trouble. Why not simply run FreeBSD in a VirtualBox on a Linux machine?
I've left Linux for several years and I won't come back just for a driver problem. For me, debian is just a software for interfacing a device. Furthermore, the problem isn't really FreeBSD but pfSense.
 

rf10

Member

Reaction score: 6
Messages: 29

I've left Linux for several years and I won't come back just for a driver problem.
I “left” Linux as well but it doesn’t prevent me from using it when appropriate (some software just does not work on FreeBSD). Or hardware, in your case.
 
OP
T

tingo

Daemon

Reaction score: 487
Messages: 2,270

This is a neat trick, but boy so much trouble. Why not simply run FreeBSD in a VirtualBox on a Linux machine?
As I wrote in the initial post:
I wanted to try an experiment - to see if I could use a virtual machine running Linux as a gateway.
Simple and easy are things I'm familiar with - I do those all the time. Doing things that are more difficult is rewarding in itself, and it lets me learn new stuff.
 
OP
T

tingo

Daemon

Reaction score: 487
Messages: 2,270

FWIW, here are the commands I used for testing with lo1 interface, and the error message I get:
Code:
root@kg-pod530:~ # ifconfig lo1 create
root@kg-pod530:~ # ifconfig lo1 up
root@kg-pod530:~ # ifconfig bridge0 addm lo1
ifconfig: BRDGADD lo1: Invalid argument
Ok - a quick search reveals why it doesn't work - if_bridge(4) only works with ethernet-like interfaces and lo(4) isn't such a thing.
 
OP
T

tingo

Daemon

Reaction score: 487
Messages: 2,270

Testing with epair(4) interfaces:
Code:
root@kg-pod530:~ # ifconfig epair0 create
epair0a
root@kg-pod530:~ # ifconfig bridge0 addm epair0b
root@kg-pod530:~ # ifconfig bridge0
bridge0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    description: vm-glue
    ether 02:73:ff:81:33:00
    id 00:00:00:00:00:00 priority 32768 hellotime 2 fwddelay 15
    maxage 20 holdcnt 6 proto rstp maxaddr 2000 timeout 1200
    root id 00:00:00:00:00:00 priority 32768 ifcost 0 port 0
    member: epair0b flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
            ifmaxaddr 0 port 8 priority 128 path cost 2000
    member: tap1 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
            ifmaxaddr 0 port 6 priority 128 path cost 2000000
    member: tap0 flags=143<LEARNING,DISCOVER,AUTOEDGE,AUTOPTP>
            ifmaxaddr 0 port 3 priority 128 path cost 2000000
    groups: bridge vm-switch viid-1ed4d@
    nd6 options=9<PERFORMNUD,IFDISABLED>
root@kg-pod530:~ # ifconfig epair0a
epair0a: flags=8842<BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=8<VLAN_MTU>
    ether 02:9f:79:1a:2a:0a
    groups: epair
    media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
root@kg-pod530:~ # ifconfig epair0a up
root@kg-pod530:~ # ifconfig epair0a
epair0a: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
    options=8<VLAN_MTU>
    ether 02:9f:79:1a:2a:0a
    groups: epair
    media: Ethernet 10Gbase-T (10Gbase-T <full-duplex>)
    status: active
    nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
root@kg-pod530:~ # dhclient epair0a
DHCPDISCOVER on epair0a to 255.255.255.255 port 67 interval 7
DHCPDISCOVER on epair0a to 255.255.255.255 port 67 interval 16
DHCPDISCOVER on epair0a to 255.255.255.255 port 67 interval 10
DHCPDISCOVER on epair0a to 255.255.255.255 port 67 interval 13
DHCPDISCOVER on epair0a to 255.255.255.255 port 67 interval 8
DHCPDISCOVER on epair0a to 255.255.255.255 port 67 interval 7
No DHCPOFFERS received.
No working leases in persistent database - sleeping.
No error messages, which probably means that this should work, but it does not. Not sure why.
 
OP
T

tingo

Daemon

Reaction score: 487
Messages: 2,270

Ok, I figured it out. The main reason the "epair(4) solution" didn't work was because of too restrictive rules on my firewall. Once I fixed that (and set both epair interfaces up) I got an answer from the dhcp server. Currently the network setup in /etc/rc.conf looks like this:
Code:
cloned_interfaces="bridge0 epair0"
ifconfig_bridge0="addm epair0b"
defaultroute_delay="1"
background_dhclient_epair0a="YES"
ifconfig_epair0a="DHCP"
ifconfig_epair0b="up"
I put the dhclient in background and reduced the defaultroute delay because they don't help (in this situation) - the vm isn't started until the machine has booted so there is no way the machine is going to get an ip address before the vm is up and operational.
 
Top