Skip to content

Commit

Permalink
RSSHashSwitch: Switch element using the RSS software hash
Browse files Browse the repository at this point in the history
  • Loading branch information
tbarbette committed Oct 22, 2024
1 parent ae3f7de commit acdfb02
Show file tree
Hide file tree
Showing 3 changed files with 167 additions and 1 deletion.
118 changes: 118 additions & 0 deletions elements/userlevel/rsshashswitch.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* RSSHashSwitch.{cc,hh} -- element demultiplexes packets based on hash of
* specified packet fields
* Eddie Kohler
*
* Computational batching support by Georgios Katsikas
*
* Copyright (c) 1999-2000 Massachusetts Institute of Technology
* Copyright (c) 2018 Georgios Katsikas, RISE SICS
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, subject to the conditions
* listed in the Click LICENSE file. These conditions include: you must
* preserve this copyright notice, and you cannot mention the copyright
* holders in advertising related to the Software without their permission.
* The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This
* notice is a summary of the Click LICENSE file; the license in that file is
* legally binding.
*/

#include <click/config.h>
#include "rsshashswitch.hh"
#include <click/error.hh>
#include <click/args.hh>
#include <clicknet/ether.h>

#include <click/dpdkdevice.hh>
#include <click/ip6address.hh>
#include <click/ip6flowid.hh>
#include <rte_thash.h>

CLICK_DECLS

RSSHashSwitch::RSSHashSwitch()
{
}

#define RSS_HASH_KEY_LENGTH 40
static uint8_t hash_key[RSS_HASH_KEY_LENGTH] = {
0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A, 0x6D, 0x5A,
};

int
RSSHashSwitch::configure(Vector<String> &conf, ErrorHandler *errh)
{
_max = noutputs();
if (Args(conf, this, errh)
.read("MAX", _max)
.complete() < 0)
return -1;


return 0;
}

int
RSSHashSwitch::process(Packet *p)
{
union rte_thash_tuple tuple = {0};

/* A complete tuple from the packet. */
struct click_ether *eth = (click_ether*) p->mac_header();

int len = 0;
if (eth->ether_type == 0x0008) {

IPFlowID f(p);
tuple.v4.sport = f.sport();

tuple.v4.dport = f.dport();
IPAddress a = f.saddr();
memcpy(&tuple.v4.src_addr, &a, 4);
a = f.daddr();
memcpy(&tuple.v4.dst_addr, &a, 4);
len = 4 + 4 + 2 + 2;

} else if (eth->ether_type == 0xDD86) {
IP6FlowID f(p);
tuple.v6.sport = f.sport();
tuple.v6.dport = f.dport();
IP6Address a = f.saddr();
memcpy(&tuple.v6.src_addr, &a, 16);
a = f.daddr();
memcpy(&tuple.v6.dst_addr, &a, 16);
len = 16 + 16 + 2 + 2;
} else {
return 0;
}

uint32_t orig_hash = rte_softrss((uint32_t *)&tuple, len, hash_key);

return orig_hash % _max;
}

void
RSSHashSwitch::push(int port, Packet *p)
{
output(process(p)).push(p);
}

#if HAVE_BATCH
void
RSSHashSwitch::push_batch(int port, PacketBatch *batch)
{
auto fnt = [this, port](Packet *p) { return process(p); };
CLASSIFY_EACH_PACKET(_max + 1, fnt, batch, checked_output_push_batch);
}
#endif

CLICK_ENDDECLS
EXPORT_ELEMENT(RSSHashSwitch)
ELEMENT_MT_SAFE(RSSHashSwitch)
ELEMENT_REQUIRES(dpdk)
49 changes: 49 additions & 0 deletions elements/userlevel/rsshashswitch.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#ifndef CLICK_RSSHashSwitch_HH
#define CLICK_RSSHashSwitch_HH
#include <click/batchelement.hh>
CLICK_DECLS

/*
* =c
* RSSHashSwitch(OFFSET, LENGTH)
* =s classification
* classifies packets by hash of contents
* =d
* Can have any number of outputs.
* Chooses the output on which to emit each packet based on
* a hash of the LENGTH bytes starting at OFFSET.
* Could be used for stochastic fair queuing.
* =e
* This element expects IP packets and chooses the output
* based on a hash of the IP destination address:
*
* RSSHashSwitch(16, 4)
* =a
* Switch, RoundRobinSwitch, StrideSwitch, RandomSwitch
*/

class RSSHashSwitch : public BatchElement {

int _max;

public:

RSSHashSwitch() CLICK_COLD;

const char *class_name() const override { return "RSSHashSwitch"; }
const char *port_count() const override { return "1/1-"; }
const char *processing() const override { return PUSH; }

int configure(Vector<String> &, ErrorHandler *) CLICK_COLD;

int process(Packet *);
void push(int port, Packet *);
#if HAVE_BATCH
void push_batch(int port, PacketBatch *);
#endif

};

CLICK_ENDDECLS

#endif
1 change: 0 additions & 1 deletion lib/ip6flowid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ IP6FlowID::IP6FlowID(const Packet *p, bool reverse)
assign(IP6Address(ip6h->ip6_dst), udph->uh_dport, IP6Address(ip6h->ip6_src), udph->uh_sport);
}
} else {
assert(IP_FIRSTFRAG(iph));
if (likely(!reverse))
assign(iph->ip_src, udph->uh_sport,
iph->ip_dst, udph->uh_dport);
Expand Down

0 comments on commit acdfb02

Please sign in to comment.