aboutgitcodebugslistschat
diff options
context:
space:
mode:
-rw-r--r--tap.c37
1 files changed, 22 insertions, 15 deletions
diff --git a/tap.c b/tap.c
index 9fc84c1..e31a419 100644
--- a/tap.c
+++ b/tap.c
@@ -197,11 +197,12 @@ void tap_ip_send(struct ctx *c, struct in6_addr *src, uint8_t proto,
* @msg: Array of messages with the same L3 protocol
* @count: Count of messages with the same L3 protocol
* @now: Current timestamp
+ * @first: First call for an IPv4 packet in this batch
*
* Return: count of packets consumed by handlers
*/
static int tap4_handler(struct ctx *c, struct tap_msg *msg, size_t count,
- struct timespec *now)
+ struct timespec *now, int first)
{
char buf_s[INET_ADDRSTRLEN] __attribute((__unused__));
char buf_d[INET_ADDRSTRLEN] __attribute((__unused__));
@@ -230,7 +231,7 @@ static int tap4_handler(struct ctx *c, struct tap_msg *msg, size_t count,
iph = (struct iphdr *)(eh + 1);
l4h = (char *)iph + iph->ihl * 4;
- if (c->addr4_seen != iph->saddr) {
+ if (first && c->addr4_seen != iph->saddr) {
c->addr4_seen = iph->saddr;
proto_update_l2_buf(NULL, NULL, &c->addr4_seen);
}
@@ -307,11 +308,12 @@ static int tap4_handler(struct ctx *c, struct tap_msg *msg, size_t count,
* @msg: Array of messages with the same L3 protocol
* @count: Count of messages with the same L3 protocol
* @now: Current timestamp
+ * @first: First call for an IPv6 packet in this batch
*
* Return: count of packets consumed by handlers
*/
static int tap6_handler(struct ctx *c, struct tap_msg *msg, size_t count,
- struct timespec *now)
+ struct timespec *now, int first)
{
char buf_s[INET6_ADDRSTRLEN] __attribute((__unused__));
char buf_d[INET6_ADDRSTRLEN] __attribute((__unused__));
@@ -346,13 +348,16 @@ static int tap6_handler(struct ctx *c, struct tap_msg *msg, size_t count,
msg[i].l4h = l4h;
msg[i].l4_len = len - ((intptr_t)l4h - (intptr_t)eh);
- if (IN6_IS_ADDR_LINKLOCAL(&ip6h->saddr)) {
- c->addr6_ll_seen = ip6h->saddr;
+ if (first) {
+ if (IN6_IS_ADDR_LINKLOCAL(&ip6h->saddr)) {
+ c->addr6_ll_seen = ip6h->saddr;
- if (IN6_IS_ADDR_UNSPECIFIED(&c->addr6_seen))
+ if (IN6_IS_ADDR_UNSPECIFIED(&c->addr6_seen)) {
+ c->addr6_seen = ip6h->saddr;
+ }
+ } else {
c->addr6_seen = ip6h->saddr;
- } else {
- c->addr6_seen = ip6h->saddr;
+ }
}
ip6h->saddr = c->addr6;
@@ -431,7 +436,7 @@ static int tap6_handler(struct ctx *c, struct tap_msg *msg, size_t count,
*/
static int tap_handler_passt(struct ctx *c, struct timespec *now)
{
- int msg_count = 0, same, i = 0;
+ int msg_count = 0, same, i = 0, first_v4 = 1, first_v6 = 1;
struct tap_msg msg[TAP_MSGS];
struct ethhdr *eh;
char *p = pkt_buf;
@@ -483,7 +488,7 @@ static int tap_handler_passt(struct ctx *c, struct timespec *now)
switch (ntohs(eh->h_proto)) {
case ETH_P_ARP:
- tap4_handler(c, msg + i, 1, now);
+ tap4_handler(c, msg + i, 1, now, 1);
i++;
break;
case ETH_P_IP:
@@ -496,7 +501,8 @@ static int tap_handler_passt(struct ctx *c, struct timespec *now)
break;
}
- i += tap4_handler(c, msg + i, same, now);
+ i += tap4_handler(c, msg + i, same, now, first_v4);
+ first_v4 = 0;
break;
case ETH_P_IPV6:
for (same = 1; i + same < msg_count &&
@@ -508,7 +514,8 @@ static int tap_handler_passt(struct ctx *c, struct timespec *now)
break;
}
- i += tap6_handler(c, msg + i, same, now);
+ i += tap6_handler(c, msg + i, same, now, first_v6);
+ first_v6 = 0;
break;
default:
i++;
@@ -544,13 +551,13 @@ static int tap_handler_pasta(struct ctx *c, struct timespec *now)
switch (ntohs(eh->h_proto)) {
case ETH_P_ARP:
- tap4_handler(c, &msg, 1, now);
+ tap4_handler(c, &msg, 1, now, 1);
break;
case ETH_P_IP:
- tap4_handler(c, &msg, 1, now);
+ tap4_handler(c, &msg, 1, now, 1);
break;
case ETH_P_IPV6:
- tap6_handler(c, &msg, 1, now);
+ tap6_handler(c, &msg, 1, now, 1);
break;
}
}