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/datapath.h b/patchpanel/datapath.h
index b0337e1..c2dcbfd 100644
--- a/patchpanel/datapath.h
+++ b/patchpanel/datapath.h
@@ -235,9 +235,20 @@
virtual bool AddAdbPortAccessRule(const std::string& ifname);
virtual void DeleteAdbPortAccessRule(const std::string& ifname);
+ // Set or override the interface name to index mapping for |ifname|.
+ // Only used for testing.
+ void SetIfnameIndex(const std::string& ifname, int ifindex);
+
MinijailedProcessRunner& runner() const;
private:
+ bool ModifyConnmarkRestore(IpFamily family,
+ const std::string& chain,
+ const std::string& op,
+ const std::string& iif);
+ bool ModifyFwmarkRoutingTag(const std::string& op,
+ const std::string& ext_ifname,
+ const std::string& int_ifname);
bool ModifyFwmarkSourceTag(const std::string& op,
const std::string& iif,
TrafficSource source);
@@ -252,12 +263,22 @@
const std::string& iif,
const std::string& oif,
bool log_failures = true);
+ bool ModifyRtentry(ioctl_req_t op, struct rtentry* route);
+ int FindIfIndex(const std::string& ifname);
MinijailedProcessRunner* process_runner_;
Firewall* firewall_;
ioctl_t ioctl_;
- bool ModifyRtentry(ioctl_req_t op, struct rtentry* route);
+ // A map used for remembering the interface index of an interface. This
+ // information is necessary when cleaning up iptables fwmark rules that
+ // directly references the interface index. When removing these rules on
+ // an RTM_DELLINK event, the interface index cannot be retrieved anymore.
+ // A new entry is only added when a new physical device appears, and entries
+ // are not removed.
+ // TODO(b/161507671) Rely on RoutingService to obtain this information once
+ // shill/routing_table.cc has been migrated to patchpanel.
+ std::map<std::string, int> if_nametoindex_;
DISALLOW_COPY_AND_ASSIGN(Datapath);
};