Skip to content
Permalink
Browse files

Openflow switch extension ext244 (#123)

* added rofl-common.spec

* fixing dates in rofl-common.spec*

* adjusting spec file

* added additional test for cofmsgpacketout

* renaming version from v0.13.1 to 0.13.1

* updating rofl-common.spec => 0.13.1

* rofl-common.spec => updating source

* openflow ext-244
  • Loading branch information...
akoepsel committed Oct 23, 2019
1 parent f1abe0a commit 764b5b2bd2e1ef47789ae93d1b89dba8786b1776
@@ -69,6 +69,9 @@ AC_CONFIG_FILES([
src/rofl/common/Makefile
src/rofl/common/openflow/Makefile
src/rofl/common/openflow/messages/Makefile
src/rofl/common/openflow/extensions/Makefile
src/rofl/common/openflow/extensions/actions/Makefile
src/rofl/common/openflow/extensions/matches/Makefile
src/rofl/common/openflow/experimental/Makefile
src/rofl/common/openflow/experimental/actions/Makefile
src/rofl/common/openflow/experimental/matches/Makefile
@@ -1,6 +1,6 @@
MAINTAINERCLEANFILES = Makefile.in

SUBDIRS = messages experimental
SUBDIRS = messages experimental extensions

noinst_LTLIBRARIES = libopenflow.la

@@ -128,7 +128,7 @@ libopenflow_la_SOURCES= \
cofmeterfeatures.h \
cofmeterfeatures.cc

libopenflow_la_LIBADD=messages/libopenflow_messages.la experimental/libopenflow_experimental.la
libopenflow_la_LIBADD=messages/libopenflow_messages.la experimental/libopenflow_experimental.la extensions/libopenflow_extensions.la

library_includedir=$(includedir)/rofl/common/openflow
library_include_HEADERS = \
@@ -27,6 +27,7 @@

#include "rofl/common/openflow/coxmatch.h"
#include "rofl/common/openflow/coxmatch_output.h"
#include "rofl/common/openflow/extensions/matches/ext244_matches.h"
#include "rofl/common/openflow/experimental/matches/capwap_matches.h"
#include "rofl/common/openflow/experimental/matches/gtp_matches.h"
#include "rofl/common/openflow/experimental/matches/pppoe_matches.h"
@@ -3538,6 +3539,93 @@ class coxmatches {
matches.end()));
};

public:
/**
*
*/
rofl::openflow::extensions::ext244::coxmatch_packet_register &add_packet_register(uint8_t pkt_reg_index, uint64_t value = 0) {
// dynamic oxm-id for packet register "pkt_reg_index"
uint32_t oxm_id = (OFPXMC_PACKET_REGS << 16) | (pkt_reg_index << 9) | sizeof(uint64_t);
AcquireReadWriteLock lock(rwlock);
if (matches.find(OXM_ROFL_OFB_TYPE(oxm_id)) != matches.end()) {
delete matches[OXM_ROFL_OFB_TYPE(oxm_id)];
}
matches[OXM_ROFL_OFB_TYPE(oxm_id)] =
new rofl::openflow::extensions::ext244::coxmatch_packet_register(pkt_reg_index, value);
return dynamic_cast<rofl::openflow::extensions::ext244::coxmatch_packet_register &>(
*matches[OXM_ROFL_OFB_TYPE(oxm_id)]);
};

/**
*
*/
rofl::openflow::extensions::ext244::coxmatch_packet_register &add_packet_register(uint8_t pkt_reg_index, uint64_t value, uint64_t mask) {
// dynamic oxm-id for packet register "pkt_reg_index"
uint32_t oxm_id = (OFPXMC_PACKET_REGS << 16) | (pkt_reg_index << 9) | HAS_MASK_FLAG | 2*sizeof(uint64_t);
AcquireReadWriteLock lock(rwlock);
if (matches.find(OXM_ROFL_OFB_TYPE(pkt_reg_index)) != matches.end()) {
delete matches[OXM_ROFL_OFB_TYPE(oxm_id)];
}
matches[OXM_ROFL_OFB_TYPE(oxm_id)] =
new rofl::openflow::extensions::ext244::coxmatch_packet_register(pkt_reg_index, value, mask);
return dynamic_cast<rofl::openflow::extensions::ext244::coxmatch_packet_register &>(
*matches[OXM_ROFL_OFB_TYPE(oxm_id)]);
};

/**
*
*/
rofl::openflow::extensions::ext244::coxmatch_packet_register &set_packet_register(uint8_t pkt_reg_index) {
// dynamic oxm-id for packet register "pkt_reg_index"
uint32_t oxm_id = (OFPXMC_PACKET_REGS << 16) | (pkt_reg_index << 9) | HAS_MASK_FLAG | 2*sizeof(uint64_t);
AcquireReadWriteLock lock(rwlock);
if (matches.find(OXM_ROFL_OFB_TYPE(oxm_id)) == matches.end()) {
matches[OXM_ROFL_OFB_TYPE(oxm_id)] =
new rofl::openflow::extensions::ext244::coxmatch_packet_register(pkt_reg_index);
}
return dynamic_cast<rofl::openflow::extensions::ext244::coxmatch_packet_register &>(
*matches[OXM_ROFL_OFB_TYPE(oxm_id)]);
};

/**
*
*/
const rofl::openflow::extensions::ext244::coxmatch_packet_register &get_packet_register(uint8_t pkt_reg_index) const {
// dynamic oxm-id for packet register "pkt_reg_index"
uint32_t oxm_id = (OFPXMC_PACKET_REGS << 16) | (pkt_reg_index << 9) | HAS_MASK_FLAG | 2*sizeof(uint64_t);
AcquireReadLock lock(rwlock);
if (matches.find(OXM_ROFL_OFB_TYPE(oxm_id)) == matches.end()) {
throw eOxmInval("coxmatches::get_packet_register() not found");
}
return dynamic_cast<const rofl::openflow::extensions::ext244::coxmatch_packet_register &>(*matches.at(
OXM_ROFL_OFB_TYPE(oxm_id)));
};

/**
*
*/
bool drop_packet_register(uint8_t pkt_reg_index) {
// dynamic oxm-id for packet register "pkt_reg_index"
uint32_t oxm_id = (OFPXMC_PACKET_REGS << 16) | (pkt_reg_index << 9) | HAS_MASK_FLAG | 2*sizeof(uint64_t);
AcquireReadWriteLock lock(rwlock);
if (matches.find(OXM_ROFL_OFB_TYPE(oxm_id)) == matches.end()) {
return false;
}
delete matches[OXM_ROFL_OFB_TYPE(oxm_id)];
matches.erase(OXM_ROFL_OFB_TYPE(oxm_id));
return true;
};

/**
*
*/
bool has_packet_register(uint8_t pkt_reg_index) const {
// dynamic oxm-id for packet register "pkt_reg_index"
uint32_t oxm_id = (OFPXMC_PACKET_REGS << 16) | (pkt_reg_index << 9) | HAS_MASK_FLAG | 2*sizeof(uint64_t);
AcquireReadLock lock(rwlock);
return (not(matches.find(OXM_ROFL_OFB_TYPE(oxm_id)) == matches.end()));
};

public:
/**
*
@@ -3757,7 +3845,16 @@ class coxmatches {
os << oxmatches.get_ofx_tp_dst();
} break;
default: {
if (OXM_ROFL_CLASS(*it) == 0xffff0000) {
// EXT-244: packet register
if (OXM_ROFL_CLASS(*it) == (uint32_t)(OFPXMC_PACKET_REGS << 16)) {
for (int i = 0; i < 128; i++) {
if (oxmatches.has_packet_register(i)) {
os << oxmatches.get_packet_register(i);
}
}

}
if (OXM_ROFL_CLASS(*it) == (uint32_t)(OFPXMC_EXPERIMENTER << 16)) {
os << oxmatches.get_exp_match((*it & 0xffffffff00000000) >> 32,
(*it & 0x00000000fffffe00) >> 0);
}
@@ -0,0 +1,7 @@
MAINTAINERCLEANFILES = Makefile.in

SUBDIRS = actions matches

noinst_LTLIBRARIES = libopenflow_extensions.la
libopenflow_extensions_la_SOURCES=
libopenflow_extensions_la_LIBADD= actions/libopenflow_extensions_actions.la matches/libopenflow_extensions_matches.la
@@ -0,0 +1,7 @@
MAINTAINERCLEANFILES = Makefile.in

noinst_LTLIBRARIES = libopenflow_extensions_actions.la
libopenflow_extensions_actions_la_SOURCES =

library_includedir=$(includedir)/rofl/common/openflow/extensions/actions
library_include_HEADERS =
@@ -0,0 +1,11 @@
MAINTAINERCLEANFILES = Makefile.in

noinst_LTLIBRARIES = libopenflow_extensions_matches.la
libopenflow_extensions_matches_la_SOURCES = \
ext244_matches.h \
ext244_matches.cc


library_includedir=$(includedir)/rofl/common/openflow/extensions/matches
library_include_HEADERS = \
ext244_matches.h
@@ -0,0 +1,3 @@
#include <rofl/common/openflow/extensions/matches/ext244_matches.h>

using namespace rofl::openflow::extensions::ext244;
@@ -0,0 +1,46 @@
#ifndef EXT244_MATCHES
#define EXT244_MATCHES 1

#include <rofl/common/openflow/coxmatch.h>

namespace rofl {
namespace openflow {
namespace extensions {
namespace ext244 {

/**
* @brief OXM_OF_EXT244
*
*/
class coxmatch_packet_register : public coxmatch_64 {
public:
coxmatch_packet_register(uint8_t pkt_reg)
: coxmatch_64((OFPXMC_PACKET_REGS << 16) | (pkt_reg << 9) | sizeof(uint64_t)){};
coxmatch_packet_register(uint8_t pkt_reg, uint64_t value)
: coxmatch_64((OFPXMC_PACKET_REGS << 16) | (pkt_reg << 9) | sizeof(uint64_t), value){};
coxmatch_packet_register(uint8_t pkt_reg, uint64_t value, uint64_t mask)
: coxmatch_64((OFPXMC_PACKET_REGS << 16) | (pkt_reg << 9) | HAS_MASK_FLAG | 2*sizeof(uint64_t), value, mask){};
coxmatch_packet_register(const coxmatch_64 &oxm) : coxmatch_64(oxm){};
virtual ~coxmatch_packet_register(){};

public:
friend std::ostream &operator<<(std::ostream &os,
const coxmatch_packet_register &oxm) {
os << dynamic_cast<const coxmatch_64 &>(oxm);
// oxm-field represents the packet register index
os << "<ext244-packet-register(" << (int)oxm.get_oxm_field() << "): "
<< std::hex
<< "0x" << (unsigned long long)oxm.get_u64value() << "/"
<< "0x" << (unsigned long long)oxm.get_u64mask() << " >"
<< std::dec
<< std::endl;
return os;
};
};

}; // end of namespace ext244
}; // end of namespace extensions
}; // end of namespace openflow
}; // end of namespace rofl

