LCOV - code coverage report
Current view: top level - vnsw/agent/oper - physical_interface.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 198 0.0 %
Date: 2026-06-22 02:21:21 Functions: 0 26 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include <boost/uuid/uuid_io.hpp>
       6             : #include <vnc_cfg_types.h>
       7             : #include <cmn/agent_cmn.h>
       8             : 
       9             : #include <net/if.h>
      10             : #include <ifmap/ifmap_node.h>
      11             : #include <cfg/cfg_init.h>
      12             : #include <cfg/cfg_listener.h>
      13             : #include <oper/agent_sandesh.h>
      14             : #include <oper/ifmap_dependency_manager.h>
      15             : #include <oper/interface_common.h>
      16             : #include <oper/physical_device.h>
      17             : #include <oper/nexthop.h>
      18             : #include <oper/config_manager.h>
      19             : 
      20             : #include <vector>
      21             : #include <string>
      22             : 
      23             : using std::string;
      24             : 
      25             : /////////////////////////////////////////////////////////////////////////////
      26             : // PhysicalInterface routines
      27             : /////////////////////////////////////////////////////////////////////////////
      28           0 : PhysicalInterface::PhysicalInterface(const std::string &name,
      29           0 :                            const boost::uuids::uuid &logical_router_uuid) :
      30           0 :     Interface(Interface::PHYSICAL, boost::uuids::nil_uuid(), name, NULL, true,
      31             :               logical_router_uuid),
      32           0 :     persistent_(false), subtype_(INVALID), physical_device_(NULL) {
      33           0 : }
      34             : 
      35           0 : PhysicalInterface::~PhysicalInterface() {
      36           0 : }
      37             : 
      38           0 : PhysicalDevice *PhysicalInterface::physical_device() const {
      39           0 :     return physical_device_.get();
      40             : }
      41             : 
      42           0 : string PhysicalInterface::ToString() const {
      43           0 :     return "PORT <" + name() + ">";
      44             : }
      45             : 
      46           0 : bool PhysicalInterface::CmpInterface(const DBEntry &rhs) const {
      47           0 :     const PhysicalInterface &a = static_cast<const PhysicalInterface &>(rhs);
      48           0 :     return name() < a.name();
      49             : }
      50             : 
      51           0 : DBEntryBase::KeyPtr PhysicalInterface::GetDBRequestKey() const {
      52           0 :     InterfaceKey *key = new PhysicalInterfaceKey(name());
      53           0 :     return DBEntryBase::KeyPtr(key);
      54             : }
      55             : 
      56           0 : bool PhysicalInterface::OnChange(const InterfaceTable *table,
      57             :                                  const PhysicalInterfaceData *data) {
      58           0 :     bool ret = false;
      59             :     const PhysicalInterfaceOsOperStateData *osOperStateData =
      60           0 :         dynamic_cast<const PhysicalInterfaceOsOperStateData *>(data);
      61             : 
      62           0 :     if(osOperStateData) {
      63           0 :         ret = osOperStateData->OnResync(this);
      64             :     }
      65             :     else {
      66             :         // Handle VRF Change
      67           0 :         VrfKey key(data->vrf_name_);
      68           0 :         VrfEntry *new_vrf = static_cast<VrfEntry *>
      69           0 :             (table->agent()->vrf_table()->FindActiveEntry(&key));
      70           0 :         if (new_vrf != vrf_.get()) {
      71           0 :             vrf_.reset(new_vrf);
      72           0 :             ret = true;
      73             : 
      74             :         }
      75             : 
      76             :         PhysicalDevice *dev =
      77           0 :             table->agent()->physical_device_table()->Find(data->device_uuid_);
      78           0 :         if (dev != physical_device_.get()) {
      79           0 :             physical_device_.reset(dev);
      80           0 :             ret = true;
      81             :         }
      82           0 :     }
      83           0 :     return ret;
      84             : }
      85             : 
      86             : bool
      87           0 : PhysicalInterfaceOsOperStateData::OnResync(PhysicalInterface *phy_intf) const
      88             : {
      89           0 :     bool ret = false;
      90           0 :     if(type_ == PhysicalInterfaceOsOperStateData::VR_FABRIC) {
      91           0 :         if(phy_intf->os_params_.os_oper_state_ != oper_state_) {
      92           0 :             phy_intf->os_params_.os_oper_state_ = oper_state_;
      93           0 :             ret = true;
      94             :         }
      95           0 :     } else if(type_ == PhysicalInterfaceOsOperStateData::VR_BOND_SLAVES) {
      96           0 :         PhysicalInterface::Bond_ChildIntf bondIntf;
      97             : 
      98           0 :         bondIntf.intf_name = intf_name;
      99           0 :         bondIntf.intf_drv_name = intf_drv_name;
     100           0 :         bondIntf.intf_status = oper_state_;
     101             :         PhysicalInterface::BondChildIntfMap bond_childIntf_map =
     102           0 :               phy_intf->getBondChildIntfMap();
     103           0 :         bond_childIntf_map[intf_name] = bondIntf;
     104           0 :         phy_intf->setBondChildIntfMap(bond_childIntf_map);
     105           0 :         ret = true;
     106           0 :     }
     107             : 
     108           0 :     return ret;
     109             : }
     110             : 
     111           0 : bool PhysicalInterface::Delete(const DBRequest *req) {
     112           0 :     flow_key_nh_.reset();
     113           0 :     InterfaceNH::DeletePhysicalInterfaceNh(name(), mac());
     114           0 :     return true;
     115             : }
     116             : 
     117           0 : std::string PhysicalInterface::GetPhysicalInterfaceName() const {
     118           0 :     std::size_t pos = name().find_last_of(":");
     119           0 :     if (pos != string::npos) {
     120           0 :         return name().substr(pos + 1);
     121             :     }
     122           0 :     return name();
     123             : }
     124             : 
     125           0 : void PhysicalInterface::PostAdd() {
     126           0 :     InterfaceNH::CreatePhysicalInterfaceNh(name(), mac());
     127             : 
     128           0 :     InterfaceTable *table = static_cast<InterfaceTable *>(get_table());
     129           0 :     Agent *agent = table->agent();
     130             : 
     131           0 :     InterfaceNHKey key(new PhysicalInterfaceKey(name()), false, InterfaceNHFlags::INET4, mac());
     132             :     flow_key_nh_ = static_cast<InterfaceNH *>
     133           0 :         (agent->nexthop_table()->FindActiveEntry(&key));
     134           0 :     assert(flow_key_nh_);
     135             : 
     136             : 
     137           0 :     if (table->agent()->test_mode()) {
     138           0 :         return;
     139             :     }
     140             : 
     141           0 :     std::string interface_name = name();
     142             :     // Interfaces in VMWARE mode and having remote VMs
     143             :     // must be put into promiscuous mode
     144           0 :     if (subtype_ != VMWARE) {
     145           0 :         if (!table->agent()->server_gateway_mode() ||
     146           0 :             subtype_ == PhysicalInterface::FABRIC) {
     147           0 :             return;
     148             :         } else {
     149           0 :             interface_name = GetPhysicalInterfaceName();
     150             :         }
     151             :     }
     152             : 
     153           0 :     int fd = socket(AF_LOCAL, SOCK_STREAM, 0);
     154           0 :     assert(fd >= 0);
     155             : 
     156             :     struct ifreq ifr;
     157           0 :     memset(&ifr, 0, sizeof(ifr));
     158           0 :     strncpy(ifr.ifr_name, interface_name.c_str(), IF_NAMESIZE-1);
     159             : 
     160           0 :     if (ioctl(fd, SIOCGIFFLAGS, (void *)&ifr) < 0) {
     161           0 :         LOG(ERROR, "Error <" << errno << ": " << strerror(errno) <<
     162             :             "> setting promiscuous flag for interface <" << interface_name << ">");
     163           0 :         close(fd);
     164           0 :         return;
     165             :     }
     166             : 
     167           0 :     ifr.ifr_flags |= IFF_PROMISC;
     168           0 :     if (ioctl(fd, SIOCSIFFLAGS, (void *)&ifr) < 0) {
     169           0 :         LOG(ERROR, "Error <" << errno << ": " << strerror(errno) <<
     170             :             "> setting promiscuous flag for interface <" << interface_name << ">");
     171           0 :         close(fd);
     172           0 :         return;
     173             :     }
     174             : 
     175           0 :     close(fd);
     176             : 
     177           0 : }
     178             : 
     179             : /////////////////////////////////////////////////////////////////////////////
     180             : // PhysicalInterfaceKey routines
     181             : /////////////////////////////////////////////////////////////////////////////
     182           0 : PhysicalInterfaceKey::PhysicalInterfaceKey(const std::string &name) :
     183             :     InterfaceKey(AgentKey::ADD_DEL_CHANGE, Interface::PHYSICAL,
     184           0 :                  boost::uuids::nil_uuid(), name, false) {
     185           0 : }
     186             : 
     187           0 : PhysicalInterfaceKey::~PhysicalInterfaceKey() {
     188           0 : }
     189             : 
     190           0 : Interface *PhysicalInterfaceKey::AllocEntry(const InterfaceTable *table) const {
     191           0 :     return new PhysicalInterface(name_, boost::uuids::nil_uuid());
     192             : }
     193             : 
     194           0 : Interface *PhysicalInterfaceKey::AllocEntry(const InterfaceTable *table,
     195             :                                             const InterfaceData *data) const {
     196           0 :     PhysicalInterface *intf = new PhysicalInterface(name_,
     197           0 :                                                     data->logical_router_uuid_);
     198           0 :     const PhysicalInterfaceData *phy_data =
     199             :         static_cast<const PhysicalInterfaceData *>(data);
     200           0 :     intf->encap_type_ = phy_data->encap_type_;
     201           0 :     intf->no_arp_ = phy_data->no_arp_;
     202           0 :     intf->subtype_ = phy_data->subtype_;
     203           0 :     intf->display_name_ = phy_data->display_name_;
     204           0 :     if (intf->subtype_ == PhysicalInterface::VMWARE ||
     205           0 :         intf->subtype_ == PhysicalInterface::CONFIG) {
     206           0 :         intf->persistent_ = true;
     207             :     }
     208             : 
     209           0 :     intf->OnChange(table, phy_data);
     210           0 :     return intf;
     211             : }
     212             : 
     213           0 : InterfaceKey *PhysicalInterfaceKey::Clone() const {
     214           0 :     return new PhysicalInterfaceKey(name_);
     215             : }
     216             : 
     217             : /////////////////////////////////////////////////////////////////////////////
     218             : // PhysicalInterfaceData routines
     219             : /////////////////////////////////////////////////////////////////////////////
     220           0 : PhysicalInterfaceData::PhysicalInterfaceData(Agent *agent, IFMapNode *node,
     221             :                                              const string &vrf_name,
     222             :                                              PhysicalInterface::SubType subtype,
     223             :                                              PhysicalInterface::EncapType encap,
     224             :                                              bool no_arp,
     225             :                                              const boost::uuids::uuid &device_uuid,
     226             :                                              const string &display_name,
     227             :                                              const Ip4Address &ip,
     228           0 :                                              Interface::Transport transport) :
     229           0 :     InterfaceData(agent, node, transport), subtype_(subtype), encap_type_(encap),
     230           0 :     no_arp_(no_arp), device_uuid_(device_uuid), display_name_(display_name),
     231           0 :     ip_(ip) {
     232           0 :     EthInit(vrf_name);
     233           0 : }
     234             : 
     235             : /////////////////////////////////////////////////////////////////////////////
     236             : // Config handling routines
     237             : /////////////////////////////////////////////////////////////////////////////
     238           0 : static PhysicalInterfaceKey *BuildKey(const std::string &name) {
     239           0 :     return new PhysicalInterfaceKey(name);
     240             : }
     241             : 
     242           0 : bool InterfaceTable::PhysicalInterfaceIFNodeToReq(IFMapNode *node,
     243             :                                                   DBRequest &req,
     244             :                                                   const boost::uuids::uuid &u) {
     245             : 
     246             :     // Enqueue request to config-manager if add/change
     247           0 :     if ((req.oper != DBRequest::DB_ENTRY_DELETE) &&
     248           0 :                             (node->IsDeleted() == false)) {
     249           0 :         agent()->config_manager()->AddPhysicalInterfaceNode(node);
     250           0 :         return false;
     251             :     }
     252             : 
     253             :     autogen::PhysicalInterface *port =
     254           0 :         static_cast <autogen::PhysicalInterface *>(node->GetObject());
     255           0 :     assert(port);
     256             : 
     257             :     // Get the physical-router from FQDN
     258           0 :     string device = "";
     259           0 :     vector<string> elements;
     260           0 :     split(elements, node->name(), boost::is_any_of(":"), boost::token_compress_on);
     261           0 :     if (elements.size() == 3) {
     262           0 :         device = elements[1];
     263             :     }
     264             : 
     265           0 :     if (elements.size() == 3 && device != agent()->agent_name()) {
     266           0 :         if (RemotePhysicalInterfaceIFNodeToReq(node, req, u)) {
     267           0 :             Enqueue(&req);
     268             :         }
     269           0 :         return false;
     270             :     }
     271             : 
     272           0 :     req.key.reset(BuildKey(node->name()));
     273           0 :     req.oper = DBRequest::DB_ENTRY_DELETE;
     274           0 :     return true;
     275           0 : }
     276             : 
     277           0 : bool InterfaceTable::PhysicalInterfaceProcessConfig(IFMapNode *node,
     278             :         DBRequest &req, const boost::uuids::uuid &u) {
     279             : 
     280           0 :     if (node->IsDeleted()) {
     281           0 :         return false;
     282             :     }
     283             : 
     284             :     autogen::PhysicalInterface *port =
     285           0 :         static_cast <autogen::PhysicalInterface *>(node->GetObject());
     286           0 :     assert(port);
     287             : 
     288             :     // Get the physical-router from FQDN
     289           0 :     string device = "";
     290           0 :     vector<string> elements;
     291           0 :     split(elements, node->name(), boost::is_any_of(":"), boost::token_compress_on);
     292           0 :     if (elements.size() == 3) {
     293           0 :         device = elements[1];
     294             :     }
     295             : 
     296             :     // If physical-router does not match agent_name, treat as remote interface
     297           0 :     if (elements.size() == 3 && device != agent()->agent_name()) {
     298           0 :         return RemotePhysicalInterfaceIFNodeToReq(node, req, u);
     299             :     }
     300             : 
     301           0 :     req.key.reset(BuildKey(node->name()));
     302             : 
     303           0 :     boost::uuids::uuid dev_uuid = boost::uuids::nil_uuid();
     304             :     // Find link with physical-router adjacency
     305           0 :     IFMapNode *adj_node = NULL;
     306           0 :     adj_node = agent()->config_manager()->FindAdjacentIFMapNode(node,
     307             :                                                             "physical-router");
     308           0 :     if (adj_node) {
     309             :         autogen::PhysicalRouter *router =
     310           0 :             static_cast<autogen::PhysicalRouter *>(adj_node->GetObject());
     311           0 :         autogen::IdPermsType id_perms = router->id_perms();
     312           0 :         CfgUuidSet(id_perms.uuid.uuid_mslong, id_perms.uuid.uuid_lslong,
     313             :                    dev_uuid);
     314           0 :     }
     315           0 :     req.oper = DBRequest::DB_ENTRY_ADD_CHANGE;
     316           0 :     req.data.reset(new PhysicalInterfaceData(agent(), node,
     317           0 :                                              agent()->fabric_vrf_name(),
     318             :                                              PhysicalInterface::CONFIG,
     319             :                                              PhysicalInterface::ETHERNET,
     320             :                                              false, dev_uuid,
     321           0 :                                              port->display_name(),
     322           0 :                                              Ip4Address(0),
     323           0 :                                              Interface::TRANSPORT_ETHERNET));
     324           0 :     pi_ifnode_to_req_++;
     325           0 :     Enqueue(&req);
     326           0 :     return false;
     327           0 : }
     328             : 
     329             : /////////////////////////////////////////////////////////////////////////////
     330             : // Utility methods
     331             : /////////////////////////////////////////////////////////////////////////////
     332             : // Enqueue DBRequest to create a Host Interface
     333           0 : void PhysicalInterface::CreateReq(InterfaceTable *table, const string &ifname,
     334             :                                   const string &vrf_name, SubType subtype,
     335             :                                   EncapType encap, bool no_arp,
     336             :                                   const boost::uuids::uuid &device_uuid,
     337             :                                   const Ip4Address &ip,
     338             :                                   Interface::Transport transport) {
     339           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     340           0 :     req.key.reset(new PhysicalInterfaceKey(ifname));
     341           0 :     req.data.reset(new PhysicalInterfaceData(NULL, NULL, vrf_name, subtype,
     342             :                                              encap, no_arp, device_uuid,
     343           0 :                                              ifname, ip, transport));
     344           0 :     table->Enqueue(&req);
     345           0 : }
     346             : 
     347           0 : void PhysicalInterface::Create(InterfaceTable *table, const string &ifname,
     348             :                                const string &vrf_name, SubType subtype,
     349             :                                EncapType encap, bool no_arp,
     350             :                                const boost::uuids::uuid &device_uuid,
     351             :                                const Ip4Address &ip,
     352             :                                Interface::Transport transport) {
     353           0 :     DBRequest req(DBRequest::DB_ENTRY_ADD_CHANGE);
     354           0 :     req.key.reset(new PhysicalInterfaceKey(ifname));
     355           0 :     req.data.reset(new PhysicalInterfaceData(NULL, NULL, vrf_name, subtype,
     356             :                                              encap, no_arp, device_uuid,
     357           0 :                                              ifname, ip, transport));
     358           0 :     table->Process(req);
     359           0 : }
     360             : 
     361             : // Enqueue DBRequest to delete a Host Interface
     362           0 : void PhysicalInterface::DeleteReq(InterfaceTable *table, const string &ifname) {
     363           0 :     DBRequest req(DBRequest::DB_ENTRY_DELETE);
     364           0 :     req.key.reset(new PhysicalInterfaceKey(ifname));
     365           0 :     req.data.reset(NULL);
     366           0 :     table->Enqueue(&req);
     367           0 : }
     368             : 
     369           0 : void PhysicalInterface::Delete(InterfaceTable *table, const string &ifname) {
     370           0 :     DBRequest req(DBRequest::DB_ENTRY_DELETE);
     371           0 :     req.key.reset(new PhysicalInterfaceKey(ifname));
     372           0 :     req.data.reset(NULL);
     373           0 :     table->Process(req);
     374           0 : }

Generated by: LCOV version 1.14