TetherIngressValue - add output path/route mtu field
This doesn't actually change anything, since we initialize it with
1500 default just like we blindly assume it always is today.
Tested: builds
Bug: 149816401
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Ie448a988c3a769be07f895621711fe4e59d4535c
Merged-In: Ie448a988c3a769be07f895621711fe4e59d4535c
diff --git a/bpf_progs/offload.c b/bpf_progs/offload.c
index fbb5318..9bcfdcd 100644
--- a/bpf_progs/offload.c
+++ b/bpf_progs/offload.c
@@ -81,19 +81,22 @@
// If we don't have a limit, then abort...
if (!limit_v) return TC_ACT_OK;
- // This is approximate handling of tcp/ip overhead for incoming LRO/GRO packets:
- // mtu of 1500 is not necessarily correct, but worst case we simply undercount,
- // which is still better then not accounting for this overhead at all.
- // Note: this really shouldn't be device mtu at all, but rather should be derived
- // from this particular connection's mss - which requires a much newer kernel.
- const int mtu = 1500;
+ // Required IPv6 minimum mtu is 1280, below that not clear what we should do, abort...
+ const int pmtu = v->pmtu;
+ if (pmtu < IPV6_MIN_MTU) return TC_ACT_OK;
+
+ // Approximate handling of TCP/IPv6 overhead for incoming LRO/GRO packets: default
+ // outbound path mtu of 1500 is not necessarily correct, but worst case we simply
+ // undercount, which is still better then not accounting for this overhead at all.
+ // Note: this really shouldn't be device/path mtu at all, but rather should be
+ // derived from this particular connection's mss (ie. from gro segment size).
+ // This would require a much newer kernel with newer ebpf accessors.
+ // (This is also blindly assuming 12 bytes of tcp timestamp option in tcp header)
uint64_t packets = 1;
uint64_t bytes = skb->len;
- if (bytes > mtu) {
- const bool is_ipv6 = (skb->protocol == htons(ETH_P_IPV6));
- const int ip_overhead = (is_ipv6 ? sizeof(struct ipv6hdr) : sizeof(struct iphdr));
- const int tcp_overhead = ip_overhead + sizeof(struct tcphdr) + 12;
- const int mss = mtu - tcp_overhead;
+ if (bytes > pmtu) {
+ const int tcp_overhead = sizeof(struct ipv6hdr) + sizeof(struct tcphdr) + 12;
+ const int mss = pmtu - tcp_overhead;
const uint64_t payload = bytes - tcp_overhead;
packets = (payload + mss - 1) / mss;
bytes = tcp_overhead * packets + payload;
diff --git a/libnetdbpf/include/netdbpf/bpf_shared.h b/libnetdbpf/include/netdbpf/bpf_shared.h
index 9d5f690..6f31879 100644
--- a/libnetdbpf/include/netdbpf/bpf_shared.h
+++ b/libnetdbpf/include/netdbpf/bpf_shared.h
@@ -205,6 +205,7 @@
// because all downstream types that are currently supported (WiFi, USB, Bluetooth and
// Ethernet) have 6-byte MAC addresses.
struct ethhdr macHeader; // includes dst/src mac and ethertype
+ uint16_t pmtu; // The maximum L3 output path/route mtu
} TetherIngressValue;
#define TETHER_STATS_MAP_PATH BPF_PATH "/map_offload_tether_stats_map"
diff --git a/server/TetherController.cpp b/server/TetherController.cpp
index 560a01c..50ae966 100644
--- a/server/TetherController.cpp
+++ b/server/TetherController.cpp
@@ -870,8 +870,9 @@
};
TetherIngressValue value = {
- static_cast<uint32_t>(rule.outputInterfaceIndex),
- hdr,
+ .oif = static_cast<uint32_t>(rule.outputInterfaceIndex),
+ .macHeader = hdr,
+ .pmtu = 1500, // TODO: don't just blindly use this default
};
return mBpfIngressMap.writeValue(key, value, BPF_ANY);
@@ -1185,7 +1186,7 @@
return;
}
- dw.println("BPF ingress map: iif v6addr -> oif srcmac dstmac ethertype");
+ dw.println("BPF ingress map: iif v6addr -> oif srcmac dstmac ethertype [pmtu]");
const auto printIngressMap = [&dw](const TetherIngressKey& key, const TetherIngressValue& value,
const BpfMap<TetherIngressKey, TetherIngressValue>&) {
char addr[INET6_ADDRSTRLEN];
@@ -1193,8 +1194,8 @@
std::string dst = l2ToString(value.macHeader.h_dest, sizeof(value.macHeader.h_dest));
inet_ntop(AF_INET6, &key.neigh6, addr, sizeof(addr));
- dw.println("%u %s -> %u %s %s %04x", key.iif, addr, value.oif, src.c_str(), dst.c_str(),
- ntohs(value.macHeader.h_proto));
+ dw.println("%u %s -> %u %s %s %04x [%u]", key.iif, addr, value.oif, src.c_str(),
+ dst.c_str(), ntohs(value.macHeader.h_proto), value.pmtu);
return Result<void>();
};