Re: [netsniff-ng] multiple instances of netsniff-ng with AF_PACKET hash fanout

2015-04-14 Thread Michał Purzyński
Thanks a lot for a review. I have corrected the naming, set up the
whole git-email infrastructure and (I think so) sent the email here.

On Mon, Apr 13, 2015 at 9:44 AM, Daniel Borkmann borkm...@iogearbox.net wrote:
 On 04/11/2015 06:59 PM, Michał Purzyński wrote:

 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).


 I'd prefer if we name it fanout-type and fanout-group perhaps,
 that way it's clear that we mean the packet-sockets fanout mechanism.
 What do you think?

 Other than that, there's a couple of more fanout disciplines:

   http://lingrok.org/xref/linux-net-next/net/packet/af_packet.c#1371

 So it would be: hash/lb/cpu/rnd/qm/roll

 I think we might need to describe the exact meaning of that in the
 --help option. But I'm totally fine if we do that as follow-up.

 Now, kernel does not allow to choose what we are hashing on, and it
 seems to be 4-tuple.


 With QM (queue-mapping), you can just use the NICs HW queue flow
 steering for the fanout group distribution.

 I tested it with lb and hash cluster types and everything worked. The


 That's great.

 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.


 Sure, if we add it, we might also want to give the user a choice. I
 think that hash/cpu/qm and roll (== moves to the next fanout socket
 after the first's queue is full) might be useful.

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [netsniff-ng] multiple instances of netsniff-ng with AF_PACKET hash fanout

2015-04-14 Thread Michał Purzyński
Hopefuly done!! I have learned a few useful skills in the process.

Result: 250 2.0.0 OK something - gsmtp

On Mon, Apr 13, 2015 at 9:23 AM, Tobias Klauser tklau...@distanz.ch wrote:
 On 2015-04-11 at 18:59:08 +0200, Michał Purzyński 
 michalpurzyns...@gmail.com wrote:
 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).

 The patch looks line-wrapped and has tabs converted to spaces. Could you
 please resend it without these changes? Usually this is due to the mail
 agent line-wrapping even pasted text. I'd suggest to use `git
 send-email' which will generate a proper patch e-mail which can directly
 be reviewed and applied. Care to retry?

 (Therefor I did not review the patch content-wise yet)

 Thanks
 Tobias


 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

Re: [netsniff-ng] [Re: multiple instances of netsniff-ng with AF_PACKET hash fanout] Initial implementation of a multiprocess functionality.

2015-04-14 Thread Daniel Borkmann

Thanks Michal, looks almost ready to go in!

Other than Tobias' excellent feedback, some minor things from my side:
On 04/14/2015 01:10 AM, Michal Purzynski wrote:

---
  netsniff-ng.c | 28 +---
  ring_rx.c | 17 -
  ring_rx.h |  2 +-
  3 files changed, 42 insertions(+), 5 deletions(-)

diff --git a/netsniff-ng.c b/netsniff-ng.c
index dfb99bb..c603919 100644
--- a/netsniff-ng.c
+++ b/netsniff-ng.c
@@ -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;


I know you have changed the naming from the command line site,
but please also rename this internally, e.g. fanout_group, fanout_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'},
+   {fanout-group,  required_argument,  NULL, 'C'},
+   {fanout-type,required_argument, NULL, 'K'},


Looks like we run out of short option chars, I guess C/K is fine.


{rand,  no_argument,NULL, 'r'},
{rfraw, no_argument,NULL, 'R'},
{mmap,  no_argument,NULL, 'm'},

...

diff --git a/ring_rx.c b/ring_rx.c
index 8ad64d1..c97dd2d 100644
--- a/ring_rx.c
+++ b/ring_rx.c
@@ -209,9 +209,23 @@ static void alloc_rx_ring_frames(int sock, struct ring 
*ring)
  rx_ring_get_size(ring, v3));
  }

+void create_cluster(int sock, uint32_t cluster_id, uint32_t cluster_mode)


create_fanout_instance() or something along that line.


+{
+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, int sock, size_t 
size, int ifindex,
alloc_rx_ring_frames(sock, ring);
bind_ring_generic(sock, ring, ifindex, false);
prepare_polling(sock, poll);
+create_cluster(sock, cluster_id, cluster_type);


As Tobias mentioned, this should only be enabled if the user specifies
at least fanout_group over the command line. fanout_type, if not specified,
could be on default hash.


  }

  void sock_rx_net_stats(int sock, unsigned long seen)
diff --git a/ring_rx.h b/ring_rx.h
index edd0feb..ae2cd76 100644
--- a/ring_rx.h
+++ b/ring_rx.h
@@ -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);




--
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.