OK, try one. I'm ready to accept heavy artillery fire ;-) Man, it
takes a while to find a free letter for getopt.
Two new parameters were added:
-C <cluster id> with integer that represents the socket fanout group
identifier and must be shared between all processes in the group
-K hash/lb/cpu/rnd - the type of fanout. The only really useful here
is "hash" because it preserves flows. If it is choosen, kernel side
defragmentation is enabled as well (fragments would have different
hash).
Now, kernel does not allow to choose what we are hashing on, and it
seems to be 4-tuple.
I tested it with lb and hash cluster types and everything worked. The
lb cluster type is useless (as is anything that is not "hash" but
given how advanced the nesniff-ng software is, someone might find it
useful and it's just a few lines more.
Patch is below (inline, for comments).
diff -uprN netsniff-ng/netsniff-ng.c
netsniff-ng-multiprocess-clean/netsniff-ng.c
--- netsniff-ng/netsniff-ng.c 2015-04-11 18:48:19.861108673 +0200
+++ netsniff-ng-multiprocess-clean/netsniff-ng.c 2015-04-11
18:51:01.286156858 +0200
@@ -60,12 +60,13 @@ struct ctx {
bool randomize, promiscuous, enforce, jumbo, dump_bpf, hwtimestamp, verbose;
enum pcap_ops_groups pcap; enum dump_mode dump_mode;
uid_t uid; gid_t gid; uint32_t link_type, magic;
+ uint32_t cluster_id, cluster_type;
};
static volatile sig_atomic_t sigint = 0;
static volatile bool next_dump = false;
-static const char *short_options =
"d:i:o:rf:MNJt:S:k:n:b:HQmcsqXlvhF:RGAP:Vu:g:T:DBU";
+static const char *short_options =
"d:i:o:rf:MNJt:S:k:n:b:HQmcsqXlvhF:RGAP:Vu:g:T:DBU:C:K:";
static const struct option long_options[] = {
{"dev", required_argument, NULL, 'd'},
{"in", required_argument, NULL, 'i'},
@@ -81,6 +82,8 @@ static const struct option long_options[
{"user", required_argument, NULL, 'u'},
{"group", required_argument, NULL, 'g'},
{"magic", required_argument, NULL, 'T'},
+ {"cluster-id", required_argument, NULL, 'C'},
+ {"cluster-type", required_argument, NULL, 'K'},
{"rand", no_argument, NULL, 'r'},
{"rfraw", no_argument, NULL, 'R'},
{"mmap", no_argument, NULL, 'm'},
@@ -376,7 +379,7 @@ static void receive_to_xmit(struct ctx *
bpf_dump_all(&bpf_ops);
bpf_attach_to_sock(rx_sock, &bpf_ops);
- ring_rx_setup(&rx_ring, rx_sock, size_in, ifindex_in, &rx_poll,
false, ctx->jumbo, ctx->verbose);
+ ring_rx_setup(&rx_ring, rx_sock, size_in, ifindex_in, &rx_poll,
false, ctx->jumbo, ctx->verbose, ctx->cluster_id, ctx->cluster_type);
ring_tx_setup(&tx_ring, tx_sock, size_out, ifindex_out, ctx->jumbo,
ctx->verbose);
dissector_init_all(ctx->print_mode);
@@ -932,7 +935,7 @@ static void recv_only_or_dump(struct ctx
printf("HW timestamping enabled\n");
}
- ring_rx_setup(&rx_ring, sock, size, ifindex, &rx_poll,
is_defined(HAVE_TPACKET3), true, ctx->verbose);
+ ring_rx_setup(&rx_ring, sock, size, ifindex, &rx_poll,
is_defined(HAVE_TPACKET3), true, ctx->verbose, ctx->cluster_id,
ctx->cluster_type);
dissector_init_all(ctx->print_mode);
@@ -1366,6 +1369,23 @@ int main(int argc, char **argv)
case 'h':
help();
break;
+ case 'C':
+ ctx.cluster_id = (uint32_t) strtoul(optarg, NULL, 0);
+ break;
+ case 'K':
+ if (!strncmp(optarg, "hash", strlen("hash")))
+ ctx.cluster_type = PACKET_FANOUT_HASH;
+ else if (!strncmp(optarg, "lb", strlen("lb")))
+ ctx.cluster_type = PACKET_FANOUT_LB;
+ else if (!strncmp(optarg, "cpu", strlen("cpu")))
+ ctx.cluster_type = PACKET_FANOUT_CPU;
+ else if (!strncmp(optarg, "rnd", strlen("rnd")))
+ ctx.cluster_type = PACKET_FANOUT_RND;
+ else if (!strncmp(optarg, "rollover", strlen("rollover")))
+ ctx.cluster_type = PACKET_FANOUT_ROLLOVER;
+/* else if (!strncmp(optarg, "qm", strlen("qm")))
+ ctx.cluster_type = PACKET_FANOUT_QM;*/
+ break;
case '?':
switch (optopt) {
case 'd':
diff -uprN netsniff-ng/ring_rx.c netsniff-ng-multiprocess-clean/ring_rx.c
--- netsniff-ng/ring_rx.c 2015-04-11 18:48:19.877111409 +0200
+++ netsniff-ng-multiprocess-clean/ring_rx.c 2015-04-11 18:50:50.661402061 +0200
@@ -209,9 +209,23 @@ static void alloc_rx_ring_frames(int soc
rx_ring_get_size(ring, v3));
}
+void create_cluster(int sock, uint32_t cluster_id, uint32_t cluster_mode)
+{
+ uint32_t cluster_option = 0;
+ int ret = 0;
+
+ if (cluster_mode == PACKET_FANOUT_HASH)
+ cluster_mode = PACKET_FANOUT_HASH | PACKET_FANOUT_FLAG_DEFRAG;
+ else
+ cluster_option = (cluster_id | (cluster_mode << 16));
+ ret = setsockopt(sock, SOL_PACKET, PACKET_FANOUT,(void
*)&cluster_option, sizeof(cluster_option));
+ if (ret < 0)
+ panic("Cannot set fanout ring mode!\n");
+}
+
void ring_rx_setup(struct ring *ring, int sock, size_t size, int ifindex,
struct pollfd *poll, bool v3, bool jumbo_support,
- bool verbose)
+ bool verbose, uint32_t cluster_id, uint32_t cluster_type)
{
fmemset(ring, 0, sizeof(*ring));
setup_rx_ring_layout(sock, ring, size, jumbo_support, v3);
@@ -220,6 +234,7 @@ void ring_rx_setup(struct ring *ring, in
alloc_rx_ring_frames(sock, ring);
bind_ring_generic(sock, ring, ifindex, false);
prepare_polling(sock, poll);
+ create_cluster(sock, cluster_id, cluster_type);
}
void sock_rx_net_stats(int sock, unsigned long seen)
diff -uprN netsniff-ng/ring_rx.h netsniff-ng-multiprocess-clean/ring_rx.h
--- netsniff-ng/ring_rx.h 2015-04-11 18:48:19.877111409 +0200
+++ netsniff-ng-multiprocess-clean/ring_rx.h 2015-04-11 18:50:50.661402061 +0200
@@ -13,7 +13,7 @@
extern void ring_rx_setup(struct ring *ring, int sock, size_t size,
int ifindex,
struct pollfd *poll, bool v3, bool jumbo_support,
- bool verbose);
+ bool verbose, uint32_t cluster_id, uint32_t cluster_type);
extern void destroy_rx_ring(int sock, struct ring *ring);
extern void sock_rx_net_stats(int sock, unsigned long seen);
On Fri, Apr 10, 2015 at 10:31 PM, Jon Schipp <
jons...@gmail.com> wrote:
> Awesome, glad to see this coming up again :)
>
> On Wed, Apr 8, 2015 at 6:43 AM, Daniel Borkmann <
bork...@iogearbox.net>
> wrote:
>>
>> On 04/07/2015 04:34 PM, Daniel Borkmann wrote:
>>>
>>> On 04/07/2015 04:28 PM, Michał Purzyński wrote:
>>>>
>>>> So the crash was caused by a real OOM condition, I was testing it in a
>>>> VM with 512MB RAM. Changed to 4GB and now I have two netsniff-ng
>>>> instances working and getting portion of the flows, hashed by the
>>>> kernel, per flow :-)
>>>>
>>>> I will work on the code and submit patches for review in a few days.
>>>
>>>
>>> Ok, great, looking forward!
>>
>>
>> I think you might also want to let the user choose which fanout
>> discipline to use in kernel side. There are several useful ones
>> available.
>>
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "netsniff-ng" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to
netsniff-ng...@googlegroups.com.