#endif
@@ -394,6 +394,7 @@ enum ofp_oxm_class {
OFPXMC_NXM_0 = 0x0000, /* Backward compatibility with NXM */
OFPXMC_NXM_1 = 0x0001, /* Backward compatibility with NXM */
OFPXMC_OPENFLOW_BASIC = 0x8000, /* Basic class for OpenFlow */
OFPXMC_PACKET_REGS = 0x8001, /* EXT-244: packet register class id */
OFPXMC_EXPERIMENTER = 0xFFFF, /* Experimenter class */
};

@@ -928,3 +928,59 @@ void coxmatchtest::testExp64() {
CPPUNIT_ASSERT(clone.get_oxm_length() ==
sizeof(uint32_t) + 2 * sizeof(uint64_t));
}

void coxmatchtest::test_ext244_pkt_reg() {
uint8_t pkt_reg_index = 17;
uint64_t value = 0xa1a2a3a4a5a6a7a8;
rofl::openflow::extensions::ext244::coxmatch_packet_register oxmatch(pkt_reg_index, value);

rofl::cmemory mem(oxmatch.length());
oxmatch.pack(mem.somem(), mem.length());
rofl::openflow::extensions::ext244::coxmatch_packet_register oxm(pkt_reg_index);
oxm.unpack(mem.somem(), mem.length());

std::cerr << oxmatch << std::endl;
std::cerr << oxm << std::endl;
std::cerr << mem << std::endl;

CPPUNIT_ASSERT(oxm.length() ==
sizeof(struct rofl::openflow::ofp_oxm_hdr) + 1*sizeof(uint64_t));
CPPUNIT_ASSERT(oxm.get_oxm_class() == rofl::openflow::OFPXMC_PACKET_REGS);
CPPUNIT_ASSERT(oxm.get_oxm_field() == pkt_reg_index);
CPPUNIT_ASSERT(oxm.get_oxm_hasmask() == false);
CPPUNIT_ASSERT(oxm.get_oxm_type() ==
(uint32_t)((rofl::openflow::OFPXMC_PACKET_REGS << 16) |
(pkt_reg_index << 9)));
CPPUNIT_ASSERT(oxm.get_u64value() == value);
CPPUNIT_ASSERT(oxm.get_u64masked_value() == value);
}

