From 263845fcf114212c6fc2628b93dbe22ae5072e53 Mon Sep 17 00:00:00 2001 From: Mengdie Song Date: Fri, 21 Aug 2020 09:14:03 +0800 Subject: [PATCH] [IPv6] Use separate fields for IPv4 and IPv6 in GatewayConfig (#1111) Replace IP slice in GatewayConfig with separate IPv4 and IPv6 fields. --- pkg/agent/agent.go | 13 +++++-- .../handlers/ovstracing/handler_test.go | 2 +- pkg/agent/cniserver/server.go | 35 +++++++++---------- pkg/agent/cniserver/server_test.go | 14 ++++---- pkg/agent/config/node_config.go | 9 ++--- .../flowexporter/connections/conntrack.go | 13 +++---- .../connections/conntrack_linux_test.go | 4 +-- test/integration/agent/cniserver_test.go | 2 +- test/integration/agent/route_test.go | 2 +- 9 files changed, 52 insertions(+), 42 deletions(-) diff --git a/pkg/agent/agent.go b/pkg/agent/agent.go index 066bdc5c672..6586e3f2f92 100644 --- a/pkg/agent/agent.go +++ b/pkg/agent/agent.go @@ -454,7 +454,12 @@ func (i *Initializer) configureGatewayInterface(gatewayIface *interfacestore.Int gatewayIface.MAC = gwMAC if i.networkConfig.TrafficEncapMode.IsNetworkPolicyOnly() { // Assign IP to gw as required by SpoofGuard. - i.nodeConfig.GatewayConfig.IPs = []net.IP{i.nodeConfig.NodeIPAddr.IP} + // NodeIPAddr can be either IPv4 or IPv6. + if i.nodeConfig.NodeIPAddr.IP.To4() != nil { + i.nodeConfig.GatewayConfig.IPv4 = i.nodeConfig.NodeIPAddr.IP + } else { + i.nodeConfig.GatewayConfig.IPv6 = i.nodeConfig.NodeIPAddr.IP + } gatewayIface.IPs = []net.IP{i.nodeConfig.NodeIPAddr.IP} // No need to assign local CIDR to gw0 because local CIDR is not managed by Antrea return nil @@ -736,8 +741,12 @@ func (i *Initializer) allocateGatewayAddress(localSubnet *net.IPNet, gatewayIfac if err := util.ConfigureLinkAddress(i.nodeConfig.GatewayConfig.LinkIndex, gwIP); err != nil { return err } + if gwIP.IP.To4() != nil { + i.nodeConfig.GatewayConfig.IPv4 = gwIP.IP + } else { + i.nodeConfig.GatewayConfig.IPv6 = gwIP.IP + } - i.nodeConfig.GatewayConfig.IPs = append(i.nodeConfig.GatewayConfig.IPs, gwIP.IP) gatewayIface.IPs = append(gatewayIface.IPs, gwIP.IP) return nil } diff --git a/pkg/agent/apiserver/handlers/ovstracing/handler_test.go b/pkg/agent/apiserver/handlers/ovstracing/handler_test.go index b370bf823e0..a6515dec8c3 100644 --- a/pkg/agent/apiserver/handlers/ovstracing/handler_test.go +++ b/pkg/agent/apiserver/handlers/ovstracing/handler_test.go @@ -46,7 +46,7 @@ var ( testNodeConfig = &config.NodeConfig{ GatewayConfig: &config.GatewayConfig{ Name: "antrea-gw0", - IPs: []net.IP{net.ParseIP("10.1.1.1")}, + IPv4: net.ParseIP("10.1.1.1"), MAC: gatewayMAC}, } diff --git a/pkg/agent/cniserver/server.go b/pkg/agent/cniserver/server.go index 9f29a7b9a4b..9c2d7f322f6 100644 --- a/pkg/agent/cniserver/server.go +++ b/pkg/agent/cniserver/server.go @@ -139,7 +139,7 @@ type CNIConfig struct { // gateway (if missing) based on the subnet and setting the interface pointer to the container // interface // * if there is no default route, add one using the provided default gateway -func updateResultIfaceConfig(result *current.Result, defaultGateways []net.IP) { +func updateResultIfaceConfig(result *current.Result, defaultIPv4Gateway net.IP, defaultIPv6Gateway net.IP) { for _, ipc := range result.IPs { // result.Interfaces[0] is host interface, and result.Interfaces[1] is container interface ipc.Interface = current.Int(1) @@ -165,14 +165,14 @@ func updateResultIfaceConfig(result *current.Result, defaultGateways []net.IP) { } else { result.Routes = []*cnitypes.Route{} } - for _, gw := range defaultGateways { - if (!foundV4DefaultRoute) && (gw.To4() != nil) { - _, defaultV4RouteDstNet, _ := net.ParseCIDR(defaultV4RouteDst) - result.Routes = append(result.Routes, &cnitypes.Route{Dst: *defaultV4RouteDstNet, GW: gw}) - } else if (!foundV6DefaultRoute) && (gw.To4() == nil) { - _, defaultV6RouteDstNet, _ := net.ParseCIDR(defaultV6RouteDst) - result.Routes = append(result.Routes, &cnitypes.Route{Dst: *defaultV6RouteDstNet, GW: gw}) - } + + if (!foundV4DefaultRoute) && (defaultIPv4Gateway != nil) { + _, defaultV4RouteDstNet, _ := net.ParseCIDR(defaultV4RouteDst) + result.Routes = append(result.Routes, &cnitypes.Route{Dst: *defaultV4RouteDstNet, GW: defaultIPv4Gateway}) + } + if (!foundV6DefaultRoute) && (defaultIPv6Gateway != nil) { + _, defaultV6RouteDstNet, _ := net.ParseCIDR(defaultV6RouteDst) + result.Routes = append(result.Routes, &cnitypes.Route{Dst: *defaultV6RouteDstNet, GW: defaultIPv6Gateway}) } } @@ -227,14 +227,13 @@ func (s *CNIServer) checkRequestMessage(request *cnipb.CniCmdRequest) (*CNIConfi } func (s *CNIServer) updateLocalIPAMSubnet(cniConfig *CNIConfig) { - for _, gatewayIP := range s.nodeConfig.GatewayConfig.IPs { - if (gatewayIP.To4() != nil) && (s.nodeConfig.PodIPv4CIDR != nil) { - cniConfig.NetworkConfig.IPAM.Ranges = append(cniConfig.NetworkConfig.IPAM.Ranges, - ipam.RangeSet{ipam.Range{Subnet: s.nodeConfig.PodIPv4CIDR.String(), Gateway: gatewayIP.String()}}) - } else if (gatewayIP.To4() == nil) && (s.nodeConfig.PodIPv6CIDR != nil) { - cniConfig.NetworkConfig.IPAM.Ranges = append(cniConfig.NetworkConfig.IPAM.Ranges, - ipam.RangeSet{ipam.Range{Subnet: s.nodeConfig.PodIPv6CIDR.String(), Gateway: gatewayIP.String()}}) - } + if (s.nodeConfig.GatewayConfig.IPv4 != nil) && (s.nodeConfig.PodIPv4CIDR != nil) { + cniConfig.NetworkConfig.IPAM.Ranges = append(cniConfig.NetworkConfig.IPAM.Ranges, + ipam.RangeSet{ipam.Range{Subnet: s.nodeConfig.PodIPv4CIDR.String(), Gateway: s.nodeConfig.GatewayConfig.IPv4.String()}}) + } + if (s.nodeConfig.GatewayConfig.IPv6 != nil) && (s.nodeConfig.PodIPv6CIDR != nil) { + cniConfig.NetworkConfig.IPAM.Ranges = append(cniConfig.NetworkConfig.IPAM.Ranges, + ipam.RangeSet{ipam.Range{Subnet: s.nodeConfig.PodIPv6CIDR.String(), Gateway: s.nodeConfig.GatewayConfig.IPv6.String()}}) } cniConfig.NetworkConfiguration, _ = json.Marshal(cniConfig.NetworkConfig) } @@ -415,7 +414,7 @@ func (s *CNIServer) CmdAdd(ctx context.Context, request *cnipb.CniCmdRequest) (* result.IPs = ipamResult.IPs result.Routes = ipamResult.Routes // Ensure interface gateway setting and mapping relations between result.Interfaces and result.IPs - updateResultIfaceConfig(result, s.nodeConfig.GatewayConfig.IPs) + updateResultIfaceConfig(result, s.nodeConfig.GatewayConfig.IPv4, s.nodeConfig.GatewayConfig.IPv6) // Setup pod interfaces and connect to ovs bridge podName := string(cniConfig.K8S_POD_NAME) podNamespace := string(cniConfig.K8S_POD_NAMESPACE) diff --git a/pkg/agent/cniserver/server_test.go b/pkg/agent/cniserver/server_test.go index 36451c5148a..168b17dadec 100644 --- a/pkg/agent/cniserver/server_test.go +++ b/pkg/agent/cniserver/server_test.go @@ -85,7 +85,7 @@ func TestLoadNetConfig(t *testing.T) { "Network configuration (PodIPv4CIDR) was not updated", ) assert.Equal( - netCfg.IPAM.Ranges[0][0].Gateway, testNodeConfig.GatewayConfig.IPs[0].String(), + netCfg.IPAM.Ranges[0][0].Gateway, testNodeConfig.GatewayConfig.IPv4.String(), "Network configuration (Gateway IP) was not updated", ) assert.Equal( @@ -93,7 +93,7 @@ func TestLoadNetConfig(t *testing.T) { "Network configuration (PodIPv6CIDR) was not updated", ) assert.Equal( - netCfg.IPAM.Ranges[1][0].Gateway, testNodeConfig.GatewayConfig.IPs[1].String(), + netCfg.IPAM.Ranges[1][0].Gateway, testNodeConfig.GatewayConfig.IPv6.String(), "Network configuration (Gateway IPv6) was not updated", ) } @@ -345,14 +345,14 @@ func TestUpdateResultIfaceConfig(t *testing.T) { testIps := []string{"192.168.1.100/24, , 4", "fd74:ca9b:172:18::8/64, , 6"} - require.Equal(gwIPv4, testNodeConfig.GatewayConfig.IPs[0]) - require.Equal(gwIPv6, testNodeConfig.GatewayConfig.IPs[1]) + require.Equal(gwIPv4, testNodeConfig.GatewayConfig.IPv4) + require.Equal(gwIPv6, testNodeConfig.GatewayConfig.IPv6) t.Run("Gateways updated", func(t *testing.T) { assert := assert.New(t) result := ipamtest.GenerateIPAMResult(supportedCNIVersion, testIps, routes, dns) - updateResultIfaceConfig(result, []net.IP{gwIPv4, gwIPv6}) + updateResultIfaceConfig(result, gwIPv4, gwIPv6) assert.Len(result.IPs, 2, "Failed to construct result") for _, ipc := range result.IPs { @@ -370,7 +370,7 @@ func TestUpdateResultIfaceConfig(t *testing.T) { t.Run("Default route added", func(t *testing.T) { emptyRoutes := []string{} result := ipamtest.GenerateIPAMResult(supportedCNIVersion, testIps, emptyRoutes, dns) - updateResultIfaceConfig(result, []net.IP{gwIPv4, gwIPv6}) + updateResultIfaceConfig(result, gwIPv4, gwIPv6) require.NotEmpty(t, result.Routes) require.Equal(2, len(result.Routes)) for _, route := range result.Routes { @@ -610,6 +610,6 @@ func init() { _, nodePodCIDRv4, _ := net.ParseCIDR("192.168.1.0/24") _, nodePodCIDRv6, _ := net.ParseCIDR("fd74:ca9b:172:18::/64") gwMAC, _ := net.ParseMAC("00:00:00:00:00:01") - gateway := &config.GatewayConfig{Name: "", IPs: []net.IP{gwIPv4, gwIPv6}, MAC: gwMAC} + gateway := &config.GatewayConfig{Name: "", IPv4: gwIPv4, IPv6: gwIPv6, MAC: gwMAC} testNodeConfig = &config.NodeConfig{Name: nodeName, PodIPv4CIDR: nodePodCIDRv4, PodIPv6CIDR: nodePodCIDRv6, GatewayConfig: gateway} } diff --git a/pkg/agent/config/node_config.go b/pkg/agent/config/node_config.go index d588413ca46..73eb1a199b4 100644 --- a/pkg/agent/config/node_config.go +++ b/pkg/agent/config/node_config.go @@ -45,15 +45,16 @@ const ( type GatewayConfig struct { // Name is the name of host gateway, e.g. antrea-gw0. Name string - // TODO: Separate IPs into two IP fields, one IPv4 field and one IPv6 field. - IPs []net.IP - MAC net.HardwareAddr + + IPv4 net.IP + IPv6 net.IP + MAC net.HardwareAddr // LinkIndex is the link index of host gateway. LinkIndex int } func (g *GatewayConfig) String() string { - return fmt.Sprintf("Name %s: IP %s, MAC %s", g.Name, g.IPs, g.MAC) + return fmt.Sprintf("Name %s: IPv4 %s, IPv6 %s, MAC %s", g.Name, g.IPv4, g.IPv6, g.MAC) } type AdapterNetConfig struct { diff --git a/pkg/agent/flowexporter/connections/conntrack.go b/pkg/agent/flowexporter/connections/conntrack.go index 05c9f3402b6..d94cc1cbf41 100644 --- a/pkg/agent/flowexporter/connections/conntrack.go +++ b/pkg/agent/flowexporter/connections/conntrack.go @@ -38,7 +38,6 @@ func InitializeConnTrackDumper(nodeConfig *config.NodeConfig, serviceCIDR *net.I func filterAntreaConns(conns []*flowexporter.Connection, nodeConfig *config.NodeConfig, serviceCIDR *net.IPNet, zoneFilter uint16) []*flowexporter.Connection { filteredConns := conns[:0] -conLoop: for _, conn := range conns { if conn.Zone != zoneFilter { continue @@ -47,11 +46,13 @@ conLoop: dstIP := conn.TupleReply.SourceAddress // Only get Pod-to-Pod flows. Pod-to-ExternalService flows are ignored for now. - for _, ip := range nodeConfig.GatewayConfig.IPs { - if srcIP.Equal(ip) || dstIP.Equal(ip) { - klog.V(4).Infof("Detected flow through gateway :%v", conn) - continue conLoop - } + if srcIP.Equal(nodeConfig.GatewayConfig.IPv4) || dstIP.Equal(nodeConfig.GatewayConfig.IPv4) { + klog.V(4).Infof("Detected flow through IPv4 gateway :%v", conn) + continue + } + if srcIP.Equal(nodeConfig.GatewayConfig.IPv6) || dstIP.Equal(nodeConfig.GatewayConfig.IPv6) { + klog.V(4).Infof("Detected flow through IPv6 gateway :%v", conn) + continue } // Pod-to-Service flows w/ kube-proxy: There are two conntrack flows for every Pod-to-Service flow. diff --git a/pkg/agent/flowexporter/connections/conntrack_linux_test.go b/pkg/agent/flowexporter/connections/conntrack_linux_test.go index 6ca6bc7c377..619c5f2ec37 100644 --- a/pkg/agent/flowexporter/connections/conntrack_linux_test.go +++ b/pkg/agent/flowexporter/connections/conntrack_linux_test.go @@ -68,7 +68,7 @@ func TestConnTrackSystem_DumpFlows(t *testing.T) { // Create nodeConfig and gateWayConfig // Set antreaGWFlow.TupleOrig.IP.DestinationAddress as gateway IP gwConfig := &config.GatewayConfig{ - IPs: []net.IP{{8, 7, 6, 5}}, + IPv4: net.IP{8, 7, 6, 5}, } nodeConfig := &config.NodeConfig{ GatewayConfig: gwConfig, @@ -104,7 +104,7 @@ func TestConnTrackOvsAppCtl_DumpFlows(t *testing.T) { // Create nodeConfig and gateWayConfig // Set antreaGWFlow.TupleOrig.IP.DestinationAddress as gateway IP gwConfig := &config.GatewayConfig{ - IPs: []net.IP{{8, 7, 6, 5}}, + IPv4: net.IP{8, 7, 6, 5}, } nodeConfig := &config.NodeConfig{ GatewayConfig: gwConfig, diff --git a/test/integration/agent/cniserver_test.go b/test/integration/agent/cniserver_test.go index f0498832a75..dae83b36add 100644 --- a/test/integration/agent/cniserver_test.go +++ b/test/integration/agent/cniserver_test.go @@ -845,7 +845,7 @@ func init() { nodeName := "node1" gwIP := net.ParseIP("192.168.1.1") gwMAC, _ = net.ParseMAC("11:11:11:11:11:11") - nodeGateway := &config.GatewayConfig{IPs: []net.IP{gwIP}, MAC: gwMAC, Name: ""} + nodeGateway := &config.GatewayConfig{IPv4: gwIP, MAC: gwMAC, Name: ""} _, nodePodCIDR, _ := net.ParseCIDR("192.168.1.0/24") nodeMTU := 1500 diff --git a/test/integration/agent/route_test.go b/test/integration/agent/route_test.go index 44857ab0d7f..9d74ec82340 100644 --- a/test/integration/agent/route_test.go +++ b/test/integration/agent/route_test.go @@ -56,7 +56,7 @@ var ( gwIP = net.ParseIP("10.10.10.1") gwMAC, _ = net.ParseMAC("12:34:56:78:bb:cc") gwName = "antrea-gw0" - gwConfig = &config.GatewayConfig{IPs: []net.IP{gwIP}, MAC: gwMAC, Name: gwName} + gwConfig = &config.GatewayConfig{IPv4: gwIP, MAC: gwMAC, Name: gwName} nodeConfig = &config.NodeConfig{ Name: "test", PodIPv4CIDR: podCIDR,