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)
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)
double GetSeconds(void) const 
Get an approximation of the time stored in this instance in the indicated unit. 
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.