Drop packets to the clat address.

These packets are not needed for 464xlat to function because
clatd reads packets from packet sockets, which run before
iptables, and the TC action also happens before packet sockets.

Their existence complicates data usage accounting, and in
certain situations results in applications receiving duplicate
UDP packets.

Bug: 65674744
Bug: 136193260
Test: atest netd_unit_test
Change-Id: I26bd8a1e7a54dbac86971b4e62f88f46ae5466f1
diff --git a/server/ClatdControllerTest.cpp b/server/ClatdControllerTest.cpp
index a4a271a..e90dd1a 100644
--- a/server/ClatdControllerTest.cpp
+++ b/server/ClatdControllerTest.cpp
@@ -31,6 +31,8 @@
 }
 
 #include "ClatdController.h"
+#include "IptablesBaseTest.h"
+#include "NetworkController.h"
 #include "tun_interface.h"
 
 static const char kIPv4LocalAddr[] = "192.0.0.4";
@@ -57,11 +59,21 @@
     return (ntohl(addr) & 0xff) == 10;
 }
 
-class ClatdControllerTest : public ::testing::Test {
+class ClatdControllerTest : public IptablesBaseTest {
   public:
+    ClatdControllerTest() : mClatdCtrl(nullptr) {
+        ClatdController::iptablesRestoreFunction = fakeExecIptablesRestore;
+    }
+
     void SetUp() { resetIpv4AddressFreeFunc(); }
 
   protected:
+    ClatdController mClatdCtrl;
+    bool isEbpfDisabled() { return mClatdCtrl.getEbpfMode() == ClatdController::ClatEbpfDisabled; }
+    void maybeSetIptablesDropRule(bool a, const char* b, const char* c) {
+        std::lock_guard guard(mClatdCtrl.mutex);
+        return mClatdCtrl.maybeSetIptablesDropRule(a, b, c);
+    }
     void setIpv4AddressFreeFunc(bool (*func)(in_addr_t)) {
         ClatdController::isIpv4AddressFreeFunc = func;
     }
@@ -175,5 +187,27 @@
     EXPECT_GE(3210000, onebits);
 }
 
+TEST_F(ClatdControllerTest, AddRemoveIptablesRule) {
+    if (isEbpfDisabled()) return;
+
+    ExpectedIptablesCommands expected = {
+            {V6,
+             "*raw\n"
+             "-A clat_raw_PREROUTING -s 64:ff9b::/96 -d 2001:db8::1:2:3:4 -j DROP\n"
+             "COMMIT\n"},
+    };
+    maybeSetIptablesDropRule(true, "64:ff9b::", "2001:db8::1:2:3:4");
+    expectIptablesRestoreCommands(expected);
+
+    expected = {
+            {V6,
+             "*raw\n"
+             "-D clat_raw_PREROUTING -s 64:ff9b::/96 -d 2001:db8::a:b:c:d -j DROP\n"
+             "COMMIT\n"},
+    };
+    maybeSetIptablesDropRule(false, "64:ff9b::", "2001:db8::a:b:c:d");
+    expectIptablesRestoreCommands(expected);
+}
+
 }  // namespace net
 }  // namespace android