diff --git a/go.mod b/go.mod index d6440796f73..21bc3087262 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.9.0 github.com/ti-mo/conntrack v0.5.0 - github.com/vishvananda/netlink v1.2.1-beta.2 + github.com/vishvananda/netlink v1.2.1-beta.2.0.20240411215012-578e95cc3190 github.com/vmware/go-ipfix v0.9.0 go.uber.org/mock v0.4.0 golang.org/x/crypto v0.22.0 diff --git a/go.sum b/go.sum index 41c8d242ffc..3ca46b50dde 100644 --- a/go.sum +++ b/go.sum @@ -725,8 +725,8 @@ github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljT github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/vishvananda/netlink v1.1.1-0.20211101163509-b10eb8fe5cf6/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= -github.com/vishvananda/netlink v1.2.1-beta.2 h1:Llsql0lnQEbHj0I1OuKyp8otXp0r3q0mPkuhwHfStVs= -github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netlink v1.2.1-beta.2.0.20240411215012-578e95cc3190 h1:G9ovFHG2n9BlIxcwYufO4UVMCS9WnjyvGvjRv0Ckbhk= +github.com/vishvananda/netlink v1.2.1-beta.2.0.20240411215012-578e95cc3190/go.mod h1:whJevzBpTrid75eZy99s3DqCmy05NfibNaF2Ol5Ox5A= github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8= github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= @@ -943,6 +943,7 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= diff --git a/pkg/agent/route/route_linux.go b/pkg/agent/route/route_linux.go index 31890415aa5..2ebc09c52ca 100644 --- a/pkg/agent/route/route_linux.go +++ b/pkg/agent/route/route_linux.go @@ -33,6 +33,7 @@ import ( utilnet "k8s.io/utils/net" "antrea.io/antrea/pkg/agent/config" + "antrea.io/antrea/pkg/agent/openflow" "antrea.io/antrea/pkg/agent/servicecidr" "antrea.io/antrea/pkg/agent/types" "antrea.io/antrea/pkg/agent/util/ipset" @@ -1918,29 +1919,37 @@ func (c *Client) DeleteRouteForLink(cidr *net.IPNet, linkIndex int) error { func (c *Client) ClearConntrackEntryForService(svcIP net.IP, svcPort uint16, endpointIP net.IP, protocol binding.Protocol) error { var protoVar uint8 - var ipFamily netlink.InetFamily + var ipFamilyVar int + var zone uint16 switch protocol { case binding.ProtocolTCP: - ipFamily = unix.AF_INET + ipFamilyVar = unix.AF_INET protoVar = unix.IPPROTO_TCP + zone = openflow.CtZone case binding.ProtocolTCPv6: - ipFamily = unix.AF_INET6 + ipFamilyVar = unix.AF_INET6 protoVar = unix.IPPROTO_TCP + zone = openflow.CtZoneV6 case binding.ProtocolUDP: - ipFamily = unix.AF_INET + ipFamilyVar = unix.AF_INET protoVar = unix.IPPROTO_UDP + zone = openflow.CtZone case binding.ProtocolUDPv6: - ipFamily = unix.AF_INET6 + ipFamilyVar = unix.AF_INET6 protoVar = unix.IPPROTO_UDP + zone = openflow.CtZoneV6 case binding.ProtocolSCTP: - ipFamily = unix.AF_INET + ipFamilyVar = unix.AF_INET protoVar = unix.IPPROTO_SCTP + zone = openflow.CtZone case binding.ProtocolSCTPv6: - ipFamily = unix.AF_INET6 + ipFamilyVar = unix.AF_INET6 protoVar = unix.IPPROTO_SCTP + zone = openflow.CtZoneV6 } filter := &netlink.ConntrackFilter{} filter.AddProtocol(protoVar) + filter.AddZone(zone) if svcIP != nil { filter.AddIP(netlink.ConntrackOrigDstIP, svcIP) } @@ -1950,7 +1959,7 @@ func (c *Client) ClearConntrackEntryForService(svcIP net.IP, svcPort uint16, end if endpointIP != nil { filter.AddIP(netlink.ConntrackReplySrcIP, endpointIP) } - _, err := c.netlink.ConntrackDeleteFilter(netlink.ConntrackTable, ipFamily, filter) + _, err := c.netlink.ConntrackDeleteFilter(netlink.ConntrackTableType(netlink.ConntrackTable), netlink.InetFamily(ipFamilyVar), filter) return err } diff --git a/pkg/agent/route/route_linux_test.go b/pkg/agent/route/route_linux_test.go index ab266186509..a07db698003 100644 --- a/pkg/agent/route/route_linux_test.go +++ b/pkg/agent/route/route_linux_test.go @@ -23,9 +23,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/vishvananda/netlink" "go.uber.org/mock/gomock" + "golang.org/x/sys/unix" "k8s.io/apimachinery/pkg/util/sets" "antrea.io/antrea/pkg/agent/config" + "antrea.io/antrea/pkg/agent/openflow" servicecidrtest "antrea.io/antrea/pkg/agent/servicecidr/testing" "antrea.io/antrea/pkg/agent/types" "antrea.io/antrea/pkg/agent/util/ipset" @@ -33,7 +35,7 @@ import ( "antrea.io/antrea/pkg/agent/util/iptables" iptablestest "antrea.io/antrea/pkg/agent/util/iptables/testing" netlinktest "antrea.io/antrea/pkg/agent/util/netlink/testing" - "antrea.io/antrea/pkg/ovs/openflow" + binding "antrea.io/antrea/pkg/ovs/openflow" "antrea.io/antrea/pkg/ovs/ovsconfig" "antrea.io/antrea/pkg/util/ip" ) @@ -1322,7 +1324,7 @@ func TestAddNodePort(t *testing.T) { name string nodePortAddresses []net.IP port uint16 - protocol openflow.Protocol + protocol binding.Protocol expectedCalls func(ipset *ipsettest.MockInterfaceMockRecorder) }{ { @@ -1332,7 +1334,7 @@ func TestAddNodePort(t *testing.T) { net.ParseIP("1.1.2.2"), }, port: 30000, - protocol: openflow.ProtocolTCP, + protocol: binding.ProtocolTCP, expectedCalls: func(ipset *ipsettest.MockInterfaceMockRecorder) { ipset.AddEntry(antreaNodePortIPSet, "1.1.1.1,tcp:30000") ipset.AddEntry(antreaNodePortIPSet, "1.1.2.2,tcp:30000") @@ -1345,7 +1347,7 @@ func TestAddNodePort(t *testing.T) { net.ParseIP("fd00:1234:5678:dead:beaf::2"), }, port: 30001, - protocol: openflow.ProtocolUDPv6, + protocol: binding.ProtocolUDPv6, expectedCalls: func(ipset *ipsettest.MockInterfaceMockRecorder) { ipset.AddEntry(antreaNodePortIP6Set, "fd00:1234:5678:dead:beaf::1,udp:30001") ipset.AddEntry(antreaNodePortIP6Set, "fd00:1234:5678:dead:beaf::2,udp:30001") @@ -1368,7 +1370,7 @@ func TestDeleteNodePort(t *testing.T) { name string nodePortAddresses []net.IP port uint16 - protocol openflow.Protocol + protocol binding.Protocol expectedCalls func(ipset *ipsettest.MockInterfaceMockRecorder) }{ { @@ -1378,7 +1380,7 @@ func TestDeleteNodePort(t *testing.T) { net.ParseIP("1.1.2.2"), }, port: 30000, - protocol: openflow.ProtocolTCP, + protocol: binding.ProtocolTCP, expectedCalls: func(ipset *ipsettest.MockInterfaceMockRecorder) { ipset.DelEntry(antreaNodePortIPSet, "1.1.1.1,tcp:30000") ipset.DelEntry(antreaNodePortIPSet, "1.1.2.2,tcp:30000") @@ -1391,7 +1393,7 @@ func TestDeleteNodePort(t *testing.T) { net.ParseIP("fd00:1234:5678:dead:beaf::2"), }, port: 30001, - protocol: openflow.ProtocolUDPv6, + protocol: binding.ProtocolUDPv6, expectedCalls: func(ipset *ipsettest.MockInterfaceMockRecorder) { ipset.DelEntry(antreaNodePortIP6Set, "fd00:1234:5678:dead:beaf::1,udp:30001") ipset.DelEntry(antreaNodePortIP6Set, "fd00:1234:5678:dead:beaf::2,udp:30001") @@ -2156,3 +2158,72 @@ COMMIT }) } } + +func TestClearConntrackEntryForService(t *testing.T) { + testCases := []struct { + name string + svcIP net.IP + svcPort uint16 + endpointIP net.IP + protocol binding.Protocol + expectedCalls func(mockNetlink *netlinktest.MockInterfaceMockRecorder) + }{ + { + name: "TCPv4 with all parameters", + svcIP: net.ParseIP("192.168.1.1"), + svcPort: 80, + endpointIP: net.ParseIP("10.10.0.2"), + protocol: binding.ProtocolTCP, + expectedCalls: func(mockNetlink *netlinktest.MockInterfaceMockRecorder) { + filter := &netlink.ConntrackFilter{} + filter.AddProtocol(unix.IPPROTO_TCP) + filter.AddZone(openflow.CtZone) + filter.AddIP(netlink.ConntrackOrigDstIP, net.ParseIP("192.168.1.1")) + filter.AddPort(netlink.ConntrackOrigDstPort, 80) + filter.AddIP(netlink.ConntrackReplySrcIP, net.ParseIP("10.10.0.2")) + mockNetlink.ConntrackDeleteFilter(netlink.ConntrackTableType(netlink.ConntrackTable), netlink.InetFamily(unix.AF_INET), filter).Times(1) + }, + }, + { + name: "UDPv4 with svcIP and svcPort", + svcIP: net.ParseIP("192.168.1.1"), + svcPort: 53, + endpointIP: nil, + protocol: binding.ProtocolUDP, + expectedCalls: func(mockNetlink *netlinktest.MockInterfaceMockRecorder) { + filter := &netlink.ConntrackFilter{} + filter.AddProtocol(unix.IPPROTO_UDP) + filter.AddZone(openflow.CtZone) + filter.AddIP(netlink.ConntrackOrigDstIP, net.ParseIP("192.168.1.1")) + filter.AddPort(netlink.ConntrackOrigDstPort, 53) + mockNetlink.ConntrackDeleteFilter(netlink.ConntrackTableType(netlink.ConntrackTable), netlink.InetFamily(unix.AF_INET), filter).Times(1) + }, + }, + { + name: "SCTPv6 with endpointIP", + svcIP: nil, + svcPort: 0, + endpointIP: net.ParseIP("fec0::2"), + protocol: binding.ProtocolSCTPv6, + expectedCalls: func(mockNetlink *netlinktest.MockInterfaceMockRecorder) { + filter := &netlink.ConntrackFilter{} + filter.AddProtocol(unix.IPPROTO_SCTP) + filter.AddZone(openflow.CtZoneV6) + filter.AddIP(netlink.ConntrackReplySrcIP, net.ParseIP("fec0::2")) + mockNetlink.ConntrackDeleteFilter(netlink.ConntrackTableType(netlink.ConntrackTable), netlink.InetFamily(unix.AF_INET6), filter).Times(1) + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctrl := gomock.NewController(t) + mockNetlink := netlinktest.NewMockInterface(ctrl) + c := &Client{ + netlink: mockNetlink, + } + tc.expectedCalls(mockNetlink.EXPECT()) + assert.NoError(t, c.ClearConntrackEntryForService(tc.svcIP, tc.svcPort, tc.endpointIP, tc.protocol)) + }) + } +} diff --git a/test/integration/agent/cniserver_test.go b/test/integration/agent/cniserver_test.go index 290eb3cdbeb..5956b6ab343 100644 --- a/test/integration/agent/cniserver_test.go +++ b/test/integration/agent/cniserver_test.go @@ -336,7 +336,8 @@ func matchRoute(expectedCIDR string, routes []netlink.Route) (*netlink.Route, er return nil, err } for _, route := range routes { - if route.Dst == nil && route.Src == nil && route.Gw.Equal(gwIP) { + // For default route, `Dst` is 0.0.0.0/0 or ::/0, rather than nil. + if route.Dst != nil && route.Dst.IP.IsUnspecified() && route.Src == nil && route.Gw.Equal(gwIP) { return &route, nil } }