Gre /

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 with network address translation. 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
up

Here, you must replace 2001:db8::1 with a publicly routable IPv6 address and 48 with its actual prefix length. 10.0.20.1 however is deliberately chosen to be a reserved IP address, since we are applying network address translation.

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:

$ 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 fd19:: 127
keepalive 10 6
!route add -inet6 default fd19::1
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 fd19::1 127
keepalive 10 6
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

We add a translation rule to pf.conf on gre3:

match on egress from fd19::/127 to any binat-to (vio0:0)

Now, on gre2, run ping6 to test connectivity:

gre2# ping6 2001:db8::10:0:20:3
PING 2001:db8::10:0:20:3 (2001:db8::10:0:20:3): 56 data bytes
64 bytes from 2001:db8::10:0:20:3: icmp_seq=0 hlim=64 time=0.646 ms
64 bytes from 2001:db8::10:0:20:3: icmp_seq=1 hlim=64 time=0.678 ms
64 bytes from 2001:db8::10:0:20:3: icmp_seq=2 hlim=64 time=0.631 ms
64 bytes from 2001:db8::10:0:20:3: icmp_seq=3 hlim=64 time=0.615 ms
64 bytes from 2001:db8::10:0:20:3: icmp_seq=4 hlim=64 time=0.609 ms
^C
--- 2001:db8::10:0:20: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::10:0:20:2 > 2001:db8::10:0:20:3: icmp6: echo request
14:42:46.562772 2001:db8::10:0:20:3 > 2001:db8::10:0:20:2: icmp6: echo reply
14:42:47.579278 2001:db8::10:0:20:2 > 2001:db8::10:0:20:3: icmp6: echo request
14:42:47.579301 2001:db8::10:0:20:3 > 2001:db8::10:0:20:2: icmp6: echo reply
14:42:48.579188 2001:db8::10:0:20:2 > 2001:db8::10:0:20:3: icmp6: echo request
14:42:48.579210 2001:db8::10:0:20:3 > 2001:db8::10:0:20:2: icmp6: echo reply
14:42:49.579212 2001:db8::10:0:20:2 > 2001:db8::10:0:20:3: icmp6: echo request
14:42:49.579234 2001:db8::10:0:20:3 > 2001:db8::10:0:20:2: icmp6: echo reply
14:42:50.579228 2001:db8::10:0:20:2 > 2001:db8::10:0:20:3: icmp6: echo request
14:42:50.579250 2001:db8::10:0:20:3 > 2001:db8::10:0:20: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 e8:8b:a3:22:22:22 e8:8b:a3: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 e8:8b:a3:33:33:33 e8:8b:a3:22:22:22 0800 54: 10.0.20.3 > 10.0.20.2: gre keep-alive [tos 0xc0]
14:47:32.697773 e8:8b:a3:33:33:33 e8:8b:a3: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 e8:8b:a3:22:22:22 e8:8b:a3:33:33:33 0800 54: 10.0.20.2 > 10.0.20.3: gre keep-alive [tos 0xc0]
14:47:33.060019 e8:8b:a3:22:22:22 e8:8b:a3:33:33:33 0800 142: 10.0.20.2 > 10.0.20.3: gre 2001:db8::10:0:20:2 > 2001:db8::10:0:20:3: icmp6: echo request
14:47:33.060104 e8:8b:a3:33:33:33 e8:8b:a3:22:22:22 0800 142: 10.0.20.3 > 10.0.20.2: gre 2001:db8::10:0:20:3 > 2001:db8::10:0:20:2: icmp6: echo reply
14:47:34.078159 e8:8b:a3:22:22:22 e8:8b:a3:33:33:33 0800 142: 10.0.20.2 > 10.0.20.3: gre 2001:db8::10:0:20:2 > 2001:db8::10:0:20:3: icmp6: echo request
14:47:34.078225 e8:8b:a3:33:33:33 e8:8b:a3:22:22:22 0800 142: 10.0.20.3 > 10.0.20.2: gre 2001:db8::10:0:20:3 > 2001:db8::10:0:20: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