OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rd.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "net/rd.h"
6 
7 #include <string>
8 
9 #include "base/parse_object.h"
10 #include "base/address.h"
11 
12 using std::string;
13 
15 
17  memset(data_, 0, kSize);
18 }
19 
21  memcpy(data_, data, kSize);
22 }
23 
24 RouteDistinguisher::RouteDistinguisher(uint32_t address, uint16_t vrf_id) {
26  put_value(data_ + 2, 4, address);
27  put_value(data_ + 6, 2, vrf_id);
28 }
29 
30 RouteDistinguisher::RouteDistinguisher(bool is_bgpaas, uint32_t asn, uint16_t vmi_index) {
32  put_value(data_ + 2, 4, asn);
33  put_value(data_ + 6, 2, vmi_index);
34 }
35 
36 RouteDistinguisher::RouteDistinguisher(uint16_t cluster_seed, uint32_t address,
37  uint16_t vrf_id) {
39  put_value(data_ + 2, 2, cluster_seed);
40  put_value(data_ + 4, 2, (address & 0xFFFF));
41  put_value(data_ + 6, 2, vrf_id);
42 }
43 
44 uint16_t RouteDistinguisher::Type() const {
45  return get_value(data_, 2);
46 }
47 
49  return (Type() == TypeIpAddressBased ? get_value(data_ + 2, 4) : 0);
50 }
51 
52 uint16_t RouteDistinguisher::GetVrfId() const {
53  return (Type() == TypeIpAddressBased ? get_value(data_ + 6, 2) : 0);
54 }
55 
57  char temp[32];
58 
59  uint16_t rd_type = get_value(data_, 2);
60  if (rd_type == Type2ByteASBased) {
61  uint16_t asn = get_value(data_ + 2, 2);
62  uint32_t value = get_value(data_ + 4, 4);
63  snprintf(temp, sizeof(temp), "%u:%u", asn, value);
64  return string(temp);
65  } else if (rd_type == TypeIpAddressBased) {
66  Ip4Address ip(get_value(data_ + 2, 4));
67  uint16_t value = get_value(data_ + 6, 2);
68  snprintf(temp, sizeof(temp), ":%u", value);
69  return ip.to_string() + temp;
70  } else if (rd_type == Type4ByteASBased) {
71  uint32_t asn = get_value(data_ + 2, 4);
72  uint16_t value = get_value(data_ + 6, 2);
73  snprintf(temp, sizeof(temp), "%u:%u", asn, value);
74  return string(temp);
75  } else {
76  snprintf(temp, sizeof(temp), "%u:%02x:%02x:%02x:%02x:%02x:%02x",
77  rd_type, data_[2], data_[3], data_[4], data_[5], data_[6],
78  data_[7]);
79  return string(temp);
80  }
81 }
82 
84  const string &str, boost::system::error_code *errorp) {
86  size_t pos = str.rfind(':');
87  if (pos == string::npos) {
88  if (errorp != NULL) {
89  *errorp = make_error_code(boost::system::errc::invalid_argument);
90  }
92  }
93 
94  boost::system::error_code ec;
95  string first(str.substr(0, pos));
96  Ip4Address addr = Ip4Address::from_string(first, ec);
97  int offset;
98  char *endptr;
99  int32_t asn = -1;
100  if (ec.value() != 0) {
101  // Not an IP address, try ASN.
102  asn = strtol(first.c_str(), &endptr, 10);
103  if (asn >= 65535 || *endptr != '\0') {
104  if (errorp != NULL) {
105  *errorp =
106  make_error_code(boost::system::errc::invalid_argument);
107  }
109  }
110 
111  put_value(rd.data_, 2, 0);
112  put_value(rd.data_ + 2, 2, asn);
113  offset = 4;
114  } else {
115  put_value(rd.data_, 2, 1);
116  put_value(rd.data_ + 2, 4, addr.to_ulong());
117  offset = 6;
118  }
119 
120  string second(str, pos + 1);
121  uint64_t value = strtol(second.c_str(), &endptr, 10);
122  if (*endptr != '\0') {
123  if (errorp != NULL) {
124  *errorp = make_error_code(boost::system::errc::invalid_argument);
125  }
127  }
128 
129  // ASN 0 is not allowed if the assigned number is not 0.
130  if (asn == 0 && value != 0) {
131  if (errorp != NULL) {
132  *errorp = make_error_code(boost::system::errc::invalid_argument);
133  }
135  }
136 
137  // Check assigned number for type 0.
138  if (offset == 4 && value > 0xFFFFFFFF) {
139  if (errorp != NULL) {
140  *errorp = make_error_code(boost::system::errc::invalid_argument);
141  }
143  }
144 
145  // Check assigned number for type 1.
146  if (offset == 6 && value > 0xFFFF) {
147  if (errorp != NULL) {
148  *errorp = make_error_code(boost::system::errc::invalid_argument);
149  }
151  }
152 
153  put_value(rd.data_ + offset, 8 - offset, value);
154  return rd;
155 }
156 
158  return memcmp(data_, rhs.data_, kSize);
159 }
static RouteDistinguisher FromString(const std::string &str, boost::system::error_code *error=NULL)
Definition: rd.cc:83
uint16_t Type() const
Definition: rd.cc:44
int CompareTo(const RouteDistinguisher &rhs) const
Definition: rd.cc:157
static uint64_t get_value(const uint8_t *data, int size)
Definition: parse_object.h:39
static const size_t kSize
Definition: rd.h:13
uint16_t GetVrfId() const
Definition: rd.cc:52
static RouteDistinguisher kZeroRd
Definition: rd.h:14
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
uint32_t GetAddress() const
Definition: rd.cc:48
uint8_t data_[kSize]
Definition: rd.h:62
std::string ToString() const
Definition: rd.cc:56
RouteDistinguisher()
Definition: rd.cc:16
static void put_value(uint8_t *data, int size, uint64_t value)
Definition: parse_object.h:55