implement ClatdController::dumpEgress()

combined with later commits that populate the map this results in:

$ echo; adb shell dumpsys netd | sed -rn '/^  ClatdController$/,/^$/p'

  ClatdController
    Trackers: iif[iface] nat64Prefix v6Addr -> v4Addr v4iif[v4iface] [netId]
      11[rmnet_data1] 2607:7700:0:1c:0:1::/96 2607:fb90:270a:a0c7:86e7:29f:b165:fe89 -> 192.0.0.4 33[v4-rmnet_data1] [100]
      30[wlan0] 64:ff9b::/96 2401:fa00:480:13d:ca58:52b2:68ee:164d -> 192.0.0.5 34[v4-wlan0] [102]
    BPF ingress map: iif(iface) nat64Prefix v6Addr -> v4Addr oif(iface)
      30(wlan0) 64:ff9b::/96 2401:fa00:480:13d:ca58:52b2:68ee:164d -> 192.0.0.5 34(v4-wlan0)
      11(rmnet_data1) 2607:7700:0:1c:0:1::/96 2607:fb90:270a:a0c7:86e7:29f:b165:fe89 -> 192.0.0.4 33(v4-rmnet_data1)
    BPF egress map: iif(iface) v4Addr -> v6Addr nat64Prefix oif(iface)
      34(v4-wlan0) 192.0.0.5 -> 2401:fa00:480:13d:ca58:52b2:68ee:164d 64:ff9b::/96 30(wlan0)
      33(v4-rmnet_data1) 192.0.0.4 -> 2607:fb90:270a:a0c7:86e7:29f:b165:fe89 2607:7700:0:1c:0:1::/96 11(rmnet_data1)

Test: compiles, atest, flashed to a device and ran dumpsys netd (see above)
Bug: 139396664
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I802554463d78cad7fe8d289ae5f0c1730384894c
diff --git a/server/ClatdController.cpp b/server/ClatdController.cpp
index 746948c..7270b6e 100644
--- a/server/ClatdController.cpp
+++ b/server/ClatdController.cpp
@@ -569,6 +569,39 @@
     return 0;
 }
 
+void ClatdController::dumpEgress(DumpWriter& dw) {
+    int mapFd = getClatEgressMapFd();
+    if (mapFd < 0) return;  // if unsupported just don't dump anything
+    BpfMap<ClatEgressKey, ClatEgressValue> configMap(mapFd);
+
+    ScopedIndent bpfIndent(dw);
+    dw.println("BPF egress map: iif(iface) v4Addr -> v6Addr nat64Prefix oif(iface)");
+
+    ScopedIndent bpfDetailIndent(dw);
+    const auto printClatMap = [&dw](const ClatEgressKey& key, const ClatEgressValue& value,
+                                    const BpfMap<ClatEgressKey, ClatEgressValue>&) {
+        char iifStr[IFNAMSIZ] = "?";
+        char local4Str[INET_ADDRSTRLEN] = "?";
+        char local6Str[INET6_ADDRSTRLEN] = "?";
+        char pfx96Str[INET6_ADDRSTRLEN] = "?";
+        char oifStr[IFNAMSIZ] = "?";
+
+        if_indextoname(key.iif, iifStr);
+        inet_ntop(AF_INET, &key.local4, local4Str, sizeof(local4Str));
+        inet_ntop(AF_INET6, &value.local6, local6Str, sizeof(local6Str));
+        inet_ntop(AF_INET6, &value.pfx96, pfx96Str, sizeof(pfx96Str));
+        if_indextoname(value.oif, oifStr);
+
+        dw.println("%u(%s) %s -> %s %s/96 %u(%s)", key.iif, iifStr, local4Str, local6Str, pfx96Str,
+                   value.oif, oifStr);
+        return netdutils::status::ok;
+    };
+    auto res = configMap.iterateWithValue(printClatMap);
+    if (!isOk(res)) {
+        dw.println("Error printing BPF map: %s", res.msg().c_str());
+    }
+}
+
 void ClatdController::dumpIngress(DumpWriter& dw) {
     int mapFd = getClatIngressMapFd();
     if (mapFd < 0) return;  // if unsupported just don't dump anything
@@ -623,6 +656,7 @@
 
     dumpTrackers(dw);
     dumpIngress(dw);
+    dumpEgress(dw);
 }
 
 auto ClatdController::isIpv4AddressFreeFunc = isIpv4AddressFree;