OffloadUtils - add tcFilterDelDevIngressClatIpv6 & tcFilterDelDevEgressClatIpv4

Test: build, atest
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I92537f335ab74e58db6317032c12ddf93874f516
diff --git a/server/OffloadUtils.cpp b/server/OffloadUtils.cpp
index e86c686..b2bc48c 100644
--- a/server/OffloadUtils.cpp
+++ b/server/OffloadUtils.cpp
@@ -407,5 +407,35 @@
     return tcFilterAddDevBpf(fd, ifIndex, bpfFd, ethernet, /*ingress*/ false, /*ipv6*/ false);
 }
 
+// tc filter del dev .. in/egress prio .. protocol ..
+int tcFilterDelDev(int fd, int ifIndex, bool ingress, uint16_t prio, uint16_t proto) {
+    struct {
+        nlmsghdr n;
+        tcmsg t;
+    } req = {
+            .n =
+                    {
+                            .nlmsg_len = sizeof(req),
+                            .nlmsg_type = RTM_DELTFILTER,
+                            .nlmsg_flags = NETLINK_REQUEST_FLAGS,
+                    },
+            .t =
+                    {
+                            .tcm_family = AF_UNSPEC,
+                            .tcm_ifindex = ifIndex,
+                            .tcm_handle = TC_H_UNSPEC,
+                            .tcm_parent = TC_H_MAKE(TC_H_CLSACT,
+                                                    ingress ? TC_H_MIN_INGRESS : TC_H_MIN_EGRESS),
+                            .tcm_info = static_cast<__u32>((prio << 16) | htons(proto)),
+                    },
+    };
+
+    const int rv = send(fd, &req, sizeof(req), 0);
+    if (rv == -1) return -errno;
+    if (rv != sizeof(req)) return -EMSGSIZE;
+
+    return processNetlinkResponse(fd);
+}
+
 }  // namespace net
 }  // namespace android
diff --git a/server/OffloadUtils.h b/server/OffloadUtils.h
index c75c0a7..f93bc61 100644
--- a/server/OffloadUtils.h
+++ b/server/OffloadUtils.h
@@ -16,6 +16,8 @@
 
 #pragma once
 
+#include <linux/if_ether.h>
+
 #include <string>
 
 namespace android {
@@ -42,5 +44,18 @@
 int tcFilterAddDevIngressBpf(int fd, int ifIndex, int bpfFd, bool ethernet);
 int tcFilterAddDevEgressBpf(int fd, int ifIndex, int bpfFd, bool ethernet);
 
+// tc filter del dev .. in/egress prio .. protocol ..
+int tcFilterDelDev(int fd, int ifIndex, bool ingress, uint16_t prio, uint16_t proto);
+
+// tc filter del dev .. ingress prio 1 protocol ipv6
+static inline int tcFilterDelDevIngressClatIpv6(int fd, int ifIndex) {
+    return tcFilterDelDev(fd, ifIndex, /*ingress*/ true, /*prio*/ 1, ETH_P_IPV6);
+}
+
+// tc filter del dev .. egress prio 1 protocol ip
+static inline int tcFilterDelDevEgressClatIpv4(int fd, int ifIndex) {
+    return tcFilterDelDev(fd, ifIndex, /*ingress*/ false, /*prio*/ 1, ETH_P_IP);
+}
+
 }  // namespace net
 }  // namespace android
diff --git a/server/OffloadUtilsTest.cpp b/server/OffloadUtilsTest.cpp
index ed39c2e..f86fc20 100644
--- a/server/OffloadUtilsTest.cpp
+++ b/server/OffloadUtilsTest.cpp
@@ -181,7 +181,7 @@
     close(fd);
 }
 
-static void checkAttachBpfFilterClsactLo(const bool ingress, const bool ethernet) {
+static void checkAttachDetachBpfFilterClsactLo(const bool ingress, const bool ethernet) {
     // This test requires kernel 4.9-Q or better
     SKIP_IF_BPF_NOT_SUPPORTED;
     if (!kernelSupportsNetSchIngress()) return;
@@ -200,8 +200,10 @@
         EXPECT_EQ(0, tcQdiscAddDevClsact(fd, LOOPBACK_IFINDEX));
         if (ingress) {
             EXPECT_EQ(0, tcFilterAddDevIngressBpf(fd, LOOPBACK_IFINDEX, bpf_fd, ethernet));
+            EXPECT_EQ(0, tcFilterDelDevIngressClatIpv6(fd, LOOPBACK_IFINDEX));
         } else {
             EXPECT_EQ(0, tcFilterAddDevEgressBpf(fd, LOOPBACK_IFINDEX, bpf_fd, ethernet));
+            EXPECT_EQ(0, tcFilterDelDevEgressClatIpv4(fd, LOOPBACK_IFINDEX));
         }
         EXPECT_EQ(0, tcQdiscDelDevClsact(fd, LOOPBACK_IFINDEX));
         close(fd);
@@ -211,19 +213,19 @@
 }
 
 TEST_F(OffloadUtilsTest, CheckAttachBpfFilterRawIpClsactEgressLo) {
-    checkAttachBpfFilterClsactLo(/*ingress*/ false, /*ethernet*/ false);
+    checkAttachDetachBpfFilterClsactLo(/*ingress*/ false, /*ethernet*/ false);
 }
 
 TEST_F(OffloadUtilsTest, CheckAttachBpfFilterEthernetClsactEgressLo) {
-    checkAttachBpfFilterClsactLo(/*ingress*/ false, /*ethernet*/ true);
+    checkAttachDetachBpfFilterClsactLo(/*ingress*/ false, /*ethernet*/ true);
 }
 
 TEST_F(OffloadUtilsTest, CheckAttachBpfFilterRawIpClsactIngressLo) {
-    checkAttachBpfFilterClsactLo(/*ingress*/ true, /*ethernet*/ false);
+    checkAttachDetachBpfFilterClsactLo(/*ingress*/ true, /*ethernet*/ false);
 }
 
 TEST_F(OffloadUtilsTest, CheckAttachBpfFilterEthernetClsactIngressLo) {
-    checkAttachBpfFilterClsactLo(/*ingress*/ true, /*ethernet*/ true);
+    checkAttachDetachBpfFilterClsactLo(/*ingress*/ true, /*ethernet*/ true);
 }
 
 }  // namespace net