Open vSwitch¶
install
$ sudo apt install openvswitch-switch openvswitch-common
basic operations
# ovs-vsctl show
# ovs-vsctl add-br <switch>
# ovs-vsctl add-port <switch> <port>
# ovs-vsctl del-port <switch> <port>
# ovs-vsctl set-manager ptcp:6632
# ovs-vsctl list port <switch>
# ovs-ofctl show <switch>
OFPT_FEATURES_REPLY (xid=0x2): dpid:0000a0369f391a68
n_tables:254, n_buffers:256
capabilities: FLOW_STATS TABLE_STATS PORT_STATS QUEUE_STATS ARP_MATCH_IP
actions: output enqueue set_vlan_vid set_vlan_pcp strip_vlan mod_dl_src mod_dl_dst mod_nw_src mod_nw_dst mod_nw_tos mod_tp_src mod_tp_dst
1(eth2): addr:a0:36:9f:39:1a:68
config: 0
state: 0
current: 10GB-FD COPPER AUTO_NEG
advertised: 100MB-FD 1GB-FD 10GB-FD COPPER AUTO_NEG
supported: 1GB-FD 10GB-FD COPPER AUTO_NEG
speed: 10000 Mbps now, 10000 Mbps max
2(eth3): addr:a0:36:9f:39:1a:6a
config: 0
state: 0
current: 10GB-FD COPPER AUTO_NEG
advertised: 100MB-FD 1GB-FD 10GB-FD COPPER AUTO_NEG
supported: 1GB-FD 10GB-FD COPPER AUTO_NEG
speed: 10000 Mbps now, 10000 Mbps max
LOCAL(ovs0): addr:a0:36:9f:39:1a:68
config: PORT_DOWN
state: LINK_DOWN
speed: 0 Mbps now, 0 Mbps max
OFPT_GET_CONFIG_REPLY (xid=0x4): frags=normal miss_send_len=0
# ovs-ofctl dump-flows <switch>
# ovs-ofctl add-flow <switch> in_port=1,actions=output:2
# ovs-ofctl add-flow <switch> arp,actions=all
# ovs-ofctl add-flow br100 \
dl_src=aa:aa:aa:bb:bb:bb, \
actions=mod_dl_src=11:11:11:22:22:22,output:all
ovs-ofctl¶
in_port,
dl_vlan, dl_vlan_pcp, dl_src, dl_dst, dl_type,
nw_src, nw_dst, nw_proto, nw_tos, nw_ecn, nw_ttl,
tp_src, tp_dst,
icmp_type, icmp_code,
ipv6_src, ipv6_dst, ipv6_label,
arp_sha, arp_tha,
table, vlan_tci, ip_frag,
nd_target, nd_sll,
nd_tll, tun_id, regX
#!/bin/sh
BR=ovs0
ovs-ofctl del-flows $BR
ovs-ofctl add-flow $BR dl_type=0x0806,actions=drop
ovs-ofctl add-flow $BR in_port=1,actions=output:2
ovs-ofctl add-flow $BR in_port=2,actions=output:1
ovs-ofctl add-flow $BR actions=drop
ovs-ofctl dump-flows $BR
Add VM’s NIC to OVS¶
VMのconfigに追加
# virsh edit vm0
+ <interface type='bridge'>
+ <source bridge='ovs0'/>
+ <virtualport type='openvswitch'/>
+ </interface>
VXLAN¶
# ovs-vsctl add-br ovs0
# ovs-vsctl add-port ovs0 eth0 tag=100
# ovs-vsctl add-port ovs0 vxlan0 tag=100 \
-- set interface vxlan0 type=vxlan \
options:key=100 \
options:remote_ip=172.16.100.1
# ovs-vsctl list interface vxlan0
if up/down
auto-ovs ovs0
iface ovs0 inet static
ovs_type OVSBridge
ovs_ports eth0 vxlan0
auto vxlan0
iface vxlan0 inet manual
ovs_bridge ovs0
ovs_type OVSTunnel
ovs_options tag=100
ovs_tunnel_type vxlan
ovs_tunnel_options options:key=100 options:remote_ip=133.25.196.23
auto eth0
iface eth0 inet manual
ovs_bridge ovs0
ovs_type OVSPort
ovs_options tag=100
- http://komeiy.hatenablog.com/entry/2014/10/26/225654
OVS-dpdk¶
Using OVS builed ourselves is better than apt-installed ovs, I think. Because apt-installed DPDK is not stable and not-usefull than original-DPDK. Building and Installing OVS from source code is easy and simple, so you should choice it.
$ git clone http://github.com/openvswitch/ovs
$ cd ovs
...
Start OVS Shell Script
#!/bin/sh
BR=ovs0
killall ovsdb-server ovs-vswitchd
rm -rf /tmp/openvswitch
mkdir -p /tmp/openvswitch
rm -f /usr/local/var/run/openvswitch/conf.db
ovsdb-tool create \
/usr/local/var/run/openvswitch/conf.db \
/usr/local/share/openvswitch/vswitch.ovsschema
ovsdb-server \
--remote=punix:/usr/local/var/run/openvswitch/db.sock \
--remote=db:Open_vSwitch,Open_vSwitch,manager_options --pidfile --detach
ovs-vsctl --no-wait init
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-lcore-mask=0x3f
ovs-vsctl --no-wait set Open_vSwitch . other_config:pmd-cpu-mask=0x30
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-socket-mem=1024,0
ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true
ovs-vswitchd unix:/usr/local/var/run/openvswitch/db.sock --pidfile
Create OVS-dpdk instance Shell Script
#!/bin/sh
BR=ovs0
ovs-vsctl del-br $BR
ovs-vsctl add-br $BR -- set bridge $BR datapath_type=netdev
ovs-vsctl add-port $BR dpdk0 -- set Interface dpdk0 type=dpdk options:dpdk-devargs=0000:3b:00.0
ovs-vsctl add-port $BR dpdk1 -- set Interface dpdk1 type=dpdk options:dpdk-devargs=0000:3b:00.1
ovs-vsctl add-port $BR vhost_user0 -- set Interface vhost_user0 type=dpdkvhostuser
ovs-vsctl add-port $BR vhost_user1 -- set Interface vhost_user1 type=dpdkvhostuser
ip link set $BR up
QEMU w/ vhost-user¶
#!/bin/sh
sudo qemu-system-x86_64 \
-cpu host -enable-kvm -m 4000M -hda vm0.img \
-object memory-backend-file,id=mem,size=4000M,mem-path=/dev/hugepages,share=on \
-numa node,memdev=mem -mem-prealloc -smp sockets=1,cores=2 \
-net nic -net tap,ifname=vtap0,script=./ifup.sh \
-vnc :5,password -monitor stdio \
\
-chardev socket,id=chr0,path=/usr/local/var/run/openvswitch/vhost_user1 \
-netdev type=vhost-user,id=net0,chardev=chr0,vhostforce,queues=1 \
-device virtio-net-pci,netdev=net0,mrg_rxbuf=off \
\
-chardev socket,id=chr1,path=/usr/local/var/run/openvswitch/vhost_user2 \
-netdev type=vhost-user,id=net1,chardev=chr1,vhostforce,queues=1 \
-device virtio-net-pci,netdev=net1,mrg_rxbuf=off
KVM w/ vhost-user¶
- vhost.sock should be placed on
/var/lib/libvirt/qemu/
..? - vhost.sock should be set permission as
root:libvirt
…? –>root:root
was ok… :(
<memory unit='KiB'>1048576</memory>
<currentMemory unit='KiB'>1048576</currentMemory>
+ <memoryBacking><hugepages/></memoryBacking>
+ <cpu mode='host-passthrough'>
+ <numa>
+ <cell id='0' cpus='0' memory='1048576' unit='KiB' memAccess='shared'/>
+ </numa>
+ </cpu>
+ <interface type='vhostuser'>
+ <source type='unix' path='/var/lib/libvirt/qemu/vhost_user0.sock' mode='client'/>
+ <model type='virtio'/>
+ </interface>
Vhost-user Trouble Shooting¶
- invalid socket-file path
error: internal error: process exited while connecting to monitor: 2019-08-05T07:36:56.146971Z qemu-system-x86_64: -chardev socket,id=charnet1,path=/tmp/vhost2.sock: Failed to connect socket /tmp/vhost2.sock: No such file or directory
- kvm and qemu’s persmission setting is invalid.
- http://docs.openvswitch.org/en/latest/topics/dpdk/vhost-user/#adding-vhost-user-ports-to-the-guest-libvirt
error: internal error: process exited while connecting to monitor: 2019-08-05T07:36:28.579478Z qemu-system-x86_64: -chardev socket,id=charnet1,path=/tmp/vhost2.sock: Failed to connect socket /tmp/vhost2.sock: Permission denied
- add more hugepages when following case.
- if hugepages is few to create vm, kvm prints such error logs.
error: internal error: process exited while connecting to monitor: 2019-08-05T07:37:14.159699Z qemu-system-x86_64: -object memory-backend-file,id=ram-node0,prealloc=yes,mem-path=/dev/hugepages/libvirt/qemu/9-vm01,share=yes,size=8388608000: unable to map backing store for guest RAM: Cannot allocate memory
Good references¶
- https://software.intel.com/en-us/articles/configure-vhost-user-multiqueue-for-ovs-with-dpdk
- https://www.redhat.com/ja/blog/ovs-dpdk-migrating-vhostuser-socket-mode-red-hat-openstack
- https://wiki.qemu.org/Features/VirtioVhostUser
- https://www.youtube.com/watch?v=OnTQRgUyiv8&t=3s –> describing how to configure ovs-dpdk w/ vhost-user “[2017] Configuring and Benchmarking Open vSwitch, DPDK and vhost-user by Pei Zhang”
- http://www.virtualopensystems.com/en/solutions/guides/snabbswitch-qemu/ –> describing the architecture of vhost-user and how they are performing low-cost packet delivery.