Configure GRE inside VMM
In this guide, we demonstrate the use of gre(4) to tunnel IPv6 packets inside IPv4. This demonstration will be performed with virtual machines inside vmm using network address translation for the private IPv4 subnet. One virtual machine will be configured IPv4-only, the other with both IPv4 and IPv6. Once the gre(4) tunnel has been properly configured, both machines will have IPv6 access.
First, in the hypervisor, we configure the proper interfaces:
host# cat /etc/hostname.veb0 add vport0 link1 host# cat /etc/hostname.vport0 inet 10.0.20.1 0xffffff00 inet6 2001:db8::1 48 !route add -inet6 2001:db8:0:3::1 -cloning -link -iface vport0 !route add -inet6 2001:db8:0:3::/64 2001:db8:0:3::1 up
In these examples, you must replace all IPv6 addresses with publicly routable
IPv6 addresses. So, for example, the address 2001:db8::1
and prefix
length 48
must both be replaced. 10.0.20.1, however, is deliberately
chosen to be a reserved IP address, and we will later apply network address
translation to conserve on IPv4 addresses.
host# cat /etc/vm.conf socket owner :vmdusers switch "switch0" { locked lladdr interface veb0 } bsdiso="/home/iso/install75.iso" vm "gre2" { owner user memory 1G cdrom $bsdiso disk /home/user/gre2.qcow2 format qcow2 interface tap2 { locked lladdr ab:cd:ef:22:22:22 switch "switch0" } } vm "gre3" { owner user memory 1G cdrom $bsdiso disk /home/user/gre3.qcow2 format qcow2 interface tap3 { locked lladdr ab:cd:ef:33:33:33 switch "switch0" } }
We also need to create the qcow2 images and install the system:
$ vmctl create -s 20G $HOME/gre2.qcow2 $ vmctl create -s 20G $HOME/gre3.qcow2
In /etc/pf.conf?, you will need a rule similar to the following for performing NAT:
match out on egress from !(egress:network) to any nat-to (egress:0)
Then reload the ruleset:
# pfctl -f /etc/pf.conf
Inside the virtual machines, we first configure machine gre2:
gre2# cat /etc/hostname.vio0 inet 10.0.20.2 0xffffff00 gre2# cat /etc/mygate 10.0.20.1 gre2# cat /etc/hostname.gre0 tunnel 10.0.20.2 10.0.20.3 inet6 2001:db8:0:3::2 64 keepalive 10 6 !route add -inet6 default 2001:db8:0:3::3 gre2# sysctl net.inet.gre.allow=1 gre2# echo "net.inet.gre.allow=1" >> /etc/sysctl.conf gre2# sysctl net.inet.ip.forwarding=1 gre2# echo "net.inet.ip.forwarding=1" >> /etc/sysctl.conf
Then we configure machine gre3:
gre3# cat /etc/hostname.vio0 inet 10.0.20.3 0xffffff00 inet6 2001:db8:0:3::1 64 !route add -inet6 2001:db8::1 -cloning -link -iface vio0 !route add -inet6 default 2001:db8::1 gre3# cat /etc/mygate 10.0.20.1 gre3# cat /etc/hostname.gre0 tunnel 10.0.20.3 10.0.20.2 inet6 2001:db8:0:3::3 64 keepalive 10 6 !route add -inet6 2001:db8:0:3::2 -cloning -link -iface gre0 gre3# sysctl net.inet.gre.allow=1 gre3# echo "net.inet.gre.allow=1" >> /etc/sysctl.conf gre3# sysctl net.inet.ip.forwarding=1 gre3# echo "net.inet.ip.forwarding=1" >> /etc/sysctl.conf gre3# sysctl net.inet6.ip6.forwarding=1 gre3# echo "net.inet6.ip6.forwarding=1" >> /etc/sysctl.conf
Now, on gre2, run ping6 to test connectivity:
gre2# ping6 2001:db8:0:3::3 PING 2001:db8:0:3::3 (2001:db8:0:3::3): 56 data bytes 64 bytes from 2001:db8:0:3::3: icmp_seq=0 hlim=64 time=0.646 ms 64 bytes from 2001:db8:0:3::3: icmp_seq=1 hlim=64 time=0.678 ms 64 bytes from 2001:db8:0:3::3: icmp_seq=2 hlim=64 time=0.631 ms 64 bytes from 2001:db8:0:3::3: icmp_seq=3 hlim=64 time=0.615 ms 64 bytes from 2001:db8:0:3::3: icmp_seq=4 hlim=64 time=0.609 ms ^C --- 2001:db8:0:3::3 ping statistics --- 5 packets transmitted, 5 packets received, 0.0% packet loss round-trip min/avg/max/std-dev = 0.609/0.636/0.678/0.025 ms
On gre3, run tcpdump to view packets:
gre3# tcpdump -ne -i gre0 tcpdump: listening on gre0, link-type LOOP 14:42:46.562742 2001:db8:0:3::2 > 2001:db8:0:3::3: icmp6: echo request 14:42:46.562772 2001:db8:0:3::3 > 2001:db8:0:3::2: icmp6: echo reply 14:42:47.579278 2001:db8:0:3::2 > 2001:db8:0:3::3: icmp6: echo request 14:42:47.579301 2001:db8:0:3::3 > 2001:db8:0:3::2: icmp6: echo reply 14:42:48.579188 2001:db8:0:3::2 > 2001:db8:0:3::3: icmp6: echo request 14:42:48.579210 2001:db8:0:3::3 > 2001:db8:0:3::2: icmp6: echo reply 14:42:49.579212 2001:db8:0:3::2 > 2001:db8:0:3::3: icmp6: echo request 14:42:49.579234 2001:db8:0:3::3 > 2001:db8:0:3::2: icmp6: echo reply 14:42:50.579228 2001:db8:0:3::2 > 2001:db8:0:3::3: icmp6: echo request 14:42:50.579250 2001:db8:0:3::3 > 2001:db8:0:3::2: icmp6: echo reply ^C 10 packets received by filter 0 packets dropped by kernel
You should also be able to see the gre encapsulation if you run tcpdump on the vio0 interface:
gre3# tcpdump -ne -i vio0 tcpdump: listening on vio0, link-type EN10MB 14:47:32.358103 ab:cd:ef:22:22:22 ab:cd:ef:33:33:33 0800 78: 10.0.20.2 > 10.0.20.3: gre 10.0.20.3 > 10.0.20.2: gre keep-alive [tos 0xc0] [tos 0xc0] 14:47:32.358153 ab:cd:ef:33:33:33 ab:cd:ef:22:22:22 0800 54: 10.0.20.3 > 10.0.20.2: gre keep-alive [tos 0xc0] 14:47:32.697773 ab:cd:ef:33:33:33 ab:cd:ef:22:22:22 0800 78: 10.0.20.3 > 10.0.20.2: gre 10.0.20.2 > 10.0.20.3: gre keep-alive [tos 0xc0] [tos 0xc0] 14:47:32.698305 ab:cd:ef:22:22:22 ab:cd:ef:33:33:33 0800 54: 10.0.20.2 > 10.0.20.3: gre keep-alive [tos 0xc0] 14:47:33.060019 ab:cd:ef:22:22:22 ab:cd:ef:33:33:33 0800 142: 10.0.20.2 > 10.0.20.3: gre 2001:db8:0:3::2 > 2001:db8:0:3::3: icmp6: echo request 14:47:33.060104 ab:cd:ef:33:33:33 ab:cd:ef:22:22:22 0800 142: 10.0.20.3 > 10.0.20.2: gre 2001:db8:0:3::3 > 2001:db8:0:3::2: icmp6: echo reply 14:47:34.078159 ab:cd:ef:22:22:22 ab:cd:ef:33:33:33 0800 142: 10.0.20.2 > 10.0.20.3: gre 2001:db8:0:3::2 > 2001:db8:0:3::3: icmp6: echo request 14:47:34.078225 ab:cd:ef:33:33:33 ab:cd:ef:22:22:22 0800 142: 10.0.20.3 > 10.0.20.2: gre 2001:db8:0:3::3 > 2001:db8:0:3::2: icmp6: echo reply
Finally, on gre2, test IPv6 connectivity to the Internet:
gre2# ping6 google.com ping6: Warning: google.com has multiple addresses; using 2607:f8b0:4023:1000::71 PING google.com (2607:f8b0:4023:1000::71): 56 data bytes 64 bytes from 2607:f8b0:4023:1000::71: icmp_seq=0 hlim=102 time=9.077 ms 64 bytes from 2607:f8b0:4023:1000::71: icmp_seq=1 hlim=102 time=8.976 ms ^C --- google.com ping statistics --- 2 packets transmitted, 2 packets received, 0.0% packet loss round-trip min/avg/max/std-dev = 8.976/9.027/9.077/0.051 ms
Relevant routing tables:
gre2# route -n show -inet6 Routing tables Internet6: Destination Gateway Flags Refs Use Mtu Prio Iface default 2001:db8:0:3::3 UGS 0 7 - 8 gre0 2001:db8:0:3::/64 2001:db8:0:3::2 UCn 1 0 - 4 gre0 2001:db8:0:3::2 2001:db8:0:3::2 UHl 0 3 - 1 gre0 2001:db8:0:3::3 link#0 UHch 1 2 - 3 gre0 gre2# route get 2607:f8b0:4023:1000::66 route to: rs-in-f102.1e100.net destination: :: mask: :: gateway: 2001:db8:0:3::3 interface: gre0 if address: 2001:db8:0:3::2 priority: 8 (static) flags: <UP,GATEWAY,DONE,STATIC> use mtu expire 7 0 0 gre3# route -n show -inet6 Routing tables Internet6: Destination Gateway Flags Refs Use Mtu Prio Iface default 2001:db8::1 UGS 0 64 - 8 vio0 2001:db8::1 ab:cd:ef:11:11:11 UHLch 1 37 - 7 vio0 2001:db8::1 link#1 UHCS 1 0 - 8 vio0 2001:db8:0:3::/64 2001:db8:0:3::1 UCPn 0 1 - 4 vio0 2001:db8:0:3::/64 2001:db8:0:3::3 UCPn 0 0 - 4 gre0 2001:db8:0:3::1 ab:cd:ef:33:33:33 UHLl 0 8 - 1 vio0 2001:db8:0:3::2 link#0 UHc 0 64 - 7 gre0 2001:db8:0:3::2 link#4 UHCS 1 0 - 8 gre0 2001:db8:0:3::3 2001:db8:0:3::3 UHl 0 0 - 1 gre0 gre3# route get 2607:f8b0:4023:1000::66 route to: rs-in-f102.1e100.net destination: :: mask: :: gateway: 2001:db8::1 interface: vio0 if address: fe80::abcd:efff:fe33:3333%vio0 priority: 8 (static) flags: <UP,GATEWAY,DONE,STATIC> use mtu expire 64 0 0 host# route -n show -inet6 Routing tables Internet6: Destination Gateway Flags Refs Use Mtu Prio Iface 2001:db8::/48 2001:db8::1 UCn 0 2 - 4 vport0 2001:db8::1 ab:cd:ef:11:11:11 UHLl 0 7066 - 1 vport0 2001:db8:0:3::/64 2001:db8:0:3::1 UGS 0 205 - 8 vport0 2001:db8:0:3::1 ab:cd:ef:33:33:33 UHLch 1 186 - 7 vport0 2001:db8:0:3::1 link#68 UHCS 1 0 - 8 vport0