LCOV - code coverage report
Current view: top level - vnsw/agent/test-xml - test_xml_packet.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 228 261 87.4 %
Date: 2026-11-09 02:10:49 Functions: 26 30 86.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.14