diff --git a/README.md b/README.md index b5cb0d8d..475ec6b2 100644 --- a/README.md +++ b/README.md @@ -483,10 +483,14 @@ connected to the bridge is the weave router container, which is given the IP address & netmask supplied in 'weave launch'. A weave router captures Ethernet packets from its bridge-connected -interface in promiscuous mode, using 'pcap'. It forwards these packets -over UDP to weave router peers running on other hosts. On receipt of -such a packet, a router injects the packet on its bridge interface -using 'pcap' and/or forwards the packet to peers. +interface in promiscuous mode, using 'pcap'. This typically excludes +traffic between local containers, and between the host and local +containers, all of which is routed straight over the bridge by the +kernel. Captured packets are forwarded over UDP to weave router peers +running on other hosts. On receipt of such a packet, a router injects +the packet on its bridge interface using 'pcap' and/or forwards the +packet to peers. + Weave routers learn which peer host a particular MAC address resides on. They combine this knowledge with topology information in order to diff --git a/pcap.go b/pcap.go index 2a326d16..354ec818 100644 --- a/pcap.go +++ b/pcap.go @@ -8,9 +8,19 @@ type PcapIO struct { handle *pcap.Handle } -func NewPcapIO(ifName string, bufSz int) (pio PacketSourceSink, err error) { - pio, err = newPcapIO(ifName, true, 65535, bufSz) - return +func NewPcapIO(ifName string, bufSz int) (PacketSourceSink, error) { + pio, err := newPcapIO(ifName, true, 65535, bufSz) + if err != nil { + return pio, err + } + + // Under Linux, libpcap implements the SetDirection filtering + // in userspace. So set a BPF filter to discard outbound + // packets inside the kernel. We do this here rather than in + // newPcapIO because libpcap doesn't like this in combination + // with a 0 snaplen. + err = pio.handle.SetBPFFilter("inbound") + return pio, err } func NewPcapO(ifName string) (po PacketSink, err error) { diff --git a/weaver/weave b/weaver/weave index 55ae3c82..371f3cec 100755 --- a/weaver/weave +++ b/weaver/weave @@ -115,22 +115,43 @@ configure_container_networking() { NSPID=$DOCKERPID [ ! -d /var/run/netns ] && mkdir -p /var/run/netns - [ -f /var/run/netns/$NSPID ] && rm -f /var/run/netns/$NSPID + rm -f /var/run/netns/$NSPID ln -s /proc/$NSPID/ns/net /var/run/netns/$NSPID + EXITCODE=1 LOCAL_IFNAME="v${CONTAINER_IFNAME}pl${NSPID}" GUEST_IFNAME="v${CONTAINER_IFNAME}pg${NSPID}" - ip link add name $LOCAL_IFNAME mtu $MTU type veth peer name $GUEST_IFNAME mtu $MTU - ip link set $LOCAL_IFNAME master $BRIDGE - ip link set $LOCAL_IFNAME up - ip link set $GUEST_IFNAME netns $NSPID - ip netns exec $NSPID ip link set $GUEST_IFNAME name $CONTAINER_IFNAME - ip netns exec $NSPID ip addr add $2 dev $CONTAINER_IFNAME - ip netns exec $NSPID ip link set $CONTAINER_IFNAME up + IP_TMPFILE=/tmp/weave_ip_output_$$ + rm -f $IP_TMPFILE + if ip link add name $LOCAL_IFNAME mtu $MTU type veth peer name $GUEST_IFNAME mtu $MTU >$IP_TMPFILE 2>&1 ; then + if (ip link set $LOCAL_IFNAME master $BRIDGE && + ip link set $LOCAL_IFNAME up && + ip link set $GUEST_IFNAME netns $NSPID) >$IP_TMPFILE 2>&1 + then + (ip netns exec $NSPID ip link set $GUEST_IFNAME name $CONTAINER_IFNAME && + ip netns exec $NSPID ip addr add $2 dev $CONTAINER_IFNAME && + ip netns exec $NSPID ip link set $CONTAINER_IFNAME up && + check_command_and_run ethtool ip netns exec $NSPID ethtool -K $3 tx off >/dev/null) >$IP_TMPFILE 2>&1 && + EXITCODE=0 + else + # failed before we assigned the veth to the container's namespace - delete it + ip link del $LOCAL_IFNAME type veth || true + fi + fi - check_command_and_run ethtool ip netns exec $NSPID ethtool -K $3 tx off >/dev/null + if [ "$EXITCODE" -ne 0 ] ; then + if ! ps -p $DOCKERPID >/dev/null 2>&1 ; then + echo "Container $1 died" >&2 + else + echo "Failure during network configuration for container $1:" >&2 + cat $IP_TMPFILE >&2 + fi + fi - [ -f /var/run/netns/$NSPID ] && rm -f /var/run/netns/$NSPID + rm -f $IP_TMPFILE + rm -f /var/run/netns/$NSPID + + return $EXITCODE } case "$COMMAND" in