From 0674aa6e4cfe37d5e7f5e7e2c52ba5788d07b290 Mon Sep 17 00:00:00 2001 From: Tomas Hruby Date: Thu, 20 Oct 2022 16:02:10 -0700 Subject: [PATCH] felix/bpf: mark CALI_ST_SKIP_FIB packets on ingress of heps Disable FIB, let the packet go through the host after it is policed. It is ingress into the system and we do not know what exactly is the packet's destination. It may be a local VM or something similar and we let the host to route it or dump it. https://github.com/projectcalico/calico/issues/6450 --- felix/bpf-gpl/tc.c | 10 ++++++++++ felix/bpf/ut/bpf_prog_test.go | 1 + felix/bpf/ut/icmp_related_test.go | 6 ++++++ felix/bpf/ut/nat_test.go | 16 ++++++++-------- felix/bpf/ut/whitelist_test.go | 11 ++++++----- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/felix/bpf-gpl/tc.c b/felix/bpf-gpl/tc.c index fd7516f9991..7b6a20d4388 100644 --- a/felix/bpf-gpl/tc.c +++ b/felix/bpf-gpl/tc.c @@ -525,6 +525,16 @@ static CALI_BPF_INLINE void calico_tc_process_ct_lookup(struct cali_tc_ctx *ctx) if (!dest_rt) { CALI_DEBUG("No route for post DNAT dest %x\n", bpf_ntohl(ctx->state->post_nat_ip_dst)); + if (CALI_F_FROM_HEP) { + /* Disable FIB, let the packet go through the host after it is + * policed. It is ingress into the system and we do not know what + * exactly is the packet's destination. It may be a local VM or + * something similar and we let the host to route it or dump it. + * + * https://github.com/projectcalico/calico/issues/6450 + */ + ctx->state->flags |= CALI_ST_SKIP_FIB; + } goto do_policy; } diff --git a/felix/bpf/ut/bpf_prog_test.go b/felix/bpf/ut/bpf_prog_test.go index eafea24bc5e..77d3c68a8cd 100644 --- a/felix/bpf/ut/bpf_prog_test.go +++ b/felix/bpf/ut/bpf_prog_test.go @@ -993,6 +993,7 @@ var payloadDefault = []byte("ABCDEABCDEXXXXXXXXXXXX") var srcIP = net.IPv4(1, 1, 1, 1) var dstIP = net.IPv4(2, 2, 2, 2) var srcV4CIDR = ip.CIDRFromNetIP(srcIP).(ip.V4CIDR) +var dstV4CIDR = ip.CIDRFromNetIP(dstIP).(ip.V4CIDR) var ipv4Default = &layers.IPv4{ Version: 4, diff --git a/felix/bpf/ut/icmp_related_test.go b/felix/bpf/ut/icmp_related_test.go index af6314e0241..ac14e4580ff 100644 --- a/felix/bpf/ut/icmp_related_test.go +++ b/felix/bpf/ut/icmp_related_test.go @@ -32,6 +32,7 @@ import ( ) var rulesAllowUDP = &polprog.Rules{ + SuppressNormalHostPolicy: true, Tiers: []polprog.Tier{{ Name: "base tier", Policies: []polprog.Policy{{ @@ -174,6 +175,11 @@ func TestICMPRelatedFromHost(t *testing.T) { Expect(err).NotTo(HaveOccurred()) udp := l4.(*layers.UDP) + rtKey := routes.NewKey(dstV4CIDR).AsBytes() + rtVal := routes.NewValue(routes.FlagsLocalHost).AsBytes() + err = rtMap.Update(rtKey, rtVal) + Expect(err).NotTo(HaveOccurred()) + skbMark = 0 runBpfTest(t, "calico_from_host_ep", rulesAllowUDP, func(bpfrun bpfProgRunFn) { res, err := bpfrun(pktBytes) diff --git a/felix/bpf/ut/nat_test.go b/felix/bpf/ut/nat_test.go index 88683c13dca..ab184186f5c 100644 --- a/felix/bpf/ut/nat_test.go +++ b/felix/bpf/ut/nat_test.go @@ -170,6 +170,14 @@ func TestNATPodPodXNode(t *testing.T) { skbMark = 0 + // Insert the reverse route for backend for RPF check. + resetRTMap(rtMap) + beV4CIDR := ip.CIDRFromNetIP(natIP).(ip.V4CIDR) + bertKey := routes.NewKey(beV4CIDR).AsBytes() + bertVal := routes.NewValueWithIfIndex(routes.FlagsLocalWorkload|routes.FlagInIPAMPool, 1).AsBytes() + err = rtMap.Update(bertKey, bertVal) + Expect(err).NotTo(HaveOccurred()) + bpfIfaceName = "NAT2" // Arriving at node 2 runBpfTest(t, "calico_from_host_ep", nil, func(bpfrun bpfProgRunFn) { @@ -191,14 +199,6 @@ func TestNATPodPodXNode(t *testing.T) { Expect(v.Type()).To(Equal(conntrack.TypeNormal)) Expect(v.Flags()).To(Equal(uint16(0))) - // Insert the reverse route for backend for RPF check. - resetRTMap(rtMap) - beV4CIDR := ip.CIDRFromNetIP(natIP).(ip.V4CIDR) - bertKey := routes.NewKey(beV4CIDR).AsBytes() - bertVal := routes.NewValueWithIfIndex(routes.FlagsLocalWorkload|routes.FlagInIPAMPool, 1).AsBytes() - err = rtMap.Update(bertKey, bertVal) - Expect(err).NotTo(HaveOccurred()) - // Arriving at workload at node 2 expectMark(tcdefs.MarkSeen) runBpfTest(t, "calico_to_workload_ep", rulesDefaultAllow, func(bpfrun bpfProgRunFn) { diff --git a/felix/bpf/ut/whitelist_test.go b/felix/bpf/ut/whitelist_test.go index 5625b209fab..f54988a2c16 100644 --- a/felix/bpf/ut/whitelist_test.go +++ b/felix/bpf/ut/whitelist_test.go @@ -115,13 +115,14 @@ func TestAllowEnterHostToWorkload(t *testing.T) { // Insert a reverse route for the source workload. rtKey := routes.NewKey(srcV4CIDR).AsBytes() - rtVal := routes.NewValueWithIfIndex(routes.FlagsLocalWorkload|routes.FlagInIPAMPool, 1).AsBytes() + rtVal := routes.NewValue(routes.FlagsRemoteWorkload | routes.FlagInIPAMPool).AsBytes() + err = rtMap.Update(rtKey, rtVal) + Expect(err).NotTo(HaveOccurred()) + rtKey = routes.NewKey(dstV4CIDR).AsBytes() + rtVal = routes.NewValueWithIfIndex(routes.FlagsRemoteWorkload|routes.FlagInIPAMPool, 1).AsBytes() err = rtMap.Update(rtKey, rtVal) - defer func() { - err := rtMap.Delete(rtKey) - Expect(err).NotTo(HaveOccurred()) - }() Expect(err).NotTo(HaveOccurred()) + defer resetRTMap(rtMap) ctKey := conntrack.NewKey(uint8(ipv4.Protocol), ipv4.SrcIP, uint16(udp.SrcPort), ipv4.DstIP, uint16(udp.DstPort))