void coxmatchtest::test_ext244_pkt_reg_mask() {
uint8_t pkt_reg_index = 17;
uint64_t value = 0xa1a2a3a4a5a6a7a8;
uint64_t mask = 0xff00ff00f0f0f0f0;
rofl::openflow::extensions::ext244::coxmatch_packet_register oxmatch(pkt_reg_index, value, mask);

rofl::cmemory mem(oxmatch.length());
oxmatch.pack(mem.somem(), mem.length());
rofl::openflow::extensions::ext244::coxmatch_packet_register oxm(pkt_reg_index);
oxm.unpack(mem.somem(), mem.length());

std::cerr << ">>>oxmatch<<< " << std::endl << oxmatch << std::endl;
std::cerr << ">>>oxm<<< " << std::endl << oxm << std::endl;
std::cerr << ">>>mem<<< " << std::endl << mem << std::endl;

CPPUNIT_ASSERT(oxm.length() ==
sizeof(struct rofl::openflow::ofp_oxm_hdr) + 2*sizeof(uint64_t));
CPPUNIT_ASSERT(oxm.get_oxm_class() == rofl::openflow::OFPXMC_PACKET_REGS);
CPPUNIT_ASSERT(oxm.get_oxm_field() == pkt_reg_index);
CPPUNIT_ASSERT(oxm.get_oxm_hasmask() == true);
CPPUNIT_ASSERT(oxm.get_oxm_type() ==
(uint32_t)((rofl::openflow::OFPXMC_PACKET_REGS << 16) |
(pkt_reg_index << 9)));
CPPUNIT_ASSERT(oxm.get_u64value() == value);
CPPUNIT_ASSERT(oxm.get_u64mask() == mask);
CPPUNIT_ASSERT(oxm.get_u64masked_value() == (value & mask));
}


@@ -13,6 +13,7 @@

#include "rofl/common/cmemory.h"
#include "rofl/common/openflow/coxmatch.h"
#include "rofl/common/openflow/extensions/matches/ext244_matches.h"

class coxmatchtest : public CppUnit::TestFixture {
CPPUNIT_TEST_SUITE(coxmatchtest);
@@ -40,6 +41,8 @@ class coxmatchtest : public CppUnit::TestFixture {
CPPUNIT_TEST(testExp32);
CPPUNIT_TEST(testExp48);
CPPUNIT_TEST(testExp64);
CPPUNIT_TEST(test_ext244_pkt_reg);
CPPUNIT_TEST(test_ext244_pkt_reg_mask);
CPPUNIT_TEST_SUITE_END();

public:
@@ -75,6 +78,9 @@ class coxmatchtest : public CppUnit::TestFixture {
void testExp48();
void testExp64();

void test_ext244_pkt_reg();
void test_ext244_pkt_reg_mask();

private:
uint32_t oxm_id_exp;
uint32_t exp_id;

0 comments on commit 764b5b2

Please sign in to comment.
You can’t perform that action at this time.