-
Notifications
You must be signed in to change notification settings - Fork 322
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added elements for setting various IPv6 fields #292
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* setip6ecn.{cc,hh} -- element sets IP6 header ECN field | ||
* Glenn Minne | ||
* | ||
* Copyright (c) 2009 Intel Corporation | ||
* | ||
* 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 "setip6ecn.hh" | ||
#include <clicknet/ip6.h> | ||
#include <click/args.hh> | ||
#include <click/error.hh> | ||
CLICK_DECLS | ||
|
||
SetIP6ECN::SetIP6ECN() | ||
{ | ||
} | ||
|
||
SetIP6ECN::~SetIP6ECN() | ||
{ | ||
} | ||
|
||
int | ||
SetIP6ECN::configure(Vector<String> &conf, ErrorHandler *errh) | ||
{ | ||
String ecn; | ||
if (Args(conf, this, errh).read_mp("ECN", AnyArg(), ecn).complete() < 0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for " anyarg()," |
||
return -1; | ||
if (ecn.length() == 1 && ecn[0] >= '0' && ecn[0] <= '3') | ||
_ecn = ecn[0] - '0'; // subtract zero ASCII character since we are working with integers, not with chars | ||
else if (ecn.equals("no", 2) || ecn.equals("-", 1)) | ||
_ecn = 0; | ||
else if (ecn.equals("ect1", 4) || ecn.equals("ECT(1)", 6)) | ||
_ecn = 1; | ||
else if (ecn.equals("ect2", 4) || ecn.equals("ECT(0)", 6)) | ||
_ecn = 2; | ||
else if (ecn.equals("ce", 2) || ecn.equals("CE", 2)) | ||
_ecn = 3; | ||
else | ||
return errh->error("bad ECN argument"); | ||
return 0; | ||
} | ||
|
||
Packet * | ||
SetIP6ECN::simple_action(Packet *p) | ||
{ | ||
assert(p->has_network_header()); | ||
WritablePacket *q; | ||
if (!(q = p->uniqueify())) | ||
return 0; | ||
click_ip6 *ip6 = q->ip6_header(); | ||
// This first sets the original ECN bits to 00 with & 0b11111111110011111111111111111111, after which the two new ECN bits | ||
// are set with an OR operation. Our two bits are internally saved as 00000000000000000000000000000xx with our x's | ||
// always being '1' or '0'. | ||
// Because they need to come on position 11 and 12 of our ip6_flow and not on position 31 or 32, they need to be shifted 20 places | ||
// to the left first to get them where they finally need to be in ip6_flow of our IPv6 packet, before we can OR. | ||
ip6->ip6_flow = ((ip6->ip6_flow & htonl(0b11111111110011111111111111111111)) | htonl(_ecn << 20)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is pretty ugly, I'd say to use at least a constant. Don't know about ECN field but what are those? Can you create a function which actually make sens of the value and build this value? |
||
|
||
return q; | ||
} | ||
|
||
void | ||
SetIP6ECN::add_handlers() | ||
{ | ||
add_read_handler("ecn", read_keyword_handler, "0 ECN", Handler::CALM); | ||
add_write_handler("ecn", reconfigure_keyword_handler, "0 ECN"); | ||
} | ||
|
||
CLICK_ENDDECLS | ||
EXPORT_ELEMENT(SetIP6ECN) | ||
ELEMENT_MT_SAFE(SetIP6ECN) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
#ifndef CLICK_SETIP6ECN_HH | ||
#define CLICK_SETIP6ECN_HH | ||
#include <click/element.hh> | ||
CLICK_DECLS | ||
|
||
/* | ||
* =c | ||
* SetIP6ECN(ECN) | ||
* =s ip6 | ||
* sets IPv6 packets' ECN fields | ||
* =d | ||
* Expects IPv6 packets as input and | ||
* sets their ECN bits to ECN. | ||
* This value is either a number from 0 to 3 or a keyword, namely "no", | ||
* "ect1"/"ECT(1)", "ect2"/"ECT(0)", or "ce"/"CE". | ||
* Then it passes the packet to output 0. | ||
* The ECN bits are the 2 least-significant bits in the Traffic Class field. | ||
* =sa SetIPDSCP, MarkIPCE | ||
*/ | ||
|
||
class SetIP6ECN : public Element { public: | ||
|
||
SetIP6ECN() CLICK_COLD; | ||
~SetIP6ECN() CLICK_COLD; | ||
|
||
const char *class_name() const { return "SetIP6ECN"; } | ||
const char *port_count() const { return PORTS_1_1; } | ||
|
||
int configure(Vector<String> &, ErrorHandler *) CLICK_COLD; | ||
bool can_live_reconfigure() const { return true; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It cannot live_reconfigure(), remove line (may be elsewhere too). |
||
void add_handlers() CLICK_COLD; | ||
|
||
Packet *simple_action(Packet *); | ||
|
||
private: | ||
|
||
uint32_t _ecn; | ||
|
||
}; | ||
|
||
CLICK_ENDDECLS | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* | ||
* setip6flowlabel.{cc,hh} -- element sets IP6 flow label field | ||
* Glenn Minne | ||
* | ||
* Copyright (c) 2002 Massachusetts Institute of Technology | ||
* | ||
* 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 "setip6flowlabel.hh" | ||
#include <clicknet/ip6.h> | ||
#include <click/args.hh> | ||
#include <click/error.hh> | ||
CLICK_DECLS | ||
|
||
SetIP6FlowLabel::SetIP6FlowLabel() | ||
{ | ||
} | ||
|
||
SetIP6FlowLabel::~SetIP6FlowLabel() | ||
{ | ||
} | ||
|
||
int | ||
SetIP6FlowLabel::configure(Vector<String> &conf, ErrorHandler *errh) | ||
{ | ||
if (Args(conf, this, errh).read_mp("FLOW", _flow_label).complete() < 0) | ||
return -1; | ||
if (_flow_label > 1048575) | ||
return errh->error("flow label out of range"); | ||
|
||
return 0; | ||
} | ||
|
||
|
||
inline Packet * | ||
SetIP6FlowLabel::smaction(Packet *p_in) | ||
{ | ||
WritablePacket *p = p_in->uniqueify(); | ||
assert(p->has_network_header()); | ||
click_ip6 *ip6 = p->ip6_header(); | ||
|
||
ip6->ip6_ctlun.ip6_un1.ip6_un1_flow = ((htonl(0b11111111111100000000000000000000) & ip6->ip6_ctlun.ip6_un1.ip6_un1_flow) | htonl(_flow_label)); | ||
|
||
return p; | ||
} | ||
|
||
void | ||
SetIP6FlowLabel::push(int, Packet *p) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for this pull and push, just implement simple_action() and the default push and pull will do that |
||
{ | ||
if ((p = smaction(p)) != 0) | ||
output(0).push(p); | ||
} | ||
|
||
Packet * | ||
SetIP6FlowLabel::pull(int) | ||
{ | ||
Packet *p = input(0).pull(); | ||
if (p) | ||
p = smaction(p); | ||
return p; | ||
} | ||
|
||
void | ||
SetIP6FlowLabel::add_handlers() | ||
{ | ||
add_read_handler("flowlabel", read_keyword_handler, "0 FlowLabel", Handler::CALM); | ||
add_write_handler("flowlabel", reconfigure_keyword_handler, "0 FlowLabel"); | ||
} | ||
|
||
CLICK_ENDDECLS | ||
EXPORT_ELEMENT(SetIP6FlowLabel) | ||
ELEMENT_MT_SAFE(SetIP6FlowLabel) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#ifndef CLICK_SETIP6FLOWLABEL_HH | ||
#define CLICK_SETIP6FLOWLABEL_HH | ||
|
||
/* | ||
* =c | ||
* SetIP6FlowLabel(VAL) | ||
* =s ip6 | ||
* sets IP6 packets' Flow Label field | ||
* =d | ||
* Expects IP6 packets as input and | ||
* sets their Flow Label to VAL | ||
* and passes the packet to output 0. | ||
*/ | ||
|
||
#include <click/element.hh> | ||
#include <click/glue.hh> | ||
#include <clicknet/ip6.h> | ||
CLICK_DECLS | ||
|
||
class SetIP6FlowLabel : public Element { public: | ||
|
||
SetIP6FlowLabel(); | ||
~SetIP6FlowLabel(); | ||
|
||
const char *class_name() const { return "SetIP6FlowLabel"; } | ||
const char *port_count() const { return PORTS_1_1; } | ||
|
||
int configure(Vector<String> &conf, ErrorHandler *errh) CLICK_COLD; | ||
bool can_live_reconfigure() const { return true; } | ||
void add_handlers() CLICK_COLD; | ||
|
||
inline Packet *smaction(Packet *p); | ||
void push(int port, Packet *p); | ||
Packet *pull(int port); | ||
|
||
private: | ||
|
||
uint32_t _flow_label;/* is only 20 bits long but we cannot represent a 20-bit type */ | ||
/* however, we prevent from assigning this a value longer than 20-bits, */ | ||
/* if it still happens, we return an error */ | ||
|
||
}; | ||
|
||
CLICK_ENDDECLS | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
/* | ||
* setip6hlim.{cc,hh} -- element sets IP6 hop limit field | ||
* Glenn Minne | ||
* | ||
* Copyright (c) 2002 Massachusetts Institute of Technology | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MIT or Intel? :p |
||
* | ||
* 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 "setip6hlim.hh" | ||
#include <clicknet/ip6.h> | ||
#include <click/args.hh> | ||
#include <click/error.hh> | ||
CLICK_DECLS | ||
|
||
SetIP6Hlim::SetIP6Hlim() | ||
{ | ||
} | ||
|
||
SetIP6Hlim::~SetIP6Hlim() | ||
{ | ||
} | ||
|
||
int | ||
SetIP6Hlim::configure(Vector<String> &conf, ErrorHandler *errh) | ||
{ | ||
if (Args(conf, this, errh).read_mp("HLIM", _hlim).complete() < 0) | ||
return -1; | ||
|
||
return 0; | ||
} | ||
|
||
|
||
inline Packet * | ||
SetIP6Hlim::smaction(Packet *p_in) | ||
{ | ||
WritablePacket *p = p_in->uniqueify(); | ||
assert(p->has_network_header()); | ||
click_ip6 *ip6 = p->ip6_header(); | ||
|
||
ip6->ip6_ctlun.ip6_un1.ip6_un1_hlim = _hlim; | ||
|
||
return p; | ||
} | ||
|
||
void | ||
SetIP6Hlim::push(int, Packet *p) | ||
{ | ||
if ((p = smaction(p)) != 0) | ||
output(0).push(p); | ||
} | ||
|
||
Packet * | ||
SetIP6Hlim::pull(int) | ||
{ | ||
Packet *p = input(0).pull(); | ||
if (p) | ||
p = smaction(p); | ||
return p; | ||
} | ||
|
||
void | ||
SetIP6Hlim::add_handlers() | ||
{ | ||
add_read_handler("hopLimit", read_keyword_handler, "0 SetIP6Hlim", Handler::CALM); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Traditionnally handler name would be hop_limit. |
||
add_write_handler("hopLimit", reconfigure_keyword_handler, "0 SetIP6Hlim"); | ||
} | ||
|
||
CLICK_ENDDECLS | ||
EXPORT_ELEMENT(SetIP6Hlim) | ||
ELEMENT_MT_SAFE(SetIP6Hlim) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#ifndef CLICK_SETIP6HLIM_HH | ||
#define CLICK_SETIP6HLIM_HH | ||
|
||
/* | ||
* =c | ||
* SetIP6HLim(VAL) | ||
* =s ip6 | ||
* sets IP6 packets' Hop Limit field | ||
* =d | ||
* Expects IP6 packets as input and | ||
* sets their Hop Limit to VAL | ||
* and passes the packet to output 0. | ||
*/ | ||
|
||
#include <click/element.hh> | ||
#include <click/glue.hh> | ||
#include <clicknet/ip6.h> | ||
CLICK_DECLS | ||
|
||
class SetIP6Hlim : public Element { public: | ||
SetIP6Hlim(); | ||
~SetIP6Hlim(); | ||
|
||
const char *class_name() const { return "SetIP6Hlim"; } | ||
const char *port_count() const { return PORTS_1_1; } | ||
|
||
int configure(Vector<String> &conf, ErrorHandler *errh) CLICK_COLD; | ||
bool can_live_reconfigure() const { return true; } | ||
void add_handlers() CLICK_COLD; | ||
|
||
inline Packet *smaction(Packet *p); | ||
void push(int port, Packet *p); | ||
Packet *pull(int port); | ||
|
||
private: | ||
uint8_t _hlim; /* field containing the hop limit */ | ||
|
||
}; | ||
|
||
CLICK_ENDDECLS | ||
#endif /* CLICK_SETIP6HLIM_HH */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only doing a very fast look, but the copyrights seem to be wrong on some files.