42 min_body = max_body =
sizeof(ofp_flow_stats_request);
45 min_body = max_body =
sizeof(ofp_aggregate_stats_request);
55 case OFPST_PORT_TABLE:
62 if ((min_body != 0 || max_body != 0) && (body_len < min_body || body_len > max_body))
64 NS_LOG_ERROR(
"stats request type " <<
type <<
" with bad body length " << body_len);
84 case OFPST_PORT_TABLE:
94 Stats::DoDump(Ptr<OpenFlowSwitchNetDevice> swtch,
void* state, ofpbuf* buffer)
102 case OFPST_AGGREGATE:
108 case OFPST_PORT_TABLE:
125 free((FlowStatsState*)state);
127 case OFPST_AGGREGATE:
128 free((ofp_aggregate_stats_request*)state);
133 free(((PortStatsState*)state)->ports);
134 free((PortStatsState*)state);
136 case OFPST_PORT_TABLE:
146 ofp_desc_stats* ods = (ofp_desc_stats*)ofpbuf_put_zeros(buffer,
sizeof *ods);
147 strncpy(ods->mfr_desc,
149 sizeof ods->mfr_desc);
156 #define MAX_FLOW_STATS_BYTES 4096
161 const ofp_flow_stats_request* fsr = (ofp_flow_stats_request*)body;
162 FlowStatsState* s = (FlowStatsState*)xmalloc(
sizeof *s);
164 s->table_idx = fsr->table_id == 0xff ? 0 : fsr->table_id;
165 memset(&s->position, 0,
sizeof s->position);
172 Stats_FlowDumpCallback(sw_flow* flow,
void* state)
174 Stats::FlowStatsState* s = (Stats::FlowStatsState*)state;
178 int length =
sizeof *ofs + flow->sf_acts->actions_len;
179 ofs = (ofp_flow_stats*)ofpbuf_put_zeros(s->buffer, length);
180 ofs->length = htons(length);
181 ofs->table_id = s->table_idx;
182 ofs->match.wildcards = htonl(flow->key.wildcards);
183 ofs->match.in_port = flow->key.flow.in_port;
184 memcpy(ofs->match.dl_src, flow->key.flow.dl_src, ETH_ADDR_LEN);
185 memcpy(ofs->match.dl_dst, flow->key.flow.dl_dst, ETH_ADDR_LEN);
186 ofs->match.dl_vlan = flow->key.flow.dl_vlan;
187 ofs->match.dl_type = flow->key.flow.dl_type;
188 ofs->match.nw_src = flow->key.flow.nw_src;
189 ofs->match.nw_dst = flow->key.flow.nw_dst;
190 ofs->match.nw_proto = flow->key.flow.nw_proto;
191 ofs->match.tp_src = flow->key.flow.tp_src;
192 ofs->match.tp_dst = flow->key.flow.tp_dst;
193 ofs->duration = htonl(s->now - flow->created);
194 ofs->priority = htons(flow->priority);
195 ofs->idle_timeout = htons(flow->idle_timeout);
196 ofs->hard_timeout = htons(flow->hard_timeout);
197 ofs->packet_count = htonll(flow->packet_count);
198 ofs->byte_count = htonll(flow->byte_count);
199 memcpy(ofs->actions, flow->sf_acts->actions, flow->sf_acts->actions_len);
201 return s->buffer->size >= MAX_FLOW_STATS_BYTES;
207 sw_flow_key match_key;
209 flow_extract_match(&match_key, &s->rq.match);
213 while (s->table_idx < swtch->GetChain()->n_tables &&
214 (s->rq.table_id == 0xff || s->rq.table_id == s->table_idx))
216 sw_table* table = swtch->GetChain()->tables[s->table_idx];
218 if (table->iterate(table,
229 memset(&s->position, 0,
sizeof s->position);
231 return s->buffer->size >= MAX_FLOW_STATS_BYTES;
238 *state = (ofp_aggregate_stats_request*)body;
243 Stats_AggregateDumpCallback(sw_flow* flow,
void* state)
245 ofp_aggregate_stats_reply* s = (ofp_aggregate_stats_reply*)state;
246 s->packet_count += flow->packet_count;
247 s->byte_count += flow->byte_count;
254 ofp_aggregate_stats_request* s,
257 ofp_aggregate_stats_request* rq = s;
258 ofp_aggregate_stats_reply* rpy =
259 (ofp_aggregate_stats_reply*)ofpbuf_put_zeros(buffer,
sizeof *rpy);
260 sw_flow_key match_key;
261 flow_extract_match(&match_key, &rq->match);
262 int table_idx = rq->table_id == 0xff ? 0 : rq->table_id;
264 sw_table_position position;
265 memset(&position, 0,
sizeof position);
267 while (table_idx < swtch->GetChain()->n_tables &&
268 (rq->table_id == 0xff || rq->table_id == table_idx))
270 sw_table* table = swtch->GetChain()->tables[table_idx];
271 int error = table->iterate(table,
283 memset(&position, 0,
sizeof position);
286 rpy->packet_count = htonll(rpy->packet_count);
287 rpy->byte_count = htonll(rpy->byte_count);
288 rpy->flow_count = htonl(rpy->flow_count);
295 sw_chain* ft = swtch->GetChain();
296 for (
int i = 0; i < ft->n_tables; i++)
298 ofp_table_stats* ots = (ofp_table_stats*)ofpbuf_put_zeros(buffer,
sizeof *ots);
299 sw_table_stats stats;
300 ft->tables[i]->stats(ft->tables[i], &stats);
301 strncpy(ots->name, stats.name,
sizeof ots->name);
303 ots->wildcards = htonl(stats.wildcards);
304 ots->max_entries = htonl(stats.max_flows);
305 ots->active_count = htonl(stats.n_flows);
306 ots->lookup_count = htonll(stats.n_lookup);
307 ots->matched_count = htonll(stats.n_matched);
316 ofp_vport_table_stats* opts = (ofp_vport_table_stats*)ofpbuf_put_zeros(buffer,
sizeof *opts);
317 opts->max_vports = htonl(swtch->GetVPortTable().max_vports);
318 opts->active_vports = htonl(swtch->GetVPortTable().active_vports);
319 opts->lookup_count = htonll(swtch->GetVPortTable().lookup_count);
320 opts->port_match_count = htonll(swtch->GetVPortTable().port_match_count);
321 opts->chain_match_count = htonll(swtch->GetVPortTable().chain_match_count);
329 PortStatsState* s = (PortStatsState*)xmalloc(
sizeof *s);
332 s->ports = (uint32_t*)xmalloc(body_len);
333 memcpy(s->ports, body, body_len);
334 s->num_ports = body_len /
sizeof(uint32_t);
347 for (
size_t i = 0; i < s->num_ports; i++)
349 port = ntohl(s->ports[i]);
351 if (
port <= OFPP_MAX)
353 Port p = swtch->GetSwitchPort(
port);
360 ops = (ofp_port_stats*)ofpbuf_put_zeros(buffer,
sizeof *ops);
361 ops->port_no = htonl(swtch->GetSwitchPortIndex(p));
362 ops->rx_packets = htonll(p.rx_packets);
363 ops->tx_packets = htonll(p.tx_packets);
364 ops->rx_bytes = htonll(p.rx_bytes);
365 ops->tx_bytes = htonll(p.tx_bytes);
366 ops->rx_dropped = htonll(-1);
367 ops->tx_dropped = htonll(p.tx_dropped);
368 ops->rx_errors = htonll(-1);
369 ops->tx_errors = htonll(-1);
370 ops->rx_frame_err = htonll(-1);
371 ops->rx_over_err = htonll(-1);
372 ops->rx_crc_err = htonll(-1);
373 ops->collisions = htonll(-1);
374 ops->mpls_ttl0_dropped = htonll(p.mpls_ttl0_dropped);
377 else if (
port >= OFPP_VP_START &&
port <= OFPP_VP_END)
380 vport_table_t vt = swtch->GetVPortTable();
381 vport_table_entry* vpe = vport_table_lookup(&vt,
port);
388 ops = (ofp_port_stats*)ofpbuf_put_zeros(buffer,
sizeof *ops);
389 ops->port_no = htonl(vpe->vport);
390 ops->rx_packets = htonll(-1);
391 ops->tx_packets = htonll(vpe->packet_count);
392 ops->rx_bytes = htonll(-1);
393 ops->tx_bytes = htonll(vpe->byte_count);
394 ops->rx_dropped = htonll(-1);
395 ops->tx_dropped = htonll(-1);
396 ops->rx_errors = htonll(-1);
397 ops->tx_errors = htonll(-1);
398 ops->rx_frame_err = htonll(-1);
399 ops->rx_over_err = htonll(-1);
400 ops->rx_crc_err = htonll(-1);
401 ops->collisions = htonll(-1);
402 ops->mpls_ttl0_dropped = htonll(-1);
415 case OFPAT_SET_VLAN_VID:
416 case OFPAT_SET_VLAN_PCP:
417 case OFPAT_STRIP_VLAN:
418 case OFPAT_SET_DL_SRC:
419 case OFPAT_SET_DL_DST:
420 case OFPAT_SET_NW_SRC:
421 case OFPAT_SET_NW_DST:
422 case OFPAT_SET_TP_SRC:
423 case OFPAT_SET_TP_DST:
424 case OFPAT_SET_MPLS_LABEL:
425 case OFPAT_SET_MPLS_EXP:
435 const sw_flow_key* key,
436 const ofp_action_header* ah)
443 if (len !=
sizeof(ofp_action_output))
445 return OFPBAC_BAD_LEN;
448 ofp_action_output* oa = (ofp_action_output*)ah;
453 if (oa->port == OFPP_NONE || oa->port == key->flow.in_port)
455 return OFPBAC_BAD_OUT_PORT;
458 return ACT_VALIDATION_OK;
460 case OFPAT_SET_VLAN_VID:
461 size =
sizeof(ofp_action_vlan_vid);
463 case OFPAT_SET_VLAN_PCP:
464 size =
sizeof(ofp_action_vlan_pcp);
466 case OFPAT_STRIP_VLAN:
467 size =
sizeof(ofp_action_header);
469 case OFPAT_SET_DL_SRC:
470 case OFPAT_SET_DL_DST:
471 size =
sizeof(ofp_action_dl_addr);
473 case OFPAT_SET_NW_SRC:
474 case OFPAT_SET_NW_DST:
475 size =
sizeof(ofp_action_nw_addr);
477 case OFPAT_SET_TP_SRC:
478 case OFPAT_SET_TP_DST:
479 size =
sizeof(ofp_action_tp_port);
481 case OFPAT_SET_MPLS_LABEL:
482 size =
sizeof(ofp_action_mpls_label);
484 case OFPAT_SET_MPLS_EXP:
485 size =
sizeof(ofp_action_mpls_exp);
493 return OFPBAC_BAD_LEN;
495 return ACT_VALIDATION_OK;
499 Action::Execute(ofp_action_type
type, ofpbuf* buffer, sw_flow_key* key,
const ofp_action_header* ah)
505 case OFPAT_SET_VLAN_VID:
508 case OFPAT_SET_VLAN_PCP:
511 case OFPAT_STRIP_VLAN:
514 case OFPAT_SET_DL_SRC:
515 case OFPAT_SET_DL_DST:
518 case OFPAT_SET_NW_SRC:
519 case OFPAT_SET_NW_DST:
522 case OFPAT_SET_TP_SRC:
523 case OFPAT_SET_TP_DST:
526 case OFPAT_SET_MPLS_LABEL:
529 case OFPAT_SET_MPLS_EXP:
542 case OFPPAT_POP_MPLS:
543 case OFPPAT_PUSH_MPLS:
544 case OFPPAT_SET_MPLS_LABEL:
545 case OFPPAT_SET_MPLS_EXP:
559 case OFPPAT_POP_MPLS:
560 size =
sizeof(ofp_vport_action_pop_mpls);
562 case OFPPAT_PUSH_MPLS:
563 size =
sizeof(ofp_vport_action_push_mpls);
565 case OFPPAT_SET_MPLS_LABEL:
566 size =
sizeof(ofp_vport_action_set_mpls_label);
568 case OFPPAT_SET_MPLS_EXP:
569 size =
sizeof(ofp_vport_action_set_mpls_exp);
577 return OFPBAC_BAD_LEN;
579 return ACT_VALIDATION_OK;
585 const sw_flow_key* key,
586 const ofp_action_header* ah)
590 case OFPPAT_POP_MPLS: {
591 ofp_vport_action_pop_mpls* opapm = (ofp_vport_action_pop_mpls*)ah;
592 pop_mpls_act(
nullptr, buffer, key, &opapm->apm);
595 case OFPPAT_PUSH_MPLS: {
596 ofp_vport_action_push_mpls* opapm = (ofp_vport_action_push_mpls*)ah;
597 push_mpls_act(
nullptr, buffer, key, &opapm->apm);
600 case OFPPAT_SET_MPLS_LABEL: {
601 ofp_vport_action_set_mpls_label* oparml = (ofp_vport_action_set_mpls_label*)ah;
602 set_mpls_label_act(buffer, key, oparml->label_out);
605 case OFPPAT_SET_MPLS_EXP: {
606 ofp_vport_action_set_mpls_exp* oparme = (ofp_vport_action_set_mpls_exp*)ah;
607 set_mpls_exp_act(buffer, key, oparme->exp);
636 size =
sizeof(er_action_pop_mpls);
639 size =
sizeof(er_action_push_mpls);
647 return OFPBAC_BAD_LEN;
649 return ACT_VALIDATION_OK;
655 const sw_flow_key* key,
656 const er_action_header* ah)
660 case ERXT_POP_MPLS: {
661 er_action_pop_mpls* erapm = (er_action_pop_mpls*)ah;
662 pop_mpls_act(
nullptr, buffer, key, &erapm->apm);
665 case ERXT_PUSH_MPLS: {
666 er_action_push_mpls* erapm = (er_action_push_mpls*)ah;
667 push_mpls_act(
nullptr, buffer, key, &erapm->apm);
679 static TypeId tid = TypeId(
"ns3::ofi::Controller")
681 .SetGroupName(
"OpenFlow")
682 .AddConstructor<Controller>();
696 NS_LOG_INFO(
"This Controller has already registered this switch!");
709 NS_LOG_ERROR(
"Can't send to this switch, not registered to the Controller.");
713 swtch->ForwardControlInput(msg, length);
725 ofp_flow_mod* ofm = (ofp_flow_mod*)malloc(
sizeof(ofp_flow_mod) + actions_len);
726 ofm->header.version = OFP_VERSION;
727 ofm->header.type = OFPT_FLOW_MOD;
728 ofm->header.length = htons(
sizeof(ofp_flow_mod) + actions_len);
729 ofm->command = htons(command);
730 ofm->idle_timeout = htons(idle_timeout);
731 ofm->hard_timeout = htons(hard_timeout);
732 ofm->buffer_id = htonl(buffer_id);
733 ofm->priority = OFP_DEFAULT_PRIORITY;
734 memcpy(ofm->actions, acts, actions_len);
736 ofm->match.wildcards = key.wildcards;
737 ofm->match.in_port = key.flow.in_port;
738 memcpy(ofm->match.dl_src,
740 sizeof ofm->match.dl_src);
741 memcpy(ofm->match.dl_dst,
743 sizeof ofm->match.dl_dst);
744 ofm->match.dl_vlan = key.flow.dl_vlan;
745 ofm->match.dl_type = key.flow.dl_type;
746 ofm->match.nw_proto = key.flow.nw_proto;
747 ofm->match.nw_src = key.flow.nw_src;
748 ofm->match.nw_dst = key.flow.nw_dst;
749 ofm->match.tp_src = key.flow.tp_src;
750 ofm->match.tp_dst = key.flow.tp_dst;
751 ofm->match.mpls_label1 = key.flow.mpls_label1;
752 ofm->match.mpls_label2 =
753 key.flow.mpls_label1;
761 ofp_header* hdr = (ofp_header*)ofpbuf_try_pull(buffer,
sizeof(ofp_header));
762 uint8_t
type = hdr->type;
763 ofpbuf_push_uninit(buffer,
sizeof(ofp_header));
775 error = cb->swtch->StatsDump(cb);
780 NS_LOG_WARN(
"Dump Callback Error: " << strerror(-error));
784 cb->swtch->StatsDone(cb);
792 static TypeId tid = TypeId(
"ns3::ofi::DropController")
794 .SetGroupName(
"OpenFlow")
804 NS_LOG_ERROR(
"Can't receive from this switch, not registered to the Controller.");
812 if (
type == OFPT_PACKET_IN)
815 ofp_packet_in* opi = (ofp_packet_in*)ofpbuf_try_pull(buffer, offsetof(ofp_packet_in,
data));
816 int port = ntohs(opi->in_port);
821 flow_extract(buffer,
port != -1 ?
port : OFPP_NONE, &key.flow);
838 TypeId(
"ns3::ofi::LearningController")
840 .SetGroupName(
"Openflow")
842 .AddAttribute(
"ExpirationTime",
843 "Time it takes for learned MAC state entry/created flow to expire.",
855 NS_LOG_ERROR(
"Can't receive from this switch, not registered to the Controller.");
863 if (
type == OFPT_PACKET_IN)
866 ofp_packet_in* opi = (ofp_packet_in*)ofpbuf_try_pull(buffer, offsetof(ofp_packet_in,
data));
867 int port = ntohs(opi->in_port);
872 flow_extract(buffer,
port != -1 ?
port : OFPP_NONE, &key.flow);
874 uint16_t out_port = OFPP_FLOOD;
875 uint16_t in_port = ntohs(key.flow.in_port);
878 Mac48Address dst_addr;
879 dst_addr.CopyFrom(key.flow.dl_dst);
880 if (!dst_addr.IsBroadcast())
882 LearnState_t::iterator st =
m_learnState.find(dst_addr);
885 out_port = st->second.port;
889 NS_LOG_INFO(
"Setting to flood; don't know yet what port " << dst_addr
890 <<
" is connected to");
895 NS_LOG_INFO(
"Setting to flood; this packet is a broadcast");
899 ofp_action_output
x[1];
900 x[0].type = htons(OFPAT_OUTPUT);
901 x[0].len = htons(
sizeof(ofp_action_output));
902 x[0].port = out_port;
917 Mac48Address src_addr;
918 src_addr.CopyFrom(key.flow.dl_src);
919 LearnState_t::iterator st =
m_learnState.find(src_addr);
925 NS_LOG_INFO(
"Learned that " << src_addr <<
" can be found over port " << in_port);
928 ofp_action_output x2[1];
929 x2[0].type = htons(OFPAT_OUTPUT);
930 x2[0].len = htons(
sizeof(ofp_action_output));
931 x2[0].port = in_port;
934 src_addr.CopyTo(key.flow.dl_dst);
935 dst_addr.CopyTo(key.flow.dl_src);
936 key.flow.in_port = out_port;
955 const ofp_action_header* actions,
966 uint16_t in_port = key->flow.in_port;
967 uint8_t* p = (uint8_t*)actions;
971 if (actions_len == 0)
973 NS_LOG_INFO(
"No actions set to this flow. Dropping packet.");
979 while (actions_len > 0)
981 ofp_action_header* ah = (ofp_action_header*)p;
982 size_t len = htons(ah->len);
986 swtch->DoOutput(packet_uid, in_port, max_len, prev_port, ignore_no_fwd);
990 if (ah->type == htons(OFPAT_OUTPUT))
992 ofp_action_output* oa = (ofp_action_output*)p;
995 prev_port = oa->port;
997 max_len = ntohs(oa->max_len);
1001 uint16_t
type = ntohs(ah->type);
1003 (ofp_action_type)
type))
1007 else if (
type == OFPAT_VENDOR)
1017 if (prev_port != -1)
1019 swtch->DoOutput(packet_uid, in_port, max_len, prev_port, ignore_no_fwd);
1024 ValidateActions(
const sw_flow_key* key,
const ofp_action_header* actions,
size_t actions_len)
1026 uint8_t* p = (uint8_t*)actions;
1029 while (actions_len >=
sizeof(ofp_action_header))
1031 ofp_action_header* ah = (ofp_action_header*)p;
1032 size_t len = ntohs(ah->len);
1037 if ((actions_len < len) || (len % 8) != 0)
1039 return OFPBAC_BAD_LEN;
1042 type = ntohs(ah->type);
1046 if (err != ACT_VALIDATION_OK)
1051 else if (
type == OFPAT_VENDOR)
1054 if (err != ACT_VALIDATION_OK)
1061 return OFPBAC_BAD_TYPE;
1069 if (actions_len != 0)
1071 return OFPBAC_BAD_LEN;
1074 return ACT_VALIDATION_OK;
1079 uint64_t packet_uid,
1082 const ofp_action_header* actions,
1091 uint16_t in_port = ntohs(key->flow.in_port);
1092 uint8_t* p = (uint8_t*)actions;
1094 ofp_action_output* oa;
1099 while (actions_len > 0)
1101 ofp_action_header* ah = (ofp_action_header*)p;
1102 size_t len = htons(ah->len);
1103 if (prev_port != -1)
1105 swtch->DoOutput(packet_uid, in_port, max_len, prev_port,
false);
1109 if (ah->type == htons(OFPAT_OUTPUT))
1111 oa = (ofp_action_output*)p;
1112 prev_port = ntohl(oa->port);
1113 max_len = ntohs(oa->max_len);
1125 if (prev_port != -1)
1127 swtch->DoOutput(packet_uid, in_port, max_len, prev_port,
false);
1134 uint8_t* p = (uint8_t*)actions;
1137 while (actions_len >=
sizeof(ofp_action_header))
1139 ofp_action_header* ah = (ofp_action_header*)p;
1140 size_t len = ntohs(ah->len);
1145 if ((actions_len < len) || (len % 8) != 0)
1147 return OFPBAC_BAD_LEN;
1150 type = ntohs(ah->type);
1152 (ofp_vport_action_type)
type))
1155 if (err != ACT_VALIDATION_OK)
1162 return OFPBAC_BAD_TYPE;
1170 if (actions_len != 0)
1172 return OFPBAC_BAD_LEN;
1175 return ACT_VALIDATION_OK;
1179 ExecuteVendor(ofpbuf* buffer,
const sw_flow_key* key,
const ofp_action_header* ah)
1181 ofp_action_vendor_header* avh = (ofp_action_vendor_header*)ah;
1183 switch (ntohl(avh->vendor))
1188 case ER_VENDOR_ID: {
1189 const er_action_header* erah = (
const er_action_header*)avh;
1195 NS_LOG_INFO(
"attempt to execute action with unknown vendor: " << ntohl(avh->vendor));
1201 ValidateVendor(
const sw_flow_key* key,
const ofp_action_header* ah, uint16_t len)
1203 ofp_action_vendor_header* avh;
1204 int ret = ACT_VALIDATION_OK;
1206 if (len <
sizeof(ofp_action_vendor_header))
1208 return OFPBAC_BAD_LEN;
1211 avh = (ofp_action_vendor_header*)ah;
1213 switch (ntohl(avh->vendor))
1216 ret = OFPBAC_BAD_VENDOR_TYPE;
1220 const er_action_header* erah = (
const er_action_header*)avh;
1225 return OFPBAC_BAD_VENDOR;
static const char * GetSerialNumber()
static const char * GetSoftwareDescription()
static const char * GetManufacturerDescription()
static const char * GetHardwareDescription()
double GetSeconds() const
Get an approximation of the time stored in this instance in the indicated unit.
bool IsZero() const
Exactly equivalent to t == 0.
TypeId AddConstructor()
Record in this TypeId the fact that the default constructor is accessible.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
uint8_t GetPacketType(ofpbuf *buffer)
Get the packet type on the buffer, which can then be used to determine how to handle the buffer.
Switches_t m_switches
The collection of switches registered to this controller.
~Controller() override
Destructor.
virtual void SendToSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, void *msg, size_t length)
However the controller is implemented, this method is to be used to pass a message on to a switch.
ofp_flow_mod * BuildFlow(sw_flow_key key, uint32_t buffer_id, uint16_t command, void *acts, size_t actions_len, int idle_timeout, int hard_timeout)
Construct flow data from a matching key to build a flow entry for adding, modifying,...
void StartDump(StatsDumpCallback *cb)
Starts a callback-based, reliable, possibly multi-message reply to a request made by the controller.
static TypeId GetTypeId()
Register this type.
virtual void AddSwitch(Ptr< OpenFlowSwitchNetDevice > swtch)
Adds a switch to the controller.
void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer) override
A switch calls this method to pass a message on to the Controller.
static TypeId GetTypeId()
Register this type.
static TypeId GetTypeId()
Register this type.
void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer) override
A switch calls this method to pass a message on to the Controller.
Time m_expirationTime
Time it takes for learned MAC state entry/created flow to expire.
LearnState_t m_learnState
Learned state data.
int PortStatsInit(const void *body, int body_len, void **state)
Initialize the stats.
int PortTableStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, void *state, ofpbuf *buffer)
Dump the stats.
int FlowStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, FlowStatsState *state, ofpbuf *buffer)
Dump the stats.
int(* AggregateDumpCallback)(sw_flow *flow, void *state)
Aggregate dump callback functor.
Stats(ofp_stats_types _type, size_t body_len)
Constructor.
void DoCleanup(void *state)
Cleans any state created by the init or dump functions.
int AggregateStatsInit(const void *body, int body_len, void **state)
Initialize the stats.
int DoDump(Ptr< OpenFlowSwitchNetDevice > swtch, void *state, ofpbuf *buffer)
Appends statistics for OpenFlowSwitchNetDevice to 'buffer'.
int DoInit(const void *body, int body_len, void **state)
Prepares to dump some kind of statistics on the connected OpenFlowSwitchNetDevice.
int AggregateStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, ofp_aggregate_stats_request *state, ofpbuf *buffer)
Dump the stats.
int TableStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, void *state, ofpbuf *buffer)
Dump the stats.
int PortStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, PortStatsState *state, ofpbuf *buffer)
Dump the stats.
ofp_stats_types type
Status type.
int FlowStatsInit(const void *body, int body_len, void **state)
Initialize the stats.
int DescStatsDump(void *state, ofpbuf *buffer)
Dumps the stats description.
int(* FlowDumpCallback)(sw_flow *flow, void *state)
Flow dump callback functor.
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method.
#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_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Time Seconds(double value)
Construct a Time in the indicated unit.
void ExecuteVPortActions(Ptr< OpenFlowSwitchNetDevice > swtch, uint64_t packet_uid, ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *actions, size_t actions_len)
Executes a list of virtual port table entry actions.
void ExecuteActions(Ptr< OpenFlowSwitchNetDevice > swtch, uint64_t packet_uid, ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *actions, size_t actions_len, int ignore_no_fwd)
Executes a list of flow table actions.
uint16_t ValidateVendor(const sw_flow_key *key, const ofp_action_header *ah, uint16_t len)
Validates a vendor-defined action.
void ExecuteVendor(ofpbuf *buffer, const sw_flow_key *key, const ofp_action_header *ah)
Executes a vendor-defined action.
uint16_t ValidateActions(const sw_flow_key *key, const ofp_action_header *actions, size_t actions_len)
Validates a list of flow table actions.
uint16_t ValidateVPortActions(const ofp_action_header *actions, size_t actions_len)
Validates a list of virtual port table entry actions.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
time_t time_now(void)
Overriding BOFUSS time_now weak function from timeval.c.
void strip_vlan(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_mpls_label(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_dl_addr(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_nw_addr(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_vlan_pcp(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_tp_port(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_mpls_exp(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
void set_vlan_vid(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
static bool IsValidType(ofp_action_type type)
static uint16_t Validate(ofp_action_type type, size_t len, const sw_flow_key *key, const ofp_action_header *ah)
Validates the action on whether its data is valid or not.
static void Execute(ofp_action_type type, ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
Executes the action.
static bool IsValidType(er_action_type type)
static uint16_t Validate(er_action_type type, size_t len)
Validates the action on whether its data is valid or not.
static void Execute(er_action_type type, ofpbuf *buffer, const sw_flow_key *key, const er_action_header *ah)
Executes the action.
static uint16_t Validate(ofp_vport_action_type type, size_t len, const ofp_action_header *ah)
Validates the action on whether its data is valid or not.
static bool IsValidType(ofp_vport_action_type type)
static void Execute(ofp_vport_action_type type, ofpbuf *buffer, const sw_flow_key *key, const ofp_action_header *ah)
Executes the action.