OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
ermvpn_route.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
6 
7 #include <algorithm>
8 #include <string>
9 #include <vector>
10 
11 #include "base/string_util.h"
13 
14 using std::copy;
15 using std::string;
16 using std::vector;
17 
18 // BgpProtoPrefix format for erm-vpn prefix.
19 //
20 // +------------------------------------+
21 // | RD (8 octets) |
22 // +------------------------------------+
23 // | Router-Id (4 octets) |
24 // +------------------------------------+
25 // | Multicast Source length (1 octet) |
26 // +------------------------------------+
27 // | Multicast Source (4) |
28 // +------------------------------------+
29 // | Multicast Group length (1 octet) |
30 // +------------------------------------+
31 // | Multicast Group (4) |
32 // +------------------------------------+
33 
35 }
36 
38  const Ip4Address &group, const Ip4Address &source)
39  : type_(type), rd_(rd), group_(group), source_(source) {
40 }
41 
43  const Ip4Address &router_id,
44  const Ip4Address &group, const Ip4Address &source)
45  : type_(type), rd_(rd), router_id_(router_id),
46  group_(group), source_(source) {
47 }
48 
50  ErmVpnPrefix *prefix) {
51  size_t rd_size = RouteDistinguisher::kSize;
52  size_t rtid_size = Address::kMaxV4Bytes;
53  size_t nlri_size = proto_prefix.prefix.size();
54  size_t expected_nlri_size =
55  rd_size + rtid_size + 2 * (Address::kMaxV4Bytes + 1);
56 
57  if (!IsValidForBgp(proto_prefix.type))
58  return -1;
59  if (nlri_size != expected_nlri_size)
60  return -1;
61 
62  prefix->type_ = proto_prefix.type;
63  size_t rd_offset = 0;
64  prefix->rd_ = RouteDistinguisher(&proto_prefix.prefix[rd_offset]);
65  size_t rtid_offset = rd_offset + rd_size;
66  prefix->router_id_ =
67  Ip4Address(get_value(&proto_prefix.prefix[rtid_offset], rtid_size));
68 
69  size_t source_offset = rtid_offset + rtid_size + 1;
70  if (proto_prefix.prefix[source_offset - 1] != Address::kMaxV4PrefixLen)
71  return -1;
72  prefix->source_ = Ip4Address(
73  get_value(&proto_prefix.prefix[source_offset], Address::kMaxV4Bytes));
74 
75  size_t group_offset = source_offset + Address::kMaxV4Bytes + 1;
76  if (proto_prefix.prefix[group_offset - 1] != Address::kMaxV4PrefixLen)
77  return -1;
78  prefix->group_ = Ip4Address(
79  get_value(&proto_prefix.prefix[group_offset], Address::kMaxV4Bytes));
80 
81  return 0;
82 }
83 
85  const BgpProtoPrefix &proto_prefix,
86  const BgpAttr *attr,
87  const Address::Family family,
88  ErmVpnPrefix *prefix,
89  BgpAttrPtr *new_attr, uint32_t *label,
90  uint32_t *l3_label) {
91  return FromProtoPrefix(proto_prefix, prefix);
92 }
93 
95  assert(IsValidForBgp(type_));
96 
97  size_t rd_size = RouteDistinguisher::kSize;
98  size_t rtid_size = Address::kMaxV4Bytes;
99 
100  proto_prefix->type = type_;
101  proto_prefix->prefix.clear();
102  proto_prefix->prefixlen =
103  (rd_size + rtid_size + 2 * (1 + Address::kMaxV4Bytes)) * 8;
104  proto_prefix->prefix.resize(proto_prefix->prefixlen / 8, 0);
105 
106  size_t rd_offset = 0;
107  copy(rd_.GetData(), rd_.GetData() + rd_size,
108  proto_prefix->prefix.begin() + rd_offset);
109 
110  size_t rtid_offset = rd_offset + rd_size;
111  const Ip4Address::bytes_type &rtid_bytes = router_id_.to_bytes();
112  copy(rtid_bytes.begin(), rtid_bytes.begin() + Address::kMaxV4Bytes,
113  proto_prefix->prefix.begin() + rtid_offset);
114 
115  size_t source_offset = rtid_offset + rtid_size + 1;
116  proto_prefix->prefix[source_offset - 1] = Address::kMaxV4PrefixLen;
117  const Ip4Address::bytes_type &source_bytes = source_.to_bytes();
118  copy(source_bytes.begin(), source_bytes.begin() + Address::kMaxV4Bytes,
119  proto_prefix->prefix.begin() + source_offset);
120 
121  size_t group_offset = source_offset + Address::kMaxV4Bytes + 1;
122  proto_prefix->prefix[group_offset - 1] = Address::kMaxV4PrefixLen;
123  const Ip4Address::bytes_type &group_bytes = group_.to_bytes();
124  copy(group_bytes.begin(), group_bytes.begin() + Address::kMaxV4Bytes,
125  proto_prefix->prefix.begin() + group_offset);
126 }
127 
129  boost::system::error_code *errorp) {
130  ErmVpnPrefix prefix, null_prefix;
131  string temp_str;
132 
133  // Look for Type.
134  size_t pos1 = str.find('-');
135  if (pos1 == string::npos) {
136  if (errorp != NULL) {
137  *errorp = make_error_code(boost::system::errc::invalid_argument);
138  }
139  return null_prefix;
140  }
141  temp_str = str.substr(0, pos1);
142  stringToInteger(temp_str, prefix.type_);
143  if (!IsValid(prefix.type_)) {
144  if (errorp != NULL) {
145  *errorp = make_error_code(boost::system::errc::invalid_argument);
146  }
147  return null_prefix;
148  }
149 
150  // Look for RD.
151  size_t pos2 = str.find('-', pos1 + 1);
152  if (pos2 == string::npos) {
153  if (errorp != NULL) {
154  *errorp = make_error_code(boost::system::errc::invalid_argument);
155  }
156  return null_prefix;
157  }
158  temp_str = str.substr(pos1 + 1, pos2 - pos1 - 1);
159  boost::system::error_code rd_err;
160  prefix.rd_ = RouteDistinguisher::FromString(temp_str, &rd_err);
161  if (rd_err.failed()) {
162  if (errorp != NULL) {
163  *errorp = rd_err;
164  }
165  return null_prefix;
166  }
167 
168  // Look for router-id.
169  size_t pos3 = str.find(',', pos2 + 1);
170  if (pos3 == string::npos) {
171  if (errorp != NULL) {
172  *errorp = make_error_code(boost::system::errc::invalid_argument);
173  }
174  return null_prefix;
175  }
176  temp_str = str.substr(pos2 + 1, pos3 - pos2 - 1);
177  boost::system::error_code rtid_err;
178  prefix.router_id_ = Ip4Address::from_string(temp_str, rtid_err);
179  if (rtid_err.failed()) {
180  if (errorp != NULL) {
181  *errorp = rtid_err;
182  }
183  return null_prefix;
184  }
185 
186  // Look for group.
187  size_t pos4 = str.find(',', pos3 + 1);
188  if (pos4 == string::npos) {
189  if (errorp != NULL) {
190  *errorp = make_error_code(boost::system::errc::invalid_argument);
191  }
192  return null_prefix;
193  }
194  temp_str = str.substr(pos3 + 1, pos4 - pos3 - 1);
195  boost::system::error_code group_err;
196  prefix.group_ = Ip4Address::from_string(temp_str, group_err);
197  if (group_err.failed()) {
198  if (errorp != NULL) {
199  *errorp = group_err;
200  }
201  return null_prefix;
202  }
203 
204  // Rest is source.
205  temp_str = str.substr(pos4 + 1, string::npos);
206  boost::system::error_code source_err;
207  prefix.source_ = Ip4Address::from_string(temp_str, source_err);
208  if (source_err.failed()) {
209  if (errorp != NULL) {
210  *errorp = source_err;
211  }
212  return null_prefix;
213  }
214 
215  return prefix;
216 }
217 
218 string ErmVpnPrefix::ToString() const {
219  string repr = integerToString(type_);
220  repr += "-" + rd_.ToString();
221  repr += "-" + router_id_.to_string();
222  repr += "," + group_.to_string();
223  repr += "," + source_.to_string();
224  return repr;
225 }
226 
228  assert(type_ == 0);
229  string repr = rd_.ToString();
230  repr += ":" + group_.to_string();
231  repr += "," + source_.to_string();
232  return repr;
233 }
234 
236  return (type == LocalTreeRoute || type == GlobalTreeRoute);
237 }
238 
240  return (type == NativeRoute || IsValidForBgp(type));
241 }
242 
243 bool ErmVpnPrefix::operator==(const ErmVpnPrefix &rhs) const {
244  return (
245  type_ == rhs.type_ &&
246  rd_ == rhs.rd_ &&
247  router_id_ == rhs.router_id_ &&
248  group_ == rhs.group_ &&
249  source_ == rhs.source_);
250 }
251 
252 ErmVpnRoute::ErmVpnRoute(const ErmVpnPrefix &prefix) : prefix_(prefix) {
253 }
254 
255 int ErmVpnRoute::CompareTo(const Route &rhs) const {
256  const ErmVpnRoute &other = static_cast<const ErmVpnRoute &>(rhs);
258  KEY_COMPARE(prefix_.group(), other.prefix_.group());
259  KEY_COMPARE(prefix_.type(), other.prefix_.type());
260  KEY_COMPARE(
263  return 0;
264 }
265 
266 string ErmVpnRoute::ToString() const {
267  return prefix_.ToString();
268 }
269 
271  if (xmpp_id_str_.empty())
273  return xmpp_id_str_;
274 }
275 
276 bool ErmVpnRoute::IsValid() const {
277  if (!BgpRoute::IsValid())
278  return false;
279 
280  const BgpAttr *attr = BestPath()->GetAttr();
281  switch (prefix_.type()) {
283  return attr->label_block().get() != NULL;
285  return attr->edge_discovery() != NULL;
287  return attr->edge_forwarding() != NULL;
289  break;
290  }
291 
292  return false;
293 }
294 
295 void ErmVpnRoute::SetKey(const DBRequestKey *reqkey) {
296  const ErmVpnTable::RequestKey *key =
297  static_cast<const ErmVpnTable::RequestKey *>(reqkey);
298  prefix_ = key->prefix;
299 }
300 
302  const BgpAttr *attr, uint32_t label, uint32_t l3_label) const {
303  prefix_.BuildProtoPrefix(prefix);
304 }
305 
307  vector<uint8_t> &nh, IpAddress nexthop) const {
308  nh.resize(4);
309  const Ip4Address::bytes_type &addr_bytes = nexthop.to_v4().to_bytes();
310  copy(addr_bytes.begin(), addr_bytes.end(), nh.begin());
311 }
312 
315  key = new ErmVpnTable::RequestKey(GetPrefix(), NULL);
316  return KeyPtr(key);
317 }
318 
319 const std::string ErmVpnPrefix::GetType() const {
320  switch (type_) {
321  case NativeRoute:
322  return "NativeRoute";
323  case LocalTreeRoute:
324  return "LocalTreeRoute";
325  case GlobalTreeRoute:
326  return "GlobalTreeRoute";
327  case Invalid:
328  return "Invalid";
329  }
330  return "";
331 }
332 
333 const std::string ErmVpnRoute::GetType() const {
334  return GetPrefix().GetType();
335 }
virtual std::string ToXmppIdString() const
void BuildProtoPrefix(BgpProtoPrefix *prefix) const
Definition: ermvpn_route.cc:94
const BgpPath * BestPath() const
Definition: bgp_route.cc:46
const ErmVpnPrefix & GetPrefix() const
Definition: ermvpn_route.h:81
LabelBlockPtr label_block() const
Definition: bgp_attr.h:924
virtual int CompareTo(const Route &rhs) const
std::string ToString() const
Family
Definition: address.h:24
#define KEY_COMPARE(x, y)
Definition: util.h:70
static bool IsValid(uint8_t type)
boost::asio::ip::address IpAddress
Definition: address.h:13
bool stringToInteger(const std::string &str, NumberType &num)
Definition: string_util.h:71
Ip4Address group_
Definition: ermvpn_route.h:69
RouteDistinguisher rd_
Definition: ermvpn_route.h:67
Definition: route.h:14
static RouteDistinguisher FromString(const std::string &str, boost::system::error_code *error=NULL)
Definition: rd.cc:83
Ip4Address router_id_
Definition: ermvpn_route.h:68
static const uint8_t kMaxV4PrefixLen
Definition: address.h:20
std::string ToXmppIdString() const
std::unique_ptr< DBRequestKey > KeyPtr
Definition: db_entry.h:25
static uint64_t get_value(const uint8_t *data, int size)
Definition: parse_object.h:39
uint8_t type_
Definition: ermvpn_route.h:66
static ErmVpnPrefix FromString(const std::string &str, boost::system::error_code *errorp=NULL)
static const size_t kSize
Definition: rd.h:13
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:991
uint8_t type() const
Definition: ermvpn_route.h:56
const std::string GetType() const
uint8_t type
Definition: load_balance.h:109
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
static const uint8_t kMaxV4Bytes
Definition: address.h:19
Ip4Address source_
Definition: ermvpn_route.h:70
std::vector< uint8_t > prefix
virtual std::string ToString() const
Ip4Address router_id() const
Definition: ermvpn_route.h:58
const RouteDistinguisher & route_distinguisher() const
Definition: ermvpn_route.h:57
std::string xmpp_id_str_
Definition: ermvpn_route.h:102
Ip4Address source() const
Definition: ermvpn_route.h:60
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
static bool IsValidForBgp(uint8_t type)
Ip4Address group() const
Definition: ermvpn_route.h:59
const std::string GetType() const
virtual KeyPtr GetDBRequestKey() const
bool operator==(const ErmVpnPrefix &rhs) const
const BgpAttr * GetAttr() const
Definition: bgp_path.h:87
ErmVpnRoute(const ErmVpnPrefix &prefix)
std::string ToString() const
Definition: rd.cc:56
ErmVpnPrefix prefix_
Definition: ermvpn_route.h:101
static int FromProtoPrefix(const BgpProtoPrefix &proto_prefix, ErmVpnPrefix *prefix)
Definition: ermvpn_route.cc:49
const EdgeForwarding * edge_forwarding() const
Definition: bgp_attr.h:921
virtual void BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr=NULL, uint32_t label=0, uint32_t l3_label=0) const
const EdgeDiscovery * edge_discovery() const
Definition: bgp_attr.h:918
const uint8_t * GetData() const
Definition: rd.h:59
virtual void SetKey(const DBRequestKey *reqkey)
virtual bool IsValid() const
Definition: bgp_route.cc:338
virtual bool IsValid() const
virtual void BuildBgpProtoNextHop(std::vector< uint8_t > &nh, IpAddress nexthop) const