From ebf4b4b48a9a2e42df0e5d3108939e71c59438d7 Mon Sep 17 00:00:00 2001 From: Martynas Pumputis Date: Thu, 10 May 2018 13:13:50 +0200 Subject: [PATCH] Implement and start using NoMasqLocalTracker The tracker updates the "no-masq-local" ipset with CIDR ranges allocated by IPAM. --- net/bridge.go | 42 +++++++++++++++++++++++++++++++++++++++++- prog/weaver/main.go | 9 ++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/net/bridge.go b/net/bridge.go index deff2e11..4d228405 100644 --- a/net/bridge.go +++ b/net/bridge.go @@ -10,9 +10,12 @@ import ( "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/vishvananda/netlink" + "k8s.io/apimachinery/pkg/types" "github.com/weaveworks/weave/common" "github.com/weaveworks/weave/common/odp" + "github.com/weaveworks/weave/ipam/tracker" + "github.com/weaveworks/weave/net/address" "github.com/weaveworks/weave/net/ipset" ) @@ -499,7 +502,8 @@ func configureIPTables(config *BridgeConfig) error { // k8s-only: Create the ipset to store CIDRs allocated by IPAM for local pods. // External traffic sent to these CIDRs avoids SNAT'ing so that NodePort - // with `"externalTrafficPolicy":"Local"` would have the correct src IP addr. + // with `"externalTrafficPolicy":"Local"` would receive packets with correct + // src IP addr. if config.NoMasqLocal { ips := ipset.New(common.LogLogger()) _ = ips.Destroy(NoMasqLocalIpset) @@ -514,6 +518,42 @@ func configureIPTables(config *BridgeConfig) error { return nil } +type NoMasqLocalTracker struct { + ips ipset.Interface + owner types.UID +} + +func NewNoMasqLocalTracker() *NoMasqLocalTracker { + return &NoMasqLocalTracker{ + // TODO(mp) Reuse ipset object as each time calling New creates a test set. + ips: ipset.New(common.LogLogger()), + owner: types.UID(0), // dummy ipset owner + } +} + +func (t *NoMasqLocalTracker) String() string { + return "no-masq-local" +} + +func (t *NoMasqLocalTracker) HandleUpdate(prevRanges, currRanges []address.Range, local bool) error { + prev, curr := tracker.RemoveCommon( + address.NewCIDRs(tracker.Merge(prevRanges)), + address.NewCIDRs(tracker.Merge(currRanges))) + + for _, cidr := range curr { + if err := t.ips.AddEntry(t.owner, NoMasqLocalIpset, cidr.String(), ""); err != nil { + return err + } + } + for _, cidr := range prev { + if err := t.ips.DelEntry(t.owner, NoMasqLocalIpset, cidr.String()); err != nil { + return err + } + } + + return nil +} + func linkSetUpByName(linkName string) error { link, err := netlink.LinkByName(linkName) if err != nil { diff --git a/prog/weaver/main.go b/prog/weaver/main.go index c81dd05d..514a6596 100644 --- a/prog/weaver/main.go +++ b/prog/weaver/main.go @@ -337,6 +337,9 @@ func main() { if bridgeConfig.AWSVPC && !ipamConfig.Enabled() { Log.Fatalf("--awsvpc mode requires IPAM enabled") } + if bridgeConfig.AWSVPC && bridgeConfig.NoMasqLocal { + Log.Fatalf("--awsvpc mode is not compatible with the --no-masq-local option") + } db, err := db.NewBoltDB(dbPrefix) checkFatal(err) @@ -400,11 +403,15 @@ func main() { if ipamConfig.Enabled() { var t tracker.LocalRangeTracker if bridgeConfig.AWSVPC { - Log.Infoln("Creating AWSVPC LocalRangeTracker") t, err = tracker.NewAWSVPCTracker(bridgeConfig.WeaveBridgeName) if err != nil { Log.Fatalf("Cannot create AWSVPC LocalRangeTracker: %s", err) } + } else if bridgeConfig.NoMasqLocal { + t = weavenet.NewNoMasqLocalTracker() + } + if t != nil { + Log.Infof("Using %q LocalRangeTracker", t) } preClaims, err := findExistingAddresses(dockerCli, bridgeConfig.WeaveBridgeName)