OpenSDN source code
vgw.cc
Go to the documentation of this file.
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 VirtualGateway::VirtualGateway(Agent *agent) : agent_(agent) {
29 }
30 
34  bool active_;
35 };
36 
38  if ((static_cast<Interface *>(entry))->type() != Interface::INET)
39  return;
40 
41  InetInterface *intf = static_cast<InetInterface *>(entry);
43  return;
44 
45  VirtualGatewayState *state = static_cast<VirtualGatewayState *>
46  (entry->GetState(partition->parent(), listener_id_));
47 
48  if (entry->IsDeleted()) {
49  if (state) {
50  entry->ClearState(partition->parent(), listener_id_);
51  delete state;
52  }
53  return;
54  }
55 
56  bool active = intf->ipv4_active();
57  VirtualGatewayConfig cfg(intf->name());
58  VirtualGatewayConfigTable::Table::iterator it =
59  vgw_config_table_->table().find(cfg);
60  if (it == vgw_config_table_->table().end())
61  return;
62 
63  if (state == NULL) {
64  state = new VirtualGatewayState();
65  entry->SetState(partition->parent(), listener_id_, state);
66  it->set_interface(intf);
67  }
68 
69  InetUnicastAgentRouteTable *rt_table =
70  (agent_->vrf_table()->GetInet4UnicastRouteTable(it->vrf_name()));
71 
72  state->active_ = active;
73 
74  // Add gateway routes in virtual-network.
75  // BGP will export the route to other compute nodes
77  if (active) {
78  RouteUpdate(*it, it->routes().size(), rt_table,
79  it->routes(), empty_list, true, false);
80  } else {
81  RouteUpdate(*it, it->routes().size(), rt_table,
82  empty_list, it->routes(), false, true);
83  }
84 
85  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  SubnetUpdate(it->vrf_name(), rt_table, it->subnets(), empty_list);
90  } else {
91  // Delete the trap route added above
92  SubnetUpdate(it->vrf_name(), rt_table, empty_list, it->subnets());
93  }
94 }
95 
98  (boost::bind(&VirtualGateway::InterfaceNotify, this, _1, _2));
99 }
100 
101 // Create VRF for "public" virtual-network
103  if (vgw_config_table_ == NULL) {
104  return;
105  }
106  VirtualGatewayConfigTable::Table::iterator it;
108  for (it = table.begin(); it != table.end(); it++) {
109  CreateVrf(it->vrf_name());
110  }
111 }
112 
113 void VirtualGateway::CreateVrf(const std::string &vrf_name) {
115  vrf_name, boost::uuids::nil_uuid(), VrfData::GwVrf);
116 }
117 
118 void VirtualGateway::DeleteVrf(const std::string &vrf_name) {
119  agent_->vrf_table()->DeleteVrf(vrf_name, VrfData::GwVrf);
120 }
121 
122 // Create virtual-gateway interface
124  if (vgw_config_table_ == NULL) {
125  return;
126  }
127 
128  VirtualGatewayConfigTable::Table::iterator it;
130  for (it = table.begin(); it != table.end(); it++) {
131  CreateInterface(it->interface_name(), it->vrf_name(), transport);
132  }
133 }
134 
135 void VirtualGateway::CreateInterface(const std::string &interface_name,
136  const std::string &vrf_name,
137  Interface::Transport transport) {
138  InetInterface::Create(agent_->interface_table(), interface_name,
141  "", transport);
142 }
143 
144 void VirtualGateway::DeleteInterface(const std::string &interface_name) {
145  InetInterface::Delete(agent_->interface_table(), interface_name);
146 }
147 
148 void
150  const VirtualGatewayConfig::SubnetList &add_list,
151  const VirtualGatewayConfig::SubnetList &del_list) {
152  if (vgw.get_interface() && !vgw.get_interface()->ipv4_active())
153  return;
154 
155  InetUnicastAgentRouteTable *rt_table =
157  if (!rt_table)
158  return;
159 
160  SubnetUpdate(vgw.vrf_name(), rt_table, add_list, del_list);
161 }
162 
163 void
164 VirtualGateway::SubnetUpdate(const std::string &vrf,
165  InetUnicastAgentRouteTable *rt_table,
166  const VirtualGatewayConfig::SubnetList &add_list,
167  const VirtualGatewayConfig::SubnetList &del_list) {
168  for (uint32_t idx = 0; idx < add_list.size(); idx++) {
169  Ip4Address addr = Address::GetIp4SubnetAddress(add_list[idx].ip_,
170  add_list[idx].plen_);
172  boost::uuids::nil_uuid(),
174  rt_table->AddVHostRecvRouteReq(agent_->vgw_peer(),
176  vmi_key,
177  addr, add_list[idx].plen_,
178  vrf, false, true);
179  }
180  for (uint32_t idx = 0; idx < del_list.size(); idx++) {
181  Ip4Address addr = Address::GetIp4SubnetAddress(del_list[idx].ip_,
182  del_list[idx].plen_);
184  addr, del_list[idx].plen_, NULL);
185  }
186 }
187 
188 void
190  const VirtualGatewayConfig::SubnetList &new_list,
191  const VirtualGatewayConfig::SubnetList &add_list,
192  const VirtualGatewayConfig::SubnetList &del_list,
193  bool add_default_route) {
194  if (vgw.get_interface() && !vgw.get_interface()->ipv4_active())
195  return;
196 
197  InetUnicastAgentRouteTable *rt_table =
199 
200  RouteUpdate(vgw, new_list.size(), rt_table, add_list, del_list,
201  add_default_route, true);
202 }
203 
204 void
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  VnListType name_list;
212  name_list.insert(vgw.vrf_name());
213  if (vgw.routes().size() == 0 && del_default_route) {
214  // no routes earlier, remove default route
215  rt_table->DeleteReq(agent_->vgw_peer(), vgw.vrf_name(),
216  Ip4Address(0), 0, NULL);
217  } else if (new_list_size == 0 && add_default_route) {
218  // no routes now, add a default route
219  rt_table->AddInetInterfaceRouteReq(agent_->vgw_peer(), vgw.vrf_name(),
220  Ip4Address(0), 0,
221  vgw.interface_name(),
222  vgw.get_interface()->label(),
223  name_list);
224  }
225  // remove old routes, add new routes
226  for (uint32_t idx = 0; idx < del_list.size(); idx++) {
227  Ip4Address addr = Address::GetIp4SubnetAddress(del_list[idx].ip_,
228  del_list[idx].plen_);
229  rt_table->DeleteReq(agent_->vgw_peer(), vgw.vrf_name(),
230  addr, del_list[idx].plen_, NULL);
231  }
232  for (uint32_t idx = 0; idx < add_list.size(); idx++) {
233  Ip4Address addr = Address::GetIp4SubnetAddress(add_list[idx].ip_,
234  add_list[idx].plen_);
236  vgw.vrf_name(), addr,
237  add_list[idx].plen_,
238  vgw.interface_name(),
239  vgw.get_interface()->label(),
240  name_list);
241  }
242 }
243 
245 }
246 
248  if (vgw_config_table_ == NULL)
249  return;
250 
251  VirtualGatewayConfigTable::Table::iterator it;
253  for (it = table.begin(); it != table.end(); it++) {
254  // Delete Interface
256  it->interface_name());
257 
258  // Delete VRF for "public" virtual-network
259  agent_->vrf_table()->DeleteStaticVrf(it->vrf_name());
260  }
261 }
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:15
std::set< std::string > VnListType
Definition: agent.h:213
static Ip4Address GetIp4SubnetAddress(const Ip4Address &prefix, uint16_t plen)
Definition: address.cc:180
VirtualGatewayConfigTable * vgw_config_table() const
Definition: agent_param.h:328
Definition: agent.h:361
InterfaceTable * interface_table() const
Definition: agent.h:468
AgentParam * params() const
Definition: agent.h:1227
VrfTable * vrf_table() const
Definition: agent.h:488
const std::string & vhost_interface_name() const
Definition: agent.cc:105
const Peer * vgw_peer() const
Definition: agent.h:1029
static const std::string & NullString()
Definition: agent.h:440
const std::string & fabric_vrf_name() const
Definition: agent.h:906
DBState * GetState(DBTableBase *tbl_base, ListenerId listener) const
Definition: db_entry.cc:38
void ClearState(DBTableBase *tbl_base, ListenerId listener)
Definition: db_entry.cc:74
bool IsDeleted() const
Definition: db_entry.h:49
void Delete()
Definition: db_entry.cc:132
void SetState(DBTableBase *tbl_base, ListenerId listener, DBState *state)
Definition: db_entry.cc:23
ListenerId Register(ChangeCallback callback, const std::string &name="unspecified")
Definition: db_table.cc:208
DBTableBase * parent()
static void Create(InterfaceTable *table, const std::string &ifname, SubType sub_type, const std::string &vrf_name, const Ip4Address &addr, int plen, const Ip4Address &gw, const std::string &xconnect, const std::string &vn_name, Interface::Transport transport)
SubType sub_type() const
static void AddVHostRecvRouteReq(const Peer *peer, const string &vrf, const InterfaceKey &interface, const IpAddress &addr, uint8_t plen, const string &vn_name, bool policy, bool native_encap)
void AddInetInterfaceRouteReq(const Peer *peer, const string &vm_vrf, const Ip4Address &addr, uint8_t plen, InetInterfaceRoute *data)
static void DeleteReq(const Peer *peer, const string &vrf_name, const IpAddress &addr, uint8_t plen, AgentRouteData *data)
bool ipv4_active() const
Definition: interface.h:119
const std::string & name() const
Definition: interface.h:117
uint32_t label() const
Definition: interface.h:130
const Table & table() const
Definition: cfg_vgw.h:130
std::set< VirtualGatewayConfig, VirtualGatewayConfigCompare > Table
Definition: cfg_vgw.h:122
const InetInterface * get_interface() const
Definition: cfg_vgw.h:55
const SubnetList & routes() const
Definition: cfg_vgw.h:51
const std::string & vrf_name() const
Definition: cfg_vgw.h:49
const std::string & interface_name() const
Definition: cfg_vgw.h:48
std::vector< Subnet > SubnetList
Definition: cfg_vgw.h:31
void CreateInterface(const std::string &interface_name, const std::string &vrf_name, Interface::Transport transport)
Definition: vgw.cc:135
void CreateVrf()
Definition: vgw.cc:102
void Init()
Definition: vgw.cc:244
void RegisterDBClients()
Definition: vgw.cc:96
VirtualGatewayConfigTable * vgw_config_table_
Definition: vgw.h:50
void RouteUpdate(const VirtualGatewayConfig &vgw, const VirtualGatewayConfig::SubnetList &new_list, const VirtualGatewayConfig::SubnetList &add_list, const VirtualGatewayConfig::SubnetList &del_list, bool add_default_route)
Definition: vgw.cc:189
void SubnetUpdate(const VirtualGatewayConfig &vgw, const VirtualGatewayConfig::SubnetList &add_list, const VirtualGatewayConfig::SubnetList &del_list)
Definition: vgw.cc:149
void DeleteVrf(const std::string &vrf_name)
Definition: vgw.cc:118
DBTableBase::ListenerId listener_id_
Definition: vgw.h:49
void CreateInterfaces(Interface::Transport transport)
Definition: vgw.cc:123
Agent * agent_
Definition: vgw.h:48
void InterfaceNotify(DBTablePartBase *partition, DBEntryBase *entry)
Definition: vgw.cc:37
VirtualGateway(Agent *agent)
Definition: vgw.cc:27
void Shutdown()
Definition: vgw.cc:247
void DeleteInterface(const std::string &interface_name)
Definition: vgw.cc:144
void DeleteVrf(const string &name, uint32_t flags=VrfData::ConfigVrf)
Definition: vrf.cc:988
void DeleteStaticVrf(const string &name)
Definition: vrf.cc:1012
void CreateVrf(const string &name, const boost::uuids::uuid &vn_uuid, uint32_t flags)
Definition: vrf.cc:971
InetUnicastAgentRouteTable * GetInet4UnicastRouteTable(const std::string &vrf_name)
Definition: vrf.cc:899
uint8_t type
Definition: load_balance.h:2
@ ADD_DEL_CHANGE
Definition: agent_db.h:101
VirtualGatewayState()
Definition: vgw.cc:32
~VirtualGatewayState()
Definition: vgw.cc:33
@ GwVrf
Definition: vrf.h:48