OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
inetvpn_address.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 
9 #include "bgp/inet/inet_route.h"
10 
11 using std::copy;
12 using std::string;
13 
14 InetVpnPrefix::InetVpnPrefix() : prefixlen_(0) {
15 }
16 
18  InetVpnPrefix *prefix, const BgpAttr *attr,
19  uint32_t *label) {
20  size_t nlri_size = proto_prefix.prefix.size();
21  size_t expected_min_nlri_size =
23 
24  if (nlri_size < expected_min_nlri_size)
25  return -1;
26  if (nlri_size > expected_min_nlri_size + Address::kMaxV4Bytes)
27  return -1;
28 
29  bool is_vni = false;
30  if (attr != NULL) {
31  const ExtCommunity *extcomm = attr->ext_community();
32  if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
33  is_vni = true;
34  }
35  }
36 
37  size_t label_offset = 0;
38  *label = proto_prefix.ReadLabel(label_offset, is_vni); //was ,false
39  size_t rd_offset = label_offset + BgpProtoPrefix::kLabelSize;
40  prefix->rd_ = RouteDistinguisher(&proto_prefix.prefix[rd_offset]);
41 
42  size_t prefix_offset = rd_offset + RouteDistinguisher::kSize;
43  prefix->prefixlen_ = proto_prefix.prefixlen - prefix_offset * 8;
44  Ip4Address::bytes_type bt = { { 0 } };
45  copy(proto_prefix.prefix.begin() + prefix_offset,
46  proto_prefix.prefix.end(), bt.begin());
47  prefix->addr_ = Ip4Address(bt);
48 
49  return 0;
50 }
51 
53  const BgpProtoPrefix &proto_prefix,
54  const BgpAttr *attr,
55  const Address::Family family,
56  InetVpnPrefix *prefix,
57  BgpAttrPtr *new_attr, uint32_t *label,
58  uint32_t *l3_label) {
59  int rval = FromProtoPrefix(proto_prefix, prefix, attr, label);
60  return rval;
61 }
62 
63 void InetVpnPrefix::BuildProtoPrefix(uint32_t label,
64  BgpProtoPrefix *proto_prefix, const BgpAttr *attr) const {
65  proto_prefix->prefix.clear();
66  size_t prefix_size = (prefixlen_ + 7) / 8;
67  size_t nlri_size =
69 
70  proto_prefix->prefix.resize(nlri_size, 0);
71  size_t label_offset = 0;
72 
73  bool is_vni = false;
74  if (attr != NULL) {
75  const ExtCommunity *extcomm = attr->ext_community();
76  if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
77  is_vni = true;
78  }
79  }
80 
81  proto_prefix->WriteLabel(label_offset, label, is_vni); // was false
82  size_t rd_offset = label_offset + BgpProtoPrefix::kLabelSize;
84  proto_prefix->prefix.begin() + rd_offset);
85 
86  size_t prefix_offset = rd_offset + RouteDistinguisher::kSize;
87  proto_prefix->prefixlen = prefix_offset * 8 + prefixlen_;
88  const Ip4Address::bytes_type &addr_bytes = addr_.to_bytes();
89  copy(addr_bytes.begin(), addr_bytes.begin() + prefix_size,
90  proto_prefix->prefix.begin() + prefix_offset);
91 }
92 
93 // RD:inet4-prefix
95  boost::system::error_code *errorp) {
96  InetVpnPrefix prefix;
97 
98  size_t pos = str.rfind(':');
99  if (pos == string::npos) {
100  if (errorp != NULL) {
101  *errorp = make_error_code(boost::system::errc::invalid_argument);
102  }
103  return prefix;
104  }
105  string rdstr = str.substr(0, pos);
106  boost::system::error_code rderr;
107  prefix.rd_ = RouteDistinguisher::FromString(rdstr, &rderr);
108  if (rderr.failed()) {
109  if (errorp != NULL) {
110  *errorp = rderr;
111  }
112  return prefix;
113  }
114 
115  string ip4pstr(str, pos + 1);
116  boost::system::error_code pfxerr = Ip4SubnetParse(ip4pstr, &prefix.addr_,
117  &prefix.prefixlen_);
118  if (errorp != NULL) {
119  *errorp = pfxerr;
120  }
121  return prefix;
122 }
123 
124 string InetVpnPrefix::ToString() const {
125  Ip4Prefix prefix(addr_, prefixlen_);
126  return (rd_.ToString() + ":" + prefix.ToString());
127 }
128 
129 // Check whether 'this' is more specific than rhs.
131  Ip4Prefix this_prefix(addr_, prefixlen_);
132  Ip4Prefix match_prefix(rhs.addr(), rhs.prefixlen());
133 
134  return this_prefix.IsMoreSpecific(match_prefix);
135 }
136 
137 bool InetVpnPrefix::operator==(const InetVpnPrefix &rhs) const {
138  return (rd_ == rhs.rd_ &&
139  addr_ == rhs.addr_ &&
140  prefixlen_ == rhs.prefixlen_);
141 }
void WriteLabel(size_t label_offset, uint32_t label, bool is_vni=false)
Family
Definition: address.h:24
Ip4Address addr() const
static RouteDistinguisher FromString(const std::string &str, boost::system::error_code *error=NULL)
Definition: rd.cc:83
uint32_t ReadLabel(size_t label_offset, bool is_vni=false) const
std::string ToString() const
static InetVpnPrefix FromString(const std::string &str, boost::system::error_code *errorp=NULL)
bool IsMoreSpecific(const InetVpnPrefix &rhs) const
static const size_t kSize
Definition: rd.h:13
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:991
Ip4Address addr_
static const uint8_t kMaxV4Bytes
Definition: address.h:19
static const size_t kLabelSize
Definition: bgp_attr_base.h:98
std::vector< uint8_t > prefix
bool operator==(const InetVpnPrefix &rhs) const
static int FromProtoPrefix(const BgpProtoPrefix &proto_prefix, InetVpnPrefix *prefix, const BgpAttr *attr, uint32_t *label)
std::string ToString() const
Definition: inet_route.cc:60
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
boost::system::error_code Ip4SubnetParse(const string &str, Ip4Address *addr, int *plen)
Definition: address.cc:131
RouteDistinguisher rd_
const ExtCommunity * ext_community() const
Definition: bgp_attr.h:915
bool ContainsTunnelEncapVxlan() const
Definition: community.cc:655
bool IsMoreSpecific(const Ip4Prefix &rhs) const
Definition: inet_route.cc:96
std::string ToString() const
Definition: rd.cc:56
int prefixlen() const
const uint8_t * GetData() const
Definition: rd.h:59
void BuildProtoPrefix(uint32_t label, BgpProtoPrefix *proto_prefix, const BgpAttr *attr=NULL) const