From e64442f6de63c8142f4f6a34bed25bd963646af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80b=C3=A9j=C3=ADd=C3=A9=20=C3=80yod=C3=A9l=C3=A9?= Date: Wed, 12 Apr 2017 10:37:25 -0500 Subject: [PATCH 1/5] Highlight the forward rules --- docs/weavenpc-design.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/weavenpc-design.md b/docs/weavenpc-design.md index 5827e57f..a2240827 100644 --- a/docs/weavenpc-design.md +++ b/docs/weavenpc-design.md @@ -77,8 +77,10 @@ iptables -A WEAVE-NPC -m state --state NEW -j WEAVE-NPC-INGRESS To direct traffic into the policy engine: +``` iptables -A FORWARD -o weave -m physdev ! --physdev-out vethwe-bridge -j WEAVE-NPC iptables -A FORWARD -o weave -m physdev ! --physdev-out vethwe-bridge -j DROP +``` Note this only affects traffic which egresses the bridge on a physical port which is not the Weave Net router - in other words, it is From ca64ab54e77229294c9aaf52b35ccdc031fab143 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Tue, 30 May 2017 10:30:02 +0000 Subject: [PATCH 2/5] Remove trailing space --- test/830_cni_plugin_test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/830_cni_plugin_test.sh b/test/830_cni_plugin_test.sh index dd6dc7fd..623bb93f 100755 --- a/test/830_cni_plugin_test.sh +++ b/test/830_cni_plugin_test.sh @@ -8,7 +8,7 @@ cni_connect() { pid=$(container_pid $1 $2) id=$(docker_on $1 inspect -f '{{.Id}}' $2) run_on $1 sudo CNI_COMMAND=ADD CNI_CONTAINERID=$id CNI_IFNAME=eth0 \ - CNI_NETNS=/proc/$pid/ns/net CNI_PATH=/opt/cni/bin /opt/cni/bin/weave-net + CNI_NETNS=/proc/$pid/ns/net CNI_PATH=/opt/cni/bin /opt/cni/bin/weave-net } run_on $HOST1 sudo mkdir -p /opt/cni/bin From c05955d598e569150859ff9ed1852f4fd52d161c Mon Sep 17 00:00:00 2001 From: Avi Deitcher Date: Tue, 16 May 2017 23:16:40 +0100 Subject: [PATCH 3/5] First cut of adding hairpin functionality to weave --- net/veth.go | 8 ++++++-- plugin/net/cni.go | 11 ++++++----- prog/weaveutil/attach.go | 8 ++++++-- site/kube-addon.md | 4 ++++ weave | 7 +++++-- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/net/veth.go b/net/veth.go index a95553e8..62756e8f 100644 --- a/net/veth.go +++ b/net/veth.go @@ -113,7 +113,7 @@ func interfaceExistsInNamespace(netNSPath string, ifName string) bool { // NB: This function can be used only by a process that terminates immediately // after calling the function as it changes netns via WithNetNSLinkUnsafe. -func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool) error { +func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMulticastRoute bool, cidrs []*net.IPNet, keepTXOn bool, hairpinMode bool) error { ns, err := netns.GetFromPath(netNSPath) if err != nil { return err @@ -131,7 +131,7 @@ func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMult id = id[:maxIDLen] // trim passed ID if too long } name, peerName := vethPrefix+"pl"+id, vethPrefix+"pg"+id - _, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, func(veth netlink.Link) error { + veth, err := CreateAndAttachVeth(name, peerName, bridgeName, mtu, keepTXOn, func(veth netlink.Link) error { if err := netlink.LinkSetNsFd(veth, int(ns)); err != nil { return fmt.Errorf("failed to move veth to container netns: %s", err) } @@ -143,6 +143,10 @@ func AttachContainer(netNSPath, id, ifName, bridgeName string, mtu int, withMult if err != nil { return err } + if err = netlink.LinkSetHairpin(veth, hairpinMode); err != nil { + return fmt.Errorf("unable to set hairpin mode to %t for bridge side of veth %s: %s", hairpinMode, name, err) + } + } if err := WithNetNSLinkUnsafe(ns, ifName, func(veth netlink.Link) error { diff --git a/plugin/net/cni.go b/plugin/net/cni.go index 8265bf45..10b0e137 100644 --- a/plugin/net/cni.go +++ b/plugin/net/cni.go @@ -128,7 +128,7 @@ func (c *CNIPlugin) CmdAdd(args *skel.CmdArgs) error { id = fmt.Sprintf("%x", data) } - if err := weavenet.AttachContainer(args.Netns, id, args.IfName, conf.BrName, conf.MTU, false, []*net.IPNet{&ip.Address}, false); err != nil { + if err := weavenet.AttachContainer(args.Netns, id, args.IfName, conf.BrName, conf.MTU, false, []*net.IPNet{&ip.Address}, false, conf.HairpinMode); err != nil { return err } if err := weavenet.WithNetNSLinkUnsafe(ns, args.IfName, func(link netlink.Link) error { @@ -218,8 +218,9 @@ func logOnStderr(err error) { type NetConf struct { types.NetConf - BrName string `json:"bridge"` - IsGW bool `json:"isGateway"` - IPMasq bool `json:"ipMasq"` - MTU int `json:"mtu"` + BrName string `json:"bridge"` + IsGW bool `json:"isGateway"` + IPMasq bool `json:"ipMasq"` + MTU int `json:"mtu"` + HairpinMode bool `json:"hairpinMode"` } diff --git a/prog/weaveutil/attach.go b/prog/weaveutil/attach.go index 6de93ce4..6bd5e3bf 100644 --- a/prog/weaveutil/attach.go +++ b/prog/weaveutil/attach.go @@ -14,11 +14,12 @@ import ( func attach(args []string) error { if len(args) < 4 { - cmdUsage("attach-container", "[--no-multicast-route] [--keep-tx-on] ...") + cmdUsage("attach-container", "[--no-multicast-route] [--keep-tx-on] [--hairpin-mode=true|false] ...") } keepTXOn := false withMulticastRoute := true + hairpinMode := true for i := 0; i < len(args); { switch args[i] { case "--no-multicast-route": @@ -27,6 +28,9 @@ func attach(args []string) error { case "--keep-tx-on": keepTXOn = true args = append(args[:i], args[i+1:]...) + case "--hairpin-mode=false": + hairpinMode = false + args = append(args[:i], args[i+1:]...) default: i++ } @@ -55,7 +59,7 @@ func attach(args []string) error { return err } - err = weavenet.AttachContainer(weavenet.NSPathByPid(pid), fmt.Sprint(pid), weavenet.VethName, args[1], mtu, withMulticastRoute, cidrs, keepTXOn) + err = weavenet.AttachContainer(weavenet.NSPathByPid(pid), fmt.Sprint(pid), weavenet.VethName, args[1], mtu, withMulticastRoute, cidrs, keepTXOn, hairpinMode) // If we detected an error but the container has died, tell the user that instead. if err != nil && !processExists(pid) { err = fmt.Errorf("Container %s died", args[0]) diff --git a/site/kube-addon.md b/site/kube-addon.md index 4e664d10..27c069e7 100644 --- a/site/kube-addon.md +++ b/site/kube-addon.md @@ -241,3 +241,7 @@ The list of variables you can set is: a larger size for better performance if your network supports jumbo frames - see [here](/site/using-weave/fastdp.md#mtu) for more details. +* `HAIRPIN_MODE` - Weave Net defaults to enabling hairpin on the bridge side of + the `veth` pair for containers attached. If you need to disable hairpin, e.g. your + kernel is one of those that can panic if hairpin is enabled, then you can disable it + by setting `HAIRPIN_MODE=false`. diff --git a/weave b/weave index 68d589ef..97c4946f 100755 --- a/weave +++ b/weave @@ -1070,17 +1070,20 @@ create_cni_config() { cat >"$1" < Date: Wed, 24 May 2017 11:18:26 +0300 Subject: [PATCH 4/5] Test of hairpin mode in CNI --- test/830_cni_plugin_test.sh | 51 +++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/test/830_cni_plugin_test.sh b/test/830_cni_plugin_test.sh index 623bb93f..d0f1b934 100755 --- a/test/830_cni_plugin_test.sh +++ b/test/830_cni_plugin_test.sh @@ -19,6 +19,11 @@ weave_on $HOST1 launch C0=$(docker_on $HOST1 run --net=none --name=c0 -dt $SMALL_IMAGE /bin/sh) C1=$(docker_on $HOST1 run --net=none --privileged --name=c1 -dt $SMALL_IMAGE /bin/sh) C2=$(docker_on $HOST1 run --net=none --name=c2 -dt $SMALL_IMAGE /bin/sh) +CH0=$(docker_on $HOST1 run --net=none --name=ch0 -dt $SMALL_IMAGE /bin/sh) +CH1=$(docker_on $HOST1 run --net=none --name=ch1 -dt $SMALL_IMAGE /bin/sh) +CH2=$(docker_on $HOST1 run --net=none --name=ch2 -dt $SMALL_IMAGE /bin/sh) + + # Enable unsolicited ARPs so that ping after the address reuse does not time out exec_on $HOST1 c1 sysctl -w net.ipv4.conf.all.arp_accept=1 @@ -52,6 +57,29 @@ cni_connect $HOST1 c2 < Date: Mon, 29 May 2017 10:37:15 +0300 Subject: [PATCH 5/5] Make hairpin mode default true in CNI --- plugin/net/cni.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugin/net/cni.go b/plugin/net/cni.go index 10b0e137..bfc4f45e 100644 --- a/plugin/net/cni.go +++ b/plugin/net/cni.go @@ -34,7 +34,8 @@ func NewCNIPlugin(weave *weaveapi.Client) *CNIPlugin { func loadNetConf(bytes []byte) (*NetConf, error) { n := &NetConf{ - BrName: weavenet.WeaveBridgeName, + BrName: weavenet.WeaveBridgeName, + HairpinMode: true, } if err := json.Unmarshal(bytes, n); err != nil { return nil, fmt.Errorf("failed to load netconf: %v", err)