25 #include "ns3/openflow-switch-net-device.h"
26 #include "ns3/openflow-interface.h"
43 m_chain = chain_create ();
48 chain_destroy (m_chain);
52 virtual void DoRun (
void);
66 size_t actions_len = 0;
69 Mac48Address dl_src (
"00:00:00:00:00:00"), dl_dst (
"00:00:00:00:00:01");
70 Ipv4Address nw_src (
"192.168.1.1"), nw_dst (
"192.168.1.2");
71 int tp_src = 5000, tp_dst = 80;
77 key.flow.in_port = htons (0);
79 key.flow.dl_vlan = htons (OFP_VLAN_NONE);
80 key.flow.dl_type = htons (ETH_TYPE_IP);
81 key.flow.nw_proto = htons (IP_TYPE_UDP);
83 key.flow.reserved = 0;
84 key.flow.mpls_label1 = htonl (MPLS_INVALID_LABEL);
85 key.flow.mpls_label2 = htonl (MPLS_INVALID_LABEL);
88 dl_src.CopyTo (key.flow.dl_src);
89 dl_dst.
CopyTo (key.flow.dl_dst);
92 key.flow.nw_src = htonl (nw_src.Get ());
93 key.flow.nw_dst = htonl (nw_dst.
Get ());
96 key.flow.tp_src = htonl (tp_src);
97 key.flow.tp_dst = htonl (tp_dst);
101 ofm.header.version = OFP_VERSION;
102 ofm.header.type = OFPT_FLOW_MOD;
103 ofm.header.length = htons (
sizeof (ofp_flow_mod) + actions_len);
104 ofm.command = htons (OFPFC_ADD);
105 ofm.idle_timeout = htons (OFP_FLOW_PERMANENT);
106 ofm.hard_timeout = htons (OFP_FLOW_PERMANENT);
107 ofm.buffer_id = htonl (-1);
108 ofm.priority = OFP_DEFAULT_PRIORITY;
110 ofm.match.wildcards = key.wildcards;
111 ofm.match.in_port = key.flow.in_port;
112 memcpy (ofm.match.dl_src, key.flow.dl_src,
sizeof ofm.match.dl_src);
113 memcpy (ofm.match.dl_dst, key.flow.dl_dst,
sizeof ofm.match.dl_dst);
114 ofm.match.dl_vlan = key.flow.dl_vlan;
115 ofm.match.dl_type = key.flow.dl_type;
116 ofm.match.nw_proto = key.flow.nw_proto;
117 ofm.match.nw_src = key.flow.nw_src;
118 ofm.match.nw_dst = key.flow.nw_dst;
119 ofm.match.tp_src = key.flow.tp_src;
120 ofm.match.tp_dst = key.flow.tp_dst;
121 ofm.match.mpls_label1 = key.flow.mpls_label1;
122 ofm.match.mpls_label2 = key.flow.mpls_label1;
125 sw_flow *flow = flow_alloc (actions_len);
128 flow_extract_match (&flow->key, &ofm.match);
131 flow->priority = flow->key.wildcards ? ntohs (ofm.priority) : -1;
132 flow->idle_timeout = ntohs (ofm.idle_timeout);
133 flow->hard_timeout = ntohs (ofm.hard_timeout);
134 flow->used = flow->created = time_now ();
135 flow->sf_acts->actions_len = actions_len;
136 flow->byte_count = 0;
137 flow->packet_count = 0;
138 memcpy (flow->sf_acts->actions, ofm.actions, actions_len);
144 NS_TEST_ASSERT_MSG_NE (chain_lookup (m_chain, &key), 0,
"Key provided doesn't match to the flow that was created from it.");
147 dl_dst.
CopyTo (key.flow.dl_src);
148 dl_src.CopyTo (key.flow.dl_dst);
149 key.flow.nw_src = htonl (nw_dst.
Get ());
150 key.flow.nw_dst = htonl (nw_src.Get ());
151 key.flow.tp_src = htonl (tp_dst);
152 key.flow.tp_dst = htonl (tp_src);
154 NS_TEST_ASSERT_MSG_EQ (chain_lookup (m_chain, &key), 0,
"Key provided shouldn't match the flow but it does.");
157 dl_dst.
CopyTo (key.flow.dl_dst);
158 dl_src.CopyTo (key.flow.dl_src);
159 key.flow.nw_src = htonl (nw_src.Get ());
160 key.flow.nw_dst = htonl (nw_dst.
Get ());
161 key.flow.tp_src = htonl (tp_src);
162 key.flow.tp_dst = htonl (tp_dst);
166 ofp_action_output acts[1];
167 acts[0].type = htons (OFPAT_OUTPUT);
168 acts[0].len = htons (
sizeof (ofp_action_output));
169 acts[0].port = output_port;
171 uint16_t priority = key.wildcards ? ntohs (ofm.priority) : -1;
172 NS_TEST_ASSERT_MSG_EQ (chain_modify (m_chain, &key, priority,
false, (
const ofp_action_header*)acts,
sizeof (acts)), 1,
"Flow table failed to modify Flow.");
177 NS_TEST_ASSERT_MSG_EQ (chain_delete (m_chain, &key, output_port, 0, 0), 1,
"Flow table failed to delete Flow.");
178 NS_TEST_ASSERT_MSG_EQ (chain_lookup (m_chain, &key), 0,
"Key provided shouldn't match the flow but it does.");
SwitchFlowTableTestCase()
virtual void DoRun(void)
Implementation to actually run this TestCase.
virtual ~SwitchFlowTableTestCase()
sw_chain * m_chain
OpenFlow service function chain.
Ipv4 addresses are stored in host order in this class.
uint32_t Get(void) const
Get the host-order 32-bit IP address.
void CopyTo(uint8_t buffer[6]) const
void AddTestCase(TestCase *testCase, TestDuration duration=QUICK)
Add an individual child TestCase to this test suite.
#define NS_TEST_ASSERT_MSG_EQ(actual, limit, msg)
Test that an actual and expected (limit) value are equal and report and abort if not.
#define NS_TEST_ASSERT_MSG_NE(actual, limit, msg)
Test that an actual and expected (limit) value are not equal and report and abort if not.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
static SwitchTestSuite switchTestSuite
Do not forget to allocate an instance of this TestSuite.