patchpanel: mark forwarded traffic with fwmark routing tag

This patch adds mangle PREROUTING iptables rule for marking forwarded
traffic from VMs and containers with the fwmark routing tag.

For ARC++ and ARCVM, the traffic is directly marked with the fwmark
routing tag corresponding to the target output interface.

For other VMs that track the default network, a CONNMARK restore rule
is set to reapply the fwmark routing tag saved in conntrack. A follow-up
patch will add the POSTROUTING rules for setting CONNMARK based on the
output interface selected by routing.

BUG=b:161507671
BUG=b:161508179
TEST=Unit tests. Flashed rammus, checked ARC++ connectivity and Crosvm
connectivity, checked that traffic is correctly tagged in PREROUTING by
observing iptables counters for ARC++.

Change-Id: I648bbd55f2670192a764ce9ba65846912e7eb609
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2377336
Tested-by: Hugo Benichi <hugobenichi@google.com>
Commit-Queue: Hugo Benichi <hugobenichi@google.com>
Reviewed-by: Garrick Evans <garrick@chromium.org>
Reviewed-by: Taoyu Li <taoyl@chromium.org>
diff --git a/patchpanel/routing_service.h b/patchpanel/routing_service.h
index e80fcde..74d1789 100644
--- a/patchpanel/routing_service.h
+++ b/patchpanel/routing_service.h
@@ -18,6 +18,16 @@
 
 namespace patchpanel {
 
+// Constant used for establishing a stable mapping between routing table ids
+// and interface indexes. An interface with ifindex 2 will be assigned the
+// routing table with id 1002 by the routing layer. This stable mapping is used
+// for configuring ip rules, iptables fwmark mangle rules, and the
+// accept_ra_rt_table sysctl for all physical interfaces.
+// TODO(b/161507671) Consolidate with shill::kInterfaceTableIdIncrement
+// in platform2/shill/routing_table.cc once routing and ip rule configuration
+// is migrated to patchpanel.
+constexpr const uint32_t kInterfaceTableIdIncrement = 1000;
+
 // The list of all sources of traffic that need to be distinguished
 // for routing or traffic accounting. Currently 6 bits are used for encoding
 // the TrafficSource enum in a fwmark. The enum is split into two groups:local
@@ -124,6 +134,13 @@
     return {
         .policy = static_cast<uint8_t>(source), .legacy = 0, .rt_table_id = 0};
   }
+
+  static Fwmark FromIfIndex(uint32_t ifindex) {
+    uint32_t table_id = ifindex + kInterfaceTableIdIncrement;
+    return {.policy = 0,
+            .legacy = 0,
+            .rt_table_id = static_cast<uint16_t>(table_id)};
+  }
 };
 
 // All local sources