OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
inet6_route.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "base/misc_utils.h"
6 #include "base/string_util.h"
9 
10 using boost::system::error_code;
11 using std::copy;
12 using std::string;
13 using std::vector;
14 
16  Inet6Prefix *prefix) {
17  if (proto_prefix.prefix.size() > Address::kMaxV6Bytes)
18  return -1;
19  prefix->prefixlen_ = proto_prefix.prefixlen;
20  Ip6Address::bytes_type bt = { { 0 } };
21  copy(proto_prefix.prefix.begin(), proto_prefix.prefix.end(), bt.begin());
22  prefix->ip6_addr_ = Ip6Address(bt);
23 
24  return 0;
25 }
26 
28  const BgpProtoPrefix &proto_prefix,
29  const BgpAttr *attr,
30  const Address::Family family,
31  Inet6Prefix *prefix, BgpAttrPtr *new_attr,
32  uint32_t *label, uint32_t *l3_label) {
33  return FromProtoPrefix(proto_prefix, prefix);
34 }
35 
36 string Inet6Prefix::ToString() const {
37  string repr(ip6_addr().to_string());
38  repr.append("/" + integerToString(prefixlen()));
39  return repr;
40 }
41 
42 int Inet6Prefix::CompareTo(const Inet6Prefix &rhs) const {
43  if (ip6_addr_ < rhs.ip6_addr_) {
44  return -1;
45  }
46  if (ip6_addr_ > rhs.ip6_addr_) {
47  return 1;
48  }
49  if (prefixlen_ < rhs.prefixlen_) {
50  return -1;
51  }
52  if (prefixlen_ > rhs.prefixlen_) {
53  return 1;
54  }
55  return 0;
56 }
57 
58 Inet6Prefix Inet6Prefix::FromString(const string &str, error_code *error) {
59  Inet6Prefix prefix;
60  error_code pfxerr = Inet6SubnetParse(str, &prefix.ip6_addr_,
61  &prefix.prefixlen_);
62  if (error != NULL) {
63  *error = pfxerr;
64  }
65  return prefix;
66 }
67 
68 // Check whether 'this' is more specific than rhs.
69 bool Inet6Prefix::IsMoreSpecific(const Inet6Prefix &rhs) const {
70  // My prefixlen must be longer in order to be more specific.
71  if (prefixlen_ < rhs.prefixlen()) {
72  return false;
73  }
75  Inet6Prefix left = operator&(mask);
76  Inet6Prefix right = rhs.operator&(mask);
77 
78  return (left.ToBytes() == right.ToBytes());
79 }
80 
82  Ip6Address::bytes_type addr_bytes;
83  ARRAYBYTES_FILL(addr_bytes,0);
84 
85  Ip6Address::bytes_type lhs = ToBytes();
86  Ip6Address::bytes_type rhs = right.ToBytes();
87 
88  int plen = (prefixlen_ <= right.prefixlen_ ? prefixlen() : right.prefixlen());
89 
90  for (size_t i = 0; i < sizeof(Ip6Address::bytes_type); ++i) {
91  addr_bytes[i] = lhs[i] & rhs[i];
92  }
93 
94  return Inet6Prefix(Ip6Address(addr_bytes), plen);
95 }
96 
97 // Routines for class Inet6Route
98 
100  : prefix_(prefix),
101  prefix_str_(prefix.ToString()) {
102 }
103 
104 int Inet6Route::CompareTo(const Route &rhs) const {
105  const Inet6Route &rt_other = static_cast<const Inet6Route &>(rhs);
106  return prefix_.CompareTo(rt_other.prefix_);
107 }
108 
109 // Check whether 'this' is more specific than rhs.
110 bool Inet6Route::IsMoreSpecific(const string &match) const {
111  error_code ec;
112 
113  Inet6Prefix prefix = Inet6Prefix::FromString(match, &ec);
114  if (!ec) {
115  return GetPrefix().IsMoreSpecific(prefix);
116  }
117 
118  return false;
119 }
120 
121 // Check whether 'this' is less specific than rhs.
122 bool Inet6Route::IsLessSpecific(const string &match) const {
123  error_code ec;
124 
125  Inet6Prefix prefix = Inet6Prefix::FromString(match, &ec);
126  if (!ec) {
127  return prefix.IsMoreSpecific(GetPrefix());
128  }
129 
130  return false;
131 }
132 
135  return KeyPtr(key);
136 }
137 
138 void Inet6Route::SetKey(const DBRequestKey *reqkey) {
139  const Inet6Table::RequestKey *key =
140  static_cast<const Inet6Table::RequestKey *>(reqkey);
141  prefix_ = key->prefix;
142 }
143 
145  const BgpAttr *attr,
146  uint32_t label,
147  uint32_t l3_label) const {
148  prefix->prefixlen = prefix_.prefixlen();
149  prefix->prefix.clear();
150  const Ip6Address::bytes_type &addr_bytes = prefix_.ip6_addr().to_bytes();
151  int num_bytes = (prefix->prefixlen + 7) / 8;
152  copy(addr_bytes.begin(), addr_bytes.begin() + num_bytes,
153  back_inserter(prefix->prefix));
154 }
155 
156 //
157 // Fill in the vector based on the supplied nexthop.
158 //
159 void Inet6Route::BuildBgpProtoNextHop(vector<uint8_t> &nh,
160  IpAddress nexthop) const {
161  nh.resize(Address::kMaxV6Bytes);
162  Ip6Address address;
163  if (nexthop.is_v4()) {
164  address = Ip6Address::v4_mapped(nexthop.to_v4());
165  } else {
166  address = nexthop.to_v6();
167  }
168 
169  const Ip6Address::bytes_type &addr_bytes = address.to_bytes();
170  copy(addr_bytes.begin(), addr_bytes.end(), nh.begin());
171 }
172 
173 // Routines for class Inet6Masks
174 
175 // Definitions of the static members
176 bool Inet6Masks::initialized_ = false;
177 vector<Inet6Prefix> Inet6Masks::masks_;
178 
179 const Inet6Prefix& Inet6Masks::PrefixlenToMask(uint8_t prefix_len) {
180  assert(prefix_len <= Inet6Prefix::kMaxV6PrefixLen);
181  return masks_.at(prefix_len);
182 }
183 
185  assert(initialized_ == false);
186  for (int i = 0; i <= Inet6Prefix::kMaxV6PrefixLen; ++i) {
187  masks_.push_back(CalculateMaskFromPrefixlen(i));
188  }
189  initialized_ = true;
190 }
191 
193  masks_.clear();
194  initialized_ = false;
195 }
196 
198  int num_bytes = prefixlen / 8;
199  int num_bits = prefixlen % 8;
200 
201  Ip6Address::bytes_type addr_bytes;
202  ARRAYBYTES_FILL(addr_bytes,0);
203 
204  for (int i = 0; i < num_bytes; ++i) {
205  addr_bytes[i] = 0xff;
206  }
207  if (num_bits) {
208  uint8_t hex_val = 0xff << (8 - num_bits);
209  addr_bytes[num_bytes] = hex_val;
210  }
211  return Inet6Prefix(Ip6Address(addr_bytes), prefixlen);
212 }
213 
214 static void Inet6InitRoutines() {
216 }
Inet6Prefix prefix_
Definition: inet6_route.h:102
static bool initialized_
Definition: inet6_route.h:117
virtual void BuildBgpProtoNextHop(std::vector< uint8_t > &nh, IpAddress nexthop) const
Definition: inet6_route.cc:159
virtual bool IsMoreSpecific(const std::string &match) const
Definition: inet6_route.cc:110
static void Init()
Definition: inet6_route.cc:184
Family
Definition: address.h:24
boost::asio::ip::address IpAddress
Definition: address.h:13
virtual void SetKey(const DBRequestKey *reqkey)
Definition: inet6_route.cc:138
static int FromProtoPrefix(const BgpProtoPrefix &proto_prefix, Inet6Prefix *prefix)
Definition: inet6_route.cc:15
Definition: route.h:14
static std::vector< Inet6Prefix > masks_
Definition: inet6_route.h:116
std::unique_ptr< DBRequestKey > KeyPtr
Definition: db_entry.h:25
int CompareTo(const Inet6Prefix &rhs) const
Definition: inet6_route.cc:42
Inet6Route(const Inet6Prefix &prefix)
Definition: inet6_route.cc:99
static string ToString(PhysicalDevice::ManagementProtocol proto)
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:991
static void Inet6InitRoutines()
Definition: inet6_route.cc:214
#define ARRAYBYTES_FILL(obj, val)
Definition: misc_utils.h:31
static Inet6Prefix FromString(const std::string &str, boost::system::error_code *errorp=NULL)
Definition: inet6_route.cc:58
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
Inet6Prefix operator&(const Inet6Prefix &rhs) const
Definition: inet6_route.cc:81
std::vector< uint8_t > prefix
virtual void BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr=NULL, uint32_t label=0, uint32_t l3_label=0) const
Definition: inet6_route.cc:144
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
std::string ToString() const
Definition: inet6_route.cc:36
Ip6Address ip6_addr_
Definition: inet6_route.h:70
virtual KeyPtr GetDBRequestKey() const
Definition: inet6_route.cc:133
const Ip6Address::bytes_type ToBytes() const
Definition: inet6_route.h:29
static const uint8_t kMaxV6Bytes
Definition: address.h:21
int prefixlen_
Definition: inet6_route.h:71
Ip6Address ip6_addr() const
Definition: inet6_route.h:27
static const uint8_t kMaxV6PrefixLen
Definition: inet6_route.h:18
int prefixlen() const
Definition: inet6_route.h:33
static void Clear()
Definition: inet6_route.cc:192
static Inet6Prefix CalculateMaskFromPrefixlen(int prefixlen)
Definition: inet6_route.cc:197
const Inet6Prefix & GetPrefix() const
Definition: inet6_route.h:80
virtual bool IsLessSpecific(const std::string &match) const
Definition: inet6_route.cc:122
virtual int CompareTo(const Route &rhs) const
Definition: inet6_route.cc:104
#define MODULE_INITIALIZER(Func)
Definition: util.h:61
bool IsMoreSpecific(const Inet6Prefix &rhs) const
Definition: inet6_route.cc:69
static const Inet6Prefix & PrefixlenToMask(uint8_t prefix_len)
Definition: inet6_route.cc:179
boost::system::error_code Inet6SubnetParse(const string &str, Ip6Address *addr, int *plen)
Definition: address.cc:162