Commit f8b52e27 authored by Tom Barbette's avatar Tom Barbette

Make ICMPRewriter batch-compatible

parent 86ba5f22
......@@ -92,8 +92,16 @@ update_in_cksum(uint16_t *csum, const uint16_t *old_hw, const uint16_t *new_hw,
}
int
ICMPRewriter::handle(WritablePacket *p)
ICMPRewriter::handle(Packet* &p_in)
{
WritablePacket *p = p_in->uniqueify();
if (!p)
return -1;
else if (p->ip_header()->ip_p != IP_PROTO_ICMP) {
return noutputs();
}
p_in = p;
// check ICMP type
click_icmp *icmph = p->icmp_header();
if (icmph->icmp_type != ICMP_UNREACH
......@@ -230,17 +238,18 @@ ICMPRewriter::handle(WritablePacket *p)
void
ICMPRewriter::push(int, Packet *p_in)
{
WritablePacket *p = p_in->uniqueify();
if (!p)
return;
else if (p->ip_header()->ip_p != IP_PROTO_ICMP) {
p->kill();
return;
}
int output = handle(p_in);
if (output == -1)
return;
checked_output_push(output, p_in);
}
int output = handle(p);
checked_output_push(output, p);
#if HAVE_BATCH
void
ICMPRewriter::push_batch(int, PacketBatch *batch) {
CLASSIFY_EACH_PACKET_IGNORE(noutputs() + 1,handle,batch,checked_output_push_batch);
}
#endif
CLICK_ENDDECLS
ELEMENT_REQUIRES(IPRewriterBase ICMPPingRewriter)
......
#ifndef CLICK_ICMPREWRITER_HH
#define CLICK_ICMPREWRITER_HH
#include <click/element.hh>
#include <click/batchelement.hh>
#include <clicknet/udp.h>
#include <clicknet/icmp.h>
#include "elements/ip/iprewriterbase.hh"
......@@ -58,7 +58,7 @@ ICMPPingRewriter, or other related classes.
IPAddrRewriter, IPRewriter, ICMPPingRewriter, TCPRewriter */
class ICMPRewriter : public Element { public:
class ICMPRewriter : public BatchElement { public:
ICMPRewriter() CLICK_COLD;
~ICMPRewriter() CLICK_COLD;
......@@ -70,7 +70,9 @@ class ICMPRewriter : public Element { public:
int configure(Vector<String> &, ErrorHandler *) CLICK_COLD;
void push(int, Packet *);
#if HAVE_BATCH
void push_batch(int, PacketBatch *);
#endif
protected:
struct MapEntry {
......@@ -91,7 +93,7 @@ class ICMPRewriter : public Element { public:
void rewrite_ping_packet(WritablePacket *, click_ip *, click_icmp_echo *,
const IPFlowID &, IPRewriterEntry *);
int handle(WritablePacket *p);
int handle(Packet* &p);
};
......
......@@ -212,6 +212,66 @@ CLICK_DECLS
}\
}
/**
* Equivalent to CLASSIFY_EACH_PACKET but ignore the packet if fnt returns -1
*/
#define CLASSIFY_EACH_PACKET_IGNORE(nbatches,fnt,cep_batch,on_finish)\
{\
PacketBatch* out[(nbatches)];\
bzero(out,sizeof(PacketBatch*)*(nbatches));\
PacketBatch* cep_next = ((cep_batch != NULL)? static_cast<PacketBatch*>(cep_batch->next()) : NULL );\
Packet* p = cep_batch;\
Packet* last = NULL;\
int last_o = -1;\
int passed = 0;\
for (;p != NULL;p=cep_next,cep_next=(p==0?0:static_cast<PacketBatch*>(p->next()))) {\
int o = (fnt(p));\
if (o>=(nbatches)) o = (nbatches - 1);\
if (o == last_o) {\
passed ++;\
} else {\
if (last == NULL) {\
if (o == -1) continue;\
out[o] = static_cast<PacketBatch*>(p);\
out[o]->set_count(1);\
out[o]->set_tail(p);\
} else {\
if (last_o != -1) {\
out[last_o]->set_tail(last);\
out[last_o]->set_count(out[last_o]->count() + passed);\
}\
if (o != -1) {\
if (!out[o]) {\
out[o] = static_cast<PacketBatch*>(p);\
out[o]->set_count(1);\
out[o]->set_tail(p);\
} else {\
out[o]->append_packet(p);\
}\
}\
passed = 0;\
}\
}\
last = p;\
last_o = o;\
}\
\
if (passed && last_o != -1) {\
out[last_o]->set_tail(last);\
out[last_o]->set_count(out[last_o]->count() + passed);\
}\
\
int i = 0;\
for (; i < (nbatches); i++) {\
if (out[i]) {\
out[i]->tail()->set_next(NULL);\
(on_finish(i,out[i]));\
}\
}\
}
/**
* Create a batch by calling multiple times (up to max) a given function and
* linking them together in respect to the PacketBatch semantic.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment