Skip to content

Commit

Permalink
Make some tunneling UCs work + patch for IPv6 secondary addresses (de…
Browse files Browse the repository at this point in the history
…fault address selection)
  • Loading branch information
pierrecdn committed Mar 5, 2015
1 parent c42c6ad commit 298ff0a
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 25 deletions.
30 changes: 25 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Pipework uses cgroups and namespace and works with "plain" LXC containers
* [Support Open vSwitch](#openvswitch)
* [Support Infiniband](#infiniband)
* [Cleanup](#cleanup)
* [Debugging](#debug)
* [Experimental](#experimental)


Expand Down Expand Up @@ -125,7 +126,8 @@ Voilà!

<a name="setting_internal"/>
### Setting container internal interface ##
By default pipework creates a new interface `eth1` inside the container. In case you want to change this interface name like `eth2`, e.g., to have more than one interface set by pipework, use:
By default pipework creates a new interface `eth1` inside the container. In case you want to
change this interface name like `eth2`, e.g., to have more than one interface set by pipework, use:

`pipework br1 web1 -i eth2 ...`

Expand Down Expand Up @@ -315,7 +317,7 @@ ovs0 and attach the container to VLAN ID 10.
<a name="ipv6"/>
### IPv6

IPv6 adressing is also supported, using the same options :
IPv6 global scope adressing is also supported, using the same options :

pipework eth0 eth0 $(docker run -d haproxy) -a ip 2001:db8::beef/64@2001:db8::1

Expand Down Expand Up @@ -374,15 +376,33 @@ the network interfaces are garbage collected. The interface in the container
is automatically destroyed, and the interface in the docker host (part of the
bridge) is then destroyed as well.

<a name="debug"/>
### Debugging

2 switchs makes you able to debug some tedious situations :

-v logs every iproute2 calls

-x enable shell debugging (similar to sh -x pipework ...)

<a name="experimental"/>
### Experimental

TBD : test/kernel watch/...

- Tunnel interfaces (GRE/IPIP/IP6_TUNNEL)

pipework eth0 $(docker run -d haproxy) -a ipip 192.168.1.3/32
pipework eth0 $(docker run -d haproxy) -a ipip 2001:db8::2/32
pipework eth0 $(docker run -d haproxy) -i eth1 -a ipip 192.168.1.3
pipework eth0 $(docker run -d haproxy) -a ipip 2001:db8::2

If the container has more than one internal interface, specify the internal interface (-i) to attach
the tunnel to the good device

No more driver/mode to remember (ipip, ip6_tunnel, ipip6, ip6ip6, gre, ip6_gre,...), pipeworks adapts itself
to the right situation regarding your adressing scheme (doing ipv4-in-ipv4 or ipv6-in-ipv6 encapsulation)

Be careful about the MTU in these situations... (tunneling in the container over tunneling on the host may lead
to problems).

- Clean OVS bridge
- Clean OVS bridge unused ports

72 changes: 52 additions & 20 deletions pipework
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,17 @@ set_netns_ip() {
IPROUTE_PREFIX="ip -6"
}

if [ "$IPROUTE_PREFIX" = "ip -6" ]
then
# Patch for secondary IPv6 : add preffered_lft 0 cause you may not want the last added IP to be the source of the whole v6 traffic
# https://lists.debian.org/debian-isp/2011/05/msg00047.html
ip netns exec $NSPID $IPROUTE_PREFIX addr sh $CONTAINER_IFNAME | grep -q inet6 > /dev/null 2>&1 && {
IPROUTE_OPTIONS="preferred_lft 0"
}
fi

# Set IP/gateway/routes
run ip netns exec $NSPID $IPROUTE_PREFIX addr add $IPADDR dev $CONTAINER_IFNAME
run ip netns exec $NSPID $IPROUTE_PREFIX addr add $IPADDR dev $CONTAINER_IFNAME $IPROUTE_OPTIONS
[ "$GATEWAY" ] && {
run ip netns exec $NSPID $IPROUTE_PREFIX route delete default >/dev/null 2>&1 && true
}
Expand Down Expand Up @@ -110,32 +119,45 @@ set_tunnel() {
ROUTES=$5

# Test IPv4/IPv6
if [ $(echo $IPADDR | grep -q :) ];
if echo $IPADDR | grep -q :
then
IPROUTE_PREFIX="ip -6"
if [ $ACTION = ipip ]
then
TUNL_NAME=ip6tnl0
TUNL_NAME=ip6tnl1 # TODO kernel 3.16 : output "No such device" and doesn't work with ip6tnl0
TUNL_MODE=ip6ip6
elif [ $ACTION = gre ]
then
TUNL_NAME=ip6gre0
TUNL_MODE=sit
TUNL_NAME=ip6gre1
TUNL_MODE=ip6gre
fi
else
else
IPROUTE_PREFIX="ip -4"
if [ $ACTION = ipip ]
then
TUNL_NAME=tunl0
TUNL_NAME=tunl1
TUNL_MODE=ipip
elif [ $ACTION = gre ]
then
TUNL_NAME=gre0
TUNL_NAME=gre1
TUNL_MODE=gre
fi
fi
run ip netns exec $NSPID ip tunnel add $TUNL_NAME mode $TUNL_MODE dev $CONTAINER_IFNAME
# If the tunnel already exists, just address it (allows secondary address on tunneling interfaces)
run ip netns exec $NSPID $IPROUTE_PREFIX tunnel add $TUNL_NAME mode $TUNL_MODE dev $CONTAINER_IFNAME 3>&1 1>&2 2>&3 | grep -v "File exists" && true

# Patch for secondary IPv6 : add preffered_lft 0 cause you may not want the last added IP to be the source of the whole v6 traffic
# https://lists.debian.org/debian-isp/2011/05/msg00047.html
if [ "$IPROUTE_PREFIX" = "ip -6" ]
then
ip netns exec $NSPID $IPROUTE_PREFIX tunnel sh $TUNL_NAME > /dev/null 2>&1 && {
IPROUTE_OPTIONS="preferred_lft 0"
}
fi

ADDRS=$(echo $IPADDR | tr ',' ' ')
for ADDR in $ADDRS; do
run ip netns exec $NSPID ip addr add $IPADDR dev $TUNL_NAME
for ADDR in $ADDRS; do
run ip netns exec $NSPID $IPROUTE_PREFIX addr add $IPADDR dev $TUNL_NAME $IPROUTE_OPTIONS
done

[ "$ROUTES" ] && {
Expand All @@ -144,6 +166,7 @@ set_tunnel() {
run ip netns exec $NSPID $IPROUTE_PREFIX route add $ROUTE via $GATEWAY dev $CONTAINER_IFNAME
done
}
run ip netns exec $NSPID $IPROUTE_PREFIX link set $TUNL_NAME up
}


Expand Down Expand Up @@ -209,12 +232,21 @@ while [ $# -gt 0 ]; do
shift
check_kernel_module ipip
check_kernel_module ip6_tunnel
[ $# -eq 0 ] && {
help
exit 1
}
IPADDR=$1
;;
gre)
shift
check_kernel_module gre
check_kernel_module ip6_gre
IPADDR=$2
[ $# -eq 0 ] && {
help
exit 1
}
IPADDR=$1
;;
tc)
shift
Expand Down Expand Up @@ -464,19 +496,19 @@ ln -s /proc/$NSPID/ns/net /var/run/netns/$NSPID
}
run ip link set $IFNAME up
IFNAME=$IFNAME.$VLAN
}
}
GUEST_IFNAME=ph$NSPID$CONTAINER_IFNAME
run ip link add link $IFNAME dev $GUEST_IFNAME mtu $MTU type macvlan mode bridge
run ip link set $IFNAME up
}

run ip link set $GUEST_IFNAME netns $NSPID
run ip netns exec $NSPID ip link set $GUEST_IFNAME name $CONTAINER_IFNAME
[ "$MACADDR" ] && run ip netns exec $NSPID ip link set dev $CONTAINER_IFNAME address $MACADDR
}

case "$ACTION" in
link)
link)
exit 0
;;
dhcp)
Expand All @@ -487,20 +519,20 @@ case "$ACTION" in
run ip netns exec $NSPID $DHCP_CLIENT -pf "/var/run/dhclient.$NSPID.pid" $CONTAINER_IFNAME
kill "$(cat "/var/run/dhclient.$NSPID.pid")"
rm "/var/run/dhclient.$NSPID.pid"
fi
fi
[ $DHCP_CLIENT = "dhcpcd" ] && run ip netns exec $NSPID $DHCP_CLIENT -q $CONTAINER_IFNAME -h $GUESTNAME
;;
ip|sec_ip)
ip|sec_ip)
set_netns_ip $NSPID $CONTAINER_IFNAME $IPADDR $GATEWAY $ROUTES
;;
ipip|gre)
set_tunnel $ACTION $NSPID $CONTAINER_IFNAME $IPADDR $ROUTES
;;
tc)
tc)
run ip netns exec $NSPID tc $QOS
;;
esac
esac

# Remove NSPID to avoid `ip netns` catch it.
[ -f /var/run/netns/$NSPID ] && rm -f /var/run/netns/$NSPID
exit 0

0 comments on commit 298ff0a

Please sign in to comment.