OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
test_xml_packet.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3  */
4 #include <base/os.h>
5 #include <iostream>
6 #include <fstream>
7 #include <pugixml/pugixml.hpp>
8 #include <boost/uuid/uuid.hpp>
9 #include <boost/uuid/string_generator.hpp>
10 
11 #include <test/test_cmn_util.h>
12 #include <pkt/test/test_pkt_util.h>
13 #include <oper/physical_device.h>
15 
16 #include <test-xml/test_xml.h>
17 #include <test-xml/test_xml_oper.h>
20 
21 using namespace std;
22 using namespace pugi;
23 using namespace boost::uuids;
24 using namespace AgentUtXmlUtils;
25 int hash_id = 1;
26 
28  name_ = "pkt";
29  len_ = 64;
30  vrf_id_ = -1;
31  vrf_str_ = "";
32  ingress_ = false;
33  fwd_mode_ = "l3";
34  pkt_module_ = "flow";
35 
36  intf_id_ = 0;
37  intf_ = "";
38 
39  tunnel_type_ = "";
40  tunnel_sip_ = "0.0.0.0";
41  tunnel_dip_ = "0.0.0.0";
42  label_ = -1;
43  vxlan_id_ = 0;
44 
45  smac_ = "00:00:00:00:00:01";
46  dmac_ = "00:00:00:00:00:02";
47  sip_ = "1.1.1.1";
48  dip_ = "1.1.1.2";
49  proto_id_ = 1;
50  proto_ = "icmp";
51  sport_ = 1;
52  dport_ = 2;
53  tcp_ack_ = false;
54 
55  trap_code_ = "flow";
56  hash_id_ = 0;
57 }
58 
60 }
61 
63  const {
64  if (tunnel_type_ == "gre" || tunnel_type_ == "GRE")
65  return TunnelType::MPLS_GRE;
66  if (tunnel_type_ == "udp" || tunnel_type_ == "UDP")
67  return TunnelType::MPLS_UDP;
68  if (tunnel_type_ == "vxlan" || tunnel_type_ == "VXLAN")
69  return TunnelType::VXLAN;
70  return TunnelType::INVALID;
71 }
72 
74  if (proto_ == "tcp")
75  return 6;
76  if (proto_ == "udp")
77  return 17;
78  if (proto_ == "icmp")
79  return 1;
80 
81  return atoi(proto_.c_str());
82 }
83 
85  if (trap_code_ == "flow")
87 
88  assert(0);
89  return AgentHdr::INVALID;
90 }
91 
93  if (pkt_module_ == "flow" || pkt_module_ == "FLOW")
94  return PktHandler::FLOW;
95  if (pkt_module_ == "invalid" || pkt_module_ == "INVALID")
96  return PktHandler::INVALID;
97 
98  assert(0);
99  return PktHandler::INVALID;
100 }
101 
103  if (fwd_mode_ == "l2" || fwd_mode_ == "L2")
104  return true;
105  return false;
106 }
107 
109  if (fwd_mode_ == "l3" || fwd_mode_ == "L3")
110  return true;
111  return false;
112 }
113 
114 bool AgentUtXmlPacketUtils::ReadXml(const pugi::xml_node &node) {
115  GetStringAttribute(node, "fwd_mode", &fwd_mode_);
116  GetStringAttribute(node, "pkt-module", &pkt_module_);
117 
118  GetStringAttribute(node, "tunnel_type", &tunnel_type_);
119  if (tunnel_type_ != "") {
120  GetStringAttribute(node, "tunnel_sip", &tunnel_sip_);
121  GetStringAttribute(node, "tunnel_dip", &tunnel_dip_);
122  GetUintAttribute(node, "label", (uint16_t *)&label_);
123  GetUintAttribute(node, "vxlan-id", (uint16_t *)&vxlan_id_);
124  }
125 
126  GetStringAttribute(node, "smac", &smac_);
127  GetStringAttribute(node, "dmac", &dmac_);
128 
129  GetUintAttribute(node, "intf-id", (uint16_t *)&intf_id_);
130  GetStringAttribute(node, "intf", &intf_);
131  GetStringAttribute(node, "interface", &intf_);
132 
133  GetStringAttribute(node, "sip", &sip_);
134  GetStringAttribute(node, "dip", &dip_);
135  GetStringAttribute(node, "proto", &proto_);
136  GetUintAttribute(node, "proto", &proto_id_);
137  GetUintAttribute(node, "sport", &sport_);
138  GetUintAttribute(node, "dport", &dport_);
139  GetUintAttribute(node, "hash_id", (uint16_t *)&hash_id_);
140 
141  if (hash_id_ == 0) {
142  hash_id_ = hash_id++;
143  }
144  return true;
145 }
146 
148  stringstream s;
149  if (tunnel_type_ == "") {
150  s << "Packet < " << name_ << "> Interface <" << intf_ << "> ";
151  } else {
152  s << "Packet < " << name_ << "> Tunnel <" << tunnel_type_ << " : "
153  << intf_ << " : " << label_ << " : " << tunnel_sip_ << " : "
154  << tunnel_dip_ << "> ";
155  }
156  s << "<" << sip_ << " : " << dip_ << " : " << proto_ << " : " << sport_
157  << " : " << dport_ << ">" << endl;
158  return s.str();
159 }
160 
161 static int GetVxlan(Interface *intf) {
162  int vxlan = 0;
163  if (intf) {
164  VmInterface *vmi = static_cast<VmInterface *>(intf);
165  if (vmi->vn()) {
166  vxlan = vmi->vn()->GetVxLanId();
167  }
168  }
169  return vxlan;
170 }
171 
173  PktGen *pkt) {
174  TunnelType::Type tun_type = GetTunnelType();
175  if (tun_type != TunnelType::INVALID) {
176  pkt->AddEthHdr("00:00:00:00:00:01", "00:00:00:00:00:02", 0x800);
177  const VmInterface *vhost = static_cast<const VmInterface *>
178  (agent->vhost_interface());
179  string dip = tunnel_dip_;
180  if (dip == "0.0.0.0") {
181  dip = vhost->primary_ip_addr().to_string();
182  }
183 
184  uint8_t proto = IPPROTO_UDP;
185  if (tun_type == TunnelType::MPLS_GRE)
186  proto = IPPROTO_GRE;
187 
188  pkt->AddIpHdr(tunnel_sip_.c_str(), dip.c_str(), proto);
189  if (tun_type == TunnelType::MPLS_GRE) {
190  pkt->AddGreHdr();
191  pkt->AddMplsHdr(label_, true);
192  } else if (tun_type == TunnelType::MPLS_UDP) {
193  pkt->AddUdpHdr(VR_MPLS_OVER_UDP_SRC_PORT, VR_MPLS_OVER_UDP_DST_PORT,
194  (len_ + 100));
195  pkt->AddMplsHdr(label_, true);
196  } else if (tun_type == TunnelType::VXLAN) {
197  pkt->AddUdpHdr(VR_VXLAN_UDP_SRC_PORT, VR_VXLAN_UDP_DST_PORT, 0);
198  int vxlan = GetVxlan(intf);
199  pkt->AddVxlanHdr(vxlan);
200  }
201 
202  if (fwd_mode_ == "l2") {
203  pkt->AddEthHdr(dmac_.c_str(), smac_.c_str(), 0x800);
204  }
205  } else {
206  pkt->AddEthHdr(dmac_.c_str(), smac_.c_str(), 0x800);
207  }
208 
209  pkt->AddIpHdr(sip_.c_str(), dip_.c_str(), proto_id_);
210  if (proto_id_ == 17) {
211  pkt->AddUdpHdr(sport_, dport_, len_);
212  } else if (proto_id_ == 6) {
213  pkt->AddTcpHdr(sport_, dport_, false, false, tcp_ack_, len_);
214  } else if (proto_id_ == 1) {
215  pkt->AddIcmpHdr();
216  } else {
217  assert(0);
218  }
219  return true;
220 }
221 
223  PktGen *pkt) {
224  return true;
225 }
226 
227 bool AgentUtXmlPacketUtils::MakePacket(Agent *agent, PktGen *pkt) {
228  bool ret = false;
229 
230  boost::system::error_code ec;
231  IpAddress ip = IpAddress::from_string(sip_, ec);
232 
233  bool ingress_flow = true;
234  TunnelType::Type tunnel_type = GetTunnelType();
235  if (tunnel_type != TunnelType::INVALID) {
236  ingress_flow = false;
237  }
238 
239  VmInterface *intf = NULL;
240  if (atoi(intf_.c_str())) {
241  intf = static_cast<VmInterface *>(VmPortGet(atoi(intf_.c_str())));
242  if (intf) {
243  intf_id_ = intf->id();
244  }
245  }
246 
247  if (tunnel_type == TunnelType::MPLS_GRE) {
248  if (IsL2Mode()) {
249  label_ = intf->l2_label();
250  } else {
251  label_ = intf->label();
252  }
253  }
254 
255  if (fwd_mode_ != "l2") {
256  if (ingress_flow)
257  dmac_ = agent->vrrp_mac().ToString();
258  else
259  dmac_ = intf->mac().ToString();
260  }
261 
262  if (proto_id_ == 0) {
263  proto_id_ = GetIpProto();
264  }
265 
266  uint16_t if_id = intf_id_;
267  if (tunnel_type != TunnelType::INVALID) {
268  const VmInterface *vhost = static_cast<const VmInterface *>
269  (agent->vhost_interface());
270  if_id = vhost->parent_list()[0]->id();
271  }
272 
273  int vxlan_id = 0;
274  if ((tunnel_type == TunnelType::VXLAN) && (ingress_flow == false)) {
275  vxlan_id = GetVxlan(intf);
276  }
277 
278  if (intf->vmi_type() == VmInterface::BAREMETAL) {
279  vxlan_id = GetVxlan(intf);
280  }
281 
282  pkt->AddEthHdr("00:00:00:00:00:01", "00:00:00:00:00:02", 0x800);
283  pkt->AddAgentHdr(if_id, GetTrapCode(), hash_id_, vrf_id_, label_, vxlan_id);
284  if (ip.is_v4()) {
285  ret = InetPacket(intf, agent, pkt);
286  } else {
287  ret = Inet6Packet(intf, agent, pkt);
288  }
289 
290  return ret;
291 }
292 
294 // AgentUtXmlPacket routines
296 AgentUtXmlPacket::AgentUtXmlPacket(const string &name, const xml_node &node,
297  AgentUtXmlTestCase *test_case) :
298  AgentUtXmlNode(name, node, false, test_case), pkt_() {
299 }
300 
302 }
303 
306  return pkt_.ReadXml(node());
307 }
308 
309 bool AgentUtXmlPacket::ToXml(xml_node *parent) {
310  assert(0);
311  return true;
312 }
313 
314 void AgentUtXmlPacket::ToString(string *str) {
315  *str = pkt_.ToString();
316  return;
317 }
318 
320  return "packet";
321 }
322 
324  cout << "Generate packet" << endl;
325  Agent *agent = Agent::GetInstance();
326  PktGen pkt;
327  pkt_.MakePacket(agent, &pkt);
328 
329  uint8_t *ptr(new uint8_t[pkt.GetBuffLen()]);
330  memcpy(ptr, pkt.GetBuff(), pkt.GetBuffLen());
331 
332  TestPkt0Interface *pkt0 = static_cast<TestPkt0Interface *>
333  (agent->pkt()->control_interface());
334  pkt0->ProcessFlowPacket(ptr, pkt.GetBuffLen(), pkt.GetBuffLen());
335  return true;
336 }
337 
339 // AgentUtXmlPktParseValidate routines
342  const xml_node &node) :
343  AgentUtXmlValidationNode(name, node), pkt_() {
344 }
345 
347 }
348 
350  return pkt_.ReadXml(node());
351 }
352 
354  return pkt_.ToString();
355 }
356 
358  PktInfo *info) {
359  bool ret = true;
360 
361  if (type != pkt_.GetPacketModule())
362  return false;
363 
364  if (type == PktHandler::INVALID)
365  return true;
366 
367  if (info->ip_saddr != Ip4Address::from_string(pkt_.sip_) &&
368  (info->ip_saddr != Ip6Address::from_string(pkt_.sip_)))
369  return false;
370 
371  if (info->ip_daddr != Ip4Address::from_string(pkt_.dip_) &&
372  (info->ip_daddr != Ip6Address::from_string(pkt_.dip_)))
373  return false;
374 
375  if (pkt_.IsL3Mode() == false) {
376  if (info->smac != MacAddress::FromString(pkt_.smac_))
377  return false;
378  if (info->dmac != MacAddress::FromString(pkt_.dmac_))
379  return false;
380  }
381 
382  if (pkt_.proto_id_ != info->ip_proto) {
383  return false;
384  }
385 
386  if (pkt_.proto_id_ == 6 || pkt_.proto_id_ == 17) {
387  if (pkt_.sport_ != info->sport)
388  return false;
389  if (pkt_.dport_ != info->dport)
390  return false;
391  }
392 
393  return ret;
394 }
395 
397  Agent *agent = Agent::GetInstance();
398  cout << "Generating packet" << endl;
399 
400  PktGen pkt;
401  pkt_.MakePacket(agent, &pkt);
402 
403  uint32_t buff_len = pkt.GetBuffLen();
404  uint32_t payload_len = pkt.GetBuffLen();
405  uint8_t *ptr(new uint8_t[buff_len]);
406  memcpy(ptr, pkt.GetBuff(), pkt.GetBuffLen());
407 
409  (PktHandler::RX_PACKET, ptr, buff_len, buff_len - payload_len,
410  payload_len, 0));
411 
412  PktInfo pkt_info(buff);
413  VrouterControlInterface *pkt0 = static_cast<VrouterControlInterface *>
414  (agent->pkt()->control_interface());
415 
416  AgentHdr agent_hdr;
417  pkt0->DecodeAgentHdr(&agent_hdr, (uint8_t *)(ptr), payload_len);
418 
420  type = agent->pkt()->pkt_handler()->ParsePacket(agent_hdr, &pkt_info,
421  (ptr + ETH_HLEN +
422  sizeof(struct agent_hdr)));
423  return Validate(type, &pkt_info);
424 }
int GetVxLanId() const
Definition: vn.cc:727
uint32_t dport
Definition: pkt_handler.h:398
IpAddress ip_saddr
Definition: pkt_handler.h:394
boost::shared_ptr< PacketBuffer > PacketBufferPtr
Definition: packet_buffer.h:18
int hash_id
static Agent * GetInstance()
Definition: agent.h:436
const uint32_t id() const
Definition: interface.h:123
bool Inet6Packet(Interface *intf, Agent *agent, PktGen *pkt)
uint8_t ip_proto
Definition: pkt_handler.h:396
const Interface * vhost_interface() const
Definition: agent.h:935
virtual bool Run()
boost::asio::ip::address IpAddress
Definition: address.h:13
static const MacAddress & vrrp_mac()
Definition: agent.h:439
virtual bool ReadXml()=0
Definition: test_xml.cc:466
virtual void ToString(std::string *str)
MacAddress dmac
Definition: pkt_handler.h:393
AgentUtXmlPktParseValidate(const std::string &name, const pugi::xml_node &node)
virtual std::string NodeType()
ControlInterface * control_interface() const
Definition: pkt_init.h:46
const MacAddress & mac() const
Definition: interface.h:131
std::string ToString() const
Definition: mac_address.cc:53
uint32_t sport
Definition: pkt_handler.h:397
uint32_t label() const
Definition: interface.h:127
virtual ~AgentUtXmlPacketUtils()
uint8_t type
Definition: load_balance.h:109
PktHandler::PktModuleName GetPacketModule() const
Definition: agent.h:358
uint8_t GetIpProto() const
AgentUtXmlPacket(const std::string &name, const pugi::xml_node &node, AgentUtXmlTestCase *test_case)
virtual const std::string ToString()
AgentUtXmlPacketUtils pkt_
bool MakePacket(Agent *agent, PktGen *pkt)
AgentUtXmlPacketUtils pkt_
virtual bool ReadXml()
bool GetStringAttribute(const xml_node &node, const string &name, string *value)
Definition: test_xml.cc:25
PktHandler * pkt_handler() const
Definition: pkt_init.h:31
const VnEntry * vn() const
PktModuleName ParsePacket(const AgentHdr &hdr, PktInfo *pkt_info, uint8_t *pkt)
Definition: pkt_handler.cc:280
static int GetVxlan(Interface *intf)
bool InetPacket(Interface *intf, Agent *agent, PktGen *pkt)
const Ip4Address & primary_ip_addr() const
uint8_t GetTrapCode() const
PacketBufferManager * packet_buffer_manager() const
Definition: pkt_init.h:33
bool GetUintAttribute(const xml_node &node, const string &name, uint16_t *value)
Definition: test_xml.cc:37
VmInterface::VmiType vmi_type() const
bool ReadXml(const pugi::xml_node &node)
uint32_t l2_label() const
Definition: interface.h:128
virtual bool ToXml(pugi::xml_node *parent)
PacketBufferPtr Allocate(uint32_t module, uint16_t len, uint32_t mdata)
MacAddress smac
Definition: pkt_handler.h:392
const pugi::xml_node & node() const
IpAddress ip_daddr
Definition: pkt_handler.h:395
TunnelType::Type GetTunnelType() const
PktModule * pkt() const
Definition: agent.cc:965
static MacAddress FromString(const std::string &str, boost::system::error_code *error=NULL)
Definition: mac_address.cc:71
virtual ~AgentUtXmlPacket()
InterfaceList parent_list() const
const pugi::xml_node & node() const
Definition: test_xml.h:131
int DecodeAgentHdr(AgentHdr *hdr, uint8_t *buff, uint32_t len)