LEFT | RIGHT |
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ | 1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
2 /* | 2 /* |
3 * This program is free software; you can redistribute it and/or modify | 3 * This program is free software; you can redistribute it and/or modify |
4 * it under the terms of the GNU General Public License version 2 as | 4 * it under the terms of the GNU General Public License version 2 as |
5 * published by the Free Software Foundation; | 5 * published by the Free Software Foundation; |
6 * | 6 * |
7 * This program is distributed in the hope that it will be useful, | 7 * This program is distributed in the hope that it will be useful, |
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 * GNU General Public License for more details. | 10 * GNU General Public License for more details. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 .SetParent<NetDevice> () | 64 .SetParent<NetDevice> () |
65 .AddConstructor<SwitchNetDevice> () | 65 .AddConstructor<SwitchNetDevice> () |
66 .AddAttribute ("ID", | 66 .AddAttribute ("ID", |
67 "The identification of the SwitchNetDevice/Datapath, needed f
or OpenFlow compatibility.", | 67 "The identification of the SwitchNetDevice/Datapath, needed f
or OpenFlow compatibility.", |
68 UintegerValue (GenerateId ()), | 68 UintegerValue (GenerateId ()), |
69 MakeUintegerAccessor (&SwitchNetDevice::m_id), | 69 MakeUintegerAccessor (&SwitchNetDevice::m_id), |
70 MakeUintegerChecker<uint64_t> ()) | 70 MakeUintegerChecker<uint64_t> ()) |
71 .AddAttribute ("FlowTableLookupDelay", | 71 .AddAttribute ("FlowTableLookupDelay", |
72 "A real switch will have an overhead for looking up in the fl
ow table. For the default, we simulate a standard TCAM on an FPGA.", | 72 "A real switch will have an overhead for looking up in the fl
ow table. For the default, we simulate a standard TCAM on an FPGA.", |
73 TimeValue (NanoSeconds (30)), | 73 TimeValue (NanoSeconds (30)), |
74 MakeTimeAccessor (&SwitchNetDevice::m_lookupDelay), | 74 MakeTimeAccessor (&SwitchNetDevice::m_lookupDelay), |
75 MakeTimeChecker ()) | 75 MakeTimeChecker ()) |
76 .AddAttribute ("Flags", // Note: The Controller can configure this value, ov
erriding the user's setting. | 76 .AddAttribute ("Flags", // Note: The Controller can configure this value, ov
erriding the user's setting. |
77 "Flags to turn different functionality on/off, such as whethe
r to inform the controller when a flow expires, or how to handle fragments.", | 77 "Flags to turn different functionality on/off, such as whethe
r to inform the controller when a flow expires, or how to handle fragments.", |
78 UintegerValue (0), // Look at the ofp_config_flags enum in op
enflow/include/openflow.h for options. | 78 UintegerValue (0), // Look at the ofp_config_flags enum in op
enflow/include/openflow.h for options. |
79 MakeUintegerAccessor (&SwitchNetDevice::m_flags), | 79 MakeUintegerAccessor (&SwitchNetDevice::m_flags), |
80 MakeUintegerChecker<uint16_t> ()) | 80 MakeUintegerChecker<uint16_t> ()) |
81 .AddAttribute ("FlowTableMissSendLength", // Note: The Controller can config
ure this value, overriding the user's setting. | 81 .AddAttribute ("FlowTableMissSendLength", // Note: The Controller can config
ure this value, overriding the user's setting. |
82 "When forwarding a packet the switch didn't match up to the c
ontroller, it can be more efficient to forward only the first x bytes.", | 82 "When forwarding a packet the switch didn't match up to the c
ontroller, it can be more efficient to forward only the first x bytes.", |
83 UintegerValue (OFP_DEFAULT_MISS_SEND_LEN), // 128 bytes | 83 UintegerValue (OFP_DEFAULT_MISS_SEND_LEN), // 128 bytes |
84 MakeUintegerAccessor (&SwitchNetDevice::m_missSendLen), | 84 MakeUintegerAccessor (&SwitchNetDevice::m_missSendLen), |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 m_controller = 0; | 132 m_controller = 0; |
133 | 133 |
134 chain_destroy (m_chain); | 134 chain_destroy (m_chain); |
135 RBTreeDestroy (m_vportTable.table); | 135 RBTreeDestroy (m_vportTable.table); |
136 m_channel = 0; | 136 m_channel = 0; |
137 m_node = 0; | 137 m_node = 0; |
138 NetDevice::DoDispose (); | 138 NetDevice::DoDispose (); |
139 } | 139 } |
140 | 140 |
141 void | 141 void |
142 SwitchNetDevice::SetController (Ptr<Controller> c) | 142 SwitchNetDevice::SetController (Ptr<ofi::Controller> c) |
143 { | 143 { |
144 if (m_controller != 0) | 144 if (m_controller != 0) |
145 { | 145 { |
146 NS_LOG_ERROR ("Controller already set."); | 146 NS_LOG_ERROR ("Controller already set."); |
147 return; | 147 return; |
148 } | 148 } |
149 | 149 |
150 m_controller = c; | 150 m_controller = c; |
151 m_controller->AddSwitch (this); | 151 m_controller->AddSwitch (this); |
152 } | 152 } |
(...skipping 11 matching lines...) Expand all Loading... |
164 { | 164 { |
165 NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to swit
ch."); | 165 NS_FATAL_ERROR ("Device does not support SendFrom: cannot be added to swit
ch."); |
166 } | 166 } |
167 if (m_address == Mac48Address ()) | 167 if (m_address == Mac48Address ()) |
168 { | 168 { |
169 m_address = Mac48Address::ConvertFrom (switchPort->GetAddress ()); | 169 m_address = Mac48Address::ConvertFrom (switchPort->GetAddress ()); |
170 } | 170 } |
171 | 171 |
172 if (m_ports.size () < DP_MAX_PORTS) | 172 if (m_ports.size () < DP_MAX_PORTS) |
173 { | 173 { |
174 Port p; | 174 ofi::Port p; |
175 p.config = 0; | 175 p.config = 0; |
176 p.netdev = switchPort; | 176 p.netdev = switchPort; |
177 m_ports.push_back (p); | 177 m_ports.push_back (p); |
178 | 178 |
179 // Notify the controller that this port has been added | 179 // Notify the controller that this port has been added |
180 SendPortStatus (p, OFPPR_ADD); | 180 SendPortStatus (p, OFPPR_ADD); |
181 | 181 |
182 NS_LOG_DEBUG ("RegisterProtocolHandler for " << switchPort->GetInstanceTyp
eId ().GetName ()); | 182 NS_LOG_DEBUG ("RegisterProtocolHandler for " << switchPort->GetInstanceTyp
eId ().GetName ()); |
183 m_node->RegisterProtocolHandler (MakeCallback (&SwitchNetDevice::ReceiveFr
omDevice, this), | 183 m_node->RegisterProtocolHandler (MakeCallback (&SwitchNetDevice::ReceiveFr
omDevice, this), |
184 0, switchPort, true); | 184 0, switchPort, true); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 } | 321 } |
322 | 322 |
323 bool | 323 bool |
324 SwitchNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address
& dest, uint16_t protocolNumber) | 324 SwitchNetDevice::SendFrom (Ptr<Packet> packet, const Address& src, const Address
& dest, uint16_t protocolNumber) |
325 { | 325 { |
326 NS_LOG_FUNCTION_NOARGS (); | 326 NS_LOG_FUNCTION_NOARGS (); |
327 | 327 |
328 ofpbuf *buffer = BufferFromPacket (packet,src,dest,GetMtu (),protocolNumber); | 328 ofpbuf *buffer = BufferFromPacket (packet,src,dest,GetMtu (),protocolNumber); |
329 | 329 |
330 uint32_t packet_uid = save_buffer (buffer); | 330 uint32_t packet_uid = save_buffer (buffer); |
331 SwitchPacketMetadata data; | 331 ofi::SwitchPacketMetadata data; |
332 data.packet = packet; | 332 data.packet = packet; |
333 data.buffer = buffer; | 333 data.buffer = buffer; |
334 data.protocolNumber = protocolNumber; | 334 data.protocolNumber = protocolNumber; |
335 data.src = Address (src); | 335 data.src = Address (src); |
336 data.dst = Address (dest); | 336 data.dst = Address (dest); |
337 m_packetData.insert (make_pair (packet_uid, data)); | 337 m_packetData.insert (std::make_pair (packet_uid, data)); |
338 | 338 |
339 RunThroughFlowTable (packet_uid, -1); | 339 RunThroughFlowTable (packet_uid, -1); |
340 | 340 |
341 return true; | 341 return true; |
342 } | 342 } |
343 | 343 |
344 | 344 |
345 Ptr<Node> | 345 Ptr<Node> |
346 SwitchNetDevice::GetNode (void) const | 346 SwitchNetDevice::GetNode (void) const |
347 { | 347 { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 // check whether port table entry exists for specified port number | 402 // check whether port table entry exists for specified port number |
403 vport_table_entry *vpe = vport_table_lookup (&m_vportTable, vport); | 403 vport_table_entry *vpe = vport_table_lookup (&m_vportTable, vport); |
404 if (vpe != 0) | 404 if (vpe != 0) |
405 { | 405 { |
406 NS_LOG_ERROR ("vport " << vport << " already exists!"); | 406 NS_LOG_ERROR ("vport " << vport << " already exists!"); |
407 SendErrorMsg (OFPET_BAD_ACTION, OFPET_VPORT_MOD_FAILED, ovpm, ntohs (ovpm-
>header.length)); | 407 SendErrorMsg (OFPET_BAD_ACTION, OFPET_VPORT_MOD_FAILED, ovpm, ntohs (ovpm-
>header.length)); |
408 return EINVAL; | 408 return EINVAL; |
409 } | 409 } |
410 | 410 |
411 // check whether actions are valid | 411 // check whether actions are valid |
412 uint16_t v_code = ValidateVPortActions (ovpm->actions, actions_len); | 412 uint16_t v_code = ofi::ValidateVPortActions (ovpm->actions, actions_len); |
413 if (v_code != ACT_VALIDATION_OK) | 413 if (v_code != ACT_VALIDATION_OK) |
414 { | 414 { |
415 SendErrorMsg (OFPET_BAD_ACTION, v_code, ovpm, ntohs (ovpm->header.length))
; | 415 SendErrorMsg (OFPET_BAD_ACTION, v_code, ovpm, ntohs (ovpm->header.length))
; |
416 return EINVAL; | 416 return EINVAL; |
417 } | 417 } |
418 | 418 |
419 vpe = vport_table_entry_alloc (actions_len); | 419 vpe = vport_table_entry_alloc (actions_len); |
420 | 420 |
421 vpe->vport = vport; | 421 vpe->vport = vport; |
422 vpe->parent_port = parent_port; | 422 vpe->parent_port = parent_port; |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 { | 617 { |
618 m_rxCallback (this, packet, protocol, src); | 618 m_rxCallback (this, packet, protocol, src); |
619 } | 619 } |
620 else | 620 else |
621 { | 621 { |
622 if (packetType != PACKET_OTHERHOST) | 622 if (packetType != PACKET_OTHERHOST) |
623 { | 623 { |
624 m_rxCallback (this, packet, protocol, src); | 624 m_rxCallback (this, packet, protocol, src); |
625 } | 625 } |
626 | 626 |
627 SwitchPacketMetadata data; | 627 ofi::SwitchPacketMetadata data; |
628 data.packet = packet->Copy (); | 628 data.packet = packet->Copy (); |
629 | 629 |
630 ofpbuf *buffer = BufferFromPacket (data.packet,src,dst,netdev-
>GetMtu (),protocol); | 630 ofpbuf *buffer = BufferFromPacket (data.packet,src,dst,netdev-
>GetMtu (),protocol); |
631 m_ports[i].rx_packets++; | 631 m_ports[i].rx_packets++; |
632 m_ports[i].rx_bytes += buffer->size; | 632 m_ports[i].rx_bytes += buffer->size; |
633 data.buffer = buffer; | 633 data.buffer = buffer; |
634 uint32_t packet_uid = save_buffer (buffer); | 634 uint32_t packet_uid = save_buffer (buffer); |
635 | 635 |
636 data.protocolNumber = protocol; | 636 data.protocolNumber = protocol; |
637 data.src = Address (src); | 637 data.src = Address (src); |
638 data.dst = Address (dst); | 638 data.dst = Address (dst); |
639 m_packetData.insert (make_pair (packet_uid, data)); | 639 m_packetData.insert (std::make_pair (packet_uid, data)); |
640 | 640 |
641 RunThroughFlowTable (packet_uid, i); | 641 RunThroughFlowTable (packet_uid, i); |
642 } | 642 } |
643 } | 643 } |
644 | 644 |
645 break; | 645 break; |
646 } | 646 } |
647 } | 647 } |
648 ·· | 648 ·· |
649 // Run periodic execution. | 649 // Run periodic execution. |
650 Time now = Simulator::Now(); | 650 Time now = Simulator::Now(); |
651 if (now >= Seconds (m_lastExecute.GetSeconds () + 1)) // If a second or more h
as passed from the simulation time, execute. | 651 if (now >= Seconds (m_lastExecute.GetSeconds () + 1)) // If a second or more h
as passed from the simulation time, execute. |
652 { | 652 { |
653 // If port status is modified in any way, notify the controller. | 653 // If port status is modified in any way, notify the controller. |
654 for (size_t i = 0; i < m_ports.size (); i++) | 654 for (size_t i = 0; i < m_ports.size (); i++) |
655 { | 655 { |
656 if (UpdatePortStatus (m_ports[i])) | 656 if (UpdatePortStatus (m_ports[i])) |
657 { | 657 { |
658 SendPortStatus (m_ports[i], OFPPR_MODIFY); | 658 SendPortStatus (m_ports[i], OFPPR_MODIFY); |
659 } | 659 } |
660 } | 660 } |
661 | 661 |
662 // If any flows have expired, delete them and notify the controller. | 662 // If any flows have expired, delete them and notify the controller. |
663 List deleted = LIST_INITIALIZER (&deleted); | 663 List deleted = LIST_INITIALIZER (&deleted); |
664 sw_flow *f, *n; | 664 sw_flow *f, *n; |
665 chain_timeout (m_chain, &deleted); | 665 chain_timeout (m_chain, &deleted); |
666 LIST_FOR_EACH_SAFE (f, n, sw_flow, node, &deleted) | 666 LIST_FOR_EACH_SAFE (f, n, sw_flow, node, &deleted) |
667 { | 667 { |
| 668 std::ostringstream str; |
| 669 str << "Flow ["; |
| 670 for (int i = 0; i < 6; i++) |
| 671 str << (i!=0?":":"") << std::hex << f->key.flow.dl_src[i]/16 << f->key
.flow.dl_src[i]%16; |
| 672 str << " -> "; |
| 673 for (int i = 0; i < 6; i++) |
| 674 str << (i!=0?":":"") << std::hex << f->key.flow.dl_dst[i]/16 << f->key
.flow.dl_dst[i]%16; |
| 675 str << "] expired."; |
| 676 ········ |
| 677 NS_LOG_INFO (str.str ()); |
668 SendFlowExpired (f, (ofp_flow_expired_reason)f->reason); | 678 SendFlowExpired (f, (ofp_flow_expired_reason)f->reason); |
669 list_remove (&f->node); | 679 list_remove (&f->node); |
670 flow_free (f); | 680 flow_free (f); |
671 } | 681 } |
672 ······ | 682 ······ |
673 m_lastExecute = now; | 683 m_lastExecute = now; |
674 } | 684 } |
675 } | 685 } |
676 | 686 |
677 int | 687 int |
(...skipping 25 matching lines...) Expand all Loading... |
703 } | 713 } |
704 | 714 |
705 return 0; | 715 return 0; |
706 } | 716 } |
707 | 717 |
708 void | 718 void |
709 SwitchNetDevice::OutputPacket (uint32_t packet_uid, int out_port) | 719 SwitchNetDevice::OutputPacket (uint32_t packet_uid, int out_port) |
710 { | 720 { |
711 if (out_port >= 0 && out_port < DP_MAX_PORTS) | 721 if (out_port >= 0 && out_port < DP_MAX_PORTS) |
712 { | 722 { |
713 Port& p = m_ports[out_port]; | 723 ofi::Port& p = m_ports[out_port]; |
714 if (p.netdev != 0 && !(p.config & OFPPC_PORT_DOWN)) | 724 if (p.netdev != 0 && !(p.config & OFPPC_PORT_DOWN)) |
715 { | 725 { |
716 SwitchPacketMetadata data = m_packetData.find (packet_uid)->second; | 726 ofi::SwitchPacketMetadata data = m_packetData.find (packet_uid)->secon
d; |
717 size_t bufsize = data.buffer->size; | 727 size_t bufsize = data.buffer->size; |
718 NS_LOG_INFO ("Sending packet " << data.packet->GetUid () << " over por
t " << out_port); | 728 NS_LOG_INFO ("Sending packet " << data.packet->GetUid () << " over por
t " << out_port); |
719 if (p.netdev->SendFrom (data.packet->Copy (), data.src, data.dst, data
.protocolNumber)) | 729 if (p.netdev->SendFrom (data.packet->Copy (), data.src, data.dst, data
.protocolNumber)) |
720 { | 730 { |
721 p.tx_packets++; | 731 p.tx_packets++; |
722 p.tx_bytes += bufsize; | 732 p.tx_bytes += bufsize; |
723 } | 733 } |
724 else | 734 else |
725 { | 735 { |
726 p.tx_dropped++; | 736 p.tx_dropped++; |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 return 0; | 808 return 0; |
799 } | 809 } |
800 | 810 |
801 void | 811 void |
802 SwitchNetDevice::OutputControl (uint32_t packet_uid, int in_port, size_t max_len
, int reason) | 812 SwitchNetDevice::OutputControl (uint32_t packet_uid, int in_port, size_t max_len
, int reason) |
803 { | 813 { |
804 NS_LOG_INFO ("Sending packet to controller"); | 814 NS_LOG_INFO ("Sending packet to controller"); |
805 | 815 |
806 ofpbuf* buffer = m_packetData.find (packet_uid)->second.buffer; | 816 ofpbuf* buffer = m_packetData.find (packet_uid)->second.buffer; |
807 size_t total_len = buffer->size; | 817 size_t total_len = buffer->size; |
808 if (packet_uid != numeric_limits<uint32_t>::max () && max_len != 0 && buffer->
size > max_len) | 818 if (packet_uid != std::numeric_limits<uint32_t>::max () && max_len != 0 && buf
fer->size > max_len) |
809 { | 819 { |
810 buffer->size = max_len; | 820 buffer->size = max_len; |
811 } | 821 } |
812 | 822 |
813 ofp_packet_in *opi = (ofp_packet_in*)ofpbuf_push_uninit (buffer, offsetof (ofp
_packet_in, data)); | 823 ofp_packet_in *opi = (ofp_packet_in*)ofpbuf_push_uninit (buffer, offsetof (ofp
_packet_in, data)); |
814 opi->header.version = OFP_VERSION; | 824 opi->header.version = OFP_VERSION; |
815 opi->header.type = OFPT_PACKET_IN; | 825 opi->header.type = OFPT_PACKET_IN; |
816 opi->header.length = htons (buffer->size); | 826 opi->header.length = htons (buffer->size); |
817 opi->header.xid = htonl (0); | 827 opi->header.xid = htonl (0); |
818 opi->buffer_id = htonl (packet_uid); | 828 opi->buffer_id = htonl (packet_uid); |
819 opi->total_len = htons (total_len); | 829 opi->total_len = htons (total_len); |
820 opi->in_port = htons (in_port); | 830 opi->in_port = htons (in_port); |
821 opi->reason = reason; | 831 opi->reason = reason; |
822 opi->pad = 0; | 832 opi->pad = 0; |
823 SendOpenflowBuffer (buffer); | 833 SendOpenflowBuffer (buffer); |
824 } | 834 } |
825 | 835 |
826 void | 836 void |
827 SwitchNetDevice::FillPortDesc (Port p, ofp_phy_port *desc) | 837 SwitchNetDevice::FillPortDesc (ofi::Port p, ofp_phy_port *desc) |
828 { | 838 { |
829 desc->port_no = htons (GetSwitchPortIndex (p)); | 839 desc->port_no = htons (GetSwitchPortIndex (p)); |
830 | 840 |
831 ostringstream nm; | 841 std::ostringstream nm; |
832 nm << "eth" << GetSwitchPortIndex (p); | 842 nm << "eth" << GetSwitchPortIndex (p); |
833 strncpy ((char *)desc->name, nm.str ().c_str (), sizeof desc->name); | 843 strncpy ((char *)desc->name, nm.str ().c_str (), sizeof desc->name); |
834 | 844 |
835 p.netdev->GetAddress ().CopyTo (desc->hw_addr); | 845 p.netdev->GetAddress ().CopyTo (desc->hw_addr); |
836 desc->config = htonl (p.config); | 846 desc->config = htonl (p.config); |
837 desc->state = htonl (p.state); | 847 desc->state = htonl (p.state); |
838 ·· | 848 ·· |
839 // TODO: This should probably be fixed eventually to specify different availab
le features. | 849 // TODO: This should probably be fixed eventually to specify different availab
le features. |
840 desc->curr = 0; // htonl(netdev_get_features(p->netdev, NETDEV_FEAT_CURRENT)); | 850 desc->curr = 0; // htonl(netdev_get_features(p->netdev, NETDEV_FEAT_CURRENT)); |
841 desc->supported = 0; // htonl(netdev_get_features(p->netdev, NETDEV_FEAT_SUPPO
RTED)); | 851 desc->supported = 0; // htonl(netdev_get_features(p->netdev, NETDEV_FEAT_SUPPO
RTED)); |
(...skipping 27 matching lines...) Expand all Loading... |
869 ofpbuf *buffer; | 879 ofpbuf *buffer; |
870 ofp_vport_table_features *ovtfr = (ofp_vport_table_features*)MakeOpenflowReply
(sizeof *ovtfr, OFPT_VPORT_TABLE_FEATURES_REPLY, &buffer); | 880 ofp_vport_table_features *ovtfr = (ofp_vport_table_features*)MakeOpenflowReply
(sizeof *ovtfr, OFPT_VPORT_TABLE_FEATURES_REPLY, &buffer); |
871 ovtfr->actions = htonl (OFP_SUPPORTED_VPORT_TABLE_ACTIONS); | 881 ovtfr->actions = htonl (OFP_SUPPORTED_VPORT_TABLE_ACTIONS); |
872 ovtfr->max_vports = htonl (m_vportTable.max_vports); | 882 ovtfr->max_vports = htonl (m_vportTable.max_vports); |
873 ovtfr->max_chain_depth = htons (-1); // support a chain depth of 2^16 | 883 ovtfr->max_chain_depth = htons (-1); // support a chain depth of 2^16 |
874 ovtfr->mixed_chaining = true; | 884 ovtfr->mixed_chaining = true; |
875 SendOpenflowBuffer (buffer); | 885 SendOpenflowBuffer (buffer); |
876 } | 886 } |
877 | 887 |
878 int | 888 int |
879 SwitchNetDevice::UpdatePortStatus (Port& p) | 889 SwitchNetDevice::UpdatePortStatus (ofi::Port& p) |
880 { | 890 { |
881 uint32_t orig_config = p.config; | 891 uint32_t orig_config = p.config; |
882 uint32_t orig_state = p.state; | 892 uint32_t orig_state = p.state; |
883 | 893 |
884 // Port is always enabled because the Net Device is always enabled. | 894 // Port is always enabled because the Net Device is always enabled. |
885 p.config &= ~OFPPC_PORT_DOWN; | 895 p.config &= ~OFPPC_PORT_DOWN; |
886 | 896 |
887 if (p.netdev->IsLinkUp ()) | 897 if (p.netdev->IsLinkUp ()) |
888 { | 898 { |
889 p.state &= ~OFPPS_LINK_DOWN; | 899 p.state &= ~OFPPS_LINK_DOWN; |
890 } | 900 } |
891 else | 901 else |
892 { | 902 { |
893 p.state |= OFPPS_LINK_DOWN; | 903 p.state |= OFPPS_LINK_DOWN; |
894 } | 904 } |
895 | 905 |
896 return ((orig_config != p.config) || (orig_state != p.state)); | 906 return ((orig_config != p.config) || (orig_state != p.state)); |
897 } | 907 } |
898 | 908 |
899 void | 909 void |
900 SwitchNetDevice::SendPortStatus (Port p, uint8_t status) | 910 SwitchNetDevice::SendPortStatus (ofi::Port p, uint8_t status) |
901 { | 911 { |
902 ofpbuf *buffer; | 912 ofpbuf *buffer; |
903 ofp_port_status *ops = (ofp_port_status*)MakeOpenflowReply (sizeof *ops, OFPT_
PORT_STATUS, &buffer); | 913 ofp_port_status *ops = (ofp_port_status*)MakeOpenflowReply (sizeof *ops, OFPT_
PORT_STATUS, &buffer); |
904 ops->reason = status; | 914 ops->reason = status; |
905 memset (ops->pad, 0, sizeof ops->pad); | 915 memset (ops->pad, 0, sizeof ops->pad); |
906 FillPortDesc (p, &ops->desc); | 916 FillPortDesc (p, &ops->desc); |
907 | 917 |
908 SendOpenflowBuffer (buffer); | 918 SendOpenflowBuffer (buffer); |
909 ofpbuf_delete (buffer); | 919 ofpbuf_delete (buffer); |
910 } | 920 } |
(...skipping 28 matching lines...) Expand all Loading... |
939 } | 949 } |
940 | 950 |
941 void | 951 void |
942 SwitchNetDevice::FlowTableLookup (sw_flow_key key, ofpbuf* buffer, uint32_t pack
et_uid, int port, bool send_to_controller) | 952 SwitchNetDevice::FlowTableLookup (sw_flow_key key, ofpbuf* buffer, uint32_t pack
et_uid, int port, bool send_to_controller) |
943 { | 953 { |
944 sw_flow *flow = chain_lookup (m_chain, &key); | 954 sw_flow *flow = chain_lookup (m_chain, &key); |
945 if (flow != 0) | 955 if (flow != 0) |
946 { | 956 { |
947 NS_LOG_INFO ("Flow matched"); | 957 NS_LOG_INFO ("Flow matched"); |
948 flow_used (flow, buffer); | 958 flow_used (flow, buffer); |
949 ExecuteActions (this, packet_uid, buffer, &key, flow->sf_acts->actions, fl
ow->sf_acts->actions_len, false); | 959 ofi::ExecuteActions (this, packet_uid, buffer, &key, flow->sf_acts->action
s, flow->sf_acts->actions_len, false); |
950 } | 960 } |
951 else | 961 else |
952 { | 962 { |
953 NS_LOG_INFO ("Flow not matched."); | 963 NS_LOG_INFO ("Flow not matched."); |
954 | 964 |
955 if (send_to_controller) | 965 if (send_to_controller) |
956 { | 966 { |
957 OutputControl (packet_uid, port, m_missSendLen, OFPR_NO_MATCH); | 967 OutputControl (packet_uid, port, m_missSendLen, OFPR_NO_MATCH); |
958 } | 968 } |
959 } | 969 } |
960 | 970 |
961 // Clean up; at this point we're done with the packet. | 971 // Clean up; at this point we're done with the packet. |
962 m_packetData.erase (packet_uid); | 972 m_packetData.erase (packet_uid); |
963 discard_buffer (packet_uid); | 973 discard_buffer (packet_uid); |
964 ofpbuf_delete (buffer); | 974 ofpbuf_delete (buffer); |
965 } | 975 } |
966 | 976 |
967 void | 977 void |
968 SwitchNetDevice::RunThroughFlowTable (uint32_t packet_uid, int port, bool send_t
o_controller) | 978 SwitchNetDevice::RunThroughFlowTable (uint32_t packet_uid, int port, bool send_t
o_controller) |
969 { | 979 { |
970 SwitchPacketMetadata data = m_packetData.find (packet_uid)->second; | 980 ofi::SwitchPacketMetadata data = m_packetData.find (packet_uid)->second; |
971 ofpbuf* buffer = data.buffer; | 981 ofpbuf* buffer = data.buffer; |
972 | 982 |
973 sw_flow_key key; | 983 sw_flow_key key; |
974 key.wildcards = 0; // Lookup cannot take wildcards. | 984 key.wildcards = 0; // Lookup cannot take wildcards. |
975 // Extract the matching key's flow data from the packet's headers; if the poli
cy is to drop fragments and the message is a fragment, drop it. | 985 // Extract the matching key's flow data from the packet's headers; if the poli
cy is to drop fragments and the message is a fragment, drop it. |
976 if (flow_extract (buffer, port != -1 ? port : OFPP_NONE, &key.flow) && (m_flag
s & OFPC_FRAG_MASK) == OFPC_FRAG_DROP) | 986 if (flow_extract (buffer, port != -1 ? port : OFPP_NONE, &key.flow) && (m_flag
s & OFPC_FRAG_MASK) == OFPC_FRAG_DROP) |
977 { | 987 { |
978 ofpbuf_delete (buffer); | 988 ofpbuf_delete (buffer); |
979 return; | 989 return; |
980 } | 990 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1027 | 1037 |
1028 // run through the chain of port table entries | 1038 // run through the chain of port table entries |
1029 vport_table_entry *vpe = vport_table_lookup (&m_vportTable, vport); | 1039 vport_table_entry *vpe = vport_table_lookup (&m_vportTable, vport); |
1030 m_vportTable.lookup_count++; | 1040 m_vportTable.lookup_count++; |
1031 if (vpe) | 1041 if (vpe) |
1032 { | 1042 { |
1033 m_vportTable.port_match_count++; | 1043 m_vportTable.port_match_count++; |
1034 } | 1044 } |
1035 while (vpe != 0) | 1045 while (vpe != 0) |
1036 { | 1046 { |
1037 ExecuteVPortActions (this, packet_uid, m_packetData.find (packet_uid)->sec
ond.buffer, &key, vpe->port_acts->actions, vpe->port_acts->actions_len); | 1047 ofi::ExecuteVPortActions (this, packet_uid, m_packetData.find (packet_uid)
->second.buffer, &key, vpe->port_acts->actions, vpe->port_acts->actions_len); |
1038 vport_used (vpe, buffer); // update counters for virtual port | 1048 vport_used (vpe, buffer); // update counters for virtual port |
1039 if (vpe->parent_port_ptr == 0) | 1049 if (vpe->parent_port_ptr == 0) |
1040 { | 1050 { |
1041 // if a port table's parent_port_ptr is 0 then | 1051 // if a port table's parent_port_ptr is 0 then |
1042 // the parent_port should be a physical port | 1052 // the parent_port should be a physical port |
1043 if (vpe->parent_port <= OFPP_VP_START) // done traversing port chain,
send packet to output port | 1053 if (vpe->parent_port <= OFPP_VP_START) // done traversing port chain,
send packet to output port |
1044 { | 1054 { |
1045 OutputPort (packet_uid, port != -1 ? port : OFPP_NONE, vpe->parent
_port, false); | 1055 OutputPort (packet_uid, port != -1 ? port : OFPP_NONE, vpe->parent
_port, false); |
1046 } | 1056 } |
1047 else | 1057 else |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 buffer = retrieve_buffer (ntohl (opo->buffer_id)); | 1136 buffer = retrieve_buffer (ntohl (opo->buffer_id)); |
1127 if (buffer == 0) | 1137 if (buffer == 0) |
1128 { | 1138 { |
1129 return -ESRCH; | 1139 return -ESRCH; |
1130 } | 1140 } |
1131 } | 1141 } |
1132 | 1142 |
1133 sw_flow_key key; | 1143 sw_flow_key key; |
1134 flow_extract (buffer, opo->in_port, &key.flow); // ntohs(opo->in_port) | 1144 flow_extract (buffer, opo->in_port, &key.flow); // ntohs(opo->in_port) |
1135 | 1145 |
1136 uint16_t v_code = ValidateActions (&key, opo->actions, actions_len); | 1146 uint16_t v_code = ofi::ValidateActions (&key, opo->actions, actions_len); |
1137 if (v_code != ACT_VALIDATION_OK) | 1147 if (v_code != ACT_VALIDATION_OK) |
1138 { | 1148 { |
1139 SendErrorMsg (OFPET_BAD_ACTION, v_code, msg, ntohs (opo->header.length)); | 1149 SendErrorMsg (OFPET_BAD_ACTION, v_code, msg, ntohs (opo->header.length)); |
1140 ofpbuf_delete (buffer); | 1150 ofpbuf_delete (buffer); |
1141 return -EINVAL; | 1151 return -EINVAL; |
1142 } | 1152 } |
1143 | 1153 |
1144 ExecuteActions (this, opo->buffer_id, buffer, &key, opo->actions, actions_len,
true); | 1154 ofi::ExecuteActions (this, opo->buffer_id, buffer, &key, opo->actions, actions
_len, true); |
1145 return 0; | 1155 return 0; |
1146 } | 1156 } |
1147 | 1157 |
1148 int | 1158 int |
1149 SwitchNetDevice::ReceivePortMod (const void *msg) | 1159 SwitchNetDevice::ReceivePortMod (const void *msg) |
1150 { | 1160 { |
1151 ofp_port_mod* opm = (ofp_port_mod*)msg; | 1161 ofp_port_mod* opm = (ofp_port_mod*)msg; |
1152 ·· | 1162 ·· |
1153 int port = opm->port_no; // ntohs(opm->port_no); | 1163 int port = opm->port_no; // ntohs(opm->port_no); |
1154 if (port < DP_MAX_PORTS) | 1164 if (port < DP_MAX_PORTS) |
1155 { | 1165 { |
1156 Port& p = m_ports[port]; | 1166 ofi::Port& p = m_ports[port]; |
1157 | 1167 |
1158 // Make sure the port id hasn't changed since this was sent | 1168 // Make sure the port id hasn't changed since this was sent |
1159 Mac48Address hw_addr = Mac48Address (); | 1169 Mac48Address hw_addr = Mac48Address (); |
1160 hw_addr.CopyFrom (opm->hw_addr); | 1170 hw_addr.CopyFrom (opm->hw_addr); |
1161 if (p.netdev->GetAddress () != hw_addr) | 1171 if (p.netdev->GetAddress () != hw_addr) |
1162 { | 1172 { |
1163 return 0; | 1173 return 0; |
1164 } | 1174 } |
1165 | 1175 |
1166 if (opm->mask) | 1176 if (opm->mask) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1221 { | 1231 { |
1222 if (ntohl (ofm->buffer_id) != (uint32_t) -1) | 1232 if (ntohl (ofm->buffer_id) != (uint32_t) -1) |
1223 { | 1233 { |
1224 discard_buffer (ntohl (ofm->buffer_id)); | 1234 discard_buffer (ntohl (ofm->buffer_id)); |
1225 } | 1235 } |
1226 return -ENOMEM; | 1236 return -ENOMEM; |
1227 } | 1237 } |
1228 | 1238 |
1229 flow_extract_match (&flow->key, &ofm->match); | 1239 flow_extract_match (&flow->key, &ofm->match); |
1230 | 1240 |
1231 uint16_t v_code = ValidateActions (&flow->key, ofm->actions, actions_len); | 1241 uint16_t v_code = ofi::ValidateActions (&flow->key, ofm->actions, actions_len)
; |
1232 if (v_code != ACT_VALIDATION_OK) | 1242 if (v_code != ACT_VALIDATION_OK) |
1233 { | 1243 { |
1234 SendErrorMsg (OFPET_BAD_ACTION, v_code, ofm, ntohs (ofm->header.length)); | 1244 SendErrorMsg (OFPET_BAD_ACTION, v_code, ofm, ntohs (ofm->header.length)); |
1235 flow_free (flow); | 1245 flow_free (flow); |
1236 if (ntohl (ofm->buffer_id) != (uint32_t) -1) | 1246 if (ntohl (ofm->buffer_id) != (uint32_t) -1) |
1237 { | 1247 { |
1238 discard_buffer (ntohl (ofm->buffer_id)); | 1248 discard_buffer (ntohl (ofm->buffer_id)); |
1239 } | 1249 } |
1240 return -ENOMEM; | 1250 return -ENOMEM; |
1241 } | 1251 } |
(...skipping 18 matching lines...) Expand all Loading... |
1260 } | 1270 } |
1261 flow_free (flow); | 1271 flow_free (flow); |
1262 if (ntohl (ofm->buffer_id) != (uint32_t) -1) | 1272 if (ntohl (ofm->buffer_id) != (uint32_t) -1) |
1263 { | 1273 { |
1264 discard_buffer (ntohl (ofm->buffer_id)); | 1274 discard_buffer (ntohl (ofm->buffer_id)); |
1265 } | 1275 } |
1266 return error; | 1276 return error; |
1267 } | 1277 } |
1268 | 1278 |
1269 NS_LOG_INFO ("Added new flow."); | 1279 NS_LOG_INFO ("Added new flow."); |
1270 if (ntohl (ofm->buffer_id) != numeric_limits<uint32_t>::max ()) | 1280 if (ntohl (ofm->buffer_id) != std::numeric_limits<uint32_t>::max ()) |
1271 { | 1281 { |
1272 ofpbuf *buffer = retrieve_buffer (ofm->buffer_id); // ntohl(ofm->buffer_id
) | 1282 ofpbuf *buffer = retrieve_buffer (ofm->buffer_id); // ntohl(ofm->buffer_id
) |
1273 if (buffer) | 1283 if (buffer) |
1274 { | 1284 { |
1275 sw_flow_key key; | 1285 sw_flow_key key; |
1276 flow_used (flow, buffer); | 1286 flow_used (flow, buffer); |
1277 flow_extract (buffer, ofm->match.in_port, &key.flow); // ntohs(ofm->ma
tch.in_port); | 1287 flow_extract (buffer, ofm->match.in_port, &key.flow); // ntohs(ofm->ma
tch.in_port); |
1278 ExecuteActions (this, ofm->buffer_id, buffer, &key, ofm->actions, acti
ons_len, false); | 1288 ofi::ExecuteActions (this, ofm->buffer_id, buffer, &key, ofm->actions,
actions_len, false); |
1279 ofpbuf_delete (buffer); | 1289 ofpbuf_delete (buffer); |
1280 } | 1290 } |
1281 else | 1291 else |
1282 { | 1292 { |
1283 return -ESRCH; | 1293 return -ESRCH; |
1284 } | 1294 } |
1285 } | 1295 } |
1286 return 0; | 1296 return 0; |
1287 } | 1297 } |
1288 | 1298 |
1289 int | 1299 int |
1290 SwitchNetDevice::ModFlow (const ofp_flow_mod *ofm) | 1300 SwitchNetDevice::ModFlow (const ofp_flow_mod *ofm) |
1291 { | 1301 { |
1292 sw_flow_key key; | 1302 sw_flow_key key; |
1293 flow_extract_match (&key, &ofm->match); | 1303 flow_extract_match (&key, &ofm->match); |
1294 | 1304 |
1295 size_t actions_len = ntohs (ofm->header.length) - sizeof *ofm; | 1305 size_t actions_len = ntohs (ofm->header.length) - sizeof *ofm; |
1296 | 1306 |
1297 uint16_t v_code = ValidateActions (&key, ofm->actions, actions_len); | 1307 uint16_t v_code = ofi::ValidateActions (&key, ofm->actions, actions_len); |
1298 if (v_code != ACT_VALIDATION_OK) | 1308 if (v_code != ACT_VALIDATION_OK) |
1299 { | 1309 { |
1300 SendErrorMsg ((ofp_error_type)OFPET_BAD_ACTION, v_code, ofm, ntohs (ofm->h
eader.length)); | 1310 SendErrorMsg ((ofp_error_type)OFPET_BAD_ACTION, v_code, ofm, ntohs (ofm->h
eader.length)); |
1301 if (ntohl (ofm->buffer_id) != (uint32_t) -1) | 1311 if (ntohl (ofm->buffer_id) != (uint32_t) -1) |
1302 { | 1312 { |
1303 discard_buffer (ntohl (ofm->buffer_id)); | 1313 discard_buffer (ntohl (ofm->buffer_id)); |
1304 } | 1314 } |
1305 return -ENOMEM; | 1315 return -ENOMEM; |
1306 } | 1316 } |
1307 | 1317 |
1308 uint16_t priority = key.wildcards ? ntohs (ofm->priority) : -1; | 1318 uint16_t priority = key.wildcards ? ntohs (ofm->priority) : -1; |
1309 int strict = (ofm->command == htons (OFPFC_MODIFY_STRICT)) ? 1 : 0; | 1319 int strict = (ofm->command == htons (OFPFC_MODIFY_STRICT)) ? 1 : 0; |
1310 chain_modify (m_chain, &key, priority, strict, ofm->actions, actions_len); | 1320 chain_modify (m_chain, &key, priority, strict, ofm->actions, actions_len); |
1311 | 1321 |
1312 if (ntohl (ofm->buffer_id) != numeric_limits<uint32_t>::max ()) | 1322 if (ntohl (ofm->buffer_id) != std::numeric_limits<uint32_t>::max ()) |
1313 { | 1323 { |
1314 ofpbuf *buffer = retrieve_buffer (ofm->buffer_id); // ntohl (ofm->buffer_i
d) | 1324 ofpbuf *buffer = retrieve_buffer (ofm->buffer_id); // ntohl (ofm->buffer_i
d) |
1315 if (buffer) | 1325 if (buffer) |
1316 { | 1326 { |
1317 sw_flow_key skb_key; | 1327 sw_flow_key skb_key; |
1318 flow_extract (buffer, ofm->match.in_port, &skb_key.flow); // ntohs(ofm
->match.in_port); | 1328 flow_extract (buffer, ofm->match.in_port, &skb_key.flow); // ntohs(ofm
->match.in_port); |
1319 ExecuteActions (this, ofm->buffer_id, buffer, &skb_key, ofm->actions,
actions_len, false); | 1329 ofi::ExecuteActions (this, ofm->buffer_id, buffer, &skb_key, ofm->acti
ons, actions_len, false); |
1320 ofpbuf_delete (buffer); | 1330 ofpbuf_delete (buffer); |
1321 } | 1331 } |
1322 else | 1332 else |
1323 { | 1333 { |
1324 return -ESRCH; | 1334 return -ESRCH; |
1325 } | 1335 } |
1326 } | 1336 } |
1327 return 0; | 1337 return 0; |
1328 } | 1338 } |
1329 | 1339 |
(...skipping 26 matching lines...) Expand all Loading... |
1356 priority = key.wildcards ? ntohs (ofm->priority) : -1; | 1366 priority = key.wildcards ? ntohs (ofm->priority) : -1; |
1357 return chain_delete (m_chain, &key, ofm->out_port, priority, 1) ? 0 : -ESR
CH; | 1367 return chain_delete (m_chain, &key, ofm->out_port, priority, 1) ? 0 : -ESR
CH; |
1358 } | 1368 } |
1359 else | 1369 else |
1360 { | 1370 { |
1361 return -ENODEV; | 1371 return -ENODEV; |
1362 } | 1372 } |
1363 } | 1373 } |
1364 | 1374 |
1365 int | 1375 int |
1366 SwitchNetDevice::StatsDump (StatsDumpCallback *cb) | 1376 SwitchNetDevice::StatsDump (ofi::StatsDumpCallback *cb) |
1367 { | 1377 { |
1368 ofp_stats_reply *osr; | 1378 ofp_stats_reply *osr; |
1369 ofpbuf *buffer; | 1379 ofpbuf *buffer; |
1370 int err; | 1380 int err; |
1371 | 1381 |
1372 if (cb->done) | 1382 if (cb->done) |
1373 { | 1383 { |
1374 return 0; | 1384 return 0; |
1375 } | 1385 } |
1376 | 1386 |
(...skipping 19 matching lines...) Expand all Loading... |
1396 if (err2) | 1406 if (err2) |
1397 { | 1407 { |
1398 err = err2; | 1408 err = err2; |
1399 } | 1409 } |
1400 } | 1410 } |
1401 | 1411 |
1402 return err; | 1412 return err; |
1403 } | 1413 } |
1404 | 1414 |
1405 void | 1415 void |
1406 SwitchNetDevice::StatsDone (StatsDumpCallback *cb) | 1416 SwitchNetDevice::StatsDone (ofi::StatsDumpCallback *cb) |
1407 { | 1417 { |
1408 if (cb) | 1418 if (cb) |
1409 { | 1419 { |
1410 cb->s->DoCleanup (cb->state); | 1420 cb->s->DoCleanup (cb->state); |
1411 free (cb->s); | 1421 free (cb->s); |
1412 free (cb); | 1422 free (cb); |
1413 } | 1423 } |
1414 } | 1424 } |
1415 | 1425 |
1416 int | 1426 int |
1417 SwitchNetDevice::ReceiveStatsRequest (const void *oh) | 1427 SwitchNetDevice::ReceiveStatsRequest (const void *oh) |
1418 { | 1428 { |
1419 const ofp_stats_request *rq = (ofp_stats_request*)oh; | 1429 const ofp_stats_request *rq = (ofp_stats_request*)oh; |
1420 size_t rq_len = ntohs (rq->header.length); | 1430 size_t rq_len = ntohs (rq->header.length); |
1421 int type = ntohs (rq->type); | 1431 int type = ntohs (rq->type); |
1422 int body_len = rq_len - offsetof (ofp_stats_request, body); | 1432 int body_len = rq_len - offsetof (ofp_stats_request, body); |
1423 Stats* st = new Stats ((ofp_stats_types)type, (unsigned)body_len); | 1433 ofi::Stats* st = new ofi::Stats ((ofp_stats_types)type, (unsigned)body_len); |
1424 ·· | 1434 ·· |
1425 if (st == 0) | 1435 if (st == 0) |
1426 { | 1436 { |
1427 return -EINVAL; | 1437 return -EINVAL; |
1428 } | 1438 } |
1429 | 1439 |
1430 StatsDumpCallback cb; | 1440 ofi::StatsDumpCallback cb; |
1431 cb.done = false; | 1441 cb.done = false; |
1432 cb.rq = (ofp_stats_request*)xmemdup (rq, rq_len); | 1442 cb.rq = (ofp_stats_request*)xmemdup (rq, rq_len); |
1433 cb.s = st; | 1443 cb.s = st; |
1434 cb.state = 0; | 1444 cb.state = 0; |
1435 cb.swtch = this; | 1445 cb.swtch = this; |
1436 | 1446 |
1437 if (cb.s) | 1447 if (cb.s) |
1438 { | 1448 { |
1439 int err = cb.s->DoInit (rq->body, body_len, &cb.state); | 1449 int err = cb.s->DoInit (rq->body, body_len, &cb.state); |
1440 if (err) | 1450 if (err) |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1536 return m_chain; | 1546 return m_chain; |
1537 } | 1547 } |
1538 | 1548 |
1539 uint32_t | 1549 uint32_t |
1540 SwitchNetDevice::GetNSwitchPorts (void) const | 1550 SwitchNetDevice::GetNSwitchPorts (void) const |
1541 { | 1551 { |
1542 NS_LOG_FUNCTION_NOARGS (); | 1552 NS_LOG_FUNCTION_NOARGS (); |
1543 return m_ports.size (); | 1553 return m_ports.size (); |
1544 } | 1554 } |
1545 | 1555 |
1546 Port | 1556 ofi::Port |
1547 SwitchNetDevice::GetSwitchPort (uint32_t n) const | 1557 SwitchNetDevice::GetSwitchPort (uint32_t n) const |
1548 { | 1558 { |
1549 NS_LOG_FUNCTION_NOARGS (); | 1559 NS_LOG_FUNCTION_NOARGS (); |
1550 return m_ports[n]; | 1560 return m_ports[n]; |
1551 } | 1561 } |
1552 | 1562 |
1553 int | 1563 int |
1554 SwitchNetDevice::GetSwitchPortIndex (Port p) | 1564 SwitchNetDevice::GetSwitchPortIndex (ofi::Port p) |
1555 { | 1565 { |
1556 for (size_t i = 0; i < m_ports.size (); i++) | 1566 for (size_t i = 0; i < m_ports.size (); i++) |
1557 { | 1567 { |
1558 if (m_ports[i].netdev == p.netdev) | 1568 if (m_ports[i].netdev == p.netdev) |
1559 { | 1569 { |
1560 return i; | 1570 return i; |
1561 } | 1571 } |
1562 } | 1572 } |
1563 return -1; | 1573 return -1; |
1564 } | 1574 } |
1565 | 1575 |
1566 vport_table_t | 1576 vport_table_t |
1567 SwitchNetDevice::GetVPortTable () | 1577 SwitchNetDevice::GetVPortTable () |
1568 { | 1578 { |
1569 return m_vportTable; | 1579 return m_vportTable; |
1570 } | 1580 } |
1571 | 1581 |
1572 } // namespace ns3 | 1582 } // namespace ns3 |
1573 | 1583 |
1574 #endif // NS3_OPENFLOW | 1584 #endif // NS3_OPENFLOW |
LEFT | RIGHT |