32 size_t min_body = 0, max_body = 0;
39 min_body = max_body =
sizeof(ofp_flow_stats_request);
42 min_body = max_body =
sizeof(ofp_aggregate_stats_request);
50 case OFPST_PORT_TABLE:
57 if ((min_body != 0 || max_body != 0) && (body_len < min_body || body_len > max_body))
59 NS_LOG_ERROR (
"stats request type " <<
type <<
" with bad body length " << body_len);
79 case OFPST_PORT_TABLE:
89 Stats::DoDump (Ptr<OpenFlowSwitchNetDevice> swtch,
void *state, ofpbuf *buffer)
96 return FlowStatsDump (swtch, (FlowStatsState *)state, buffer);
102 return PortStatsDump (swtch, (PortStatsState *)state, buffer);
103 case OFPST_PORT_TABLE:
120 free ((FlowStatsState *)state);
122 case OFPST_AGGREGATE:
123 free ((ofp_aggregate_stats_request *)state);
128 free (((PortStatsState *)state)->ports);
129 free ((PortStatsState *)state);
131 case OFPST_PORT_TABLE:
141 ofp_desc_stats *ods = (ofp_desc_stats*)ofpbuf_put_zeros (buffer,
sizeof *ods);
149 #define MAX_FLOW_STATS_BYTES 4096 154 const ofp_flow_stats_request *fsr = (ofp_flow_stats_request*)body;
155 FlowStatsState *s = (FlowStatsState*)xmalloc (
sizeof *s);
157 s->table_idx = fsr->table_id == 0xff ? 0 : fsr->table_id;
158 memset (&s->position, 0,
sizeof s->position);
165 Stats_FlowDumpCallback (sw_flow *flow,
void* state)
167 Stats::FlowStatsState *s = (Stats::FlowStatsState*)state;
171 int length =
sizeof *ofs + flow->sf_acts->actions_len;
172 ofs = (ofp_flow_stats*)ofpbuf_put_zeros (s->buffer, length);
173 ofs->length = htons (length);
174 ofs->table_id = s->table_idx;
175 ofs->match.wildcards = htonl (flow->key.wildcards);
176 ofs->match.in_port = flow->key.flow.in_port;
177 memcpy (ofs->match.dl_src, flow->key.flow.dl_src, ETH_ADDR_LEN);
178 memcpy (ofs->match.dl_dst, flow->key.flow.dl_dst, ETH_ADDR_LEN);
179 ofs->match.dl_vlan = flow->key.flow.dl_vlan;
180 ofs->match.dl_type = flow->key.flow.dl_type;
181 ofs->match.nw_src = flow->key.flow.nw_src;
182 ofs->match.nw_dst = flow->key.flow.nw_dst;
183 ofs->match.nw_proto = flow->key.flow.nw_proto;
184 ofs->match.tp_src = flow->key.flow.tp_src;
185 ofs->match.tp_dst = flow->key.flow.tp_dst;
186 ofs->duration = htonl (s->now - flow->created);
187 ofs->priority = htons (flow->priority);
188 ofs->idle_timeout = htons (flow->idle_timeout);
189 ofs->hard_timeout = htons (flow->hard_timeout);
190 ofs->packet_count = htonll (flow->packet_count);
191 ofs->byte_count = htonll (flow->byte_count);
192 memcpy (ofs->actions, flow->sf_acts->actions, flow->sf_acts->actions_len);
194 return s->buffer->size >= MAX_FLOW_STATS_BYTES;
200 sw_flow_key match_key;
202 flow_extract_match (&match_key, &s->rq.match);
205 s->now = time_now ();
206 while (s->table_idx < swtch->GetChain ()->n_tables
207 && (s->rq.table_id == 0xff || s->rq.table_id == s->table_idx))
209 sw_table *table = swtch->GetChain ()->tables[s->table_idx];
217 memset (&s->position, 0,
sizeof s->position);
219 return s->buffer->size >= MAX_FLOW_STATS_BYTES;
226 *state = (ofp_aggregate_stats_request*)body;
231 Stats_AggregateDumpCallback (sw_flow *flow,
void *state)
233 ofp_aggregate_stats_reply *s = (ofp_aggregate_stats_reply*)state;
234 s->packet_count += flow->packet_count;
235 s->byte_count += flow->byte_count;
243 ofp_aggregate_stats_request *rq = s;
244 ofp_aggregate_stats_reply *rpy = (ofp_aggregate_stats_reply*)ofpbuf_put_zeros (buffer,
sizeof *rpy);
245 sw_flow_key match_key;
246 flow_extract_match (&match_key, &rq->match);
247 int table_idx = rq->table_id == 0xff ? 0 : rq->table_id;
249 sw_table_position position;
250 memset (&position, 0,
sizeof position);
252 while (table_idx < swtch->GetChain ()->n_tables
253 && (rq->table_id == 0xff || rq->table_id == table_idx))
255 sw_table *table = swtch->GetChain ()->tables[table_idx];
263 memset (&position, 0,
sizeof position);
266 rpy->packet_count = htonll (rpy->packet_count);
267 rpy->byte_count = htonll (rpy->byte_count);
268 rpy->flow_count = htonl (rpy->flow_count);
275 sw_chain* ft = swtch->GetChain ();
276 for (
int i = 0; i < ft->n_tables; i++)
278 ofp_table_stats *ots = (ofp_table_stats*)ofpbuf_put_zeros (buffer,
sizeof *ots);
279 sw_table_stats stats;
280 ft->tables[i]->stats (ft->tables[i], &stats);
281 strncpy (ots->name, stats.name,
sizeof ots->name);
283 ots->wildcards = htonl (stats.wildcards);
284 ots->max_entries = htonl (stats.max_flows);
285 ots->active_count = htonl (stats.n_flows);
286 ots->lookup_count = htonll (stats.n_lookup);
287 ots->matched_count = htonll (stats.n_matched);
296 ofp_vport_table_stats *opts = (ofp_vport_table_stats*)ofpbuf_put_zeros (buffer,
sizeof *opts);
297 opts->max_vports = htonl (swtch->GetVPortTable ().max_vports);
298 opts->active_vports = htonl (swtch->GetVPortTable ().active_vports);
299 opts->lookup_count = htonll (swtch->GetVPortTable ().lookup_count);
300 opts->port_match_count = htonll (swtch->GetVPortTable ().port_match_count);
301 opts->chain_match_count = htonll (swtch->GetVPortTable ().chain_match_count);
309 PortStatsState *s = (PortStatsState*)xmalloc (
sizeof *s);
312 s->ports = (uint32_t*)xmalloc (body_len);
313 memcpy (s->ports, body, body_len);
314 s->num_ports = body_len /
sizeof(uint32_t);
327 for (
size_t i = 0; i < s->num_ports; i++)
329 port = ntohl (s->ports[i]);
331 if (
port <= OFPP_MAX)
333 Port p = swtch->GetSwitchPort (
port);
340 ops = (ofp_port_stats*)ofpbuf_put_zeros (buffer,
sizeof *ops);
341 ops->port_no = htonl (swtch->GetSwitchPortIndex (p));
342 ops->rx_packets = htonll (p.rx_packets);
343 ops->tx_packets = htonll (p.tx_packets);
344 ops->rx_bytes = htonll (p.rx_bytes);
345 ops->tx_bytes = htonll (p.tx_bytes);
346 ops->rx_dropped = htonll (-1);
347 ops->tx_dropped = htonll (p.tx_dropped);
348 ops->rx_errors = htonll (-1);
349 ops->tx_errors = htonll (-1);
350 ops->rx_frame_err = htonll (-1);
351 ops->rx_over_err = htonll (-1);
352 ops->rx_crc_err = htonll (-1);
353 ops->collisions = htonll (-1);
354 ops->mpls_ttl0_dropped = htonll (p.mpls_ttl0_dropped);
357 else if (
port >= OFPP_VP_START &&
port <= OFPP_VP_END)
360 vport_table_t vt = swtch->GetVPortTable ();
361 vport_table_entry *vpe = vport_table_lookup (&vt,
port);
368 ops = (ofp_port_stats*)ofpbuf_put_zeros (buffer,
sizeof *ops);
369 ops->port_no = htonl (vpe->vport);
370 ops->rx_packets = htonll (-1);
371 ops->tx_packets = htonll (vpe->packet_count);
372 ops->rx_bytes = htonll (-1);
373 ops->tx_bytes = htonll (vpe->byte_count);
374 ops->rx_dropped = htonll (-1);
375 ops->tx_dropped = htonll (-1);
376 ops->rx_errors = htonll (-1);
377 ops->tx_errors = htonll (-1);
378 ops->rx_frame_err = htonll (-1);
379 ops->rx_over_err = htonll (-1);
380 ops->rx_crc_err = htonll (-1);
381 ops->collisions = htonll (-1);
382 ops->mpls_ttl0_dropped = htonll (-1);
395 case OFPAT_SET_VLAN_VID:
396 case OFPAT_SET_VLAN_PCP:
397 case OFPAT_STRIP_VLAN:
398 case OFPAT_SET_DL_SRC:
399 case OFPAT_SET_DL_DST:
400 case OFPAT_SET_NW_SRC:
401 case OFPAT_SET_NW_DST:
402 case OFPAT_SET_TP_SRC:
403 case OFPAT_SET_TP_DST:
404 case OFPAT_SET_MPLS_LABEL:
405 case OFPAT_SET_MPLS_EXP:
413 Action::Validate (ofp_action_type type,
size_t len,
const sw_flow_key *key,
const ofp_action_header *ah)
421 if (len !=
sizeof(ofp_action_output))
423 return OFPBAC_BAD_LEN;
426 ofp_action_output *oa = (ofp_action_output *)ah;
431 if (oa->port == OFPP_NONE || oa->port == key->flow.in_port)
433 return OFPBAC_BAD_OUT_PORT;
436 return ACT_VALIDATION_OK;
438 case OFPAT_SET_VLAN_VID:
439 size =
sizeof(ofp_action_vlan_vid);
441 case OFPAT_SET_VLAN_PCP:
442 size =
sizeof(ofp_action_vlan_pcp);
444 case OFPAT_STRIP_VLAN:
445 size =
sizeof(ofp_action_header);
447 case OFPAT_SET_DL_SRC:
448 case OFPAT_SET_DL_DST:
449 size =
sizeof(ofp_action_dl_addr);
451 case OFPAT_SET_NW_SRC:
452 case OFPAT_SET_NW_DST:
453 size =
sizeof(ofp_action_nw_addr);
455 case OFPAT_SET_TP_SRC:
456 case OFPAT_SET_TP_DST:
457 size =
sizeof(ofp_action_tp_port);
459 case OFPAT_SET_MPLS_LABEL:
460 size =
sizeof(ofp_action_mpls_label);
462 case OFPAT_SET_MPLS_EXP:
463 size =
sizeof(ofp_action_mpls_exp);
471 return OFPBAC_BAD_LEN;
473 return ACT_VALIDATION_OK;
477 Action::Execute (ofp_action_type type, ofpbuf *buffer, sw_flow_key *key,
const ofp_action_header *ah)
483 case OFPAT_SET_VLAN_VID:
486 case OFPAT_SET_VLAN_PCP:
489 case OFPAT_STRIP_VLAN:
492 case OFPAT_SET_DL_SRC:
493 case OFPAT_SET_DL_DST:
496 case OFPAT_SET_NW_SRC:
497 case OFPAT_SET_NW_DST:
500 case OFPAT_SET_TP_SRC:
501 case OFPAT_SET_TP_DST:
504 case OFPAT_SET_MPLS_LABEL:
507 case OFPAT_SET_MPLS_EXP:
520 case OFPPAT_POP_MPLS:
521 case OFPPAT_PUSH_MPLS:
522 case OFPPAT_SET_MPLS_LABEL:
523 case OFPPAT_SET_MPLS_EXP:
537 case OFPPAT_POP_MPLS:
538 size =
sizeof(ofp_vport_action_pop_mpls);
540 case OFPPAT_PUSH_MPLS:
541 size =
sizeof(ofp_vport_action_push_mpls);
543 case OFPPAT_SET_MPLS_LABEL:
544 size =
sizeof(ofp_vport_action_set_mpls_label);
546 case OFPPAT_SET_MPLS_EXP:
547 size =
sizeof(ofp_vport_action_set_mpls_exp);
555 return OFPBAC_BAD_LEN;
557 return ACT_VALIDATION_OK;
561 VPortAction::Execute (ofp_vport_action_type type, ofpbuf *buffer,
const sw_flow_key *key,
const ofp_action_header *ah)
565 case OFPPAT_POP_MPLS:
567 ofp_vport_action_pop_mpls *opapm = (ofp_vport_action_pop_mpls *)ah;
568 pop_mpls_act (0, buffer, key, &opapm->apm);
571 case OFPPAT_PUSH_MPLS:
573 ofp_vport_action_push_mpls *opapm = (ofp_vport_action_push_mpls *)ah;
574 push_mpls_act (0, buffer, key, &opapm->apm);
577 case OFPPAT_SET_MPLS_LABEL:
579 ofp_vport_action_set_mpls_label *oparml = (ofp_vport_action_set_mpls_label *)ah;
580 set_mpls_label_act (buffer, key, oparml->label_out);
583 case OFPPAT_SET_MPLS_EXP:
585 ofp_vport_action_set_mpls_exp *oparme = (ofp_vport_action_set_mpls_exp *)ah;
586 set_mpls_exp_act (buffer, key, oparme->exp);
615 size =
sizeof(er_action_pop_mpls);
618 size =
sizeof(er_action_push_mpls);
626 return OFPBAC_BAD_LEN;
628 return ACT_VALIDATION_OK;
632 EricssonAction::Execute (er_action_type type, ofpbuf *buffer,
const sw_flow_key *key,
const er_action_header *ah)
638 er_action_pop_mpls *erapm = (er_action_pop_mpls *)ah;
639 pop_mpls_act (0, buffer, key, &erapm->apm);
644 er_action_push_mpls *erapm = (er_action_push_mpls *)ah;
645 push_mpls_act (0, buffer, key, &erapm->apm);
657 static TypeId tid = TypeId (
"ns3::ofi::Controller")
659 .SetGroupName (
"OpenFlow")
660 .AddConstructor<Controller> ()
675 NS_LOG_INFO (
"This Controller has already registered this switch!");
688 NS_LOG_ERROR (
"Can't send to this switch, not registered to the Controller.");
692 swtch->ForwardControlInput (msg, length);
696 Controller::BuildFlow (sw_flow_key key, uint32_t buffer_id, uint16_t command,
void* acts,
size_t actions_len,
int idle_timeout,
int hard_timeout)
698 ofp_flow_mod* ofm = (ofp_flow_mod*)malloc (
sizeof(ofp_flow_mod) + actions_len);
699 ofm->header.version = OFP_VERSION;
700 ofm->header.type = OFPT_FLOW_MOD;
701 ofm->header.length = htons (
sizeof(ofp_flow_mod) + actions_len);
702 ofm->command = htons (command);
703 ofm->idle_timeout = htons (idle_timeout);
704 ofm->hard_timeout = htons (hard_timeout);
705 ofm->buffer_id = htonl (buffer_id);
706 ofm->priority = OFP_DEFAULT_PRIORITY;
707 memcpy (ofm->actions,acts,actions_len);
709 ofm->match.wildcards = key.wildcards;
710 ofm->match.in_port = key.flow.in_port;
711 memcpy (ofm->match.dl_src, key.flow.dl_src,
sizeof ofm->match.dl_src);
712 memcpy (ofm->match.dl_dst, key.flow.dl_dst,
sizeof ofm->match.dl_dst);
713 ofm->match.dl_vlan = key.flow.dl_vlan;
714 ofm->match.dl_type = key.flow.dl_type;
715 ofm->match.nw_proto = key.flow.nw_proto;
716 ofm->match.nw_src = key.flow.nw_src;
717 ofm->match.nw_dst = key.flow.nw_dst;
718 ofm->match.tp_src = key.flow.tp_src;
719 ofm->match.tp_dst = key.flow.tp_dst;
720 ofm->match.mpls_label1 = key.flow.mpls_label1;
721 ofm->match.mpls_label2 = key.flow.mpls_label1;
729 ofp_header* hdr = (ofp_header*)ofpbuf_try_pull (buffer,
sizeof (ofp_header));
730 uint8_t type = hdr->type;
731 ofpbuf_push_uninit (buffer,
sizeof (ofp_header));
743 error = cb->swtch->StatsDump (cb);
748 NS_LOG_WARN (
"Dump Callback Error: " << strerror (-error));
752 cb->swtch->StatsDone (cb);
760 static TypeId tid = TypeId (
"ns3::ofi::DropController")
762 .SetGroupName (
"OpenFlow")
773 NS_LOG_ERROR (
"Can't receive from this switch, not registered to the Controller.");
780 if (type == OFPT_PACKET_IN)
782 ofp_packet_in * opi = (ofp_packet_in*)ofpbuf_try_pull (buffer, offsetof (ofp_packet_in,
data));
783 int port = ntohs (opi->in_port);
788 flow_extract (buffer,
port != -1 ?
port : OFPP_NONE, &key.flow);
790 ofp_flow_mod* ofm =
BuildFlow (key, opi->buffer_id, OFPFC_ADD, 0, 0, OFP_FLOW_PERMANENT, OFP_FLOW_PERMANENT);
797 static TypeId tid = TypeId (
"ns3::ofi::LearningController")
799 .SetGroupName (
"Openflow")
801 .AddAttribute (
"ExpirationTime",
802 "Time it takes for learned MAC state entry/created flow to expire.",
815 NS_LOG_ERROR (
"Can't receive from this switch, not registered to the Controller.");
822 if (type == OFPT_PACKET_IN)
824 ofp_packet_in * opi = (ofp_packet_in*)ofpbuf_try_pull (buffer, offsetof (ofp_packet_in,
data));
825 int port = ntohs (opi->in_port);
830 flow_extract (buffer,
port != -1 ?
port : OFPP_NONE, &key.flow);
832 uint16_t out_port = OFPP_FLOOD;
833 uint16_t in_port = ntohs (key.flow.in_port);
836 Mac48Address dst_addr;
837 dst_addr.CopyFrom (key.flow.dl_dst);
838 if (!dst_addr.IsBroadcast ())
840 LearnState_t::iterator st =
m_learnState.find (dst_addr);
843 out_port = st->second.port;
847 NS_LOG_INFO (
"Setting to flood; don't know yet what port " << dst_addr <<
" is connected to");
852 NS_LOG_INFO (
"Setting to flood; this packet is a broadcast");
856 ofp_action_output
x[1];
857 x[0].type = htons (OFPAT_OUTPUT);
858 x[0].len = htons (
sizeof(ofp_action_output));
859 x[0].port = out_port;
866 Mac48Address src_addr;
867 src_addr.CopyFrom (key.flow.dl_src);
868 LearnState_t::iterator st =
m_learnState.find (src_addr);
874 NS_LOG_INFO (
"Learned that " << src_addr <<
" can be found over port " << in_port);
877 ofp_action_output x2[1];
878 x2[0].type = htons (OFPAT_OUTPUT);
879 x2[0].len = htons (
sizeof(ofp_action_output));
880 x2[0].port = in_port;
883 src_addr.CopyTo (key.flow.dl_dst);
884 dst_addr.CopyTo (key.flow.dl_src);
885 key.flow.in_port = out_port;
893 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)
902 uint16_t in_port = key->flow.in_port;
903 uint8_t *p = (uint8_t *)actions;
907 if (actions_len == 0)
909 NS_LOG_INFO (
"No actions set to this flow. Dropping packet.");
915 while (actions_len > 0)
917 ofp_action_header *ah = (ofp_action_header *)p;
918 size_t len = htons (ah->len);
922 swtch->DoOutput (packet_uid, in_port, max_len, prev_port, ignore_no_fwd);
926 if (ah->type == htons (OFPAT_OUTPUT))
928 ofp_action_output *oa = (ofp_action_output *)p;
931 prev_port = oa->port;
933 max_len = ntohs (oa->max_len);
937 uint16_t type = ntohs (ah->type);
942 else if (type == OFPAT_VENDOR)
954 swtch->DoOutput (packet_uid, in_port, max_len, prev_port, ignore_no_fwd);
959 ValidateActions (
const sw_flow_key *key,
const ofp_action_header *actions,
size_t actions_len)
961 uint8_t *p = (uint8_t *)actions;
964 while (actions_len >=
sizeof(ofp_action_header))
966 ofp_action_header *ah = (ofp_action_header *)p;
967 size_t len = ntohs (ah->len);
972 if ((actions_len < len) || (len % 8) != 0)
974 return OFPBAC_BAD_LEN;
977 type = ntohs (ah->type);
981 if (err != ACT_VALIDATION_OK)
986 else if (type == OFPAT_VENDOR)
989 if (err != ACT_VALIDATION_OK)
996 return OFPBAC_BAD_TYPE;
1004 if (actions_len != 0)
1006 return OFPBAC_BAD_LEN;
1009 return ACT_VALIDATION_OK;
1013 ExecuteVPortActions (Ptr<OpenFlowSwitchNetDevice> swtch, uint64_t packet_uid, ofpbuf* buffer, sw_flow_key *key,
const ofp_action_header *actions,
size_t actions_len)
1021 uint16_t in_port = ntohs (key->flow.in_port);
1022 uint8_t *p = (uint8_t *)actions;
1024 ofp_action_output *oa;
1029 while (actions_len > 0)
1031 ofp_action_header *ah = (ofp_action_header *)p;
1032 size_t len = htons (ah->len);
1033 if (prev_port != -1)
1035 swtch->DoOutput (packet_uid, in_port, max_len, prev_port,
false);
1039 if (ah->type == htons (OFPAT_OUTPUT))
1041 oa = (ofp_action_output *)p;
1042 prev_port = ntohl (oa->port);
1043 max_len = ntohs (oa->max_len);
1055 if (prev_port != -1)
1057 swtch->DoOutput (packet_uid, in_port, max_len, prev_port,
false);
1064 uint8_t *p = (uint8_t *)actions;
1067 while (actions_len >=
sizeof(ofp_action_header))
1069 ofp_action_header *ah = (ofp_action_header *)p;
1070 size_t len = ntohs (ah->len);
1075 if ((actions_len < len) || (len % 8) != 0)
1077 return OFPBAC_BAD_LEN;
1080 type = ntohs (ah->type);
1084 if (err != ACT_VALIDATION_OK)
1091 return OFPBAC_BAD_TYPE;
1099 if (actions_len != 0)
1101 return OFPBAC_BAD_LEN;
1104 return ACT_VALIDATION_OK;
1108 ExecuteVendor (ofpbuf *buffer,
const sw_flow_key *key,
const ofp_action_header *ah)
1110 ofp_action_vendor_header *avh = (ofp_action_vendor_header *)ah;
1112 switch (ntohl (avh->vendor))
1119 const er_action_header *erah = (
const er_action_header *)avh;
1125 NS_LOG_INFO (
"attempt to execute action with unknown vendor: " << ntohl (avh->vendor));
1131 ValidateVendor (
const sw_flow_key *key,
const ofp_action_header *ah, uint16_t len)
1133 ofp_action_vendor_header *avh;
1134 int ret = ACT_VALIDATION_OK;
1136 if (len <
sizeof(ofp_action_vendor_header))
1138 return OFPBAC_BAD_LEN;
1141 avh = (ofp_action_vendor_header *)ah;
1143 switch (ntohl (avh->vendor))
1146 ret = OFPBAC_BAD_VENDOR_TYPE;
1150 const er_action_header *erah = (
const er_action_header *)avh;
1155 return OFPBAC_BAD_VENDOR;
1165 #endif // NS3_OPENFLOW void StartDump(StatsDumpCallback *cb)
Starts a callback-based, reliable, possibly multi-message reply to a request made by the controller...
void strip_vlan(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
static bool IsValidType(ofp_action_type type)
TypeId AddConstructor(void)
Record in this TypeId the fact that the default constructor is accessible.
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.
static const char * GetSerialNumber()
static TypeId GetTypeId(void)
Register this type.
int(* AggregateDumpCallback)(sw_flow *flow, void *state)
double GetSeconds(void) const
Get an approximation of the time stored in this instance in the indicated unit.
static TypeId GetTypeId(void)
Register this type.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
int DoInit(const void *body, int body_len, void **state)
Prepares to dump some kind of statistics on the connected OpenFlowSwitchNetDevice.
int(* FlowDumpCallback)(sw_flow *flow, void *state)
int AggregateStatsInit(const void *body, int body_len, void **state)
static const char * GetHardwareDescription()
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer)
A switch calls this method to pass a message on to the Controller.
int AggregateStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, ofp_aggregate_stats_request *s, ofpbuf *buffer)
void ReceiveFromSwitch(Ptr< OpenFlowSwitchNetDevice > swtch, ofpbuf *buffer)
A switch calls this method to pass a message on to the Controller.
Stats(ofp_stats_types _type, size_t body_len)
int PortTableStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, void *state, ofpbuf *buffer)
void set_dl_addr(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
Ptr< const AttributeChecker > MakeTimeChecker(const Time min, const Time max)
Helper to make a Time checker with bounded range.
int TableStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, void *state, ofpbuf *buffer)
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 const char * GetManufacturerDescription()
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.
static void Execute(er_action_type type, ofpbuf *buffer, const sw_flow_key *key, const er_action_header *ah)
Executes the action.
LearnState_t m_learnState
Learned state data.
static bool IsValidType(er_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.
static TypeId GetTypeId(void)
Register this type.
Switches_t m_switches
The collection of switches registered to this controller.
static uint16_t Validate(er_action_type type, size_t len)
Validates the action on whether its data is valid or not.
static const char * GetSoftwareDescription()
int DoDump(Ptr< OpenFlowSwitchNetDevice > swtch, void *state, ofpbuf *buffer)
Appends statistics for OpenFlowSwitchNetDevice to 'buffer'.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void set_tp_port(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
int PortStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, PortStatsState *s, ofpbuf *buffer)
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...
Ptr< const AttributeAccessor > MakeTimeAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
void set_mpls_exp(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
int FlowStatsInit(const void *body, int body_len, void **state)
uint16_t ValidateActions(const sw_flow_key *key, const ofp_action_header *actions, size_t actions_len)
Validates a list of flow table actions.
virtual void AddSwitch(Ptr< OpenFlowSwitchNetDevice > swtch)
Adds a switch to the controller.
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, or deleting a flow.
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.
void set_vlan_pcp(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Time Seconds(double value)
Construct a Time in the indicated unit.
void set_nw_addr(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
Time m_expirationTime
Time it takes for learned MAC state entry/created flow to expire.
uint8_t GetPacketType(ofpbuf *buffer)
Get the packet type on the buffer, which can then be used to determine how to handle the buffer...
int DescStatsDump(void *state, ofpbuf *buffer)
int PortStatsInit(const void *body, int body_len, void **state)
#define NS_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
void set_mpls_label(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
static bool IsValidType(ofp_vport_action_type type)
uint16_t ValidateVPortActions(const ofp_action_header *actions, size_t actions_len)
Validates a list of virtual port table entry actions.
void ExecuteVendor(ofpbuf *buffer, const sw_flow_key *key, const ofp_action_header *ah)
Executes a vendor-defined action.
int FlowStatsDump(Ptr< OpenFlowSwitchNetDevice > dp, FlowStatsState *s, ofpbuf *buffer)
static void Execute(ofp_action_type type, ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
Executes the action.
TypeId SetParent(TypeId tid)
Set the parent TypeId.
void DoCleanup(void *state)
Cleans any state created by the init or dump functions.
uint16_t ValidateVendor(const sw_flow_key *key, const ofp_action_header *ah, uint16_t len)
Validates a vendor-defined action.
void set_vlan_vid(ofpbuf *buffer, sw_flow_key *key, const ofp_action_header *ah)
virtual ~Controller()
Destructor.