From dc618adf8daa4dfe421f2f68f00a3a7b13f86ad8 Mon Sep 17 00:00:00 2001 From: Gal Sagie Date: Thu, 20 Jul 2017 13:51:52 +0300 Subject: [PATCH] Add MPLS push module --- bessctl/conf/samples/mpls_push.bess | 11 ++++++ core/modules/mpls_push.cc | 52 +++++++++++++++++++++++++++++ core/modules/mpls_push.h | 29 ++++++++++++++++ protobuf/module_msg.proto | 13 ++++++++ 4 files changed, 105 insertions(+) create mode 100644 bessctl/conf/samples/mpls_push.bess create mode 100644 core/modules/mpls_push.cc create mode 100644 core/modules/mpls_push.h diff --git a/bessctl/conf/samples/mpls_push.bess b/bessctl/conf/samples/mpls_push.bess new file mode 100644 index 000000000..0890ec657 --- /dev/null +++ b/bessctl/conf/samples/mpls_push.bess @@ -0,0 +1,11 @@ +import scapy.all as scapy + +eth = scapy.Ether(src='02:1e:67:9f:4d:ae', dst='06:16:3e:1b:72:32') +ip = scapy.IP(src='192.168.0.1', dst='10.0.0.1') +udp = scapy.UDP(sport=10001, dport=10002) +test_packet = bytes(eth/ip/udp) + +mpls_push::MPLSPush() +mpls_push.set(label=7, ttl=64, tc=0, is_bottom_of_stack=True) + +Source() -> Rewrite(templates=[test_packet]) -> mpls_push -> Sink() diff --git a/core/modules/mpls_push.cc b/core/modules/mpls_push.cc new file mode 100644 index 000000000..8064d8f16 --- /dev/null +++ b/core/modules/mpls_push.cc @@ -0,0 +1,52 @@ +#include "mpls_push.h" + +#include "../utils/endian.h" +#include "../utils/ether.h" +#include "../utils/mpls.h" + +using bess::utils::Ethernet; +using bess::utils::be16_t; +using bess::utils::Mpls; + +const Commands MPLSPush::cmds = {{"set", "MplsPushArg", + MODULE_CMD_FUNC(&MPLSPush::CommandSet), + Command::THREAD_UNSAFE}}; + +MPLSPush::MPLSPush() : label_(0), ttl_(64), tc_(0), is_bottom_of_stack_(true) {} + + +CommandResponse MPLSPush::Init(const bess::pb::MplsPushArg &arg) { + return CommandSet(arg); +} + +void MPLSPush::ProcessBatch(bess::PacketBatch *batch) { + int cnt = batch->cnt(); + for (int i = 0; i < cnt; i++) { + bess::Packet *pkt = batch->pkts()[i]; + Ethernet *eth = pkt->head_data(); + + Ethernet::Address src_addr = eth->src_addr; + Ethernet::Address dst_addr = eth->dst_addr; + + pkt->prepend(4); + eth = pkt->head_data(); + eth->src_addr = src_addr; + eth->dst_addr = dst_addr; + eth->ether_type = be16_t(Ethernet::Type::kMpls); + + Mpls *mpls_hdr = reinterpret_cast(eth + 1); + mpls_hdr->SetEntry(label_, ttl_, tc_, is_bottom_of_stack_); + } + + RunNextModule(batch); +} + +CommandResponse MPLSPush::CommandSet(const bess::pb::MplsPushArg &arg) { + label_ = arg.label(); + ttl_ = arg.ttl(); + is_bottom_of_stack_ = arg.is_bottom_of_stack(); + tc_ = arg.tc(); + return CommandSuccess(); +} + +ADD_MODULE(MPLSPush, "mpls_push", "Push MPLS label") diff --git a/core/modules/mpls_push.h b/core/modules/mpls_push.h new file mode 100644 index 000000000..958cef6df --- /dev/null +++ b/core/modules/mpls_push.h @@ -0,0 +1,29 @@ +#ifndef BESS_MODULES_MPLSPUSH_H_ +#define BESS_MODULES_MPLSPUSH_H_ + +#include "../module.h" +#include "../module_msg.pb.h" + +class MPLSPush final : public Module { + public: + static const gate_idx_t kNumIGates = 1; + static const gate_idx_t kNumOGates = 1; + + static const Commands cmds; + + MPLSPush(); // constructor + + CommandResponse Init(const bess::pb::MplsPushArg &arg); + + void ProcessBatch(bess::PacketBatch *batch) override; + + CommandResponse CommandSet(const bess::pb::MplsPushArg &arg); + + private: + uint32_t label_; + uint8_t ttl_; + uint8_t tc_; + bool is_bottom_of_stack_; +}; + +#endif // BESS_MODULES_MPLSPUSH_H_ diff --git a/protobuf/module_msg.proto b/protobuf/module_msg.proto index ae89926e0..1fb742ca2 100644 --- a/protobuf/module_msg.proto +++ b/protobuf/module_msg.proto @@ -995,3 +995,16 @@ message MplsPopArg { bool remove_eth_header = 1; // Remove ETH header with the pop uint32 next_eth_type = 2; /// The next ETH type to set } + +/** + * The MPLS push module adds MPLS label + * + * __Input Gates__: 1 + * __Output Gates__: 1 + */ +message MplsPushArg { + uint32 label = 1; + uint32 ttl = 2; + uint32 tc = 3; + bool is_bottom_of_stack = 4; +}