patchpanel: implement traffic tagging for ConnectNamespace

This patch adds fwmark tagging to traffic from network namespaces
configured with the patchpanel ConnectNamespace DBus API. Both the
source tag and the routing tag are added.

The ConnectNamespace implementation has now 3 distinct routing mode:
 - tracking default physical network (previously only available mode),
 - tracking default logical network, physical or VPN,
 - tracking a specific physical network, a-la ARC.

BUG=b:174811524
BUG=b:161508179
BUG=chromium:1156894
TEST=unit tests. $ tast run <DUT_ip> network.TestProxyServer, checked
rules set in iptables -t mangle -L PREROUTING and -L POSTROUTING.

Change-Id: I10d9ea2da6e206f8f2d5270df8680d4351818a97
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2574147
Tested-by: Hugo Benichi <hugobenichi@google.com>
Commit-Queue: Hugo Benichi <hugobenichi@google.com>
Reviewed-by: Garrick Evans <garrick@chromium.org>
diff --git a/patchpanel/routing_service.cc b/patchpanel/routing_service.cc
index 2a171bb..b40adc4 100644
--- a/patchpanel/routing_service.cc
+++ b/patchpanel/routing_service.cc
@@ -67,32 +67,25 @@
   return SetFwmark(sockfd, mark, kFwmarkVpnMask);
 }
 
-const char* TrafficSourceName(TrafficSource source) {
-  switch (source) {
-    case CHROME:
-      return "CHROME";
-    case USER:
-      return "USER";
-    case UPDATE_ENGINE:
-      return "UPDATE_ENGINE";
-    case SYSTEM:
-      return "SYSTEM";
-    case HOST_VPN:
-      return "HOST_VPN";
-    case ARC:
-      return "ARC";
-    case CROSVM:
-      return "CROSVM";
-    case PLUGINVM:
-      return "PLUGINVM";
-    case TETHER_DOWNSTREAM:
-      return "TETHER_DOWNSTREAM";
-    case ARC_VPN:
-      return "ARC_VPN";
-    case UNKNOWN:
-    default:
-      return "UNKNOWN";
+const std::string& TrafficSourceName(TrafficSource source) {
+  static std::map<TrafficSource, std::string> kTrafficSourceNames = {
+      {CHROME, "CHROME"},
+      {USER, "USER"},
+      {UPDATE_ENGINE, "UPDATE_ENGINE"},
+      {SYSTEM, "SYSTEM"},
+      {HOST_VPN, "HOST_VPN"},
+      {ARC, "ARC"},
+      {CROSVM, "CROSVM"},
+      {PLUGINVM, "PLUGINVM"},
+      {TETHER_DOWNSTREAM, "TETHER_DOWNSTREAM"},
+      {ARC_VPN, "ARC_VPN"},
+      {UNKNOWN, "UNKNOWN"},
+  };
+  const auto& it = kTrafficSourceNames.find(source);
+  if (it == kTrafficSourceNames.end()) {
+    return kTrafficSourceNames.find(UNKNOWN)->second;
   }
+  return it->second;
 }
 
 std::ostream& operator<<(std::ostream& stream, const LocalSourceSpecs& source) {