LCOV - code coverage report
Current view: top level - vnsw/agent/vgw - vgw.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 0 128 0.0 %
Date: 2026-11-09 02:10:49 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  * Copyright Contributors to the OpenSDN project
       4             :  */
       5             : #include <iostream>
       6             : 
       7             : #include <base/logging.h>
       8             : #include <cmn/agent_cmn.h>
       9             : #include <init/agent_param.h>
      10             : #include <cfg/cfg_init.h>
      11             : 
      12             : #include <oper/vm.h>
      13             : #include <oper/vn.h>
      14             : #include <oper/vrf.h>
      15             : #include <oper/nexthop.h>
      16             : #include <oper/mpls.h>
      17             : #include <oper/mirror_table.h>
      18             : #include <oper/route_common.h>
      19             : #include <oper/interface_common.h>
      20             : #include <oper/vrf_assign.h>
      21             : 
      22             : #include <vgw/cfg_vgw.h>
      23             : #include <vgw/vgw.h>
      24             : 
      25             : using namespace std;
      26             : 
      27           0 : VirtualGateway::VirtualGateway(Agent *agent) : agent_(agent) {
      28           0 :     vgw_config_table_ = agent->params()->vgw_config_table();
      29           0 : }
      30             : 
      31             : struct VirtualGatewayState : DBState {
      32           0 :     VirtualGatewayState() : active_(false) { }
      33           0 :     ~VirtualGatewayState() { }
      34             :     bool active_;
      35             : };
      36             : 
      37           0 : void VirtualGateway::InterfaceNotify(DBTablePartBase *partition, DBEntryBase *entry) {
      38           0 :     if ((static_cast<Interface *>(entry))->type() != Interface::INET)
      39           0 :         return;
      40             : 
      41           0 :     InetInterface *intf = static_cast<InetInterface *>(entry);
      42           0 :     if (intf->sub_type() != InetInterface::SIMPLE_GATEWAY)
      43           0 :         return;
      44             : 
      45             :     VirtualGatewayState *state = static_cast<VirtualGatewayState *>
      46           0 :         (entry->GetState(partition->parent(), listener_id_));
      47             : 
      48           0 :     if (entry->IsDeleted()) {
      49           0 :         if (state) {
      50           0 :             entry->ClearState(partition->parent(), listener_id_);
      51           0 :             delete state;
      52             :         }
      53           0 :         return;
      54             :     }
      55             : 
      56           0 :     bool active = intf->ipv4_active();
      57           0 :     VirtualGatewayConfig cfg(intf->name());
      58             :     VirtualGatewayConfigTable::Table::iterator it =
      59           0 :         vgw_config_table_->table().find(cfg);
      60           0 :     if (it == vgw_config_table_->table().end())
      61           0 :         return;
      62             : 
      63           0 :     if (state == NULL) {
      64           0 :         state = new VirtualGatewayState();
      65           0 :         entry->SetState(partition->parent(), listener_id_, state);
      66           0 :         it->set_interface(intf);
      67             :     }
      68             : 
      69             :     InetUnicastAgentRouteTable *rt_table =
      70           0 :         (agent_->vrf_table()->GetInet4UnicastRouteTable(it->vrf_name()));
      71             : 
      72           0 :     state->active_ = active;
      73             : 
      74             :     // Add gateway routes in virtual-network.
      75             :     // BGP will export the route to other compute nodes
      76           0 :     VirtualGatewayConfig::SubnetList empty_list;
      77           0 :     if (active) {
      78           0 :         RouteUpdate(*it, it->routes().size(), rt_table,
      79             :                     it->routes(), empty_list, true, false);
      80             :     } else {
      81           0 :         RouteUpdate(*it, it->routes().size(), rt_table,
      82             :                     empty_list, it->routes(), false, true);
      83             :     }
      84             : 
      85           0 :     if (active) {
      86             :         // Packets received on fabric vrf and destined to IP address in
      87             :         // "public" network must reach kernel. Add a route in "fabric" VRF
      88             :         // inside vrouter to trap packets destined to "public" network
      89           0 :         SubnetUpdate(it->vrf_name(), rt_table, it->subnets(), empty_list);
      90             :     } else {
      91             :         // Delete the trap route added above
      92           0 :         SubnetUpdate(it->vrf_name(), rt_table, empty_list, it->subnets());
      93             :     }
      94           0 : }
      95             : 
      96           0 : void VirtualGateway::RegisterDBClients() {
      97           0 :    listener_id_ = agent_->interface_table()->Register
      98           0 :        (boost::bind(&VirtualGateway::InterfaceNotify, this, _1, _2));
      99           0 : }
     100             : 
     101             : // Create VRF for "public" virtual-network
     102           0 : void VirtualGateway::CreateVrf() {
     103           0 :     if (vgw_config_table_ == NULL) {
     104           0 :         return;
     105             :     }
     106           0 :     VirtualGatewayConfigTable::Table::iterator it;
     107           0 :     const VirtualGatewayConfigTable::Table &table = vgw_config_table_->table();
     108           0 :     for (it = table.begin(); it != table.end(); it++) {
     109           0 :         CreateVrf(it->vrf_name());
     110             :     }
     111             : }
     112             : 
     113           0 : void VirtualGateway::CreateVrf(const std::string &vrf_name) {
     114           0 :     agent_->vrf_table()->CreateVrf(
     115           0 :         vrf_name, boost::uuids::nil_uuid(), VrfData::GwVrf);
     116           0 : }
     117             : 
     118           0 : void VirtualGateway::DeleteVrf(const std::string &vrf_name) {
     119           0 :     agent_->vrf_table()->DeleteVrf(vrf_name, VrfData::GwVrf);
     120           0 : }
     121             : 
     122             : // Create virtual-gateway interface
     123           0 : void VirtualGateway::CreateInterfaces(Interface::Transport transport) {
     124           0 :     if (vgw_config_table_ == NULL) {
     125           0 :         return;
     126             :     }
     127             : 
     128           0 :     VirtualGatewayConfigTable::Table::iterator it;
     129           0 :     const VirtualGatewayConfigTable::Table &table = vgw_config_table_->table();
     130           0 :     for (it = table.begin(); it != table.end(); it++) {
     131           0 :         CreateInterface(it->interface_name(), it->vrf_name(), transport);
     132             :     }
     133             : }
     134             : 
     135           0 : void VirtualGateway::CreateInterface(const std::string &interface_name,
     136             :                                      const std::string &vrf_name,
     137             :                                      Interface::Transport transport) {
     138           0 :     InetInterface::Create(agent_->interface_table(), interface_name,
     139             :                           InetInterface::SIMPLE_GATEWAY, vrf_name,
     140           0 :                           Ip4Address(0), 0, Ip4Address(0), Agent::NullString(),
     141             :                           "", transport);
     142           0 : }
     143             : 
     144           0 : void VirtualGateway::DeleteInterface(const std::string &interface_name) {
     145           0 :     InetInterface::Delete(agent_->interface_table(), interface_name);
     146           0 : }
     147             : 
     148             : void
     149           0 : VirtualGateway::SubnetUpdate(const VirtualGatewayConfig &vgw,
     150             :                              const VirtualGatewayConfig::SubnetList &add_list,
     151             :                              const VirtualGatewayConfig::SubnetList &del_list) {
     152           0 :     if (vgw.get_interface() && !vgw.get_interface()->ipv4_active())
     153           0 :         return;
     154             : 
     155             :     InetUnicastAgentRouteTable *rt_table =
     156           0 :         (agent_->vrf_table()->GetInet4UnicastRouteTable(vgw.vrf_name()));
     157           0 :     if (!rt_table)
     158           0 :         return;
     159             : 
     160           0 :     SubnetUpdate(vgw.vrf_name(), rt_table, add_list, del_list);
     161             : }
     162             : 
     163             : void
     164           0 : VirtualGateway::SubnetUpdate(const std::string &vrf,
     165             :                              InetUnicastAgentRouteTable *rt_table,
     166             :                              const VirtualGatewayConfig::SubnetList &add_list,
     167             :                              const VirtualGatewayConfig::SubnetList &del_list) {
     168           0 :     for (uint32_t idx = 0; idx < add_list.size(); idx++) {
     169           0 :         Ip4Address addr = Address::GetIp4SubnetAddress(add_list[idx].ip_,
     170           0 :                                                        add_list[idx].plen_);
     171             :         VmInterfaceKey vmi_key(AgentKey::ADD_DEL_CHANGE,
     172           0 :                                boost::uuids::nil_uuid(),
     173           0 :                                agent_->vhost_interface_name());
     174           0 :         rt_table->AddVHostRecvRouteReq(agent_->vgw_peer(),
     175           0 :                                        agent_->fabric_vrf_name(),
     176             :                                        vmi_key,
     177           0 :                                        addr, add_list[idx].plen_,
     178             :                                        vrf, false, true);
     179           0 :     }
     180           0 :     for (uint32_t idx = 0; idx < del_list.size(); idx++) {
     181           0 :         Ip4Address addr = Address::GetIp4SubnetAddress(del_list[idx].ip_,
     182           0 :                                                        del_list[idx].plen_);
     183           0 :         rt_table->DeleteReq(agent_->vgw_peer(), agent_->fabric_vrf_name(),
     184           0 :                             addr, del_list[idx].plen_, NULL);
     185             :     }
     186           0 : }
     187             : 
     188             : void
     189           0 : VirtualGateway::RouteUpdate(const VirtualGatewayConfig &vgw,
     190             :                             const VirtualGatewayConfig::SubnetList &new_list,
     191             :                             const VirtualGatewayConfig::SubnetList &add_list,
     192             :                             const VirtualGatewayConfig::SubnetList &del_list,
     193             :                             bool add_default_route) {
     194           0 :     if (vgw.get_interface() && !vgw.get_interface()->ipv4_active())
     195           0 :         return;
     196             : 
     197             :     InetUnicastAgentRouteTable *rt_table =
     198           0 :         (agent_->vrf_table()->GetInet4UnicastRouteTable(vgw.vrf_name()));
     199             : 
     200           0 :     RouteUpdate(vgw, new_list.size(), rt_table, add_list, del_list,
     201             :                 add_default_route, true);
     202             : }
     203             : 
     204             : void
     205           0 : VirtualGateway::RouteUpdate(const VirtualGatewayConfig &vgw,
     206             :                             uint32_t new_list_size,
     207             :                             InetUnicastAgentRouteTable *rt_table,
     208             :                             const VirtualGatewayConfig::SubnetList &add_list,
     209             :                             const VirtualGatewayConfig::SubnetList &del_list,
     210             :                             bool add_default_route, bool del_default_route) {
     211           0 :     VnListType name_list;
     212           0 :     name_list.insert(vgw.vrf_name());
     213           0 :     if (vgw.routes().size() == 0 && del_default_route) {
     214             :         // no routes earlier, remove default route
     215           0 :         rt_table->DeleteReq(agent_->vgw_peer(), vgw.vrf_name(),
     216           0 :                             Ip4Address(0), 0, NULL);
     217           0 :     } else if (new_list_size == 0 && add_default_route) {
     218             :         // no routes now, add a default route
     219           0 :         rt_table->AddInetInterfaceRouteReq(agent_->vgw_peer(), vgw.vrf_name(),
     220           0 :                                            Ip4Address(0), 0,
     221             :                                            vgw.interface_name(),
     222           0 :                                            vgw.get_interface()->label(),
     223             :                                            name_list);
     224             :     }
     225             :     // remove old routes, add new routes
     226           0 :     for (uint32_t idx = 0; idx < del_list.size(); idx++) {
     227           0 :         Ip4Address addr = Address::GetIp4SubnetAddress(del_list[idx].ip_,
     228           0 :                                                        del_list[idx].plen_);
     229           0 :         rt_table->DeleteReq(agent_->vgw_peer(), vgw.vrf_name(),
     230           0 :                             addr, del_list[idx].plen_, NULL);
     231             :     }
     232           0 :     for (uint32_t idx = 0; idx < add_list.size(); idx++) {
     233           0 :         Ip4Address addr = Address::GetIp4SubnetAddress(add_list[idx].ip_,
     234           0 :                                                        add_list[idx].plen_);
     235           0 :         rt_table->AddInetInterfaceRouteReq(agent_->vgw_peer(),
     236             :                                            vgw.vrf_name(), addr,
     237           0 :                                            add_list[idx].plen_,
     238             :                                            vgw.interface_name(),
     239           0 :                                            vgw.get_interface()->label(),
     240             :                                            name_list);
     241             :     }
     242           0 : }
     243             : 
     244           0 : void VirtualGateway::Init() {
     245           0 : }
     246             : 
     247           0 : void VirtualGateway::Shutdown() {
     248           0 :     if (vgw_config_table_ == NULL)
     249           0 :         return;
     250             : 
     251           0 :     VirtualGatewayConfigTable::Table::iterator it;
     252           0 :     const VirtualGatewayConfigTable::Table &table = vgw_config_table_->table();
     253           0 :     for (it = table.begin(); it != table.end(); it++) {
     254             :         // Delete Interface
     255           0 :         InetInterface::Delete(agent_->interface_table(),
     256             :                                  it->interface_name());
     257             : 
     258             :         // Delete VRF for "public" virtual-network
     259           0 :         agent_->vrf_table()->DeleteStaticVrf(it->vrf_name());
     260             :     }
     261             : }

Generated by: LCOV version 1.14