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

Generated by: LCOV version 1.14