summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2023-03-14 00:39:56 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2023-03-14 00:39:56 +0000
commitc16cacc876aa9eeef04f693a28d7ab4c13db87cb (patch)
tree8c389e9170c6c71ff1fe3e2a545fee95a63a8dbc
parentdb02e4ef436352d8b7bb5cc9b42a50a694b731bb (diff)
parent4e764176509ec498b0afa841a177aec4a35de7ff (diff)
downloadandroid-clat-c16cacc876aa9eeef04f693a28d7ab4c13db87cb.tar.gz
Merge "clatd: use tpacket_auxdata->tp_net L3 header offset information"
-rw-r--r--clatd.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/clatd.c b/clatd.c
index a089157..c5ab952 100644
--- a/clatd.c
+++ b/clatd.c
@@ -79,12 +79,15 @@ int ipv6_address_changed(const char *interface) {
// reads L3 IPv6 packet from AF_PACKET socket, translates to IPv4, writes to tun
void process_packet_6_to_4(struct tun_data *tunnel) {
- char cmsg_buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
- uint8_t buf[MAXMTU + 1]; // +1 to make packet truncation obvious
+ // ethernet header is 14 bytes, plus 4 for a normal VLAN tag or 8 for Q-in-Q
+ // we don't really support vlans (or especially Q-in-Q)...
+ // but a few bytes of extra buffer space doesn't hurt...
+ uint8_t buf[22 + MAXMTU + 1]; // +1 to make packet truncation obvious
struct iovec iov = {
.iov_base = buf,
.iov_len = sizeof(buf),
};
+ char cmsg_buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
struct msghdr msgh = {
.msg_iov = &iov,
.msg_iovlen = 1,
@@ -108,15 +111,23 @@ void process_packet_6_to_4(struct tun_data *tunnel) {
}
__u32 tp_status = 0;
+ __u16 tp_net = 0;
for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh,cmsg)) {
if (cmsg->cmsg_level == SOL_PACKET && cmsg->cmsg_type == PACKET_AUXDATA) {
struct tpacket_auxdata *aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
tp_status = aux->tp_status;
+ tp_net = aux->tp_net;
break;
}
}
+ if (readlen < tp_net) {
+ logmsg(ANDROID_LOG_WARN, "%s: ignoring %zd byte pkt shorter than %u L2 header",
+ __func__, readlen, tp_net);
+ return;
+ }
+
// This will detect a skb->ip_summed == CHECKSUM_PARTIAL packet with non-final L4 checksum
if (tp_status & TP_STATUS_CSUMNOTREADY) {
static bool logged = false;
@@ -126,7 +137,7 @@ void process_packet_6_to_4(struct tun_data *tunnel) {
}
}
- translate_packet(tunnel->fd4, 0 /* to_ipv6 */, buf, readlen);
+ translate_packet(tunnel->fd4, 0 /* to_ipv6 */, buf + tp_net, readlen - tp_net);
}
// reads TUN_PI + L3 IPv4 packet from tun, translates to IPv6, writes to AF_INET6/RAW socket