Skip to content

Commit

Permalink
[IPv6] Use separate fields for IPv4 and IPv6 in GatewayConfig (antrea…
Browse files Browse the repository at this point in the history
…-io#1111)

Replace IP slice in GatewayConfig with separate IPv4
and IPv6 fields.
  • Loading branch information
mengdie-song authored and lzhecheng committed Nov 5, 2020
1 parent 09b01e5 commit 56d5991
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 45 deletions.
13 changes: 11 additions & 2 deletions pkg/agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,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
Expand Down Expand Up @@ -767,8 +772,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
}
2 changes: 1 addition & 1 deletion pkg/agent/apiserver/handlers/ovstracing/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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},
}

Expand Down
35 changes: 17 additions & 18 deletions pkg/agent/cniserver/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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})
}
}

Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down
14 changes: 7 additions & 7 deletions pkg/agent/cniserver/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,15 @@ 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(
netCfg.IPAM.Ranges[1][0].Subnet, testNodeConfig.PodIPv6CIDR.String(),
"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",
)
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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}
}
9 changes: 5 additions & 4 deletions pkg/agent/config/node_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
13 changes: 7 additions & 6 deletions pkg/agent/flowexporter/connections/conntrack.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ func InitializeConnTrackDumper(nodeConfig *config.NodeConfig, serviceCIDR *net.I

func filterAntreaConns(conns []*flowexporter.Connection, nodeConfig *config.NodeConfig, serviceCIDR *net.IPNet, zoneFilter uint16, isAntreaProxyEnabled bool) []*flowexporter.Connection {
filteredConns := conns[:0]
conLoop:
for _, conn := range conns {
if conn.Zone != zoneFilter {
continue
Expand All @@ -46,11 +45,13 @@ conLoop:
dstIP := conn.TupleReply.SourceAddress

// Only get Pod-to-Pod flows.
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
}

if !isAntreaProxyEnabled {
Expand Down
4 changes: 2 additions & 2 deletions pkg/agent/flowexporter/connections/conntrack_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,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,
Expand Down Expand Up @@ -107,7 +107,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,
Expand Down
6 changes: 3 additions & 3 deletions pkg/agent/openflow/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -1619,9 +1619,9 @@ func generatePipeline(bridge binding.Bridge, enableProxy, enableAntreaNP bool) m
conntrackStateTable: bridge.CreateTable(conntrackStateTable, dnatTable, binding.TableMissActionNext),
dnatTable: bridge.CreateTable(dnatTable, egressEntryTable, binding.TableMissActionNext),
EgressRuleTable: bridge.CreateTable(EgressRuleTable, EgressDefaultTable, binding.TableMissActionNext),
EgressDefaultTable: bridge.CreateTable(EgressDefaultTable, EgressMetricTable, binding.TableMissActionNext),
EgressMetricTable: bridge.CreateTable(EgressMetricTable, l3ForwardingTable, binding.TableMissActionNext),
l3ForwardingTable: bridge.CreateTable(l3ForwardingTable, l2ForwardingCalcTable, binding.TableMissActionNext),
EgressDefaultTable: bridge.CreateTable(EgressDefaultTable, EgressMetricTable, binding.TableMissActionNext),
EgressMetricTable: bridge.CreateTable(EgressMetricTable, l3ForwardingTable, binding.TableMissActionNext),
l3ForwardingTable: bridge.CreateTable(l3ForwardingTable, l2ForwardingCalcTable, binding.TableMissActionNext),
l2ForwardingCalcTable: bridge.CreateTable(l2ForwardingCalcTable, IngressEntryTable, binding.TableMissActionNext),
IngressRuleTable: bridge.CreateTable(IngressRuleTable, IngressDefaultTable, binding.TableMissActionNext),
IngressDefaultTable: bridge.CreateTable(IngressDefaultTable, IngressMetricTable, binding.TableMissActionNext),
Expand Down
2 changes: 1 addition & 1 deletion test/integration/agent/cniserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion test/integration/agent/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,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,
Expand Down

0 comments on commit 56d5991

Please sign in to comment.