OpenSDN source code
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
bgp/evpn/evpn_route.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3  */
4 
5 #include "bgp/evpn/evpn_route.h"
6 
7 #include <algorithm>
8 #include <sstream>
9 
10 #include "base/string_util.h"
11 #include "bgp/bgp_server.h"
12 #include "bgp/evpn/evpn_table.h"
13 
14 using std::copy;
15 using std::string;
16 using std::vector;
17 
19 const uint32_t EvpnPrefix::kInvalidLabel = 0x01000000;
20 const uint32_t EvpnPrefix::kNullTag = 0;
21 const uint32_t EvpnPrefix::kMaxTag = 0xFFFFFFFF;
22 const uint32_t EvpnPrefix::kMaxVni = 0x00FFFFFF;
23 const int32_t EvpnPrefix::kMaxVniSigned =
24  static_cast<uint32_t>(EvpnPrefix::kMaxVni);
25 
28 const size_t EvpnPrefix::kTagSize = 4;
29 const size_t EvpnPrefix::kIp4AddrSize = 4;
30 const size_t EvpnPrefix::kIp6AddrSize = 16;
31 const size_t EvpnPrefix::kMacSize = MacAddress::size();
33 
35  kRdSize + kEsiSize + kTagSize;
37  kRdSize + kEsiSize + kTagSize + 1 + kMacSize + 1;
39  kRdSize + kTagSize + 1;
41  kRdSize + kTagSize + 3;
43  kRdSize + kEsiSize + 1;
45  kRdSize + kEsiSize + kTagSize + 1 + 2 * kIp4AddrSize;
47  kRdSize + kEsiSize + kTagSize + 1 + 2 * kIp6AddrSize;
48 
49 //
50 // Read label from the BgpProtoPrefix.
51 // If the encapsulation is VXLAN and ethernet tag is non-zero use that as
52 // the label for backward compatibility with older JUNOS code.
53 //
54 // Note that Ethernet AD Routes per ESI always set ethernet tag to kMaxTag
55 // and their label is supposed to be set to 0 on write and ignored on read.
56 //
57 static uint32_t ReadLabel(const BgpProtoPrefix &proto_prefix,
58  const BgpAttr *attr, size_t offset, uint32_t tag = EvpnPrefix::kNullTag) {
59  if (!attr)
60  return 0;
61  const ExtCommunity *extcomm = attr->ext_community();
62  if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
63  if (tag) {
64  if (tag == EvpnPrefix::kMaxTag) {
65  return 0;
66  } else if (tag <= EvpnPrefix::kMaxVni) {
67  return tag;
68  } else {
69  return proto_prefix.ReadLabel(offset, true);
70  }
71  } else {
72  return proto_prefix.ReadLabel(offset, true);
73  }
74  } else {
75  return proto_prefix.ReadLabel(offset, false);
76  }
77 }
78 
79 //
80 // Write label to the BgpProtoPrefix.
81 //
82 static void WriteLabel(BgpProtoPrefix *proto_prefix,
83  const BgpAttr *attr, size_t offset, uint32_t label) {
84  const ExtCommunity *extcomm = attr ? attr->ext_community() : NULL;
85  if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
86  proto_prefix->WriteLabel(offset, label, true);
87  } else {
88  proto_prefix->WriteLabel(offset, label, false);
89  }
90 }
91 
92 //
93 // Read gateway address from the BgpProtoPrefix.
94 //
95 static IpAddress ReadGwAddress(const BgpProtoPrefix &proto_prefix,
96  size_t gw_offset, size_t ip_size) {
97  assert(ip_size == EvpnPrefix::kIp4AddrSize ||
98  ip_size == EvpnPrefix::kIp6AddrSize);
99  if (ip_size == EvpnPrefix::kIp4AddrSize) {
100  Ip4Address::bytes_type bytes;
101  copy(proto_prefix.prefix.begin() + gw_offset,
102  proto_prefix.prefix.begin() + gw_offset + ip_size, bytes.begin());
103  return Ip4Address(bytes);
104  } else {
105  Ip6Address::bytes_type bytes;
106  copy(proto_prefix.prefix.begin() + gw_offset,
107  proto_prefix.prefix.begin() + gw_offset + ip_size, bytes.begin());
108  return Ip6Address(bytes);
109  }
110  return IpAddress();
111 }
112 
114  : type_(Unspecified),
115  tag_(EvpnPrefix::kNullTag),
116  family_(Address::UNSPEC),
117  ip_prefixlen_(0) {
118 }
119 
121  const EthernetSegmentId &esi, uint32_t tag)
122  : type_(AutoDiscoveryRoute),
123  rd_(rd),
124  esi_(esi),
125  tag_(tag),
126  family_(Address::UNSPEC),
127  ip_prefixlen_(0) {
128 }
129 
131  const MacAddress &mac_addr, const IpAddress &ip_address)
132  : type_(MacAdvertisementRoute),
133  rd_(rd),
134  tag_(EvpnPrefix::kNullTag),
135  mac_addr_(mac_addr),
136  family_(Address::UNSPEC),
137  ip_address_(ip_address),
138  ip_prefixlen_(0) {
139  if (ip_address_.is_v4() && !ip_address_.is_unspecified()) {
141  } else if (ip_address_.is_v6() && !ip_address_.is_unspecified()) {
143  }
144 }
145 
147  const MacAddress &mac_addr, const IpAddress &ip_address)
148  : type_(MacAdvertisementRoute), rd_(rd), tag_(tag),
149  mac_addr_(mac_addr), family_(Address::UNSPEC),
150  ip_address_(ip_address), ip_prefixlen_(0) {
151  if (ip_address_.is_v4() && !ip_address_.is_unspecified()) {
153  } else if (ip_address_.is_v6() && !ip_address_.is_unspecified()) {
155  }
156 }
157 
159  const IpAddress &ip_address)
160  : type_(InclusiveMulticastRoute),
161  rd_(rd),
162  tag_(tag),
163  family_(Address::UNSPEC),
164  ip_address_(ip_address),
165  ip_prefixlen_(0) {
166  if (ip_address_.is_v4() && !ip_address_.is_unspecified()) {
168  } else if (ip_address_.is_v6() && !ip_address_.is_unspecified()) {
170  }
171 }
172 
174  const EthernetSegmentId &esi, const IpAddress &ip_address)
175  : type_(SegmentRoute),
176  rd_(rd),
177  esi_(esi),
178  tag_(EvpnPrefix::kNullTag),
179  family_(Address::UNSPEC),
180  ip_address_(ip_address),
181  ip_prefixlen_(0) {
182  if (ip_address_.is_v4() && !ip_address_.is_unspecified()) {
184  } else if (ip_address_.is_v6() && !ip_address_.is_unspecified()) {
186  }
187 }
188 
190  const IpAddress &ip_address, uint8_t ip_prefixlen)
191  : type_(IpPrefixRoute),
192  rd_(rd),
193  tag_(0),
194  family_(Address::UNSPEC),
195  ip_address_(ip_address),
196  ip_prefixlen_(ip_prefixlen) {
197  assert(ip_address_.is_v4() || ip_address_.is_v6());
198  if (ip_address_.is_v4()) {
200  } else if (ip_address_.is_v6()) {
202  }
203 }
204 
206  const IpAddress &source, const IpAddress &group,
207  const IpAddress &ip_address)
208  : type_(SelectiveMulticastRoute),
209  rd_(rd),
210  tag_(tag),
211  family_(Address::UNSPEC),
212  ip_address_(ip_address),
213  source_(source),
214  group_(group),
215  ip_prefixlen_(0), flags_(0x2) {
216  if (ip_address_.is_v4() && !ip_address_.is_unspecified()) {
218  } else if (ip_address_.is_v6() && !ip_address_.is_unspecified()) {
220  }
221  string ip = group.to_v4().to_string();
222  char *str = const_cast<char *>(ip.c_str());
223  char * mac_ip = strstr(str, ".");
224  std::ostringstream oss;
225  oss << "01:00:5e:" << strtok(mac_ip, ".");
226  oss << ":" << strtok(NULL, ".");
227  oss << ":" << strtok(NULL, "");
228  mac_addr_ = MacAddress::FromString(oss.str(), NULL);
229 }
230 
232  const BgpProtoPrefix &proto_prefix, const BgpAttr *attr,
233  const Address::Family family, EvpnPrefix *prefix, BgpAttrPtr *new_attr,
234  uint32_t *label, uint32_t *l3_label) {
235  *new_attr = attr;
236  *label = 0;
237  if (l3_label)
238  *l3_label = 0;
239  prefix->type_ = proto_prefix.type;
240  size_t nlri_size = proto_prefix.prefix.size();
241 
242  switch (prefix->type_) {
243  case AutoDiscoveryRoute: {
244  size_t expected_min_nlri_size =
245  kMinAutoDiscoveryRouteSize + (attr ? kLabelSize : 0);
246  if (nlri_size < expected_min_nlri_size)
247  return -1;
248  size_t rd_offset = 0;
249  prefix->rd_ = RouteDistinguisher(&proto_prefix.prefix[rd_offset]);
250  size_t esi_offset = rd_offset + kRdSize;
251  prefix->esi_ = EthernetSegmentId(&proto_prefix.prefix[esi_offset]);
252  size_t tag_offset = esi_offset + kEsiSize;
253  prefix->tag_ = get_value(&proto_prefix.prefix[tag_offset], kTagSize);
254  size_t label_offset = tag_offset + kTagSize;
255  *label = ReadLabel(proto_prefix, attr, label_offset, prefix->tag_);
256  break;
257  }
258  case MacAdvertisementRoute: {
259  size_t expected_min_nlri_size =
261  if (nlri_size < expected_min_nlri_size)
262  return -1;
263  size_t rd_offset = 0;
264  prefix->rd_ = RouteDistinguisher(&proto_prefix.prefix[rd_offset]);
265  size_t esi_offset = rd_offset + kRdSize;
266  if (attr) {
267  EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]);
268  *new_attr = server->attr_db()->ReplaceEsiAndLocate(attr, esi);
269  }
270  size_t tag_offset = esi_offset + kEsiSize;
271  prefix->tag_ = get_value(&proto_prefix.prefix[tag_offset], kTagSize);
272  size_t mac_len_offset = tag_offset + kTagSize;
273  size_t mac_len = proto_prefix.prefix[mac_len_offset];
274  if (mac_len != 48)
275  return -1;
276  size_t mac_offset = mac_len_offset + 1;
277  prefix->mac_addr_ = MacAddress(&proto_prefix.prefix[mac_offset]);
278  size_t ip_len_offset = mac_offset + kMacSize;
279  size_t ip_len = proto_prefix.prefix[ip_len_offset];
280  if (ip_len != 0 && ip_len != 32 && ip_len != 128)
281  return -1;
282  size_t ip_size = ip_len / 8;
283  if (nlri_size < expected_min_nlri_size + ip_size)
284  return -1;
285  size_t ip_offset = ip_len_offset + 1;
286  prefix->ReadIpAddress(proto_prefix, ip_offset, ip_size, ip_size);
287  size_t label_offset = ip_offset + ip_size;
288  *label = ReadLabel(proto_prefix, attr, label_offset, prefix->tag_);
289  size_t l3_label_offset = label_offset + kLabelSize;
290  if (l3_label && nlri_size >= l3_label_offset + kLabelSize) {
291  *l3_label = ReadLabel(proto_prefix, attr, l3_label_offset);
292  }
293  break;
294  }
296  if (nlri_size < kMinInclusiveMulticastRouteSize)
297  return -1;
298  size_t rd_offset = 0;
299  prefix->rd_ = RouteDistinguisher(&proto_prefix.prefix[rd_offset]);
300  size_t tag_offset = rd_offset + kRdSize;
301  prefix->tag_ = get_value(&proto_prefix.prefix[tag_offset], kTagSize);
302  size_t ip_len_offset = tag_offset + kTagSize;
303  size_t ip_len = proto_prefix.prefix[ip_len_offset];
304  if (ip_len != 32 && ip_len != 128)
305  return -1;
306  size_t ip_size = ip_len / 8;
307  if (nlri_size < kMinInclusiveMulticastRouteSize + ip_size)
308  return -1;
309  size_t ip_offset = ip_len_offset + 1;
310  prefix->ReadIpAddress(proto_prefix, ip_offset, ip_size, ip_size);
311  const PmsiTunnel *pmsi_tunnel = attr ? attr->pmsi_tunnel() : NULL;
312  if (pmsi_tunnel &&
313  (pmsi_tunnel->tunnel_type() == PmsiTunnelSpec::IngressReplication ||
314  pmsi_tunnel->tunnel_type() ==
316  const ExtCommunity *extcomm = attr ? attr->ext_community() : NULL;
317  if (extcomm && extcomm->ContainsTunnelEncapVxlan()) {
318  if (prefix->tag_ && prefix->tag_ <= kMaxVni) {
319  *label = prefix->tag_;
320  } else {
321  *label = pmsi_tunnel->GetLabel(extcomm);
322  }
323  } else {
324  *label = pmsi_tunnel->GetLabel(extcomm);
325  }
326  }
327  break;
328  }
329  case SegmentRoute: {
330  if (nlri_size < kMinSegmentRouteSize)
331  return -1;
332  size_t rd_offset = 0;
333  prefix->rd_ = RouteDistinguisher(&proto_prefix.prefix[rd_offset]);
334  size_t esi_offset = rd_offset + kRdSize;
335  prefix->esi_ = EthernetSegmentId(&proto_prefix.prefix[esi_offset]);
336  size_t ip_len_offset = esi_offset + kEsiSize;
337  size_t ip_len = proto_prefix.prefix[ip_len_offset];
338  if (ip_len != 32 && ip_len != 128)
339  return -1;
340  size_t ip_size = ip_len / 8;
341  if (nlri_size < kMinSegmentRouteSize + ip_size)
342  return -1;
343  size_t ip_offset = ip_len_offset + 1;
344  prefix->ReadIpAddress(proto_prefix, ip_offset, ip_size, ip_size);
345  break;
346  }
347  case IpPrefixRoute: {
348  size_t ip_size;
349  if (attr) {
350  if (nlri_size == kMinInet6PrefixRouteSize + kLabelSize) {
351  ip_size = kIp6AddrSize;
352  } else if (nlri_size == kMinInetPrefixRouteSize + kLabelSize) {
353  ip_size = kIp4AddrSize;
354  } else {
355  return -1;
356  }
357  } else {
358  if (nlri_size == kMinInet6PrefixRouteSize ||
359  nlri_size == kMinInet6PrefixRouteSize + kLabelSize) {
360  ip_size = kIp6AddrSize;
361  } else if (nlri_size == kMinInetPrefixRouteSize ||
362  nlri_size == kMinInetPrefixRouteSize + kLabelSize) {
363  ip_size = kIp4AddrSize;
364  } else {
365  return -1;
366  }
367  }
368 
369  size_t rd_offset = 0;
370  prefix->rd_ = RouteDistinguisher(&proto_prefix.prefix[rd_offset]);
371  size_t esi_offset = rd_offset + kRdSize;
372  EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]);
373  if (!esi.IsZero())
374  return -1;
375  size_t tag_offset = esi_offset + kEsiSize;
376  // Ignore tag for type5 routes.
377  prefix->tag_ = 0;
378  size_t ip_plen_offset = tag_offset + kTagSize;
379  prefix->ip_prefixlen_ = proto_prefix.prefix[ip_plen_offset];
380  if (ip_size == kIp4AddrSize && prefix->ip_prefixlen_ > 32)
381  return -1;
382  if (ip_size == kIp6AddrSize && prefix->ip_prefixlen_ > 128)
383  return -1;
384  size_t ip_offset = ip_plen_offset + 1;
385  size_t ip_psize = (prefix->ip_prefixlen_ + 7) / 8;
386  prefix->ReadIpAddress(proto_prefix, ip_offset, ip_size, ip_psize);
387  size_t gw_offset = ip_offset + ip_size;
388  IpAddress gw_address = ReadGwAddress(proto_prefix, gw_offset, ip_size);
389  if (!gw_address.is_unspecified())
390  return -1;
391  size_t label_offset = gw_offset + ip_size;
392  *label = ReadLabel(proto_prefix, attr, label_offset);
393  break;
394  }
396  if (nlri_size < kMinSelectiveMulticastRouteSize)
397  return -1;
398  size_t rd_offset = 0;
399  prefix->rd_ = RouteDistinguisher(&proto_prefix.prefix[rd_offset]);
400  size_t tag_offset = rd_offset + kRdSize;
401  prefix->tag_ = get_value(&proto_prefix.prefix[tag_offset], kTagSize);
402  size_t src_len_offset = tag_offset + kTagSize;
403  size_t src_len = proto_prefix.prefix[src_len_offset];
404  if (src_len != 32 && src_len != 128 && src_len != 0)
405  return -1;
406  size_t src_size = src_len / 8;
407  size_t src_offset = src_len_offset + 1;
408  if (src_size > 0) {
409  if (nlri_size < src_offset + src_size)
410  return -1;
411  prefix->ReadSource(proto_prefix, src_offset, src_size);
412  }
413  size_t grp_len_offset = src_offset + src_size;
414  size_t grp_len = proto_prefix.prefix[grp_len_offset];
415  if (grp_len != 32 && grp_len != 128)
416  return -1;
417  size_t grp_size = grp_len / 8;
418  size_t grp_offset = grp_len_offset + 1;
419  if (nlri_size < grp_offset + grp_size)
420  return -1;
421  prefix->ReadGroup(proto_prefix, grp_offset, grp_size);
422  size_t ip_len_offset = grp_offset + grp_size;
423  size_t ip_len = proto_prefix.prefix[ip_len_offset];
424  if (ip_len != 32 && ip_len != 128)
425  return -1;
426  size_t ip_size = ip_len / 8;
427  size_t ip_offset = ip_len_offset + 1;
428  if (nlri_size < ip_offset + ip_size)
429  return -1;
430  prefix->ReadIpAddress(proto_prefix, ip_offset, ip_size, ip_size);
431  size_t flag_offset = ip_offset + ip_size;
432  if (nlri_size <= flag_offset + 4)
433  prefix->flags_ = get_value(&proto_prefix.prefix[flag_offset], 4);
434  break;
435  }
436  default: {
437  return -1;
438  break;
439  }
440  }
441  return 0;
442 }
443 
444 //
445 // Build the BgpProtoPrefix for this EvpnPrefix.
446 //
447 // The ESI for MacAdvertisementRoute is not part of the key and hence
448 // must be obtained from the BgpAttr. The BgpAttr is NULL and label is
449 // 0 when withdrawing the route.
450 //
452  const BgpAttr *attr, uint32_t label, uint32_t l3_label) const {
453  proto_prefix->type = type_;
454  proto_prefix->prefix.clear();
455 
456  switch (type_) {
457  case AutoDiscoveryRoute: {
458  size_t nlri_size = kMinAutoDiscoveryRouteSize + kLabelSize;
459  proto_prefix->prefixlen = nlri_size * 8;
460  proto_prefix->prefix.resize(nlri_size, 0);
461 
462  size_t rd_offset = 0;
463  copy(rd_.GetData(), rd_.GetData() + kRdSize,
464  proto_prefix->prefix.begin() + rd_offset);
465  size_t esi_offset = rd_offset + kRdSize;
466  copy(esi_.GetData(), esi_.GetData() + kEsiSize,
467  proto_prefix->prefix.begin() + esi_offset);
468  size_t tag_offset = esi_offset + kEsiSize;
469  put_value(&proto_prefix->prefix[tag_offset], kTagSize, tag_);
470  size_t label_offset = tag_offset + kTagSize;
471  WriteLabel(proto_prefix, attr, label_offset, label);
472  break;
473  }
474  case MacAdvertisementRoute: {
475  size_t ip_size = GetIpAddressSize();
476  size_t nlri_size = kMinMacAdvertisementRouteSize + ip_size + kLabelSize;
477  if (l3_label)
478  nlri_size += kLabelSize;
479  proto_prefix->prefixlen = nlri_size * 8;
480  proto_prefix->prefix.resize(nlri_size, 0);
481 
482  size_t rd_offset = 0;
483  copy(rd_.GetData(), rd_.GetData() + kRdSize,
484  proto_prefix->prefix.begin() + rd_offset);
485  size_t esi_offset = rd_offset + kRdSize;
486  if (attr) {
487  copy(attr->esi().GetData(), attr->esi().GetData() + kEsiSize,
488  proto_prefix->prefix.begin() + esi_offset);
489  }
490  size_t tag_offset = esi_offset + kEsiSize;
491  put_value(&proto_prefix->prefix[tag_offset], kTagSize, tag_);
492  size_t mac_len_offset = tag_offset + kTagSize;
493  proto_prefix->prefix[mac_len_offset] = 48;
494  size_t mac_offset = mac_len_offset + 1;
496  proto_prefix->prefix.begin() + mac_offset);
497  size_t ip_len_offset = mac_offset + kMacSize;
498  proto_prefix->prefix[ip_len_offset] = ip_size * 8;
499  size_t ip_offset = ip_len_offset + 1;
500  WriteIpAddress(proto_prefix, ip_offset);
501  size_t label_offset = ip_offset + ip_size;
502  WriteLabel(proto_prefix, attr, label_offset, label);
503  if (l3_label) {
504  size_t l3_label_offset = label_offset + kLabelSize;
505  WriteLabel(proto_prefix, attr, l3_label_offset, l3_label);
506  }
507  break;
508  }
510  size_t ip_size = GetIpAddressSize();
511  size_t nlri_size = kMinInclusiveMulticastRouteSize + ip_size;
512  proto_prefix->prefixlen = nlri_size * 8;
513  proto_prefix->prefix.resize(nlri_size, 0);
514 
515  size_t rd_offset = 0;
516  copy(rd_.GetData(), rd_.GetData() + kRdSize,
517  proto_prefix->prefix.begin() + rd_offset);
518  size_t tag_offset = rd_offset + kRdSize;
519  put_value(&proto_prefix->prefix[tag_offset], kTagSize, tag_);
520  size_t ip_len_offset = tag_offset + kTagSize;
521  proto_prefix->prefix[ip_len_offset] = ip_size * 8;
522  size_t ip_offset = ip_len_offset + 1;
523  WriteIpAddress(proto_prefix, ip_offset);
524  break;
525  }
526  case SegmentRoute: {
527  size_t ip_size = GetIpAddressSize();
528  size_t nlri_size = kMinSegmentRouteSize + ip_size;
529  proto_prefix->prefixlen = nlri_size * 8;
530  proto_prefix->prefix.resize(nlri_size, 0);
531 
532  size_t rd_offset = 0;
533  copy(rd_.GetData(), rd_.GetData() + kRdSize,
534  proto_prefix->prefix.begin() + rd_offset);
535  size_t esi_offset = rd_offset + kRdSize;
536  copy(esi_.GetData(), esi_.GetData() + kEsiSize,
537  proto_prefix->prefix.begin() + esi_offset);
538  size_t ip_len_offset = esi_offset + kEsiSize;
539  proto_prefix->prefix[ip_len_offset] = ip_size * 8;
540  size_t ip_offset = ip_len_offset + 1;
541  WriteIpAddress(proto_prefix, ip_offset);
542  break;
543  }
544  case IpPrefixRoute: {
545  size_t ip_size, nlri_size;
546  if (family_ == Address::INET) {
547  ip_size = kIp4AddrSize;
548  nlri_size = kMinInetPrefixRouteSize + kLabelSize;
549  } else {
550  ip_size = kIp6AddrSize;
551  nlri_size = kMinInet6PrefixRouteSize + kLabelSize;
552  }
553  proto_prefix->prefixlen = nlri_size * 8;
554  proto_prefix->prefix.resize(nlri_size, 0);
555 
556  size_t rd_offset = 0;
557  copy(rd_.GetData(), rd_.GetData() + kRdSize,
558  proto_prefix->prefix.begin() + rd_offset);
559  size_t esi_offset = rd_offset + kRdSize;
560  if (attr) {
561  copy(attr->esi().GetData(), attr->esi().GetData() + kEsiSize,
562  proto_prefix->prefix.begin() + esi_offset);
563  }
564  size_t tag_offset = esi_offset + kEsiSize;
565  // Tag is not applicable for type5 routes.
566  put_value(&proto_prefix->prefix[tag_offset], kTagSize, 0);
567  size_t ip_plen_offset = tag_offset + kTagSize;
568  proto_prefix->prefix[ip_plen_offset] = ip_prefixlen_;
569  size_t ip_offset = ip_plen_offset + 1;
570  WriteIpAddress(proto_prefix, ip_offset);
571  size_t gw_offset = ip_offset + ip_size;
572  size_t label_offset = gw_offset + ip_size;
573  WriteLabel(proto_prefix, attr, label_offset, label);
574  break;
575  }
577  size_t ip_size = GetIpAddressSize();
578  size_t nlri_size = kMinSelectiveMulticastRouteSize + 2 * ip_size + 1;
579  if (!source_.is_unspecified())
580  nlri_size += ip_size;
581  proto_prefix->prefixlen = nlri_size * 8;
582  proto_prefix->prefix.resize(nlri_size, 0);
583 
584  size_t rd_offset = 0;
585  copy(rd_.GetData(), rd_.GetData() + kRdSize,
586  proto_prefix->prefix.begin() + rd_offset);
587  size_t tag_offset = rd_offset + kRdSize;
588  put_value(&proto_prefix->prefix[tag_offset], kTagSize, tag_);
589  size_t src_len_offset = tag_offset + kTagSize;
590  size_t grp_len_offset = src_len_offset + 1;
591  if (source_.is_unspecified()) {
592  proto_prefix->prefix[src_len_offset] = 0;
593  } else {
594  proto_prefix->prefix[src_len_offset] = ip_size * 8;
595  size_t src_offset = src_len_offset + 1;
596  WriteSource(proto_prefix, src_offset);
597  grp_len_offset += ip_size;
598  }
599  proto_prefix->prefix[grp_len_offset] = ip_size * 8;
600  size_t grp_offset = grp_len_offset + 1;
601  WriteGroup(proto_prefix, grp_offset);
602  size_t ip_len_offset = grp_offset + ip_size;
603  proto_prefix->prefix[ip_len_offset] = ip_size * 8;
604  size_t ip_offset = ip_len_offset + 1;
605  WriteIpAddress(proto_prefix, ip_offset);
606  size_t flag_offset = ip_offset + ip_size;
607  put_value(&proto_prefix->prefix[flag_offset], 1, flags_);
608  break;
609  }
610  default: {
611  assert(false);
612  break;
613  }
614  }
615 }
616 
617 int EvpnPrefix::CompareTo(const EvpnPrefix &rhs) const {
618  KEY_COMPARE(type_, rhs.type_);
619 
620  switch (type_) {
621  case AutoDiscoveryRoute:
622  KEY_COMPARE(rd_, rhs.rd_);
623  KEY_COMPARE(esi_, rhs.esi_);
624  KEY_COMPARE(tag_, rhs.tag_);
625  break;
627  KEY_COMPARE(rd_, rhs.rd_);
628  KEY_COMPARE(tag_, rhs.tag_);
631  break;
633  KEY_COMPARE(rd_, rhs.rd_);
634  KEY_COMPARE(tag_, rhs.tag_);
636  break;
637  case SegmentRoute:
638  KEY_COMPARE(rd_, rhs.rd_);
639  KEY_COMPARE(esi_, rhs.esi_);
641  break;
642  case IpPrefixRoute:
643  KEY_COMPARE(rd_, rhs.rd_);
644  KEY_COMPARE(tag_, rhs.tag_);
647  break;
649  KEY_COMPARE(rd_, rhs.rd_);
650  KEY_COMPARE(tag_, rhs.tag_);
652  KEY_COMPARE(group_, rhs.group_);
654  default:
655  break;
656  }
657 
658  return 0;
659 }
660 
661 // Check whether 'this' is more specific than rhs.
662 bool EvpnPrefix::IsMoreSpecific(const EvpnPrefix &rhs) const {
663  switch (type_) {
664  case IpPrefixRoute:
665  if (family_ == Address::INET) {
666  return inet_prefix().IsMoreSpecific(rhs.inet_prefix());
667  } else {
668  return inet6_prefix().IsMoreSpecific(rhs.inet6_prefix());
669  }
670  break;
671  default:
672  break;
673  }
674  return false;
675 }
676 
677 bool EvpnPrefix::GetSourceFromString(EvpnPrefix *prefix, const string &str,
678  size_t pos1, size_t *pos2, boost::system::error_code *errorp) {
679  *pos2 = str.find('-', pos1 + 1);
680  if (*pos2 == string::npos) {
681  if (errorp != NULL) {
682  *errorp = make_error_code(boost::system::errc::invalid_argument);
683  }
684  return false;
685  }
686  string temp_str = str.substr(pos1 + 1, *pos2 - pos1 - 1);
687  boost::system::error_code source_err;
688  prefix->source_ = Ip4Address::from_string(temp_str, source_err);
689  if (source_err.failed()) {
690  if (errorp != NULL) {
691  *errorp = source_err;
692  }
693  return false;
694  }
695  return true;
696 }
697 
698 bool EvpnPrefix::GetGroupFromString(EvpnPrefix *prefix, const string &str,
699  size_t pos1, size_t *pos2, boost::system::error_code *errorp) {
700  *pos2 = str.find('-', pos1 + 1);
701  if (*pos2 == string::npos) {
702  if (errorp != NULL) {
703  *errorp = make_error_code(boost::system::errc::invalid_argument);
704  }
705  return false;
706  }
707  string temp_str = str.substr(pos1 + 1, *pos2 - pos1 - 1);
708  boost::system::error_code group_err;
709  prefix->group_ = Ip4Address::from_string(temp_str, group_err);
710  if (group_err.failed()) {
711  if (errorp != NULL) {
712  *errorp = group_err;
713  }
714  return false;
715  }
716  return true;
717 }
718 
720  boost::system::error_code *errorp) {
721  EvpnPrefix prefix;
722 
723  // Parse type.
724  size_t pos1 = str.find('-');
725  if (pos1 == string::npos) {
726  if (errorp != NULL) {
727  *errorp = make_error_code(boost::system::errc::invalid_argument);
728  }
730  }
731 
732  string type_str = str.substr(0, pos1);
733  bool ret = stringToInteger(type_str, prefix.type_);
734  if (!ret) {
735  if (errorp != NULL) {
736  *errorp = make_error_code(boost::system::errc::invalid_argument);
737  }
739  }
740 
741  if (prefix.type_ < EvpnPrefix::AutoDiscoveryRoute ||
743  if (errorp != NULL) {
744  *errorp = make_error_code(boost::system::errc::invalid_argument);
745  }
747  }
748 
749  // Parse RD.
750  size_t pos2 = str.find('-', pos1 + 1);
751  if (pos2 == string::npos) {
752  if (errorp != NULL) {
753  *errorp = make_error_code(boost::system::errc::invalid_argument);
754  }
756  }
757  string rd_str = str.substr(pos1 + 1, pos2 - pos1 - 1);
758  boost::system::error_code rd_err;
759  prefix.rd_ = RouteDistinguisher::FromString(rd_str, &rd_err);
760  if (rd_err.failed()) {
761  if (errorp != NULL) {
762  *errorp = rd_err;
763  }
765  }
766 
767  switch (prefix.type_) {
768  case AutoDiscoveryRoute: {
769  // Parse ESI.
770  size_t pos3 = str.find('-', pos2 + 1);
771  if (pos3 == string::npos) {
772  if (errorp != NULL) {
773  *errorp =
774  make_error_code(boost::system::errc::invalid_argument);
775  }
777  }
778  string esi_str = str.substr(pos2 + 1, pos3 - pos2 - 1);
779  boost::system::error_code esi_err;
780  prefix.esi_ = EthernetSegmentId::FromString(esi_str, &esi_err);
781  if (esi_err.failed()) {
782  if (errorp != NULL) {
783  *errorp = esi_err;
784  }
786  }
787 
788  // Parse tag.
789  string tag_str = str.substr(pos3 + 1, string::npos);
790  bool ret = stringToInteger(tag_str, prefix.tag_);
791  if (!ret) {
792  if (errorp != NULL) {
793  *errorp =
794  make_error_code(boost::system::errc::invalid_argument);
795  }
797  }
798 
799  break;
800  }
801 
802  case MacAdvertisementRoute: {
803  // Parse tag.
804  size_t pos3 = str.find('-', pos2 + 1);
805  if (pos3 == string::npos) {
806  if (errorp != NULL) {
807  *errorp =
808  make_error_code(boost::system::errc::invalid_argument);
809  }
811  }
812  string tag_str = str.substr(pos2 + 1, pos3 - pos2 - 1);
813  bool ret = stringToInteger(tag_str, prefix.tag_);
814  if (!ret) {
815  if (errorp != NULL) {
816  *errorp =
817  make_error_code(boost::system::errc::invalid_argument);
818  }
820  }
821 
822  // Parse MAC.
823  size_t pos4 = str.rfind(',');
824  string mac_str = str.substr(pos3 + 1, pos4 - pos3 -1);
825  boost::system::error_code mac_err;
826  prefix.mac_addr_ = MacAddress::FromString(mac_str, &mac_err);
827  if (mac_err.failed()) {
828  if (errorp != NULL) {
829  *errorp = mac_err;
830  }
832  }
833 
834  // Parse IP - treat all 0s as unspecified.
835  string ip_str = str.substr(pos4 + 1, string::npos);
836  boost::system::error_code ip_err;
837  prefix.ip_address_ = IpAddress::from_string(ip_str, ip_err);
838  if (ip_err.failed()) {
839  if (errorp != NULL) {
840  *errorp = ip_err;
841  }
843  }
844  if (prefix.ip_address_.is_v4() && !prefix.ip_address_.is_unspecified())
845  prefix.family_ = Address::INET;
846  if (prefix.ip_address_.is_v6() && !prefix.ip_address_.is_unspecified())
847  prefix.family_ = Address::INET6;
848 
849  break;
850  }
851 
853  // Parse tag.
854  size_t pos3 = str.find('-', pos2 + 1);
855  if (pos3 == string::npos) {
856  if (errorp != NULL) {
857  *errorp =
858  make_error_code(boost::system::errc::invalid_argument);
859  }
861  }
862  string tag_str = str.substr(pos2 + 1, pos3 - pos2 - 1);
863  bool ret = stringToInteger(tag_str, prefix.tag_);
864  if (!ret) {
865  if (errorp != NULL) {
866  *errorp =
867  make_error_code(boost::system::errc::invalid_argument);
868  }
870  }
871 
872  // Parse IP.
873  string ip_str = str.substr(pos3 + 1, string::npos);
874  boost::system::error_code ip_err;
875  prefix.ip_address_ = IpAddress::from_string(ip_str, ip_err);
876  if (ip_err.failed()) {
877  if (errorp != NULL) {
878  *errorp = ip_err;
879  }
881  }
882  prefix.family_ =
883  prefix.ip_address_.is_v4() ? Address::INET : Address::INET6;
884 
885  break;
886  }
887 
888  case SegmentRoute: {
889  // Parse ESI.
890  size_t pos3 = str.find('-', pos2 + 1);
891  if (pos3 == string::npos) {
892  if (errorp != NULL) {
893  *errorp =
894  make_error_code(boost::system::errc::invalid_argument);
895  }
897  }
898  string esi_str = str.substr(pos2 + 1, pos3 - pos2 - 1);
899  boost::system::error_code esi_err;
900  prefix.esi_ = EthernetSegmentId::FromString(esi_str, &esi_err);
901  if (esi_err.failed()) {
902  if (errorp != NULL) {
903  *errorp = esi_err;
904  }
906  }
907 
908  // Parse IP.
909  string ip_str = str.substr(pos3 + 1, string::npos);
910  boost::system::error_code ip_err;
911  prefix.ip_address_ = IpAddress::from_string(ip_str, ip_err);
912  if (ip_err.failed()) {
913  if (errorp != NULL) {
914  *errorp = ip_err;
915  }
917  }
918  prefix.family_ =
919  prefix.ip_address_.is_v4() ? Address::INET : Address::INET6;
920 
921  break;
922  }
923 
924  case IpPrefixRoute: {
925  // Parse tag.
926  size_t pos3 = str.find('-', pos2 + 1);
927  if (pos3 == string::npos) {
928  if (errorp != NULL) {
929  *errorp =
930  make_error_code(boost::system::errc::invalid_argument);
931  }
933  }
934  string tag_str = str.substr(pos2 + 1, pos3 - pos2 - 1);
935  bool ret = stringToInteger(tag_str, prefix.tag_);
936  if (!ret) {
937  if (errorp != NULL) {
938  *errorp =
939  make_error_code(boost::system::errc::invalid_argument);
940  }
942  }
943 
944  // Parse IP prefix - first try v4, then v6.
945  string ip_str = str.substr(pos3 + 1, string::npos);
946  boost::system::error_code ip_err;
947 
948  Ip4Prefix inet_prefix = Ip4Prefix::FromString(ip_str, &ip_err);
949  if (!ip_err) {
950  prefix.family_ = Address::INET;
951  prefix.ip_address_ = inet_prefix.addr();
952  prefix.ip_prefixlen_ = inet_prefix.prefixlen();
953  return prefix;
954  }
955 
957  if (!ip_err) {
958  prefix.family_ = Address::INET6;
959  prefix.ip_address_ = inet6_prefix.addr();
960  prefix.ip_prefixlen_ = inet6_prefix.prefixlen();
961  return prefix;
962  }
963 
964  if (errorp != NULL) {
965  *errorp = make_error_code(boost::system::errc::invalid_argument);
966  }
968  break;
969  }
970 
972  // Parse tag.
973  size_t pos3 = str.find('-', pos2 + 1);
974  if (pos3 == string::npos) {
975  if (errorp != NULL) {
976  *errorp =
977  make_error_code(boost::system::errc::invalid_argument);
978  }
980  }
981  string tag_str = str.substr(pos2 + 1, pos3 - pos2 - 1);
982  bool ret = stringToInteger(tag_str, prefix.tag_);
983  if (!ret) {
984  if (errorp != NULL) {
985  *errorp =
986  make_error_code(boost::system::errc::invalid_argument);
987  }
989  }
990 
991  // Look for source.
992  size_t pos4;
993  if (!GetSourceFromString(&prefix, str, pos3, &pos4, errorp))
995 
996  // Look for group.
997  size_t pos5;
998  if (!GetGroupFromString(&prefix, str, pos4, &pos5, errorp))
1000 
1001  // Parse IP.
1002  string ip_str = str.substr(pos5 + 1, string::npos);
1003  boost::system::error_code ip_err;
1004  prefix.ip_address_ = IpAddress::from_string(ip_str, ip_err);
1005  if (ip_err.failed()) {
1006  if (errorp != NULL) {
1007  *errorp = ip_err;
1008  }
1009  return EvpnPrefix::kNullPrefix;
1010  }
1011  prefix.family_ =
1012  prefix.ip_address_.is_v4() ? Address::INET : Address::INET6;
1013 
1014  break;
1015  }
1016 
1017  }
1018 
1019  return prefix;
1020 }
1021 
1022 string EvpnPrefix::ToString() const {
1023  string str = integerToString(type_);
1024  str += "-" + rd_.ToString();
1025  switch (type_) {
1026  case AutoDiscoveryRoute:
1027  str += "-" + esi_.ToString();
1028  str += "-" + integerToString(tag_);
1029  break;
1030  case MacAdvertisementRoute:
1031  str += "-" + integerToString(tag_);
1032  str += "-" + mac_addr_.ToString();
1033  str += "," + ip_address_.to_string();
1034  break;
1036  str += "-" + integerToString(tag_);
1037  str += "-" + ip_address_.to_string();
1038  break;
1039  case SegmentRoute:
1040  str += "-" + esi_.ToString();
1041  str += "-" + ip_address_.to_string();
1042  break;
1043  case IpPrefixRoute:
1044  str += "-" + integerToString(tag_);
1045  if (family_ == Address::INET) {
1046  str += "-" + inet_prefix().ToString();
1047  } else {
1048  str += "-" + inet6_prefix().ToString();
1049  }
1050  break;
1052  str += "-" + integerToString(tag_);
1053  if (!source_.is_unspecified())
1054  str += "-" + source_.to_string();
1055  str += "-" + group_.to_string();
1056  str += "-" + ip_address_.to_string();
1057  break;
1058  default:
1059  break;
1060  }
1061 
1062  return str;
1063 }
1064 
1066  string str;
1067  if (tag_ != 0)
1068  str += integerToString(tag_) + "-";
1069  str += mac_addr_.ToString();
1070  str += "," + ip_address_.to_string() + "/" +
1072  if (!group_.is_unspecified()) {
1073  str += "," + group_.to_string() + "," +
1074  source_.to_string();
1075  }
1076  return str;
1077 }
1078 
1080  if (type_ == IpPrefixRoute)
1081  return ip_prefixlen_;
1082  if (family_ == Address::INET)
1083  return 32;
1084  if (family_ == Address::INET6)
1085  return 128;
1086  return 32;
1087 }
1088 
1090  if (family_ == Address::INET)
1091  return kIp4AddrSize;
1092  if (family_ == Address::INET6)
1093  return kIp6AddrSize;
1094  return 0;
1095 }
1096 
1097 void EvpnPrefix::ReadSource(const BgpProtoPrefix &proto_prefix,
1098  size_t ip_offset, size_t ip_size) {
1099  if (ip_size == 0) {
1101  } else if (ip_size == kIp4AddrSize) {
1103  Ip4Address::bytes_type bytes = { { 0 } };
1104  copy(proto_prefix.prefix.begin() + ip_offset,
1105  proto_prefix.prefix.begin() + ip_offset + ip_size, bytes.begin());
1106  source_ = Ip4Address(bytes);
1107  } else if (ip_size == kIp6AddrSize) {
1109  Ip6Address::bytes_type bytes = { { 0 } };
1110  copy(proto_prefix.prefix.begin() + ip_offset,
1111  proto_prefix.prefix.begin() + ip_offset + ip_size, bytes.begin());
1112  source_ = Ip6Address(bytes);
1113  }
1114 }
1115 
1116 void EvpnPrefix::ReadGroup(const BgpProtoPrefix &proto_prefix,
1117  size_t ip_offset, size_t ip_size) {
1118  if (ip_size == 0) {
1120  } else if (ip_size == kIp4AddrSize) {
1122  Ip4Address::bytes_type bytes = { { 0 } };
1123  copy(proto_prefix.prefix.begin() + ip_offset,
1124  proto_prefix.prefix.begin() + ip_offset + ip_size, bytes.begin());
1125  group_ = Ip4Address(bytes);
1126  } else if (ip_size == kIp6AddrSize) {
1128  Ip6Address::bytes_type bytes = { { 0 } };
1129  copy(proto_prefix.prefix.begin() + ip_offset,
1130  proto_prefix.prefix.begin() + ip_offset + ip_size, bytes.begin());
1131  group_ = Ip6Address(bytes);
1132  }
1133 }
1134 
1136  size_t ip_offset, size_t ip_size, size_t ip_psize) {
1137  assert(ip_psize <= ip_size);
1138  if (ip_size == 0) {
1140  } else if (ip_size == kIp4AddrSize) {
1142  Ip4Address::bytes_type bytes = { { 0 } };
1143  copy(proto_prefix.prefix.begin() + ip_offset,
1144  proto_prefix.prefix.begin() + ip_offset + ip_psize, bytes.begin());
1145  ip_address_ = Ip4Address(bytes);
1146  } else if (ip_size == kIp6AddrSize) {
1148  Ip6Address::bytes_type bytes = { { 0 } };
1149  copy(proto_prefix.prefix.begin() + ip_offset,
1150  proto_prefix.prefix.begin() + ip_offset + ip_psize, bytes.begin());
1151  ip_address_ = Ip6Address(bytes);
1152  }
1153 }
1154 
1156  size_t ip_offset) const {
1157  if (family_ == Address::INET) {
1158  const Ip4Address::bytes_type &bytes = ip_address_.to_v4().to_bytes();
1159  copy(bytes.begin(), bytes.begin() + kIp4AddrSize,
1160  proto_prefix->prefix.begin() + ip_offset);
1161  } else if (family_ == Address::INET6) {
1162  const Ip6Address::bytes_type &bytes = ip_address_.to_v6().to_bytes();
1163  copy(bytes.begin(), bytes.begin() + kIp6AddrSize,
1164  proto_prefix->prefix.begin() + ip_offset);
1165  }
1166 }
1167 
1169  size_t ip_offset) const {
1170  if (family_ == Address::INET) {
1171  const Ip4Address::bytes_type &bytes = source_.to_v4().to_bytes();
1172  copy(bytes.begin(), bytes.begin() + kIp4AddrSize,
1173  proto_prefix->prefix.begin() + ip_offset);
1174  } else if (family_ == Address::INET6) {
1175  const Ip6Address::bytes_type &bytes = source_.to_v6().to_bytes();
1176  copy(bytes.begin(), bytes.begin() + kIp6AddrSize,
1177  proto_prefix->prefix.begin() + ip_offset);
1178  }
1179 }
1180 
1182  size_t ip_offset) const {
1183  if (family_ == Address::INET) {
1184  const Ip4Address::bytes_type &bytes = group_.to_v4().to_bytes();
1185  copy(bytes.begin(), bytes.begin() + kIp4AddrSize,
1186  proto_prefix->prefix.begin() + ip_offset);
1187  } else if (family_ == Address::INET6) {
1188  const Ip6Address::bytes_type &bytes = group_.to_v6().to_bytes();
1189  copy(bytes.begin(), bytes.begin() + kIp6AddrSize,
1190  proto_prefix->prefix.begin() + ip_offset);
1191  }
1192 }
1193 
1195  : prefix_(prefix) {
1196 }
1197 
1198 int EvpnRoute::CompareTo(const Route &rhs) const {
1199  const EvpnRoute &evpn_rhs = static_cast<const EvpnRoute &>(rhs);
1200  return prefix_.CompareTo(evpn_rhs.prefix_);
1201 }
1202 
1203 string EvpnRoute::ToString() const {
1204  return prefix_.ToString();
1205 }
1206 
1208  if (xmpp_id_str_.empty())
1210  return xmpp_id_str_;
1211 }
1212 
1213 bool EvpnRoute::IsValid() const {
1214  if (!BgpRoute::IsValid())
1215  return false;
1216 
1217  const BgpAttr *attr = BestPath()->GetAttr();
1218  switch (prefix_.type()) {
1220  if (prefix_.tag() == EvpnPrefix::kMaxTag)
1221  return true;
1222  break;
1223  }
1225  return true;
1226  }
1228  const PmsiTunnel *pmsi_tunnel = attr->pmsi_tunnel();
1229  if (!pmsi_tunnel)
1230  return false;
1231  uint8_t tunnel_type = pmsi_tunnel->tunnel_type();
1232  uint8_t tunnel_flags = pmsi_tunnel->tunnel_flags();
1233  uint8_t ar_type =
1235  if (tunnel_type == PmsiTunnelSpec::IngressReplication) {
1236  if (ar_type == PmsiTunnelSpec::RegularNVE)
1237  return true;
1238  if (ar_type == PmsiTunnelSpec::ARReplicator &&
1239  (tunnel_flags & PmsiTunnelSpec::LeafInfoRequired)) {
1240  return true;
1241  }
1242  return false;
1243  }
1244  if (tunnel_type == PmsiTunnelSpec::AssistedReplicationContrail &&
1245  ar_type == PmsiTunnelSpec::ARLeaf) {
1246  return true;
1247  }
1248  return false;
1249  }
1250  case EvpnPrefix::SegmentRoute: {
1251  return false;
1252  }
1254  return false;
1255  }
1257  return false;
1258  }
1259  default: {
1260  break;
1261  }
1262  }
1263 
1264  return false;
1265 }
1266 
1267 void EvpnRoute::SetKey(const DBRequestKey *reqkey) {
1268  const EvpnTable::RequestKey *key =
1269  static_cast<const EvpnTable::RequestKey *>(reqkey);
1270  prefix_ = key->prefix;
1271 }
1272 
1274  const BgpAttr *attr, uint32_t label, uint32_t l3_label) const {
1275  prefix_.BuildProtoPrefix(proto_prefix, attr, label, l3_label);
1276 }
1277 
1278 void EvpnRoute::BuildBgpProtoNextHop(vector<uint8_t> &nh,
1279  IpAddress nexthop) const {
1280  nh.resize(4);
1281  const Ip4Address::bytes_type &addr_bytes = nexthop.to_v4().to_bytes();
1282  copy(addr_bytes.begin(), addr_bytes.end(), nh.begin());
1283 }
1284 
1287  return KeyPtr(key);
1288 }
EvpnRoute(const EvpnPrefix &prefix)
static const size_t kLabelSize
Ip4Address addr() const
Definition: inet_route.h:24
const BgpPath * BestPath() const
Definition: bgp_route.cc:46
EthernetSegmentId esi_
virtual KeyPtr GetDBRequestKey() const
void WriteGroup(BgpProtoPrefix *proto_prefix, size_t ip_offset) const
void WriteLabel(size_t label_offset, uint32_t label, bool is_vni=false)
uint32_t tag() const
virtual int CompareTo(const Route &rhs) const
static const size_t kMacSize
Family
Definition: address.h:24
#define KEY_COMPARE(x, y)
Definition: util.h:70
boost::asio::ip::address IpAddress
Definition: address.h:13
bool stringToInteger(const std::string &str, NumberType &num)
Definition: string_util.h:71
Definition: route.h:14
static RouteDistinguisher FromString(const std::string &str, boost::system::error_code *error=NULL)
Definition: rd.cc:83
static const size_t kIp6AddrSize
void WriteIpAddress(BgpProtoPrefix *proto_prefix, size_t ip_offset) const
static IpAddress ReadGwAddress(const BgpProtoPrefix &proto_prefix, size_t gw_offset, size_t ip_size)
uint32_t ReadLabel(size_t label_offset, bool is_vni=false) const
static const uint32_t kInvalidLabel
const uint8_t tunnel_type() const
Definition: bgp_attr.h:383
std::string ToXmppIdString() const
void WriteSource(BgpProtoPrefix *proto_prefix, size_t ip_offset) const
EvpnPrefix prefix_
static size_t size()
Definition: mac_address.h:57
static const EvpnPrefix kNullPrefix
static const size_t kMinInclusiveMulticastRouteSize
MacAddress mac_addr_
void BuildProtoPrefix(BgpProtoPrefix *proto_prefix, const BgpAttr *attr, uint32_t label, uint32_t l3_label=0) const
static const size_t kMinSegmentRouteSize
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
static const size_t kMinInet6PrefixRouteSize
int prefixlen() const
Definition: inet_route.h:27
static const size_t kMinInetPrefixRouteSize
std::string ToString() const
Definition: mac_address.cc:53
static const size_t kMinMacAdvertisementRouteSize
static EthernetSegmentId FromString(const std::string &str, boost::system::error_code *errorp=NULL)
Definition: esi.cc:29
static const uint32_t kMaxVni
static const size_t kSize
Definition: rd.h:13
boost::intrusive_ptr< const BgpAttr > BgpAttrPtr
Definition: bgp_attr.h:991
virtual void BuildProtoPrefix(BgpProtoPrefix *proto_prefix, const BgpAttr *attr=NULL, uint32_t label=0, uint32_t l3_label=0) const
void ReadSource(const BgpProtoPrefix &proto_prefix, size_t ip_offset, size_t ip_size)
const uint8_t tunnel_flags() const
Definition: bgp_attr.h:382
static bool GetGroupFromString(EvpnPrefix *prefix, const std::string &str, size_t pos1, size_t *pos2, boost::system::error_code *errorp)
static Inet6Prefix FromString(const std::string &str, boost::system::error_code *errorp=NULL)
Definition: inet6_route.cc:58
BgpAttrPtr ReplaceEsiAndLocate(const BgpAttr *attr, const EthernetSegmentId &esi)
Definition: bgp_attr.cc:1370
static const std::string integerToString(const NumberType &num)
Definition: string_util.h:19
static const size_t kIp4AddrSize
Inet6Prefix inet6_prefix() const
static const size_t kMinAutoDiscoveryRouteSize
static const size_t kLabelSize
Definition: bgp_attr_base.h:98
static const size_t kRdSize
std::vector< uint8_t > prefix
Ip6Address addr() const
Definition: inet6_route.h:26
static void WriteLabel(BgpProtoPrefix *proto_prefix, const BgpAttr *attr, size_t offset, uint32_t label)
const EthernetSegmentId & esi() const
Definition: bgp_attr.h:897
IpAddress ip_address_
boost::asio::ip::address_v6 Ip6Address
Definition: address.h:15
static const uint32_t kMaxTag
std::string ToString() const
Definition: inet6_route.cc:36
static Ip4Prefix FromString(const std::string &str, boost::system::error_code *errorp=NULL)
Definition: inet_route.cc:84
Ip4Prefix inet_prefix() const
static const size_t kMinSelectiveMulticastRouteSize
uint8_t type() const
virtual std::string ToXmppIdString() const
void ReadGroup(const BgpProtoPrefix &proto_prefix, size_t ip_offset, size_t ip_size)
static const size_t kTagSize
uint8_t ip_address_length() const
int CompareTo(const EvpnPrefix &rhs) const
std::string ToString() const
Definition: inet_route.cc:60
std::string ToString() const
static const int32_t kMaxVniSigned
virtual void BuildBgpProtoNextHop(std::vector< uint8_t > &nh, IpAddress nexthop) const
static const size_t kEsiSize
boost::asio::ip::address_v4 Ip4Address
Definition: address.h:14
void ReadIpAddress(const BgpProtoPrefix &proto_prefix, size_t ip_offset, size_t ip_size, size_t ip_psize)
const EvpnPrefix & GetPrefix() const
static const int kSize
Definition: esi.h:15
static EvpnPrefix FromString(const std::string &str, boost::system::error_code *errorp=NULL)
const ExtCommunity * ext_community() const
Definition: bgp_attr.h:915
BgpAttrDB * attr_db()
Definition: bgp_server.h:181
const EthernetSegmentId & esi() const
static uint32_t ReadLabel(const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, size_t offset, uint32_t tag=EvpnPrefix::kNullTag)
bool ContainsTunnelEncapVxlan() const
Definition: community.cc:655
const BgpAttr * GetAttr() const
Definition: bgp_path.h:87
bool IsMoreSpecific(const Ip4Prefix &rhs) const
Definition: inet_route.cc:96
std::string ToString() const
Definition: esi.cc:120
std::string ToString() const
Definition: rd.cc:56
int prefixlen() const
Definition: inet6_route.h:33
const uint8_t * GetData() const
Definition: mac_address.h:143
size_t GetIpAddressSize() const
bool IsZero() const
Definition: esi.h:43
bool IsMoreSpecific(const EvpnPrefix &rhs) const
virtual void SetKey(const DBRequestKey *reqkey)
const uint8_t * GetData() const
Definition: rd.h:59
std::string xmpp_id_str_
RouteDistinguisher rd_
const PmsiTunnel * pmsi_tunnel() const
Definition: bgp_attr.h:917
static MacAddress FromString(const std::string &str, boost::system::error_code *error=NULL)
Definition: mac_address.cc:71
static bool GetSourceFromString(EvpnPrefix *prefix, const std::string &str, size_t pos1, size_t *pos2, boost::system::error_code *errorp)
static int FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, const Address::Family family, EvpnPrefix *evpn_prefix, BgpAttrPtr *new_attr, uint32_t *label, uint32_t *l3_label=NULL)
Address::Family family_
static const uint32_t kNullTag
virtual bool IsValid() const
Definition: bgp_route.cc:338
bool IsMoreSpecific(const Inet6Prefix &rhs) const
Definition: inet6_route.cc:69
const uint8_t * GetData() const
Definition: esi.h:60
uint32_t GetLabel(const ExtCommunity *ext) const
Definition: bgp_attr.cc:415
virtual bool IsValid() const
static void put_value(uint8_t *data, int size, uint64_t value)
Definition: parse_object.h:55
virtual std::string ToString() const