44 static TypeId tid = TypeId(
"ns3::OFSwitch13LearningController")
46 .SetGroupName(
"OFSwitch13")
62 Ptr<const RemoteSwitch> swtch,
67 static int prio = 100;
68 uint32_t outPort = OFPP_FLOOD;
69 enum ofp_packet_in_reason reason = msg->reason;
72 uint64_t swDpId = swtch->GetDpId();
75 ofl_structs_match_to_string((
struct ofl_match_header*)msg->match,
80 if (reason == OFPR_NO_MATCH)
84 size_t portLen = OXM_LENGTH(OXM_OF_IN_PORT);
85 struct ofl_match_tlv* input =
86 oxm_match_lookup(OXM_OF_IN_PORT, (
struct ofl_match*)msg->match);
87 memcpy(&inPort, input->value, portLen);
90 struct ofl_match_tlv* ethSrc =
91 oxm_match_lookup(OXM_OF_ETH_SRC, (
struct ofl_match*)msg->match);
92 src48.CopyFrom(ethSrc->value);
95 struct ofl_match_tlv* ethDst =
96 oxm_match_lookup(OXM_OF_ETH_DST, (
struct ofl_match*)msg->match);
97 dst48.CopyFrom(ethDst->value);
106 if (!dst48.IsBroadcast())
108 auto itDst = l2Table->find(dst48);
109 if (itDst != l2Table->end())
111 outPort = itDst->second;
115 NS_LOG_DEBUG(
"No L2 info for mac " << dst48 <<
". Flood.");
120 NS_ASSERT_MSG(!src48.IsBroadcast(),
"Invalid src broadcast addr");
121 auto itSrc = l2Table->find(src48);
122 if (itSrc == l2Table->end())
124 std::pair<Mac48Address, uint32_t> entry(src48, inPort);
125 auto ret = l2Table->insert(entry);
126 if (ret.second ==
false)
133 << src48 <<
" can be found at port "
139 std::ostringstream
cmd;
140 cmd <<
"flow-mod cmd=add,table=0,idle=10,flags=0x0001"
141 <<
",prio=" << ++prio <<
" eth_dst=" << src48
142 <<
" apply:output=" << inPort;
149 "Inconsistent L2 switching table");
154 NS_LOG_ERROR(
"No L2 table for this datapath id " << swDpId);
158 struct ofl_msg_packet_out reply;
159 reply.header.type = OFPT_PACKET_OUT;
160 reply.buffer_id = msg->buffer_id;
161 reply.in_port = inPort;
162 reply.data_length = 0;
163 reply.data =
nullptr;
165 if (msg->buffer_id == NO_BUFFER)
168 reply.data_length = msg->data_length;
169 reply.data = msg->data;
173 struct ofl_action_output* a = (
struct ofl_action_output*)xmalloc(
174 sizeof(
struct ofl_action_output));
175 a->header.type = OFPAT_OUTPUT;
179 reply.actions_num = 1;
180 reply.actions = (
struct ofl_action_header**)&a;
182 SendToSwitch(swtch, (
struct ofl_msg_header*)&reply, xid);
187 NS_LOG_WARN(
"This controller can't handle the packet. Unkwnon reason.");
191 ofl_msg_free((
struct ofl_msg_header*)msg,
nullptr);
197 struct ofl_msg_flow_removed* msg,
198 Ptr<const RemoteSwitch> swtch,
204 uint64_t swDpId = swtch->GetDpId();
206 NS_LOG_DEBUG(
"Flow entry expired. Removing from L2 switch table.");
211 struct ofl_match_tlv* ethSrc =
212 oxm_match_lookup(OXM_OF_ETH_DST,
213 (
struct ofl_match*)msg->stats->match);
214 mac48.CopyFrom(ethSrc->value);
217 auto itSrc = l2Table->find(mac48);
218 if (itSrc != l2Table->end())
220 l2Table->erase(itSrc);
225 ofl_msg_free_flow_removed(msg,
true,
nullptr);
236 uint64_t swDpId = swtch->GetDpId();
242 "flow-mod cmd=add,table=0,prio=0 "
243 "apply:output=ctrl:128");
252 std::pair<uint64_t, L2Table_t> entry(swDpId, l2Table);
254 if (ret.second ==
false)
OFSwitch13Controller()
Default constructor.
int SendToSwitch(Ptr< const RemoteSwitch > swtch, struct ofl_msg_header *msg, uint32_t xid=0)
Send a OFLib message to a registered switch.
int DpctlExecute(uint64_t dpId, const std::string textCmd)
Execute a dpctl command to interact with the remote switch.
void DoDispose() override
Destructor implementation.
ofl_err HandlePacketIn(struct ofl_msg_packet_in *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid) override
Handle packet-in messages sent from switch to this controller.
ofl_err HandleFlowRemoved(struct ofl_msg_flow_removed *msg, Ptr< const RemoteSwitch > swtch, uint32_t xid) override
Handle flow removed messages sent from switch to this controller.
DatapathMap_t m_learnedInfo
Switching information for all dapataths.
OFSwitch13LearningController()
Default constructor.
void HandshakeSuccessful(Ptr< const RemoteSwitch > swtch) override
Function invoked after a successfully handshake procedure between this controller and a remote switch...
void DoDispose() override
Destructor implementation.
static TypeId GetTypeId()
Register this type.
std::map< Mac48Address, uint32_t > L2Table_t
L2SwitchingTable: map MacAddress to port.
~OFSwitch13LearningController() override
Dummy destructor.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Every class exported by the ns3 library is enclosed in the ns3 namespace.