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

Generated by: LCOV version 1.14