Skip to content
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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 81 additions & 0 deletions elements/ip6/setip6ecn.cc
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
Copy link
Collaborator

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.

*
* 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)
Copy link
Collaborator

Choose a reason for hiding this comment

The 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));
Copy link
Collaborator

Choose a reason for hiding this comment

The 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)
42 changes: 42 additions & 0 deletions elements/ip6/setip6ecn.hh
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; }
Copy link
Collaborator

@tbarbette tbarbette Sep 8, 2016

Choose a reason for hiding this comment

The 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
82 changes: 82 additions & 0 deletions elements/ip6/setip6flowlabel.cc
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)
Copy link
Collaborator

Choose a reason for hiding this comment

The 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)
45 changes: 45 additions & 0 deletions elements/ip6/setip6flowlabel.hh
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
80 changes: 80 additions & 0 deletions elements/ip6/setip6hlim.cc
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
Copy link
Collaborator

Choose a reason for hiding this comment

The 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);
Copy link
Collaborator

@tbarbette tbarbette Sep 8, 2016

Choose a reason for hiding this comment

The 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)
41 changes: 41 additions & 0 deletions elements/ip6/setip6hlim.hh
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 */
Loading