OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vxlan_templates.cc
Go to the documentation of this file.
1 #include <oper/bgp_as_service.h>
2 
3 template <class ItType>
4 std::vector<IpAddress> VxlanRoutingManager::ItemNexthopsToVector(ItType *item) {
5  std::vector<IpAddress> nh_addr;
6  const uint32_t n_items = item->entry.next_hops.next_hop.size();
7  for (uint32_t i_nh=0; i_nh < n_items; i_nh++) {
8  const IpAddress nh_ip = IpAddress::from_string(
9  item->entry.next_hops.next_hop[i_nh].address);
10  nh_addr.insert(nh_addr.end(), nh_ip);
11  }
12 
13  return nh_addr;
14 }
15 
16 // A nexthop is counted as BGPaaS when it has MPLS label and this
17 // label points to the VmInterface linked with the BGPaaS object
18 static bool IsBgpaasInterfaceNexthop(const Agent* agent, const NextHop* nh) {
19  if (nh->GetType() != NextHop::INTERFACE ||
20  nh->mpls_label() == NULL) {
21  return false;
22  }
23 
24  const InterfaceNH *intf_nh = static_cast<const InterfaceNH *>(nh);
25  const Interface *interface = intf_nh->GetInterface();
26  if (interface->type() != Interface::VM_INTERFACE)
27  return false;
28 
29  const VmInterface *vm_intf =
30  dynamic_cast<const VmInterface*>(interface);
31  const Ip4Address& intf_ip4 = vm_intf->primary_ip_addr();
32  const Ip6Address& intf_ip6 = vm_intf->primary_ip6_addr();
33 
34  if (agent->oper_db()->bgp_as_a_service()->
35  IsBgpService(vm_intf, IpAddress(intf_ip4), IpAddress(intf_ip4))) {
36  return true;
37  }
38  if (agent->oper_db()->bgp_as_a_service()->
39  IsBgpService(vm_intf, IpAddress(intf_ip6), IpAddress(intf_ip6))) {
40  return true;
41  }
42  return false;
43 }
44 
45 // A composite nexthop is counted as BGPaaS when at least one component is
46 // an interface
47 static bool IsBgpaasCompositeNexthop(const Agent* agent, const NextHop* nh) {
48  if (nh->GetType() != NextHop::COMPOSITE)
49  return false;
50  const CompositeNH *composite_nh = dynamic_cast<const CompositeNH*>(nh);
51  uint32_t n_comps = composite_nh->ComponentNHCount();
52  for (uint32_t i=0; i < n_comps; i++) {
53  const NextHop *c_nh = composite_nh->GetNH(i);
54  if (c_nh != nullptr &&
55  IsBgpaasInterfaceNexthop(agent, c_nh) == true) {
56  return true;
57  }
58  }
59  return false;
60 }
61 
62 template<typename NhType>
64  const std::string& vrf_name,
65  const NhType &nh_item,
66  ComponentNHKeyList& comp_nh_list,
67  std::vector<std::string> &peer_sources) {
68 
69  for (const auto &nexthop_addr : peer_sources) {
70  const Agent *agent = Agent::GetInstance();
71  IpAddress nh_ip;
72  uint32_t prefix_len;
73  boost::system::error_code ec;
74 
75  if (is_ipv4_string(nexthop_addr)) {
76  nh_ip = Ip4Address::from_string(ipv4_prefix(nexthop_addr), ec);
77  prefix_len = ipv4_prefix_len(nexthop_addr);
78  } else if (is_ipv6_string(nexthop_addr)) {
79  nh_ip = Ip6Address::from_string(ipv6_prefix(nexthop_addr), ec);
80  prefix_len = ipv6_prefix_len(nexthop_addr);
81  } else {
82  LOG(ERROR, "Error in VxlanRoutingManager"
83  << "::AddBgpaasInterfaceComponentToList"
84  << ", nexthop_addr = " << nexthop_addr
85  << " is not an IPv4 or IPv6 prefix");
86  return;
87  }
88  if (ec) {
89  continue;
90  }
91  const AgentRoute *intf_rt =
92  FindEvpnOrInetRoute(agent, vrf_name, nh_ip, prefix_len, nh_item);
93  const AgentPath *loc_path =
95  if (loc_path == nullptr) {
96  continue;
97  }
98  if (loc_path->nexthop() == nullptr) {
99  continue;
100  }
101  if (IsBgpaasInterfaceNexthop(agent, loc_path->nexthop())) {
102  DBEntryBase::KeyPtr key_ptr =
103  loc_path->nexthop()->GetDBRequestKey();
104  NextHopKey *nh_key =
105  static_cast<NextHopKey *>(key_ptr.release());
106  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
107  ComponentNHKeyPtr component_nh_key(new
109  std::move(nh_key_ptr)));
110  comp_nh_list.push_back(component_nh_key);
111  } else if (IsBgpaasCompositeNexthop(agent, loc_path->nexthop())) {
112  CompositeNH *loc_comp_nh = dynamic_cast<CompositeNH*>
113  (loc_path->nexthop());
114 
115  DBEntryBase::KeyPtr key_ptr =
116  loc_comp_nh->GetDBRequestKey();
117  CompositeNHKey *nh_key =
118  static_cast<CompositeNHKey *>(key_ptr.release());
119  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
120 
121  if (nh_key == nullptr){
122  LOG(ERROR, "Error in VxlanRoutingManager::"
123  << "::AddBgpaasInterfaceComponentToList"
124  << ", null nh key");
125  }
126 
127  const ComponentNHList& component_nh_list =
128  loc_comp_nh->component_nh_list();
129  for (auto &component_nh : component_nh_list) {
130  std::unique_ptr<const NextHopKey> nh_key_ptr;
131  ComponentNHKeyPtr component_nh_key;
132  if (component_nh.get() == nullptr) {
133  // component_nh_key.reset(NULL);
134  } else {
135  DBEntryBase::KeyPtr key =
136  component_nh.get()->nh()->GetDBRequestKey();
137  NextHopKey *nh_key =
138  static_cast<NextHopKey *>(key.release());
139  nh_key_ptr.reset(nh_key);
140  component_nh_key.reset(
142  std::move(nh_key_ptr)));
143  }
144  comp_nh_list.push_back(component_nh_key);
145  }
146  }
147  }
148 }
149 
150 template<typename NhType>
152  const std::string& prefix_str,
153  const std::string& vrf_name,
154  const NhType &nh_item,
155  ComponentNHKeyList& comp_nh_list,
156  std::vector<std::string> &peer_sources) {
157  const Agent *agent = Agent::GetInstance();
158  IpAddress ip_addr;
159  uint32_t prefix_len;
160  boost::system::error_code ec;
161 
162  if (is_ipv4_string(prefix_str)) {
163  ip_addr = Ip4Address::from_string(ipv4_prefix(prefix_str), ec);
164  prefix_len = ipv4_prefix_len(prefix_str);
165  } else if (is_ipv6_string(prefix_str)) {
166  std::string addr_str = ipv6_prefix(prefix_str);
167  prefix_len = ipv6_prefix_len(prefix_str);
168  ip_addr = Ip6Address::from_string(addr_str, ec);
169  } else {
170  LOG(ERROR, "Error in VxlanRoutingManager::AddInterfaceComponentToList"
171  << ", prefix_str = " << prefix_str
172  << " is not an IPv4 or IPv6 prefix");
173  return;
174  }
175 
176  if (ec) {
177  LOG(ERROR, "Possible error in "
178  << "VxlanRoutingManager::AddInterfaceComponentToList"
179  << ", cannot convert prefix_str = " << prefix_str
180  << " to IPv4 or IPv6 address");
181  return;
182  }
183 
184  const AgentRoute *intf_rt =
185  FindEvpnOrInetRoute(agent, vrf_name, ip_addr, prefix_len, nh_item);
186  if (intf_rt == NULL) {
187  AddBgpaasInterfaceComponentToList(vrf_name, nh_item, comp_nh_list,
188  peer_sources);
189  return;
190  }
191 
192  const AgentPath *loc_path =
194  if (loc_path == NULL) {
195  AddBgpaasInterfaceComponentToList(vrf_name, nh_item, comp_nh_list,
196  peer_sources);
197  return;
198  }
199  if (loc_path->nexthop() == NULL) {
200  AddBgpaasInterfaceComponentToList(vrf_name, nh_item, comp_nh_list,
201  peer_sources);
202  return;
203  }
204 
205  // Case 1. NextHop is an interface
206  if (loc_path->nexthop()->GetType() == NextHop::INTERFACE) {
207  DBEntryBase::KeyPtr key_ptr =
208  loc_path->nexthop()->GetDBRequestKey();
209  NextHopKey *nh_key =
210  static_cast<NextHopKey *>(key_ptr.release());
211  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
212  ComponentNHKeyPtr component_nh_key(new ComponentNHKey(MplsTable::kInvalidLabel, // label
213  std::move(nh_key_ptr)));
214  comp_nh_list.push_back(component_nh_key);
215  return;
216  }
217 
218  // Case 2. NextHop is a composite of interfaces
219  // Copy all interfaces from this composite
220  // into the components list
221  if (loc_path->nexthop()->GetType() == NextHop::COMPOSITE) {
222  CompositeNH *loc_comp_nh = dynamic_cast<CompositeNH*>
223  (loc_path->nexthop());
224 
225  DBEntryBase::KeyPtr key_ptr =
226  loc_comp_nh->GetDBRequestKey();
227  CompositeNHKey *nh_key =
228  static_cast<CompositeNHKey *>(key_ptr.release());
229  std::unique_ptr<const NextHopKey> nh_key_ptr(nh_key);
230 
231  if (nh_key == NULL){
232  LOG(ERROR, "Error in VxlanRoutingManager::AddInterfaceComponentToList"
233  << ", null nh key");
234  assert(nh_key != NULL);
235  }
236 
237  // Refresh on path_preference.sequence change
238  const ComponentNHList& component_nh_list =
239  loc_comp_nh->component_nh_list();
240  for (ComponentNHList::const_iterator
241  it_nh = component_nh_list.begin();
242  it_nh != component_nh_list.end(); it_nh++) {
243  // nullptr means deleted component, which
244  // can be reused later
245  std::unique_ptr<const NextHopKey> nh_key_ptr;
246  ComponentNHKeyPtr component_nh_key;
247  if (it_nh->get() == NULL) {
248  // component_nh_key.reset(NULL);
249  } else {
250  DBEntryBase::KeyPtr key =
251  it_nh->get()->nh()->GetDBRequestKey();
252  NextHopKey *nh_key =
253  static_cast<NextHopKey *>(key.release());
254  nh_key_ptr.reset(nh_key);
255  component_nh_key.reset(
256  new ComponentNHKey(MplsTable::kInvalidLabel, std::move(nh_key_ptr)));
257  }
258  comp_nh_list.push_back(component_nh_key);
259  }
260  }
261 } // AddInterfaceComponentToList func
262 
263 //
264 // END-OF-FILE
265 //
static Agent * GetInstance()
Definition: agent.h:436
static uint32_t ipv4_prefix_len(const std::string &prefix_str)
Extracts length of IPv4 subnet address from the prefix string.
static std::string ipv4_prefix(const std::string &prefix_str)
Extracts an IPv4 address string from the prefix string.
boost::asio::ip::address IpAddress
Definition: address.h:13
static bool IsBgpaasCompositeNexthop(const Agent *agent, const NextHop *nh)
boost::shared_ptr< const ComponentNHKey > ComponentNHKeyPtr
Definition: nexthop.h:1639
static AgentRoute * FindEvpnOrInetRoute(const Agent *agent, const std::string &vrf_name, const IpAddress &ip_addr, uint32_t prefix_len, const autogen::EnetNextHopType &nh_item)
Finds a route with the given prefix address and len in the EVPN table.
static bool is_ipv4_string(const std::string &prefix_str)
Determines whether the address string contains an IPv4 address as substring or not.
std::unique_ptr< DBRequestKey > KeyPtr
Definition: db_entry.h:25
Type GetType() const
Definition: nexthop.h:405
Base class for all Route entries in agent.
Definition: agent_route.h:224
static void AddBgpaasInterfaceComponentToList(const std::string &vrf_name, const NhType &nh_item, ComponentNHKeyList &comp_nh_list, std::vector< std::string > &peer_sources)
OperDB * oper_db() const
Definition: agent.cc:1013
std::vector< ComponentNHKeyPtr > ComponentNHKeyList
Definition: nexthop.h:1641
static std::vector< IpAddress > ItemNexthopsToVector(ItType *item)
Templates.
NextHop * nexthop() const
Definition: agent_path.cc:87
BgpAsAService * bgp_as_a_service() const
Definition: operdb_init.h:77
static bool is_ipv6_string(const std::string &prefix_str)
Determines whether the address string contains an IPv6 address as substring or not.
Definition: agent.h:358
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
static void AddInterfaceComponentToList(const std::string &prefix_str, const std::string &vrf_name, const NhType &nh_item, ComponentNHKeyList &comp_nh_list, std::vector< std::string > &peer_sources)
Adds an interface or a composite of interfaces nexthops to the list of components NH keys needed for ...
const ComponentNHList & component_nh_list() const
Definition: nexthop.h:1869
virtual KeyPtr GetDBRequestKey() const =0
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
static const uint32_t kInvalidLabel
Definition: mpls.h:101
const AgentPath * FindIntfOrCompLocalVmPortPath() const
Finds path to an interface or a composite of interfaces and returns it. The priority is given to comp...
Definition: agent_route.cc:817
const Ip4Address & primary_ip_addr() const
const Ip6Address & primary_ip6_addr() const
size_t ComponentNHCount() const
Definition: nexthop.h:1815
static uint32_t ipv6_prefix_len(const std::string &prefix_str)
Extracts length of IPv6 subnet address from the prefix string.
#define LOG(_Level, _Msg)
Definition: logging.h:33
std::vector< ComponentNHPtr > ComponentNHList
Definition: nexthop.h:1637
const NextHop * GetNH(uint32_t idx) const
Definition: nexthop.h:1832
static bool IsBgpaasInterfaceNexthop(const Agent *agent, const NextHop *nh)
static std::string ipv6_prefix(const std::string &prefix_str)
Extracts an IPv6 address string from the prefix string.
virtual KeyPtr GetDBRequestKey() const
Definition: nexthop.cc:2183
const MplsLabel * mpls_label() const
Definition: nexthop.h:434