16 #include <arpa/inet.h> 30 if (buffer_sz < 3)
return -1;
31 return *((uint8_t *) (from + 1));
53 logger->
log(FATAL,
"BgpPathAttrib::BgpPathAttrib: unknow attribute created with length != 0 but buffer NULL.\n");
54 throw "bad_value_buffer";
57 value_ptr = (uint8_t *) malloc(val_len);
66 if (value_ptr != NULL) free(value_ptr);
77 logger->
log(FATAL,
"BgpPathAttrib::clone: can't clone an attribute with error.\n");
100 written +=
_print(indent, to, buf_sz,
"Flags { }\n");
104 written +=
_print(indent, to, buf_sz,
"Flags {\n");
106 if (
optional) written +=
_print(indent, to, buf_sz,
"Optional\n");
108 if (
partial) written +=
_print(indent, to, buf_sz,
"Partial\n");
109 if (
extended) written +=
_print(indent, to, buf_sz,
"Extended\n");
111 written +=
_print(indent, to, buf_sz,
"}\n");
119 written +=
_print(indent, to, buf_sz,
"UnknowAttribute {\n");
124 written +=
_print(indent, to, buf_sz,
"}\n");
132 if (header_len < 0)
return -1;
134 const uint8_t *buffer = from + 3;
143 logger->
log(ERROR,
"BgpPathAttrib::parse: flag indicates well-known, mandatory but this attribute is unknown.\n");
152 logger->
log(ERROR,
"BgpPathAttrib::parse: optional non-transitive must not be partial.\n");
158 value_ptr = (uint8_t *) malloc(
value_len);
169 if (buffer_sz < (
size_t) (
value_len + 3)) {
170 logger->
log(ERROR,
"BgpPathAttrib::write: destination buffer size too small.\n");
175 logger->
log(ERROR,
"BgpPathAttrib::write: non-extended value has size > 65535: %d\n",
value_len);
181 uint8_t *buffer = to + 2;
183 else putValue<uint8_t>(&buffer,
value_len);
202 setError(E_UPDATE, E_UNSPEC_UPDATE, NULL, 0);
203 logger->
log(ERROR,
"BgpPathAttrib::parseHeader: invalid attribute header size.\n");
206 const uint8_t *buffer = from;
208 uint8_t flags = getValue<uint8_t>(&buffer);
216 setError(E_UPDATE, E_UNSPEC_UPDATE, NULL, 0);
217 logger->
log(ERROR,
"BgpPathAttrib::parseHeader: invalid attribute header size (extended but size < 4).\n");
222 else value_len = getValue<uint8_t>(&buffer);
230 setError(E_UPDATE, E_UNSPEC_UPDATE, NULL, 0);
231 logger->
log(ERROR,
"BgpPathAttrib::parseHeader: value_length (%d) < buffer left (%d).\n",
value_len, buffer_sz - 3);
252 if (buffer_sz < (
extended ? 3 : 4)) {
253 logger->
log(ERROR,
"BgpPathAttrib::writeHeader: dst buffer too small: %d\n", buffer_sz);
257 uint8_t *buffer = to;
259 putValue<uint8_t>(&buffer, flags);
275 logger->
log(FATAL,
"BgpPathAttribOrigin::clone: can't clone an attribute with error.\n");
282 const char *origin_name = NULL;
285 case 0: origin_name =
"IGP";
break;
286 case 1: origin_name=
"EGP";
break;
287 case 2: origin_name =
"Incomplete";
break;
288 default: origin_name =
"Invalid";
break;
292 written +=
_print(indent, to, buf_sz,
"OriginAttribute {\n");
295 written +=
_print(indent, to, buf_sz,
"Origin { %s }\n", origin_name);
298 written +=
_print(indent, to, buf_sz,
"}\n");
305 if (header_length < 0)
return -1;
308 logger->
log(FATAL,
"BgpPathAttribOrigin::parse: type in header mismatch.\n");
312 const uint8_t *buffer = from + 3;
315 logger->
log(ERROR,
"BgpPathAttribOrigin::parse: incomplete attrib.\n");
316 setError(E_UPDATE, E_UNSPEC_UPDATE, NULL, 0);
321 logger->
log(ERROR,
"BgpPathAttribOrigin::parse: bad length, want 1, saw %d.\n",
value_len);
327 logger->
log(ERROR,
"BgpPathAttribOrigin::parse: bad flag bits, must be !optional, !extended, !partial, transitive.\n");
332 origin = getValue<uint8_t>(&buffer);
335 setError(E_UPDATE, E_ORIGIN, from, 4);
336 logger->
log(ERROR,
"BgpPathAttribOrigin::parse: Bad Origin Value: %d.\n", origin);
345 logger->
log(ERROR,
"BgpPathAttribOrigin::write: destination buffer size too small.\n");
350 uint8_t *buffer = to + 2;
352 putValue<uint8_t>(&buffer, 1);
353 putValue<uint8_t>(&buffer, origin);
401 if (value.size() >= (
is_4b ? 127 : 255))
return false;
402 uint32_t prepend_asn =
is_4b ? asn : (asn >= 0xffff ? 23456 : asn);
404 value.insert(value.begin(), prepend_asn);
410 logger->
log(FATAL,
"BgpPathAttribAsPath::clone: can't clone an attribute with error.\n");
418 written +=
_print(indent, to, buf_sz,
"AsPathAttribute {\n");
420 written +=
_print(indent, to, buf_sz,
"FourOctet { %s }\n",
is_4b ?
"true" :
"false");
422 if (
as_paths.size() == 0) written +=
_print(indent, to, buf_sz,
"AsPathSegments { } \n");
424 written +=
_print(indent, to, buf_sz,
"AsPathSegments {\n");
428 case 1: written +=
_print(indent, to, buf_sz,
"AsSet {\n");
break;
429 case 2: written +=
_print(indent, to, buf_sz,
"AsSequence {\n");
break;
430 default: written +=
_print(indent, to, buf_sz,
"Invalid {\n");
break;
433 for (uint32_t asn : seg.value) {
434 written +=
_print(indent, to, buf_sz,
"%d\n", asn);
437 written +=
_print(indent, to, buf_sz,
"}\n");
440 written +=
_print(indent, to, buf_sz,
"}\n");
443 written +=
_print(indent, to, buf_sz,
"}\n");
450 if (header_length < 0)
return -1;
453 logger->
log(FATAL,
"BgpPathAttribAsPath::parse: type in header mismatch.\n");
458 logger->
log(ERROR,
"BgpPathAttribAsPath::parse: bad flag bits, must be !optional, !extended, !partial, transitive.\n");
463 const uint8_t *buffer = from + 3;
468 uint8_t parsed_len = 0;
473 logger->
log(ERROR,
"BgpPathAttribAsPath::parse: incomplete as_path segment.\n");
474 setError(E_UPDATE, E_AS_PATH, NULL, 0);
478 uint8_t type = getValue<uint8_t>(&buffer);
479 uint8_t n_asn = getValue<uint8_t>(&buffer);
484 uint8_t asns_length =
is_4b ? n_asn *
sizeof(uint32_t) : n_asn *
sizeof(uint16_t);
487 if (parsed_len + asns_length >
value_len) {
488 logger->
log(ERROR,
"BgpPathAttribAsPath::parse: as_path overflow attribute length.\n");
489 setError(E_UPDATE, E_AS_PATH, NULL, 0);
494 if (
is_4b)
for (
int i = 0; i < n_asn; i++) path.
value.push_back(ntohl(getValue<uint32_t>(&buffer)));
495 else for (
int i = 0; i < n_asn; i++) path.
value.push_back(ntohs(getValue<uint16_t>(&buffer)));
499 parsed_len += asns_length;
503 logger->
log(FATAL,
"BgpPathAttribAsPath::parse: parsed length and value length mismatch, but no error reported.\n");
507 return parsed_len + 3;
514 len += (seg.is_4b ? 4 : 2) * seg.value.size() + 2;
525 void BgpPathAttribAsPath::addSeg(uint32_t asn) {
553 if (segment->
type == AS_SET) {
558 }
else if (segment->
type == AS_SEQUENCE) {
569 logger->
log(ERROR,
"BgpPathAttribAsPath::prepend: unknow first segment type: %d, can't append.\n", segment->
type);
575 logger->
log(ERROR,
"BgpPathAttribAsPath::write: destination buffer size too small.\n");
580 uint8_t *buffer = to + 2;
583 uint8_t *len_field = buffer;
588 uint8_t written_len = 0;
591 if (seg.is_4b !=
is_4b) {
592 logger->
log(ERROR,
"BgpPathAttribAsPath::write: segment 4b-mode and message 4b-mode mismatch.\n");
596 size_t asn_count = seg.value.size();
598 if (asn_count >= (
is_4b ? 127 : 255)) {
599 logger->
log(ERROR,
"BgpPathAttribAsPath::write: segment size too big: %d\n", asn_count);
603 size_t bytes_need = asn_count * (
is_4b ?
sizeof(uint32_t) :
sizeof(uint16_t)) + 2;
605 if (written_len + bytes_need > buffer_sz) {
606 logger->
log(ERROR,
"BgpPathAttribAsPath::write: destination buffer size too small.\n");
610 putValue<uint8_t>(&buffer, seg.type);
611 putValue<uint8_t>(&buffer, asn_count);
613 if (seg.is_4b)
for (uint32_t asn : seg.value) putValue<uint32_t>(&buffer, htonl(asn));
614 else for (uint16_t asn : seg.value) putValue<uint16_t>(&buffer, htons(asn));
616 written_len += bytes_need;
620 putValue<uint8_t>(&len_field, written_len);
623 return written_len + 3;
638 written +=
_print(indent, to, buf_sz,
"NexthopAttribute {\n");
641 written +=
_print(indent, to, buf_sz,
"Nexthop { %s }\n", inet_ntoa(*(
struct in_addr*) &
next_hop));
644 written +=
_print(indent, to, buf_sz,
"}\n");
651 logger->
log(FATAL,
"BgpPathAttribNexthop::clone: can't clone an attribute with error.\n");
659 if (header_length < 0)
return -1;
662 logger->
log(FATAL,
"BgpPathAttribNexthop::parse: type in header mismatch.\n");
666 const uint8_t *buffer = from + 3;
669 logger->
log(ERROR,
"BgpPathAttribNexthop::parse: incomplete attrib.\n");
670 setError(E_UPDATE, E_UNSPEC_UPDATE, NULL, 0);
675 logger->
log(ERROR,
"BgpPathAttribNexthop::parse: bad length, want 4, saw %d.\n",
value_len);
681 logger->
log(ERROR,
"BgpPathAttribNexthop::parse: bad flag bits, must be !optional, !extended, !partial, transitive.\n");
686 next_hop = getValue<uint32_t>(&buffer);
693 logger->
log(ERROR,
"BgpPathAttribNexthop::write: destination buffer size too small.\n");
698 uint8_t *buffer = to + 2;
700 putValue<uint8_t>(&buffer, 4);
701 putValue<uint32_t>(&buffer,
next_hop);
721 written +=
_print(indent, to, buf_sz,
"MedAttribute {\n");
724 written +=
_print(indent, to, buf_sz,
"Med { %d }\n",
med);
727 written +=
_print(indent, to, buf_sz,
"}\n");
734 logger->
log(FATAL,
"BgpPathAttribMed::clone: can't clone an attribute with error.\n");
742 if (header_length < 0)
return -1;
745 logger->
log(FATAL,
"BgpPathAttribMed::parse: type in header mismatch.\n");
749 const uint8_t *buffer = from + 3;
752 logger->
log(ERROR,
"BgpPathAttribMed::parse: incomplete attrib.\n");
753 setError(E_UPDATE, E_UNSPEC_UPDATE, NULL, 0);
758 logger->
log(ERROR,
"BgpPathAttribMed::parse: bad length, want 4, saw %d.\n",
value_len);
764 logger->
log(ERROR,
"BgpPathAttribMed::parse: bad flag bits, must be optional, !extended, !partial, !transitive.\n");
769 med = ntohl(getValue<uint32_t>(&buffer));
776 logger->
log(ERROR,
"BgpPathAttribMed::write: destination buffer size too small.\n");
781 uint8_t *buffer = to + 2;
783 putValue<uint8_t>(&buffer, 4);
784 putValue<uint32_t>(&buffer, htonl(
med));
803 written +=
_print(indent, to, buf_sz,
"LocalPrefAttribute {\n");
809 written +=
_print(indent, to, buf_sz,
"}\n");
816 logger->
log(FATAL,
"BgpPathAttribLocalPref::clone: can't clone an attribute with error.\n");
824 if (header_length < 0)
return -1;
827 logger->
log(FATAL,
"BgpPathAttribLocalPref::parse: type in header mismatch.\n");
831 const uint8_t *buffer = from + 3;
834 logger->
log(ERROR,
"BgpPathAttribLocalPref::parse: incomplete attrib.\n");
835 setError(E_UPDATE, E_UNSPEC_UPDATE, NULL, 0);
840 logger->
log(ERROR,
"BgpPathAttribLocalPref::parse: bad length, want 4, saw %d.\n",
value_len);
846 logger->
log(ERROR,
"BgpPathAttribLocalPref::parse: bad flag bits, must be !optional, !extended, !partial, !transitive.\n");
851 local_pref = ntohl(getValue<uint32_t>(&buffer));
858 logger->
log(ERROR,
"BgpPathAttribLocalPref::write: destination buffer size too small.\n");
863 uint8_t *buffer = to + 2;
865 putValue<uint8_t>(&buffer, 4);
866 putValue<uint32_t>(&buffer, htonl(
local_pref));
886 written +=
_print(indent, to, buf_sz,
"AtomicAggregateAttribute {\n");
891 written +=
_print(indent, to, buf_sz,
"}\n");
898 logger->
log(FATAL,
"BgpPathAttribAtomicAggregate::clone: can't clone an attribute with error.\n");
906 if (header_length < 0)
return -1;
909 logger->
log(FATAL,
"BgpPathAttribAtomicAggregate::parse: type in header mismatch.\n");
914 logger->
log(ERROR,
"BgpPathAttribAtomicAggregate::parse: bad length, want 0, saw %d.\n",
value_len);
920 logger->
log(ERROR,
"BgpPathAttribAtomicAggregate::parse: bad flag bits, must be !optional, !extended, !partial, transitive.\n");
930 logger->
log(ERROR,
"BgpPathAttribAtomicAggregate::write: destination buffer size too small.\n");
935 uint8_t *buffer = to + 2;
937 putValue<uint8_t>(&buffer, 0);
961 written +=
_print(indent, to, buf_sz,
"AggregatorAttribute {\n");
964 written +=
_print(indent, to, buf_sz,
"Aggregator { %s }\n", inet_ntoa(*(
struct in_addr*) &
aggregator));
968 written +=
_print(indent, to, buf_sz,
"}\n");
975 logger->
log(FATAL,
"BgpPathAttribAggregator::clone: can't clone an attribute with error.\n");
983 if (header_length < 0)
return -1;
986 logger->
log(FATAL,
"BgpPathAttribAggregator::parse: type in header mismatch.\n");
990 const uint8_t *buffer = from + 3;
991 const uint8_t want_len = (
is_4b ? 8 : 6);
994 logger->
log(ERROR,
"BgpPathAttribAggregator::parse: incomplete attrib.\n");
995 setError(E_UPDATE, E_UNSPEC_UPDATE, NULL, 0);
1000 logger->
log(ERROR,
"BgpPathAttribAggregator::parse: bad length, want %d, saw %d.\n", want_len,
value_len);
1006 logger->
log(ERROR,
"BgpPathAttribAggregator::parse: bad flag bits, must be optional, !extended, !partial, transitive.\n");
1015 return 3 + want_len;
1019 uint8_t write_value_sz = (
is_4b ? 6 : 8);
1021 if (buffer_sz < (
size_t) (write_value_sz + 3)) {
1022 logger->
log(ERROR,
"BgpPathAttribAggregator::write: destination buffer size too small.\n");
1027 uint8_t *buffer = to + 2;
1029 putValue<uint8_t>(&buffer, write_value_sz);
1032 logger->
log(ERROR,
"BgpPathAttribAggregator::write: bad asn. not 4b but asn is %d.\n",
aggregator_asn);
1040 return write_value_sz + 3;
1044 return 3 + (
is_4b ? 6 : 8);
1060 written +=
_print(indent, to, buf_sz,
"As4PathAttribute {\n");
1063 if (
as4_paths.size() == 0) written +=
_print(indent, to, buf_sz,
"As4PathSegments { } \n");
1065 written +=
_print(indent, to, buf_sz,
"As4PathSegments {\n");
1069 case 1: written +=
_print(indent, to, buf_sz,
"AsSet {\n");
break;
1070 case 2: written +=
_print(indent, to, buf_sz,
"AsSequence {\n");
break;
1071 default: written +=
_print(indent, to, buf_sz,
"Invalid {\n");
break;
1074 for (uint32_t asn : seg.value) {
1075 written +=
_print(indent, to, buf_sz,
"%d\n", asn);
1078 written +=
_print(indent, to, buf_sz,
"}\n");
1081 written +=
_print(indent, to, buf_sz,
"}\n");
1084 written +=
_print(indent, to, buf_sz,
"}\n");
1091 logger->
log(FATAL,
"BgpPathAttribAs4Path::clone: can't clone an attribute with error.\n");
1098 ssize_t header_length =
parseHeader(from, length);
1099 if (header_length < 0)
return -1;
1102 logger->
log(FATAL,
"BgpPathAttribAs4Path::parse: type in header mismatch.\n");
1107 logger->
log(ERROR,
"BgpPathAttribAs4Path::parse: bad flag bits, must be optional, !extended, !partial, transitive.\n");
1112 const uint8_t *buffer = from + 3;
1117 uint8_t parsed_len = 0;
1122 logger->
log(ERROR,
"BgpPathAttribAs4Path::parse: incomplete as_path segment.\n");
1123 setError(E_UPDATE, E_AS_PATH, NULL, 0);
1127 uint8_t type = getValue<uint8_t>(&buffer);
1128 uint8_t n_asn = getValue<uint8_t>(&buffer);
1133 uint8_t asns_length = n_asn *
sizeof(uint32_t);
1136 if (parsed_len + asns_length >
value_len) {
1137 logger->
log(ERROR,
"BgpPathAttribAs4Path::parse: as_path overflow attribute length.\n");
1138 setError(E_UPDATE, E_AS_PATH, NULL, 0);
1143 for (
int i = 0; i < n_asn; i++) path.
value.push_back(ntohl(getValue<uint32_t>(&buffer)));
1147 parsed_len += asns_length;
1151 logger->
log(FATAL,
"BgpPathAttribAs4Path::parse: parsed length and value length mismatch, but no error reported.\n");
1155 return parsed_len + 3;
1162 len += 4 * seg.value.size() + 2;
1173 void BgpPathAttribAs4Path::addSeg(uint32_t asn) {
1201 if (segment->
type == AS_SET) {
1206 }
else if (segment->
type == AS_SEQUENCE) {
1217 logger->
log(ERROR,
"BgpPathAttribAs4Path::prepend: unknow first segment type: %d, can't append.\n", segment->
type);
1222 if (buffer_sz < 3) {
1223 logger->
log(ERROR,
"BgpPathAttribAs4Path::write: destination buffer size too small.\n");
1228 uint8_t *buffer = to + 2;
1231 uint8_t *len_field = buffer;
1236 uint8_t written_len = 0;
1239 size_t asn_count = seg4.value.size();
1241 if (asn_count > 127) {
1242 logger->
log(ERROR,
"BgpPathAttribAs4Path::write: segment size too big: %d\n", asn_count);
1247 size_t bytes_need = asn_count *
sizeof(uint32_t) + 2;
1249 if (written_len + bytes_need > buffer_sz) {
1250 logger->
log(ERROR,
"BgpPathAttribAs4Path::write: destination buffer size too small.\n");
1255 putValue<uint8_t>(&buffer, seg4.type);
1258 putValue<uint8_t>(&buffer, asn_count);
1261 for (uint32_t asn : seg4.value) {
1262 putValue<uint32_t>(&buffer, htonl(asn));
1265 written_len += bytes_need;
1269 putValue<uint8_t>(&len_field, written_len);
1272 return written_len + 3;
1277 logger->
log(FATAL,
"BgpPathAttribAs4Aggregator::clone: can't clone an attribute with error.\n");
1296 written +=
_print(indent, to, buf_sz,
"Aggregator4Attribute {\n");
1299 written +=
_print(indent, to, buf_sz,
"Aggregator { %s }\n", inet_ntoa(*(
struct in_addr*) &
aggregator));
1303 written +=
_print(indent, to, buf_sz,
"}\n");
1309 ssize_t header_length =
parseHeader(from, length);
1310 if (header_length < 0)
return -1;
1313 logger->
log(FATAL,
"BgpPathAttribAs4Aggregator::parse: type in header mismatch.\n");
1317 const uint8_t *buffer = from + 3;
1320 logger->
log(ERROR,
"BgpPathAttribAs4Aggregator::parse: incomplete attrib.\n");
1321 setError(E_UPDATE, E_UNSPEC_UPDATE, NULL, 0);
1326 logger->
log(ERROR,
"BgpPathAttribAs4Aggregator::parse: bad length, want 8, saw %d.\n",
value_len);
1332 logger->
log(ERROR,
"BgpPathAttribAs4Aggregator::parse: bad flag bits, must be optional, !extended, !partial, transitive.\n");
1344 if (buffer_sz < 11) {
1345 logger->
log(ERROR,
"BgpPathAttribAs4Aggregator::write: destination buffer size too small.\n");
1350 uint8_t *buffer = to + 2;
1352 putValue<uint8_t>(&buffer, 11);
1377 written +=
_print(indent, to, buf_sz,
"CommunityAttribute {\n");
1380 written +=
_print(indent, to, buf_sz,
"Community {\n");
1383 uint16_t community_[2];
1384 memcpy(community_, &community, 4);
1385 written +=
_print(indent, to, buf_sz,
"%d:%d\n", ntohs(community_[0]), ntohs(community_[1]));
1388 written +=
_print(indent, to, buf_sz,
"}\n");
1390 written +=
_print(indent, to, buf_sz,
"}\n");
1397 logger->
log(FATAL,
"BgpPathAttribCommunity::clone: can't clone an attribute with error.\n");
1404 ssize_t header_length =
parseHeader(from, length);
1405 if (header_length < 0)
return -1;
1408 logger->
log(FATAL,
"BgpPathAttribCommunity::parse: type in header mismatch.\n");
1412 const uint8_t *buffer = from + 3;
1415 logger->
log(ERROR,
"BgpPathAttribCommunity::parse: incomplete attrib.\n");
1416 setError(E_UPDATE, E_UNSPEC_UPDATE, NULL, 0);
1421 logger->
log(ERROR,
"BgpPathAttribCommunity::parse: bad length, want multiple of 4, saw %d.\n",
value_len);
1427 logger->
log(ERROR,
"BgpPathAttribCommunity::parse: bad flag bits, must be optional, !extended, !partial, transitive.\n");
1432 size_t read_len = 0;
1435 communites.push_back(getValue<uint32_t>(&buffer));
1440 logger->
log(FATAL,
" BgpPathAttribCommunity::parse: parse ends with read_len != value_len.\n");
1448 if (buffer_sz < 7) {
1449 logger->
log(ERROR,
"BgpPathAttribCommunity::write: destination buffer size too small.\n");
1454 uint8_t *buffer = to + 2;
1456 putValue<uint8_t>(&buffer, 4 *
communites.size());
1458 size_t write_len = 0;
1461 write_len += putValue<uint32_t>(&buffer, community);
1464 return 3 + write_len;
1475 int16_t BgpPathAttribMpNlriBase::GetAfiFromBuffer(
const uint8_t *buffer,
size_t length) {
1476 if (length < 3)
return -1;
1477 const uint8_t *ptr = buffer + 3;
1478 return ntohs(getValue<uint16_t>(&ptr));
1481 ssize_t BgpPathAttribMpNlriBase::parseHeader(
const uint8_t *from,
size_t length) {
1484 if (hdr_len < 0)
return -1;
1487 logger->
log(ERROR,
"BgpPathAttribMpNlriBase::parse: bad flag bits, must be optional, !extended, !partial, !transitive.\n");
1493 logger->
log(FATAL,
"BgpPathAttribMpNlriBase::parseHeader: type in header mismatch.\n");
1498 logger->
log(ERROR,
"BgpPathAttribMpNlriBase::parseHeader: incompete attribute.\n");
1499 setError(E_UPDATE, E_OPT_ATTR, NULL, 0);
1503 const uint8_t *buffer = from + hdr_len;
1504 afi = ntohs(getValue<uint16_t>(&buffer));
1505 safi = getValue<uint8_t>(&buffer);
1516 logger->
log(ERROR,
"BgpPathAttribMpReachNlriIpv6::clone: can't clone an attribute with error.\n");
1525 if (hdr_len < 0)
return -1;
1528 logger->
log(FATAL,
"BgpPathAttribMpReachNlriIpv6::parse: afi mismatch.\n");
1532 const uint8_t *buffer = from + hdr_len;
1533 uint8_t nexthop_length = getValue<uint8_t>(&buffer);
1535 if (nexthop_length != 16 && nexthop_length != 32) {
1536 logger->
log(ERROR,
"BgpPathAttribMpReachNlriIpv6::parse: bad nexthop length %d (want 16 or 32).\n", nexthop_length);
1537 setError(E_UPDATE, E_OPT_ATTR, NULL, 0);
1541 ssize_t buf_left =
value_len - hdr_len - 1 + 3;
1543 if (buf_left < (ssize_t) nexthop_length) {
1544 logger->
log(ERROR,
"BgpPathAttribMpReachNlriIpv6::parse: nexthop overflows buffer.\n");
1545 setError(E_UPDATE, E_OPT_ATTR, NULL, 0);
1549 memcpy(nexthop_global, buffer, 16); buffer += 16;
1550 if (nexthop_length == 32) {
1551 memcpy(nexthop_linklocal, buffer, 16); buffer += 16;
1552 }
else memset(nexthop_linklocal, 0, 16);
1554 buf_left -= nexthop_length;
1557 logger->
log(ERROR,
"BgpPathAttribMpReachNlriIpv6::parse: reserved bits overflows buffer.\n");
1558 setError(E_UPDATE, E_OPT_ATTR, NULL, 0);
1562 uint8_t res = getValue<uint8_t>(&buffer);
1566 logger->
log(WARN,
"BgpPathAttribMpReachNlriIpv6::parse: reserved bits != 0\n");
1569 while (buf_left > 0) {
1571 ssize_t pfx_read_len = this_prefix.
parse(buffer, buf_left);
1573 if (pfx_read_len < 0) {
1574 logger->
log(ERROR,
"BgpPathAttribMpReachNlriIpv6::parse: error parsing nlri entry.\n");
1575 setError(E_UPDATE, E_OPT_ATTR, NULL, 0);
1579 buffer += pfx_read_len;
1580 buf_left -= pfx_read_len;
1581 nlri.push_back(this_prefix);
1584 if (buf_left != 0) {
1585 logger->
log(FATAL,
"BgpPathAttribMpReachNlriIpv6::parse: parsed end with non-zero buf_left (%d).\n", buf_left);
1595 if (header_len < 0)
return -1;
1596 uint8_t *attr_len_field = to + header_len;
1597 uint8_t *buffer = attr_len_field + 1;
1599 if (buffer_sz - header_len < 5) {
1600 logger->
log(ERROR,
"BgpPathAttribMpReachNlriIpv6::write: dst buffer too small.\n");
1604 size_t written_len = header_len + 1;
1606 putValue<uint16_t>(&buffer, htons(afi));
1607 putValue<uint8_t>(&buffer, safi);
1611 putValue<uint8_t>(&buffer, has_linklocak ? 32 : 16);
1614 if ((has_linklocak && buffer_sz - written_len < 32) || (!has_linklocak && buffer_sz - written_len < 16)) {
1615 logger->
log(ERROR,
"BgpPathAttribMpReachNlriIpv6::write: dst buffer too small.\n");
1619 memcpy(buffer, nexthop_global, 16); buffer += 16; written_len += 16;
1620 if (has_linklocak) {
1621 memcpy(buffer, nexthop_linklocal, 16); buffer += 16; written_len += 16;
1624 putValue<uint8_t>(&buffer, 0);
1627 for (
const Prefix6 &route : nlri) {
1628 ssize_t rou_wrt_len = route.write(buffer, buffer_sz - written_len);
1629 if (rou_wrt_len < 0) {
1630 logger->
log(ERROR,
"BgpPathAttribMpReachNlriIpv6::write: failed to write nlri.\n");
1633 written_len += rou_wrt_len;
1634 buffer += rou_wrt_len;
1637 putValue<uint8_t>(&attr_len_field, written_len - 3);
1639 if (written_len != (
size_t) (buffer - to)) {
1640 logger->
log(FATAL,
"BgpPathAttribMpReachNlriIpv6::write: inconsistent written size (len=%d, diff=%d)\n", written_len, buffer - to);
1649 written +=
_print(indent, to, buf_sz,
"MpReachNlriAttribute {\n");
1652 const char *safi_str =
"Unknow";
1653 if (safi == UNICAST) safi_str =
"Unicast";
1654 if (safi == MULTICAST) safi_str =
"Multicast";
1655 written +=
_print(indent, to, buf_sz,
"AFI { IPv6 }\n");
1656 written +=
_print(indent, to, buf_sz,
"SAFI { %s }\n", safi_str);
1657 char nh_global_str[INET6_ADDRSTRLEN];
1658 inet_ntop(AF_INET6, nexthop_global, nh_global_str, INET6_ADDRSTRLEN);
1660 written +=
_print(indent, to, buf_sz,
"Nexthops {\n");
1662 written +=
_print(indent, to, buf_sz,
"%s\n", nh_global_str);
1664 char nh_linklocal_str[INET6_ADDRSTRLEN];
1665 inet_ntop(AF_INET6, nexthop_linklocal, nh_linklocal_str, INET6_ADDRSTRLEN);
1666 written +=
_print(indent, to, buf_sz,
"%s\n", nh_linklocal_str);
1669 written +=
_print(indent, to, buf_sz,
"}\n");
1671 written +=
_print(indent, to, buf_sz,
"NLRI {\n");
1673 for (
const Prefix6 &route : nlri) {
1675 route.getPrefix(prefix);
1676 char prefix_str[INET6_ADDRSTRLEN];
1677 inet_ntop(AF_INET6, prefix, prefix_str, INET6_ADDRSTRLEN);
1678 written +=
_print(indent, to, buf_sz,
"%s/%d\n", prefix_str, route.getLength());
1681 written +=
_print(indent, to, buf_sz,
"}\n");
1685 written +=
_print(indent, to, buf_sz,
"}\n");
1693 len += (has_linklocak ? 32 : 16);
1694 for (
const Prefix6 &route : nlri) {
1695 len += (1 + (route.getLength() + 7) / 8);
1707 BgpPathAttribMpReachNlriUnknow::BgpPathAttribMpReachNlriUnknow(
BgpLogHandler *logger,
const uint8_t *nexthop,
size_t nexthop_len,
const uint8_t *nlri,
size_t nlri_len) :
BgpPathAttribMpNlriBase(logger) {
1708 if (nexthop_len > 0) {
1709 this->nexthop = (uint8_t *) malloc(nexthop_len);
1710 memcpy(this->nexthop, nexthop, nexthop_len);
1714 this->nlri = (uint8_t *) malloc(nlri_len);
1715 memcpy(this->nlri, nlri, nlri_len);
1717 this->nexthop_len = nexthop_len;
1718 this->nlri_len = nlri_len;
1721 BgpPathAttribMpReachNlriUnknow::~BgpPathAttribMpReachNlriUnknow() {
1722 if (nlri_len != 0) free(nlri);
1723 if (nexthop_len != 0) free(nexthop);
1728 logger->
log(FATAL,
"BgpPathAttribMpReachNlriUnknow::clone: can't clone an attribute with error.\n");
1738 if (hdr_len < 0)
return -1;
1740 if (nexthop_len != 0) free(nexthop);
1742 const uint8_t *buffer = from + hdr_len;
1743 nexthop_len = getValue<uint8_t>(&buffer);
1744 size_t parsed_len = hdr_len + 1;
1746 if (length < parsed_len + nexthop_len) {
1747 logger->
log(FATAL,
"BgpPathAttribMpReachNlriUnknow::parse: unexpected end of attribute.\n");
1748 setError(E_UPDATE, E_OPT_ATTR, NULL, 0);
1752 parsed_len += nexthop_len;
1753 nexthop = (uint8_t *) malloc(nexthop_len);
1754 memcpy(nexthop, buffer, nexthop_len);
1755 buffer += nexthop_len;
1757 uint8_t res = getValue<uint8_t>(&buffer);
1761 logger->
log(WARN,
"BgpPathAttribMpReachNlriIpv6::parse: reserved bits != 0\n");
1764 if (nlri_len != 0) free(nlri);
1767 parsed_len += nlri_len;
1768 nlri = (uint8_t *) malloc(nlri_len);
1769 memcpy(nlri, buffer, nlri_len);
1775 size_t expected_len = 3 + 5 + nexthop_len + nlri_len;
1777 if (buffer_sz < expected_len) {
1778 logger->
log(ERROR,
"BgpPathAttribMpReachNlriUnknow::write: dst buffer too small.\n");
1783 if (hdr_len < 0)
return -1;
1784 uint8_t *buffer = to + hdr_len;
1786 putValue<uint8_t>(&buffer, expected_len - 3);
1787 putValue<uint16_t>(&buffer, htons(afi));
1788 putValue<uint8_t>(&buffer, safi);
1789 putValue<uint8_t>(&buffer, nexthop_len);
1790 memcpy(buffer, nexthop, nexthop_len); buffer += nexthop_len;
1791 putValue<uint8_t>(&buffer, 0);
1792 memcpy(buffer, nlri, nlri_len);
1794 if ((
size_t) (buffer - to) != expected_len) {
1795 logger->
log(ERROR,
"BgpPathAttribMpReachNlriUnknow::write: unexpected written length.\n");
1799 return expected_len;
1804 written +=
_print(indent, to, buf_sz,
"MpReachNlriAttribute {\n");
1807 written +=
_print(indent, to, buf_sz,
"AFI { %d }\n", afi);
1808 written +=
_print(indent, to, buf_sz,
"SAFI { %d }\n", safi);
1810 written +=
_print(indent, to, buf_sz,
"}\n");
1815 return 3 + 5 + nexthop_len + nlri_len;
1818 const uint8_t* BgpPathAttribMpReachNlriUnknow::getNexthop()
const {
1822 const uint8_t* BgpPathAttribMpReachNlriUnknow::getNlri()
const {
1826 size_t BgpPathAttribMpReachNlriUnknow::getNexthopLength()
const {
1830 size_t BgpPathAttribMpReachNlriUnknow::getNlriLength()
const {
1840 logger->
log(FATAL,
"BgpPathAttribMpUnreachNlriIpv6::clone: can clone attribute with error.\n");
1849 if (hdr_len < 0)
return -1;
1852 logger->
log(FATAL,
"BgpPathAttribMpUnreachNlriIpv6::parse: afi mismatch.\n");
1856 size_t buf_left =
value_len - hdr_len + 3;
1857 const uint8_t *buffer = from + hdr_len;
1859 while (buf_left > 0) {
1861 ssize_t pfx_read_len = this_prefix.
parse(buffer, buf_left);
1863 if (pfx_read_len < 0) {
1864 logger->
log(ERROR,
"BgpPathAttribMpUnreachNlriIpv6::parse: error parsing withdrawn entry.\n");
1865 setError(E_UPDATE, E_OPT_ATTR, NULL, 0);
1869 buffer += pfx_read_len;
1870 buf_left -= pfx_read_len;
1871 withdrawn_routes.push_back(this_prefix);
1874 if (buf_left != 0) {
1875 logger->
log(FATAL,
"BgpPathAttribMpUnreachNlriIpv6::parse: parsed end with non-zero buf_left (%d).\n", buf_left);
1883 if (buffer_sz < 3 + 3) {
1884 logger->
log(ERROR,
"BgpPathAttribMpUnreachNlriIpv6::write: dst buffer too small.\n");
1889 if (hdr_len < 0)
return -1;
1891 uint8_t *len_field = to + hdr_len;
1892 uint8_t *buffer = len_field + 1;
1894 putValue<uint16_t>(&buffer, htons(afi));
1895 putValue<uint8_t>(&buffer, safi);
1896 size_t written_val_len = 3;
1898 for (
const Prefix6 &route : withdrawn_routes) {
1899 ssize_t pfx_wrt_ret = route.write(buffer, buffer_sz - 3 - written_val_len);
1900 if (pfx_wrt_ret < 0) {
1901 logger->
log(ERROR,
"BgpPathAttribMpUnreachNlriIpv6::write: error writing withdrawn routes.\n");
1905 buffer += pfx_wrt_ret;
1906 written_val_len += pfx_wrt_ret;
1909 return 3 + written_val_len;
1915 written +=
_print(indent, to, buf_sz,
"MpUnreachNlriAttribute {\n");
1918 const char *safi_str =
"Unknow";
1919 if (safi == UNICAST) safi_str =
"Unicast";
1920 if (safi == MULTICAST) safi_str =
"Multicast";
1921 written +=
_print(indent, to, buf_sz,
"AFI { IPv6 }\n");
1922 written +=
_print(indent, to, buf_sz,
"SAFI { %s }\n", safi_str);
1923 written +=
_print(indent, to, buf_sz,
"WithdrawnRoutes {\n");
1925 for (
const Prefix6 &route : withdrawn_routes) {
1927 route.getPrefix(prefix);
1928 char prefix_str[INET6_ADDRSTRLEN];
1929 inet_ntop(AF_INET6, prefix, prefix_str, INET6_ADDRSTRLEN);
1930 written +=
_print(indent, to, buf_sz,
"%s/%d\n", prefix_str, route.getLength());
1933 written +=
_print(indent, to, buf_sz,
"}\n");
1935 _print(indent, to, buf_sz,
"}\n");
1942 for (
const Prefix6 &route : withdrawn_routes) {
1943 len += (1 + (route.getLength() + 7) / 8);
1949 withdrawn_routes_len = 0;
1950 withdrawn_routes = NULL;
1954 withdrawn_routes_len = len;
1957 withdrawn_routes = (uint8_t *) malloc(len);
1958 memcpy(withdrawn_routes, withdrawn, len);
1962 BgpPathAttribMpUnreachNlriUnknow::~BgpPathAttribMpUnreachNlriUnknow() {
1963 if (withdrawn_routes_len > 0) free(withdrawn_routes);
1968 logger->
log(FATAL,
"BgpPathAttribMpUnreachNlriUnknow::clone: can clone attribute with error.\n");
1978 if (hdr_len < 0)
return -1;
1980 if (withdrawn_routes_len > 0) free(withdrawn_routes);
1982 withdrawn_routes_len =
value_len - hdr_len;
1983 const uint8_t *buffer = from + hdr_len;
1985 withdrawn_routes = (uint8_t *) malloc(withdrawn_routes_len);
1986 memcpy(withdrawn_routes, buffer, withdrawn_routes_len);
1992 size_t expected_len = 3 + 3 + withdrawn_routes_len;
1993 if (buffer_sz < expected_len) {
1994 logger->
log(ERROR,
"BgpPathAttribMpUnreachNlriUnknow::write: dst buffer too small.\n");
1999 if (hdr_len < 0)
return -1;
2001 uint8_t *buffer = to + hdr_len;
2002 putValue<uint8_t>(&buffer, expected_len - 3);
2003 putValue<uint16_t>(&buffer, htons(afi));
2004 putValue<uint8_t>(&buffer, safi);
2005 memcpy(buffer, withdrawn_routes, withdrawn_routes_len);
2007 return expected_len;
2012 written +=
_print(indent, to, buf_sz,
"MpUnreachNlriAttribute {\n");
2015 written +=
_print(indent, to, buf_sz,
"AFI { %d }\n", afi);
2016 written +=
_print(indent, to, buf_sz,
"SAFI { %d }\n", safi);
2018 written +=
_print(indent, to, buf_sz,
"}\n");
2023 return 3 + 3 + withdrawn_routes_len;
2026 const uint8_t* BgpPathAttribMpUnreachNlriUnknow::getWithdrawnRoutes()
const {
2027 return withdrawn_routes;
2030 size_t BgpPathAttribMpUnreachNlriUnknow::getWithdrawnRoutesLength()
const {
2031 return withdrawn_routes_len;
ssize_t printFlags(size_t indent, uint8_t **to, size_t *buf_sz) const
Utility function to print flags for attribute.
IPv6 Route/Prefix related utilities.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
bool partial
Attribute flag: partial.
ssize_t writeHeader(uint8_t *buffer, size_t buffer_sz) const
Write attribute header to buffer. (Flag, Type)
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
ssize_t length() const
Get size in bytes required to serialize the object.
std::vector< uint32_t > value
The segment value.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
virtual ssize_t length() const
Get size in bytes required to serialize the object.
BgpPathAttrib(BgpLogHandler *logger)
Construct a new Bgp Path Attrib:: Bgp Path Attrib object.
MP-BGP ReachNlri IPv6 NLRI class.
bool is_4b
Is ASNs in the attribute four octets?
BgpPathAttribMed(BgpLogHandler *logger)
Construct a new Bgp Path Attrib Med:: Bgp Path Attrib Med object.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
size_t getCount() const
Get number of ASNs in the segment.
ssize_t length() const
Get size in bytes required to serialize the object.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
BgpPathAttrib * clone() const
Clone the attribute.
MP-BGP UnreachNlri container for unknow AFI/SAFI.
bool optional
Attribute flag: Optional.
virtual ssize_t parse(const uint8_t *from, size_t msg_sz)
Deserialize a BGP update message path attribute.
bool is_4b
Is ASNs in the attribute four octets?
ssize_t length() const
Get size in bytes required to serialize the object.
BgpPathAttribAs4Path(BgpLogHandler *logger)
Construct a new Bgp Path Attrib As 4 Path:: Bgp Path Attrib As 4 Path object.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
BgpPathAttrib * clone() const
Clone the attribute.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
static ssize_t _print(size_t indent, uint8_t **to, size_t *buf_left, const char *format,...)
Print helper.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
bool hasError() const
Check if error information available.
ssize_t length() const
Get size in bytes required to serialize the object.
BgpAsPathSegment(bool is_4b, uint8_t type)
Construct a new Bgp As Path Segment:: Bgp As Path Segment object.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
ssize_t parseHeader(const uint8_t *buffer, size_t length)
Utility function to parse attribute header. (Flag, type, length)
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
BgpPathAttribOrigin(BgpLogHandler *logger)
Construct a new Bgp Path Attrib Origin:: Bgp Path Attrib Origin object.
BgpPathAttrib * clone() const
Clone the attribute.
The serializable base class.
ssize_t length() const
Get size in bytes required to serialize the object.
BgpPathAttrib * clone() const
Clone the attribute.
uint16_t value_len
Attribute length. Length field is only used in deserialization for parseHeader() to pass length field...
AS4_AGGREGATOR attribute.
bool transitive
Attribute flag: Transitive.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
uint32_t local_pref
Local Pref.
void log(LogLevel level, const char *format_str,...)
Log a message. Consider using LIBBGP_LOG if logging the message needs a lot of computing power...
std::vector< BgpAsPathSegment > as_paths
The AS Path segments.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
std::vector< BgpAsPathSegment > as4_paths
The AS4_PATH segments.
BgpPathAttrib * clone() const
Clone the attribute.
BgpPathAttribAtomicAggregate(BgpLogHandler *logger)
Construct a new Bgp Path Attrib Atomic Aggregate:: Bgp Path Attrib Atomic Aggregate object...
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
BgpPathAttrib * clone() const
Clone the attribute.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
uint32_t aggregator_asn4
Aggregator ASN.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
bool prepend(uint32_t asn)
Prepend an ASN into AS path.
uint32_t aggregator_asn
Aggregator ASN.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
BgpPathAttribAggregator(BgpLogHandler *logger, bool is_4b)
Construct a new Bgp Path Attrib Aggregator:: Bgp Path Attrib Aggregator object.
BgpPathAttrib * clone() const
Clone the attribute.
BgpPathAttrib * clone() const
Clone the attribute.
ssize_t length() const
Get size in bytes required to serialize the object.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
uint8_t type
Segment type.
void setLogger(BgpLogHandler *logger)
Replace logger for this object.
ssize_t length() const
Get size in bytes required to serialize the object.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
BgpPathAttrib * clone() const
Clone the attribute.
bool extended
Attribute flag: extended.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
bool prepend(uint32_t asn)
Prepend an ASN into AS4 path.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
bool v6addr_is_zero(const uint8_t prefix[16])
Test if a IPv6 addresss is all zero.
void setError(uint8_t err, uint8_t suberr, const uint8_t *data, size_t data_len)
Set the error information.
ssize_t length() const
Get size in bytes required to serialize the object.
Buffer operation helpers.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
virtual BgpPathAttrib * clone() const
Clone the attribute.
bool prepend(uint32_t asn)
Prepend ASN to AS segment.
BgpPathAttrib * clone() const
Clone the attribute.
MP-BGP Reach/Unreach NLRI base class.
ssize_t parse(const uint8_t *buffer, size_t buf_sz)
Parse a IPv6 NLRI prefix from buffer.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
ssize_t length() const
Get size in bytes required to serialize the object.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
ssize_t write(uint8_t *buffer, size_t buffer_sz) const
Serialize a BGP update message path attribute.
BgpPathAttribNexthop(BgpLogHandler *logger)
Construct a new Bgp Path Attrib Nexthop:: Bgp Path Attrib Nexthop object.
An AS_PATH or AS4_PATH segment.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
BgpPathAttribAs4Aggregator(BgpLogHandler *logger)
Construct a new Bgp Path Attrib As 4 Aggregator:: Bgp Path Attrib As 4 Aggregator object...
BgpPathAttrib * clone() const
Clone the attribute.
uint32_t aggregator
Aggregator in network byte order.
ssize_t length() const
Get size in bytes required to serialize the object.
BgpPathAttrib * clone() const
Clone the attribute.
virtual ssize_t write(uint8_t *to, size_t buf_sz) const
Serialize a BGP update message path attribute.
uint32_t aggregator
Aggregator in network byte order.
ssize_t length() const
Get size in bytes required to serialize the object.
BgpPathAttribAsPath(BgpLogHandler *logger, bool is_4b)
Construct a new Bgp Path Attrib As Path:: Bgp Path Attrib As Path object.
uint32_t next_hop
The nexthop in network byte order.
ssize_t length() const
Get size in bytes required to serialize the object.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
BgpPathAttribLocalPref(BgpLogHandler *logger)
Construct a new Bgp Path Attrib Local Pref:: Bgp Path Attrib Local Pref object.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
uint8_t type_code
Attribute type code.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
MP-BGP ReachNlri container for unknow AFI/SAFI.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
ssize_t doPrint(size_t indent, uint8_t **to, size_t *buf_sz) const
Print implementation.
BgpPathAttrib * clone() const
Clone the attribute.
ssize_t parse(const uint8_t *buffer, size_t length)
Deserialize a BGP update message path attribute.
static uint8_t GetTypeFromBuffer(const uint8_t *buffer, size_t buffer_sz)
Get type of attribute from buffer.
MP-BGP UnreachNlri IPv6 class.
ssize_t length() const
Get size in bytes required to serialize the object.
virtual ~BgpPathAttrib()
Destroy the Bgp Path Attrib:: Bgp Path Attrib object.