From 02c7610c3543e9190539efe944e1c90c3ebb5623 Mon Sep 17 00:00:00 2001 Message-Id: <02c7610c3543e9190539efe944e1c90c3ebb5623.1469118440.git.pabeni@redhat.com> From: Paolo Abeni Date: Thu, 21 Jul 2016 18:25:49 +0200 Subject: [PATCH] netsniff-ng: Skip duplicated packets on loopback device Upstream commit: 81f8c546d90b7615e0e6a6777445b10b4263d598 --- netsniff-ng.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/netsniff-ng.c b/netsniff-ng.c index b238979..75b5ca0 100644 --- a/netsniff-ng.c +++ b/netsniff-ng.c @@ -54,7 +54,8 @@ enum dump_mode { struct ctx { char *device_in, *device_out, *device_trans, *filter, *prefix; - int cpu, rfraw, dump, print_mode, dump_dir, packet_type, verbose; + int cpu, rfraw, dump, print_mode, dump_dir, packet_type, verbose, + lo_ifindex; unsigned long kpull, dump_interval, reserve_size, tx_bytes, tx_packets; bool randomize, promiscuous, enforce, jumbo, dump_bpf; enum pcap_ops_groups pcap; @@ -346,6 +347,18 @@ static void pcap_to_xmit(struct ctx *ctx) printf("\r%12lu sec, %lu usec in total\n", diff.tv_sec, diff.tv_usec); } +static inline bool skip_packet(struct ctx *ctx, struct sockaddr_ll *sll) +{ + if (ctx->packet_type != -1) + return ctx->packet_type != sll->sll_pkttype; + + /* when receving from the loopback device, each packet is seen twice, + * so drop the outgoing ones to avoid duplicates + */ + return (sll->sll_ifindex == ctx->lo_ifindex) && + (sll->sll_pkttype == PACKET_OUTGOING); +} + static void receive_to_xmit(struct ctx *ctx) { short ifflags = 0; @@ -424,9 +437,8 @@ static void receive_to_xmit(struct ctx *ctx) frame_count++; - if (ctx->packet_type != -1) - if (ctx->packet_type != hdr_in->s_ll.sll_pkttype) - goto next; + if (skip_packet(ctx, &hdr_in->s_ll)) + goto next; hdr_out = tx_ring.frames[it_out].iov_base; out = ((uint8_t *) hdr_out) + TPACKET2_HDRLEN - sizeof(struct sockaddr_ll); @@ -835,9 +847,8 @@ static void walk_t3_block(struct block_desc *pbd, struct ctx *ctx, __label__ next; packet = ((uint8_t *) hdr + hdr->tp_mac); - if (ctx->packet_type != -1) - if (ctx->packet_type != sll->sll_pkttype) - goto next; + if (skip_packet(ctx, sll)) + goto next; (*frame_count)++; @@ -1414,6 +1425,9 @@ int main(int argc, char **argv) if (!ctx.device_in) ctx.device_in = xstrdup("any"); + if (!strcmp(ctx.device_in, "any") || !strcmp(ctx.device_in, "lo")) + ctx.lo_ifindex = device_ifindex("lo"); + register_signal(SIGINT, signal_handler); register_signal(SIGHUP, signal_handler); -- 1.8.3.1