diff --git a/src/bgp/bgp_peer.cc b/src/bgp/bgp_peer.cc index a1ad96bbbd8..42adf8e4300 100644 --- a/src/bgp/bgp_peer.cc +++ b/src/bgp/bgp_peer.cc @@ -1586,9 +1586,10 @@ void BgpPeer::ProcessNlri(Address::Family family, DBRequest::DBOperation oper, PrefixT prefix; BgpAttrPtr new_attr(attr); uint32_t label = 0; + uint32_t l3_label = 0; int result = PrefixT::FromProtoPrefix(server_, **it, (oper == DBRequest::DB_ENTRY_ADD_CHANGE ? attr.get() : NULL), - &prefix, &new_attr, &label); + &prefix, &new_attr, &label, &l3_label); if (result) { BGP_LOG_PEER_WARNING(Message, this, BGP_LOG_FLAG_ALL, BGP_PEER_DIR_IN, diff --git a/src/bgp/bgp_route.h b/src/bgp/bgp_route.h index 0709735faa8..f273498af4a 100644 --- a/src/bgp/bgp_route.h +++ b/src/bgp/bgp_route.h @@ -62,7 +62,8 @@ class BgpRoute : public Route { virtual void BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr = NULL, - uint32_t label = 0) const { + uint32_t label = 0, + uint32_t l3_label = 0) const { } virtual void BuildBgpProtoNextHop(std::vector &nh, IpAddress nexthop) const { diff --git a/src/bgp/ermvpn/ermvpn_route.cc b/src/bgp/ermvpn/ermvpn_route.cc index 62459ce9ce3..70e3a98068d 100644 --- a/src/bgp/ermvpn/ermvpn_route.cc +++ b/src/bgp/ermvpn/ermvpn_route.cc @@ -84,7 +84,8 @@ int ErmVpnPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, int ErmVpnPrefix::FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, ErmVpnPrefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label) { + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label) { return FromProtoPrefix(proto_prefix, prefix); } @@ -296,7 +297,7 @@ void ErmVpnRoute::SetKey(const DBRequestKey *reqkey) { } void ErmVpnRoute::BuildProtoPrefix(BgpProtoPrefix *prefix, - const BgpAttr *attr, uint32_t label) const { + const BgpAttr *attr, uint32_t label, uint32_t l3_label) const { prefix_.BuildProtoPrefix(prefix); } diff --git a/src/bgp/ermvpn/ermvpn_route.h b/src/bgp/ermvpn/ermvpn_route.h index b17dbae0aaa..90d09034803 100644 --- a/src/bgp/ermvpn/ermvpn_route.h +++ b/src/bgp/ermvpn/ermvpn_route.h @@ -40,7 +40,8 @@ class ErmVpnPrefix { static int FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, ErmVpnPrefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label); + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label); static ErmVpnPrefix FromString(const std::string &str, boost::system::error_code *errorp = NULL); @@ -81,7 +82,8 @@ class ErmVpnRoute : public BgpRoute { virtual void SetKey(const DBRequestKey *reqkey); virtual void BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr = NULL, - uint32_t label = 0) const; + uint32_t label = 0, + uint32_t l3_label = 0) const; virtual void BuildBgpProtoNextHop(std::vector &nh, IpAddress nexthop) const; diff --git a/src/bgp/evpn/evpn_route.cc b/src/bgp/evpn/evpn_route.cc index a2b386a4fb9..d2fa8157a2b 100644 --- a/src/bgp/evpn/evpn_route.cc +++ b/src/bgp/evpn/evpn_route.cc @@ -200,9 +200,12 @@ EvpnPrefix::EvpnPrefix(const RouteDistinguisher &rd, uint32_t tag, int EvpnPrefix::FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, - EvpnPrefix *prefix, BgpAttrPtr *new_attr, uint32_t *label) { + EvpnPrefix *prefix, BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label) { *new_attr = attr; *label = 0; + if (l3_label) + *l3_label = 0; prefix->type_ = proto_prefix.type; size_t nlri_size = proto_prefix.prefix.size(); @@ -253,6 +256,10 @@ int EvpnPrefix::FromProtoPrefix(BgpServer *server, prefix->ReadIpAddress(proto_prefix, ip_offset, ip_size, ip_size); size_t label_offset = ip_offset + ip_size; *label = ReadLabel(proto_prefix, attr, label_offset, prefix->tag_); + size_t l3_label_offset = label_offset + kLabelSize; + if (l3_label && nlri_size >= l3_label_offset + kLabelSize) { + *l3_label = ReadLabel(proto_prefix, attr, l3_label_offset); + } break; } case InclusiveMulticastRoute: { @@ -369,9 +376,8 @@ int EvpnPrefix::FromProtoPrefix(BgpServer *server, // must be obtained from the BgpAttr. The BgpAttr is NULL and label is // 0 when withdrawing the route. // -void EvpnPrefix::BuildProtoPrefix(const BgpAttr *attr, uint32_t label, - BgpProtoPrefix *proto_prefix) const { - assert(attr != NULL || label == 0); +void EvpnPrefix::BuildProtoPrefix(BgpProtoPrefix *proto_prefix, + const BgpAttr *attr, uint32_t label, uint32_t l3_label) const { proto_prefix->type = type_; proto_prefix->prefix.clear(); @@ -395,7 +401,9 @@ void EvpnPrefix::BuildProtoPrefix(const BgpAttr *attr, uint32_t label, } case MacAdvertisementRoute: { size_t ip_size = GetIpAddressSize(); - size_t nlri_size = kMinMacAdvertisementRouteSize + kLabelSize + ip_size; + size_t nlri_size = kMinMacAdvertisementRouteSize + ip_size + kLabelSize; + if (l3_label) + nlri_size += kLabelSize; proto_prefix->prefixlen = nlri_size * 8; proto_prefix->prefix.resize(nlri_size, 0); @@ -420,6 +428,10 @@ void EvpnPrefix::BuildProtoPrefix(const BgpAttr *attr, uint32_t label, WriteIpAddress(proto_prefix, ip_offset); size_t label_offset = ip_offset + ip_size; WriteLabel(proto_prefix, attr, label_offset, label); + if (l3_label) { + size_t l3_label_offset = label_offset + kLabelSize; + WriteLabel(proto_prefix, attr, l3_label_offset, l3_label); + } break; } case InclusiveMulticastRoute: { @@ -959,8 +971,8 @@ void EvpnRoute::SetKey(const DBRequestKey *reqkey) { } void EvpnRoute::BuildProtoPrefix(BgpProtoPrefix *proto_prefix, - const BgpAttr *attr, uint32_t label) const { - prefix_.BuildProtoPrefix(attr, label, proto_prefix); + const BgpAttr *attr, uint32_t label, uint32_t l3_label) const { + prefix_.BuildProtoPrefix(proto_prefix, attr, label, l3_label); } void EvpnRoute::BuildBgpProtoNextHop(vector &nh, diff --git a/src/bgp/evpn/evpn_route.h b/src/bgp/evpn/evpn_route.h index 2cae00729e5..902a47ae260 100644 --- a/src/bgp/evpn/evpn_route.h +++ b/src/bgp/evpn/evpn_route.h @@ -66,12 +66,13 @@ class EvpnPrefix { EvpnPrefix(const RouteDistinguisher &rd, uint32_t tag, const IpAddress &ip_address, uint8_t ip_prefixlen); - void BuildProtoPrefix(const BgpAttr *attr, uint32_t label, - BgpProtoPrefix *proto_prefix) const; + void BuildProtoPrefix(BgpProtoPrefix *proto_prefix, + const BgpAttr *attr, uint32_t label, uint32_t l3_label = 0) const; static int FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, - EvpnPrefix *evpn_prefix, BgpAttrPtr *new_attr, uint32_t *label); + EvpnPrefix *evpn_prefix, BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label = NULL); static EvpnPrefix FromString(const std::string &str, boost::system::error_code *errorp = NULL); std::string ToString() const; @@ -127,7 +128,8 @@ class EvpnRoute : public BgpRoute { virtual void SetKey(const DBRequestKey *reqkey); virtual void BuildProtoPrefix(BgpProtoPrefix *proto_prefix, - const BgpAttr *attr = NULL, uint32_t label = 0) const; + const BgpAttr *attr = NULL, uint32_t label = 0, + uint32_t l3_label = 0) const; virtual void BuildBgpProtoNextHop(std::vector &nh, IpAddress nexthop) const; diff --git a/src/bgp/evpn/test/evpn_prefix_test.cc b/src/bgp/evpn/test/evpn_prefix_test.cc index 4ea71a19b6f..e6aafe5a5c5 100644 --- a/src/bgp/evpn/test/evpn_prefix_test.cc +++ b/src/bgp/evpn/test/evpn_prefix_test.cc @@ -173,7 +173,7 @@ TEST_F(EvpnAutoDiscoveryPrefixTest, FromProtoPrefix1) { BgpAttr attr1; uint32_t label1 = 10000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(&attr1, label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, &attr1, label1); EXPECT_EQ(EvpnPrefix::AutoDiscoveryRoute, proto_prefix.type); size_t expected_size = EvpnPrefix::kMinAutoDiscoveryRouteSize + EvpnPrefix::kLabelSize; @@ -205,7 +205,7 @@ TEST_F(EvpnAutoDiscoveryPrefixTest, FromProtoPrefix2) { EXPECT_EQ(0, ec.value()); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(NULL, 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, NULL, 0); EXPECT_EQ(EvpnPrefix::AutoDiscoveryRoute, proto_prefix.type); size_t expected_size = EvpnPrefix::kMinAutoDiscoveryRouteSize + EvpnPrefix::kLabelSize; @@ -257,7 +257,7 @@ TEST_F(EvpnAutoDiscoveryPrefixTest, FromProtoPrefix3) { uint32_t label1 = 10000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::AutoDiscoveryRoute, proto_prefix.type); size_t expected_size = EvpnPrefix::kMinAutoDiscoveryRouteSize + EvpnPrefix::kLabelSize; @@ -296,7 +296,7 @@ TEST_F(EvpnAutoDiscoveryPrefixTest, FromProtoPrefix4) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::AutoDiscoveryRoute, proto_prefix.type); size_t expected_size = EvpnPrefix::kMinAutoDiscoveryRouteSize + EvpnPrefix::kLabelSize; @@ -335,7 +335,7 @@ TEST_F(EvpnAutoDiscoveryPrefixTest, FromProtoPrefix5) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::AutoDiscoveryRoute, proto_prefix.type); size_t expected_size = EvpnPrefix::kMinAutoDiscoveryRouteSize + EvpnPrefix::kLabelSize; @@ -374,7 +374,7 @@ TEST_F(EvpnAutoDiscoveryPrefixTest, FromProtoPrefix6) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::AutoDiscoveryRoute, proto_prefix.type); size_t expected_size = EvpnPrefix::kMinAutoDiscoveryRouteSize + EvpnPrefix::kLabelSize; @@ -663,7 +663,7 @@ TEST_F(EvpnMacAdvertisementPrefixTest, ParsePrefix_Error8) { } // Build and parse BgpProtoPrefix for reach, w/o ip. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix1) { +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix1a) { string temp1("2-10.1.1.1:65535-"); string temp2("-11:12:13:14:15:16,0.0.0.0"); uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; @@ -679,7 +679,7 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix1) { EthernetSegmentId esi1 = EthernetSegmentId::FromString("00:01:02:03:04:05:06:07:08:09"); attr1.set_esi(esi1); - prefix1.BuildProtoPrefix(&attr1, label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, &attr1, label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize; @@ -701,233 +701,927 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix1) { } } +// Build and parse BgpProtoPrefix for reach, w/o ip, including l3_label. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix1b) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,0.0.0.0"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpAttr attr1; + uint32_t label1 = 10000; + uint32_t l3_label1 = 20000; + BgpProtoPrefix proto_prefix; + EthernetSegmentId esi1 = + EthernetSegmentId::FromString("00:01:02:03:04:05:06:07:08:09"); + attr1.set_esi(esi1); + prefix1.BuildProtoPrefix(&proto_prefix, &attr1, label1, l3_label1); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_in2(new BgpAttr(bs_->attr_db())); + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr_in2.get(), &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_EQ(esi1, attr_out2->esi()); + EXPECT_NE(attr_in2.get(), attr_out2.get()); + EXPECT_EQ(label1, label2); + EXPECT_EQ(20000, l3_label2); + } +} + // Build and parse BgpProtoPrefix for reach w/ ipv4. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix2) { +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix2a) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,192.1.1.1"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpAttr attr1; + uint32_t label1 = 10000; + BgpProtoPrefix proto_prefix; + EthernetSegmentId esi1 = + EthernetSegmentId::FromString("00:01:02:03:04:05:06:07:08:09"); + attr1.set_esi(esi1); + prefix1.BuildProtoPrefix(&proto_prefix, &attr1, label1); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize + 4; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_in2(new BgpAttr(bs_->attr_db())); + BgpAttrPtr attr_out2; + uint32_t label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, attr_in2.get(), &prefix2, &attr_out2, &label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_EQ(esi1, attr_out2->esi()); + EXPECT_NE(attr_in2.get(), attr_out2.get()); + EXPECT_EQ(label1, label2); + } +} + +// Build and parse BgpProtoPrefix for reach w/ ipv4 including l3_label. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix2b) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,192.1.1.1"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpAttr attr1; + uint32_t label1 = 10000; + uint32_t l3_label1 = 20000; + BgpProtoPrefix proto_prefix; + EthernetSegmentId esi1 = + EthernetSegmentId::FromString("00:01:02:03:04:05:06:07:08:09"); + attr1.set_esi(esi1); + prefix1.BuildProtoPrefix(&proto_prefix, &attr1, label1, l3_label1); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize + 4; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_in2(new BgpAttr(bs_->attr_db())); + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr_in2.get(), &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_EQ(esi1, attr_out2->esi()); + EXPECT_NE(attr_in2.get(), attr_out2.get()); + EXPECT_EQ(label1, label2); + EXPECT_EQ(l3_label1, l3_label2); + } +} + +// Build and parse BgpProtoPrefix for reach w/ ipv6. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix3a) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpAttr attr1; + uint32_t label1 = 10000; + BgpProtoPrefix proto_prefix; + EthernetSegmentId esi1 = + EthernetSegmentId::FromString("00:01:02:03:04:05:06:07:08:09"); + attr1.set_esi(esi1); + prefix1.BuildProtoPrefix(&proto_prefix, &attr1, label1); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize + 16; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_in2(new BgpAttr(bs_->attr_db())); + BgpAttrPtr attr_out2; + uint32_t label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, attr_in2.get(), &prefix2, &attr_out2, &label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_EQ(esi1, attr_out2->esi()); + EXPECT_NE(attr_in2.get(), attr_out2.get()); + EXPECT_EQ(label1, label2); + } +} + +// Build and parse BgpProtoPrefix for reach w/ ipv6 including l3_label. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix3b) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpAttr attr1; + uint32_t label1 = 10000; + uint32_t l3_label1 = 20000; + BgpProtoPrefix proto_prefix; + EthernetSegmentId esi1 = + EthernetSegmentId::FromString("00:01:02:03:04:05:06:07:08:09"); + attr1.set_esi(esi1); + prefix1.BuildProtoPrefix(&proto_prefix, &attr1, label1, l3_label1); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize + 16; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_in2(new BgpAttr(bs_->attr_db())); + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr_in2.get(), &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_EQ(esi1, attr_out2->esi()); + EXPECT_NE(attr_in2.get(), attr_out2.get()); + EXPECT_EQ(label1, label2); + EXPECT_EQ(l3_label1, l3_label2); + } +} + +// Build and parse (w/ label and l3_label) BgpProtoPrefix for unreach, no ip. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix4a) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,0.0.0.0"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, NULL, 10000, 20000); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + size_t esi_offset = EvpnPrefix::kRdSize; + EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]); + EXPECT_TRUE(esi.IsZero()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result; + + result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, NULL, &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_TRUE(attr_out2.get() == NULL); + EXPECT_EQ(0, label2); + EXPECT_EQ(0, l3_label2); + } +} + +// Build and parse (w/ label) BgpProtoPrefix for unreach, no ip. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix4b) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,0.0.0.0"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, NULL, 10000, 0); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + size_t esi_offset = EvpnPrefix::kRdSize; + EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]); + EXPECT_TRUE(esi.IsZero()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result; + + result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, NULL, &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_TRUE(attr_out2.get() == NULL); + EXPECT_EQ(0, label2); + EXPECT_EQ(0, l3_label2); + } +} + +// Build and parse (w/o label) BgpProtoPrefix for unreach, no ip. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix4c) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,0.0.0.0"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, NULL, 0, 0); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + proto_prefix.prefix.resize(EvpnPrefix::kMinMacAdvertisementRouteSize); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result; + + result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, NULL, &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_TRUE(attr_out2.get() == NULL); + EXPECT_EQ(0, label2); + EXPECT_EQ(0, l3_label2); + } +} + +// Build and parse (w/ label and l3_label) BgpProtoPrefix for unreach, w/ ipv4. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix5a) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,192.1.1.1"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, NULL, 10000, 20000); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize + 4; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + size_t esi_offset = EvpnPrefix::kRdSize; + EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]); + EXPECT_TRUE(esi.IsZero()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result; + + result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, NULL, &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_TRUE(attr_out2.get() == NULL); + EXPECT_EQ(0, label2); + EXPECT_EQ(0, l3_label2); + } +} + +// Build and parse (w/ label) BgpProtoPrefix for unreach, w/ ipv4. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix5b) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,192.1.1.1"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, NULL, 10000, 0); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize + 4; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + size_t esi_offset = EvpnPrefix::kRdSize; + EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]); + EXPECT_TRUE(esi.IsZero()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result; + + result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, NULL, &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_TRUE(attr_out2.get() == NULL); + EXPECT_EQ(0, label2); + EXPECT_EQ(0, l3_label2); + } +} + +// Build and parse (w/o label) BgpProtoPrefix for unreach, w/ ipv4. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix5c) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,192.1.1.1"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, NULL, 0, 0); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + proto_prefix.prefix.resize( + EvpnPrefix::kMinMacAdvertisementRouteSize + 4); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result; + + result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, NULL, &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_TRUE(attr_out2.get() == NULL); + EXPECT_EQ(0, label2); + EXPECT_EQ(0, l3_label2); + } +} + +// Build and parse (w/ label and l3_label) BgpProtoPrefix for unreach, w/ ipv6. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix6a) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, NULL, 10000, 20000); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize + 16; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + size_t esi_offset = EvpnPrefix::kRdSize; + EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]); + EXPECT_TRUE(esi.IsZero()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result; + + result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, NULL, &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_TRUE(attr_out2.get() == NULL); + EXPECT_EQ(0, label2); + EXPECT_EQ(0, l3_label2); + } +} + +// Build and parse (w/ label) BgpProtoPrefix for unreach, w/ ipv6. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix6b) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, NULL, 10000, 0); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize + 16; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + size_t esi_offset = EvpnPrefix::kRdSize; + EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]); + EXPECT_TRUE(esi.IsZero()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result; + + result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, NULL, &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_TRUE(attr_out2.get() == NULL); + EXPECT_EQ(0, label2); + EXPECT_EQ(0, l3_label2); + } +} + +// Build and parse (w/o label) BgpProtoPrefix for unreach, w/ ipv6. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix6c) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); + uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, NULL, 0, 0); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + proto_prefix.prefix.resize( + EvpnPrefix::kMinMacAdvertisementRouteSize + 16); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result; + + result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, NULL, &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_TRUE(attr_out2.get() == NULL); + EXPECT_EQ(0, label2); + EXPECT_EQ(0, l3_label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/o ip. +// Tag is not 0, so label should be ignored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix7a) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,0.0.0.0"); + uint32_t tag_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + TunnelEncap tunnel_encap(TunnelEncapType::VXLAN); + ExtCommunitySpec comm_spec; + comm_spec.communities.push_back(tunnel_encap.GetExtCommunityValue()); + BgpAttrSpec attr_spec; + attr_spec.push_back(&comm_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + uint32_t label1 = 10000; + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = + EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, attr.get(), &prefix2, &attr_out2, &label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(tag, label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/o ip. +// Tag is not 0, so label should be ignored, but l3_label should be honored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix7b) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,0.0.0.0"); + uint32_t tag_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + string prefix_str = temp1 + integerToString(tag) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + TunnelEncap tunnel_encap(TunnelEncapType::VXLAN); + ExtCommunitySpec comm_spec; + comm_spec.communities.push_back(tunnel_encap.GetExtCommunityValue()); + BgpAttrSpec attr_spec; + attr_spec.push_back(&comm_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + uint32_t label1 = 10000; + uint32_t l3_label1 = 20000; + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1, l3_label1); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr.get(), &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(tag, label2); + EXPECT_EQ(20000, l3_label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/o ip. +// Tag is 0, so label should be honored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix8a) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,0.0.0.0"); + uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t label1, label_list) { + string prefix_str = temp1 + integerToString(0) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + TunnelEncap tunnel_encap(TunnelEncapType::VXLAN); + ExtCommunitySpec comm_spec; + comm_spec.communities.push_back(tunnel_encap.GetExtCommunityValue()); + BgpAttrSpec attr_spec; + attr_spec.push_back(&comm_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = + EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, attr.get(), &prefix2, &attr_out2, &label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(label1, label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/o ip. +// Tag is 0, so label should be honored and l3_label should also be honored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix8b) { + string temp1("2-10.1.1.1:65535-"); + string temp2("-11:12:13:14:15:16,0.0.0.0"); + uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t label1, label_list) { + string prefix_str = temp1 + integerToString(0) + temp2; + boost::system::error_code ec; + EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); + EXPECT_EQ(0, ec.value()); + + TunnelEncap tunnel_encap(TunnelEncapType::VXLAN); + ExtCommunitySpec comm_spec; + comm_spec.communities.push_back(tunnel_encap.GetExtCommunityValue()); + BgpAttrSpec attr_spec; + attr_spec.push_back(&comm_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + uint32_t l3_label1 = 20000; + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1, l3_label1); + EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize; + EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); + EXPECT_EQ(expected_size, proto_prefix.prefix.size()); + + EvpnPrefix prefix2; + BgpAttrPtr attr_out2; + uint32_t label2; + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr.get(), &prefix2, &attr_out2, &label2, &l3_label2); + EXPECT_EQ(0, result); + EXPECT_EQ(prefix1, prefix2); + EXPECT_TRUE(prefix2.esi().IsZero()); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(label1, label2); + EXPECT_EQ(20000, l3_label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. +// Tag is not 0, so label should be ignored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix9a) { string temp1("2-10.1.1.1:65535-"); string temp2("-11:12:13:14:15:16,192.1.1.1"); - uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + uint32_t tag_list[] = { 32, 10000, 1048575, 16777215 }; BOOST_FOREACH(uint32_t tag, tag_list) { string prefix_str = temp1 + integerToString(tag) + temp2; boost::system::error_code ec; EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); - BgpAttr attr1; + TunnelEncap tunnel_encap(TunnelEncapType::VXLAN); + ExtCommunitySpec comm_spec; + comm_spec.communities.push_back(tunnel_encap.GetExtCommunityValue()); + BgpAttrSpec attr_spec; + attr_spec.push_back(&comm_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + uint32_t label1 = 10000; BgpProtoPrefix proto_prefix; - EthernetSegmentId esi1 = - EthernetSegmentId::FromString("00:01:02:03:04:05:06:07:08:09"); - attr1.set_esi(esi1); - prefix1.BuildProtoPrefix(&attr1, label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize + 4; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize + 4; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); EvpnPrefix prefix2; - BgpAttrPtr attr_in2(new BgpAttr(bs_->attr_db())); BgpAttrPtr attr_out2; uint32_t label2; int result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, attr_in2.get(), &prefix2, &attr_out2, &label2); + proto_prefix, attr.get(), &prefix2, &attr_out2, &label2); EXPECT_EQ(0, result); EXPECT_EQ(prefix1, prefix2); EXPECT_TRUE(prefix2.esi().IsZero()); - EXPECT_EQ(esi1, attr_out2->esi()); - EXPECT_NE(attr_in2.get(), attr_out2.get()); - EXPECT_EQ(label1, label2); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(tag, label2); } } -// Build and parse BgpProtoPrefix for reach w/ ipv6. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix3) { +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. +// Tag is not 0, so label should be ignored, but l3_label should be honored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix9b) { string temp1("2-10.1.1.1:65535-"); - string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); - uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + string temp2("-11:12:13:14:15:16,192.1.1.1"); + uint32_t tag_list[] = { 32, 10000, 1048575, 16777215 }; BOOST_FOREACH(uint32_t tag, tag_list) { string prefix_str = temp1 + integerToString(tag) + temp2; boost::system::error_code ec; EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); - BgpAttr attr1; + TunnelEncap tunnel_encap(TunnelEncapType::VXLAN); + ExtCommunitySpec comm_spec; + comm_spec.communities.push_back(tunnel_encap.GetExtCommunityValue()); + BgpAttrSpec attr_spec; + attr_spec.push_back(&comm_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + uint32_t label1 = 10000; + uint32_t l3_label1 = 20000; BgpProtoPrefix proto_prefix; - EthernetSegmentId esi1 = - EthernetSegmentId::FromString("00:01:02:03:04:05:06:07:08:09"); - attr1.set_esi(esi1); - prefix1.BuildProtoPrefix(&attr1, label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1, l3_label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize + 16; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize + 4; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); EvpnPrefix prefix2; - BgpAttrPtr attr_in2(new BgpAttr(bs_->attr_db())); BgpAttrPtr attr_out2; uint32_t label2; - int result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, attr_in2.get(), &prefix2, &attr_out2, &label2); + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr.get(), &prefix2, &attr_out2, &label2, &l3_label2); EXPECT_EQ(0, result); EXPECT_EQ(prefix1, prefix2); EXPECT_TRUE(prefix2.esi().IsZero()); - EXPECT_EQ(esi1, attr_out2->esi()); - EXPECT_NE(attr_in2.get(), attr_out2.get()); - EXPECT_EQ(label1, label2); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(tag, label2); + EXPECT_EQ(20000, l3_label2); } } -// Build and parse (w/ and w/o label) BgpProtoPrefix for unreach, no ip. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix4) { +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. +// Tag is 0, so label should be honored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix10a) { string temp1("2-10.1.1.1:65535-"); - string temp2("-11:12:13:14:15:16,0.0.0.0"); - uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; - BOOST_FOREACH(uint32_t tag, tag_list) { - string prefix_str = temp1 + integerToString(tag) + temp2; + string temp2("-11:12:13:14:15:16,192.1.1.1"); + uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t label1, label_list) { + string prefix_str = temp1 + integerToString(0) + temp2; boost::system::error_code ec; EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); + TunnelEncap tunnel_encap(TunnelEncapType::VXLAN); + ExtCommunitySpec comm_spec; + comm_spec.communities.push_back(tunnel_encap.GetExtCommunityValue()); + BgpAttrSpec attr_spec; + attr_spec.push_back(&comm_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(NULL, 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize + 4; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); - size_t esi_offset = EvpnPrefix::kRdSize; - EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]); - EXPECT_TRUE(esi.IsZero()); EvpnPrefix prefix2; BgpAttrPtr attr_out2; uint32_t label2; - int result; - - result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, NULL, &prefix2, &attr_out2, &label2); - EXPECT_EQ(0, result); - EXPECT_EQ(prefix1, prefix2); - EXPECT_TRUE(prefix2.esi().IsZero()); - EXPECT_TRUE(attr_out2.get() == NULL); - EXPECT_EQ(0, label2); - - proto_prefix.prefix.resize(EvpnPrefix::kMinMacAdvertisementRouteSize); - prefix2 = EvpnPrefix::kNullPrefix; - label2 = EvpnPrefix::kInvalidLabel; - result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, NULL, &prefix2, &attr_out2, &label2); + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, attr.get(), &prefix2, &attr_out2, &label2); EXPECT_EQ(0, result); EXPECT_EQ(prefix1, prefix2); EXPECT_TRUE(prefix2.esi().IsZero()); - EXPECT_TRUE(attr_out2.get() == NULL); - EXPECT_EQ(0, label2); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(label1, label2); } } -// Build and parse (w/ and w/o label) BgpProtoPrefix for unreach, w/ ipv4. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix5) { +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. +// Tag is 0, so label should be honored and l3_label should be honored as well. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix10b) { string temp1("2-10.1.1.1:65535-"); string temp2("-11:12:13:14:15:16,192.1.1.1"); - uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; - BOOST_FOREACH(uint32_t tag, tag_list) { - string prefix_str = temp1 + integerToString(tag) + temp2; + uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t label1, label_list) { + string prefix_str = temp1 + integerToString(0) + temp2; boost::system::error_code ec; EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); + TunnelEncap tunnel_encap(TunnelEncapType::VXLAN); + ExtCommunitySpec comm_spec; + comm_spec.communities.push_back(tunnel_encap.GetExtCommunityValue()); + BgpAttrSpec attr_spec; + attr_spec.push_back(&comm_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + uint32_t l3_label1 = 20000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(NULL, 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1, l3_label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize + 4; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize + 4; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); - size_t esi_offset = EvpnPrefix::kRdSize; - EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]); - EXPECT_TRUE(esi.IsZero()); EvpnPrefix prefix2; BgpAttrPtr attr_out2; uint32_t label2; - int result; - - result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, NULL, &prefix2, &attr_out2, &label2); - EXPECT_EQ(0, result); - EXPECT_EQ(prefix1, prefix2); - EXPECT_TRUE(prefix2.esi().IsZero()); - EXPECT_TRUE(attr_out2.get() == NULL); - EXPECT_EQ(0, label2); - - proto_prefix.prefix.resize(EvpnPrefix::kMinMacAdvertisementRouteSize + 4); - prefix2 = EvpnPrefix::kNullPrefix; - label2 = EvpnPrefix::kInvalidLabel; - result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, NULL, &prefix2, &attr_out2, &label2); + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr.get(), &prefix2, &attr_out2, &label2, &l3_label2); EXPECT_EQ(0, result); EXPECT_EQ(prefix1, prefix2); EXPECT_TRUE(prefix2.esi().IsZero()); - EXPECT_TRUE(attr_out2.get() == NULL); - EXPECT_EQ(0, label2); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(label1, label2); + EXPECT_EQ(20000, l3_label2); } } -// Build and parse (w/ and w/o label) BgpProtoPrefix for unreach, w/ ipv6. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix6) { +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. +// Tag is not 0, so label should be ignored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix11a) { string temp1("2-10.1.1.1:65535-"); string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); - uint32_t tag_list[] = { 0, 100, 128, 4094, 65536 }; + uint32_t tag_list[] = { 32, 10000, 1048575, 16777215 }; BOOST_FOREACH(uint32_t tag, tag_list) { string prefix_str = temp1 + integerToString(tag) + temp2; boost::system::error_code ec; EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); + TunnelEncap tunnel_encap(TunnelEncapType::VXLAN); + ExtCommunitySpec comm_spec; + comm_spec.communities.push_back(tunnel_encap.GetExtCommunityValue()); + BgpAttrSpec attr_spec; + attr_spec.push_back(&comm_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + uint32_t label1 = 10000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(NULL, 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize + 16; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize + 16; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); - size_t esi_offset = EvpnPrefix::kRdSize; - EthernetSegmentId esi(&proto_prefix.prefix[esi_offset]); - EXPECT_TRUE(esi.IsZero()); EvpnPrefix prefix2; BgpAttrPtr attr_out2; uint32_t label2; - int result; - - result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, NULL, &prefix2, &attr_out2, &label2); - EXPECT_EQ(0, result); - EXPECT_EQ(prefix1, prefix2); - EXPECT_TRUE(prefix2.esi().IsZero()); - EXPECT_TRUE(attr_out2.get() == NULL); - EXPECT_EQ(0, label2); - - proto_prefix.prefix.resize(EvpnPrefix::kMinMacAdvertisementRouteSize + 16); - prefix2 = EvpnPrefix::kNullPrefix; - label2 = EvpnPrefix::kInvalidLabel; - result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, NULL, &prefix2, &attr_out2, &label2); + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), + proto_prefix, attr.get(), &prefix2, &attr_out2, &label2); EXPECT_EQ(0, result); EXPECT_EQ(prefix1, prefix2); EXPECT_TRUE(prefix2.esi().IsZero()); - EXPECT_TRUE(attr_out2.get() == NULL); - EXPECT_EQ(0, label2); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(tag, label2); } } -// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/o ip. -// Tag is not 0, so label should be ignored. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix7) { +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. +// Tag is not 0, so label should be ignored, but l3_label should be honored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix11b) { string temp1("2-10.1.1.1:65535-"); - string temp2("-11:12:13:14:15:16,0.0.0.0"); + string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); uint32_t tag_list[] = { 32, 10000, 1048575, 16777215 }; BOOST_FOREACH(uint32_t tag, tag_list) { string prefix_str = temp1 + integerToString(tag) + temp2; @@ -943,32 +1637,35 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix7) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); uint32_t label1 = 10000; + uint32_t l3_label1 = 20000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1, l3_label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize + 16; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); EvpnPrefix prefix2; BgpAttrPtr attr_out2; uint32_t label2; - int result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, attr.get(), &prefix2, &attr_out2, &label2); + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr.get(), &prefix2, &attr_out2, &label2, &l3_label2); EXPECT_EQ(0, result); EXPECT_EQ(prefix1, prefix2); EXPECT_TRUE(prefix2.esi().IsZero()); EXPECT_EQ(attr.get(), attr_out2.get()); EXPECT_EQ(tag, label2); + EXPECT_EQ(20000, l3_label2); } } -// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/o ip. +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. // Tag is 0, so label should be honored. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix8) { +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix12a) { string temp1("2-10.1.1.1:65535-"); - string temp2("-11:12:13:14:15:16,0.0.0.0"); + string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; BOOST_FOREACH(uint32_t label1, label_list) { string prefix_str = temp1 + integerToString(0) + temp2; @@ -984,10 +1681,10 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix8) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize + 16; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); @@ -1004,14 +1701,14 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix8) { } } -// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. -// Tag is not 0, so label should be ignored. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix9) { +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. +// Tag is 0, so label should be honored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix12b) { string temp1("2-10.1.1.1:65535-"); - string temp2("-11:12:13:14:15:16,192.1.1.1"); - uint32_t tag_list[] = { 32, 10000, 1048575, 16777215 }; - BOOST_FOREACH(uint32_t tag, tag_list) { - string prefix_str = temp1 + integerToString(tag) + temp2; + string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); + uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t label1, label_list) { + string prefix_str = temp1 + integerToString(0) + temp2; boost::system::error_code ec; EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); @@ -1023,36 +1720,39 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix9) { attr_spec.push_back(&comm_spec); BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); - uint32_t label1 = 10000; + uint32_t l3_label1 = 20000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1, l3_label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize + 4; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize + 16; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); EvpnPrefix prefix2; BgpAttrPtr attr_out2; uint32_t label2; - int result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, attr.get(), &prefix2, &attr_out2, &label2); + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr.get(), &prefix2, &attr_out2, &label2, &l3_label2); EXPECT_EQ(0, result); EXPECT_EQ(prefix1, prefix2); EXPECT_TRUE(prefix2.esi().IsZero()); EXPECT_EQ(attr.get(), attr_out2.get()); - EXPECT_EQ(tag, label2); + EXPECT_EQ(label1, label2); + EXPECT_EQ(20000, l3_label2); } } -// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. -// Tag is 0, so label should be honored. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix10) { +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/o ip. +// Tag is greater than kMaxVni, so label should be honored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix13a) { string temp1("2-10.1.1.1:65535-"); - string temp2("-11:12:13:14:15:16,192.1.1.1"); + string temp2("-11:12:13:14:15:16,0.0.0.0"); uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; BOOST_FOREACH(uint32_t label1, label_list) { - string prefix_str = temp1 + integerToString(0) + temp2; + string prefix_str = + temp1 + integerToString(EvpnPrefix::kMaxVni + 1) + temp2; boost::system::error_code ec; EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); @@ -1065,10 +1765,10 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix10) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize + 4; + EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); @@ -1085,14 +1785,15 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix10) { } } -// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. -// Tag is not 0, so label should be ignored. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix11) { +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/o ip. +// Tag is greater than kMaxVni, so label should be honored and l3_label as well. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix13b) { string temp1("2-10.1.1.1:65535-"); - string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); - uint32_t tag_list[] = { 32, 10000, 1048575, 16777215 }; - BOOST_FOREACH(uint32_t tag, tag_list) { - string prefix_str = temp1 + integerToString(tag) + temp2; + string temp2("-11:12:13:14:15:16,0.0.0.0"); + uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t label1, label_list) { + string prefix_str = + temp1 + integerToString(EvpnPrefix::kMaxVni + 1) + temp2; boost::system::error_code ec; EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); @@ -1104,36 +1805,39 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix11) { attr_spec.push_back(&comm_spec); BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); - uint32_t label1 = 10000; + uint32_t l3_label1 = 20000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1, l3_label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize + 16; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); EvpnPrefix prefix2; BgpAttrPtr attr_out2; uint32_t label2; - int result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, attr.get(), &prefix2, &attr_out2, &label2); + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr.get(), &prefix2, &attr_out2, &label2, &l3_label2); EXPECT_EQ(0, result); EXPECT_EQ(prefix1, prefix2); EXPECT_TRUE(prefix2.esi().IsZero()); EXPECT_EQ(attr.get(), attr_out2.get()); - EXPECT_EQ(tag, label2); + EXPECT_EQ(label1, label2); + EXPECT_EQ(20000, l3_label2); } } -// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. -// Tag is 0, so label should be honored. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix12) { +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. +// Tag is greater than kMaxVni, so label should be honored. +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix14a) { string temp1("2-10.1.1.1:65535-"); - string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); + string temp2("-11:12:13:14:15:16,192.1.1.1"); uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; BOOST_FOREACH(uint32_t label1, label_list) { - string prefix_str = temp1 + integerToString(0) + temp2; + string prefix_str = + temp1 + integerToString(EvpnPrefix::kMaxVni + 1) + temp2; boost::system::error_code ec; EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); @@ -1146,10 +1850,10 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix12) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize + 16; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize + 4; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); @@ -1166,11 +1870,11 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix12) { } } -// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/o ip. +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. // Tag is greater than kMaxVni, so label should be honored. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix13) { +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix14b) { string temp1("2-10.1.1.1:65535-"); - string temp2("-11:12:13:14:15:16,0.0.0.0"); + string temp2("-11:12:13:14:15:16,192.1.1.1"); uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; BOOST_FOREACH(uint32_t label1, label_list) { string prefix_str = @@ -1186,32 +1890,35 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix13) { attr_spec.push_back(&comm_spec); BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + uint32_t l3_label1 = 20000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1, l3_label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize + 4; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); EvpnPrefix prefix2; BgpAttrPtr attr_out2; uint32_t label2; - int result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, attr.get(), &prefix2, &attr_out2, &label2); + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr.get(), &prefix2, &attr_out2, &label2, &l3_label2); EXPECT_EQ(0, result); EXPECT_EQ(prefix1, prefix2); EXPECT_TRUE(prefix2.esi().IsZero()); EXPECT_EQ(attr.get(), attr_out2.get()); EXPECT_EQ(label1, label2); + EXPECT_EQ(20000, l3_label2); } } -// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. // Tag is greater than kMaxVni, so label should be honored. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix14) { +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix15a) { string temp1("2-10.1.1.1:65535-"); - string temp2("-11:12:13:14:15:16,192.1.1.1"); + string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; BOOST_FOREACH(uint32_t label1, label_list) { string prefix_str = @@ -1228,10 +1935,10 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix14) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize + 4; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + EvpnPrefix::kLabelSize + 16; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); @@ -1250,7 +1957,7 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix14) { // Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. // Tag is greater than kMaxVni, so label should be honored. -TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix15) { +TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix15b) { string temp1("2-10.1.1.1:65535-"); string temp2("-11:12:13:14:15:16,2001:db8:0:9::1"); uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; @@ -1268,24 +1975,27 @@ TEST_F(EvpnMacAdvertisementPrefixTest, FromProtoPrefix15) { attr_spec.push_back(&comm_spec); BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + uint32_t l3_label1 = 20000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1, l3_label1); EXPECT_EQ(EvpnPrefix::MacAdvertisementRoute, proto_prefix.type); - size_t expected_size = - EvpnPrefix::kMinMacAdvertisementRouteSize + EvpnPrefix::kLabelSize + 16; + size_t expected_size = EvpnPrefix::kMinMacAdvertisementRouteSize + + 2 * EvpnPrefix::kLabelSize + 16; EXPECT_EQ(expected_size * 8, proto_prefix.prefixlen); EXPECT_EQ(expected_size, proto_prefix.prefix.size()); EvpnPrefix prefix2; BgpAttrPtr attr_out2; uint32_t label2; - int result = EvpnPrefix::FromProtoPrefix(bs_.get(), - proto_prefix, attr.get(), &prefix2, &attr_out2, &label2); + uint32_t l3_label2; + int result = EvpnPrefix::FromProtoPrefix(bs_.get(), proto_prefix, + attr.get(), &prefix2, &attr_out2, &label2, &l3_label2); EXPECT_EQ(0, result); EXPECT_EQ(prefix1, prefix2); EXPECT_TRUE(prefix2.esi().IsZero()); EXPECT_EQ(attr.get(), attr_out2.get()); EXPECT_EQ(label1, label2); + EXPECT_EQ(20000, l3_label2); } } @@ -1671,7 +2381,7 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix1) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), 0); EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 4) * 8, proto_prefix.prefixlen); @@ -1711,7 +2421,7 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix2) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), 0); EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 16) * 8, proto_prefix.prefixlen); @@ -1755,7 +2465,7 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix3) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), 0); EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 4) * 8, proto_prefix.prefixlen); @@ -1799,7 +2509,7 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix4) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), 0); EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 4) * 8, proto_prefix.prefixlen); @@ -1844,7 +2554,7 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix5) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), 0); EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 4) * 8, proto_prefix.prefixlen); @@ -1888,7 +2598,7 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix6) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), 0); EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 16) * 8, proto_prefix.prefixlen); @@ -1932,7 +2642,7 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix7) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), 0); EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 16) * 8, proto_prefix.prefixlen); @@ -1977,7 +2687,7 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix8) { BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), 0); EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 16) * 8, proto_prefix.prefixlen); @@ -2215,7 +2925,7 @@ TEST_F(EvpnSegmentPrefixTest, FromProtoPrefix1) { BgpAttr attr1; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(&attr1, 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, &attr1, 0); EXPECT_EQ(EvpnPrefix::SegmentRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinSegmentRouteSize + 4) * 8, proto_prefix.prefixlen); @@ -2244,7 +2954,7 @@ TEST_F(EvpnSegmentPrefixTest, FromProtoPrefix2) { BgpAttr attr1; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(&attr1, 0, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, &attr1, 0); EXPECT_EQ(EvpnPrefix::SegmentRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinSegmentRouteSize + 16) * 8, proto_prefix.prefixlen); @@ -2608,7 +3318,7 @@ TEST_F(EvpnIpPrefixTest, FromProtoPrefix1) { uint32_t label1 = 10000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::IpPrefixRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInetPrefixRouteSize + 3) * 8, proto_prefix.prefixlen); @@ -2647,7 +3357,7 @@ TEST_F(EvpnIpPrefixTest, FromProtoPrefix2) { uint32_t label1 = 10000; BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(attr.get(), label1, &proto_prefix); + prefix1.BuildProtoPrefix(&proto_prefix, attr.get(), label1); EXPECT_EQ(EvpnPrefix::IpPrefixRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInetPrefixRouteSize + 3) * 8, proto_prefix.prefixlen); diff --git a/src/bgp/inet/inet_route.cc b/src/bgp/inet/inet_route.cc index 0fe997df151..f8cd798a25a 100644 --- a/src/bgp/inet/inet_route.cc +++ b/src/bgp/inet/inet_route.cc @@ -25,8 +25,8 @@ int Ip4Prefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, } int Ip4Prefix::FromProtoPrefix(BgpServer *server, - const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, - Ip4Prefix *prefix, BgpAttrPtr *new_attr, uint32_t *label) { + const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, Ip4Prefix *prefix, + BgpAttrPtr *new_attr, uint32_t *label, uint32_t *l3_label) { return FromProtoPrefix(proto_prefix, prefix); } @@ -124,7 +124,8 @@ void InetRoute::SetKey(const DBRequestKey *reqkey) { void InetRoute::BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr, - uint32_t label) const { + uint32_t label, + uint32_t l3_label) const { prefix->prefixlen = prefix_.prefixlen(); prefix->prefix.clear(); const Ip4Address::bytes_type &addr_bytes = prefix_.ip4_addr().to_bytes(); diff --git a/src/bgp/inet/inet_route.h b/src/bgp/inet/inet_route.h index dfd000d4bff..fe06fa940af 100644 --- a/src/bgp/inet/inet_route.h +++ b/src/bgp/inet/inet_route.h @@ -31,7 +31,8 @@ class Ip4Prefix { static int FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, Ip4Prefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label); + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label); static Ip4Prefix FromString(const std::string &str, boost::system::error_code *errorp = NULL); @@ -73,7 +74,8 @@ class InetRoute : public BgpRoute { virtual void BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr = NULL, - uint32_t label = 0) const; + uint32_t label = 0, + uint32_t l3_label = 0) const; virtual void BuildBgpProtoNextHop(std::vector &nh, IpAddress nexthop) const; diff --git a/src/bgp/inet6/inet6_route.cc b/src/bgp/inet6/inet6_route.cc index 3c46cd3dda2..70b57a32fcf 100644 --- a/src/bgp/inet6/inet6_route.cc +++ b/src/bgp/inet6/inet6_route.cc @@ -27,7 +27,8 @@ int Inet6Prefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, int Inet6Prefix::FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, Inet6Prefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label) { + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label) { return FromProtoPrefix(proto_prefix, prefix); } @@ -138,7 +139,8 @@ void Inet6Route::SetKey(const DBRequestKey *reqkey) { void Inet6Route::BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr, - uint32_t label) const { + uint32_t label, + uint32_t l3_label) const { prefix->prefixlen = prefix_.prefixlen(); prefix->prefix.clear(); const Ip6Address::bytes_type &addr_bytes = prefix_.ip6_addr().to_bytes(); diff --git a/src/bgp/inet6/inet6_route.h b/src/bgp/inet6/inet6_route.h index 9fe7007622d..f3d7748b7b4 100644 --- a/src/bgp/inet6/inet6_route.h +++ b/src/bgp/inet6/inet6_route.h @@ -37,7 +37,8 @@ class Inet6Prefix { static int FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, Inet6Prefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label); + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label); static Inet6Prefix FromString(const std::string &str, boost::system::error_code *errorp = NULL); std::string ToString() const; @@ -82,7 +83,8 @@ class Inet6Route : public BgpRoute { virtual void BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr = NULL, - uint32_t label = 0) const; + uint32_t label = 0, + uint32_t l3_label = 0) const; virtual void BuildBgpProtoNextHop(std::vector &nh, IpAddress nexthop) const; diff --git a/src/bgp/inet6vpn/inet6vpn_route.cc b/src/bgp/inet6vpn/inet6vpn_route.cc index 290486b6609..2f8a5c59852 100644 --- a/src/bgp/inet6vpn/inet6vpn_route.cc +++ b/src/bgp/inet6vpn/inet6vpn_route.cc @@ -45,7 +45,8 @@ int Inet6VpnPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, int Inet6VpnPrefix::FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, Inet6VpnPrefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label) { + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label) { return FromProtoPrefix(proto_prefix, prefix, label); } @@ -174,7 +175,8 @@ void Inet6VpnRoute::SetKey(const DBRequestKey *reqkey) { void Inet6VpnRoute::BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr*, - uint32_t label) const { + uint32_t label, + uint32_t l3_label) const { prefix_.BuildProtoPrefix(label, prefix); } diff --git a/src/bgp/inet6vpn/inet6vpn_route.h b/src/bgp/inet6vpn/inet6vpn_route.h index 30c9470c5ee..a0cc92c1ceb 100644 --- a/src/bgp/inet6vpn/inet6vpn_route.h +++ b/src/bgp/inet6vpn/inet6vpn_route.h @@ -28,7 +28,8 @@ class Inet6VpnPrefix { static int FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, Inet6VpnPrefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label); + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label); static Inet6VpnPrefix FromString(const std::string &str, boost::system::error_code *errorp = NULL); @@ -64,8 +65,8 @@ class Inet6VpnRoute : public BgpRoute { virtual KeyPtr GetDBRequestKey() const; virtual void SetKey(const DBRequestKey *reqkey); - virtual void BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr*, - uint32_t label) const; + virtual void BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr, + uint32_t label, uint32_t l3_label = 0) const; virtual void BuildBgpProtoNextHop(std::vector &nh, IpAddress nexthop) const; diff --git a/src/bgp/l3vpn/inetvpn_address.cc b/src/bgp/l3vpn/inetvpn_address.cc index 3b92ab3d95d..b9aed8a801c 100644 --- a/src/bgp/l3vpn/inetvpn_address.cc +++ b/src/bgp/l3vpn/inetvpn_address.cc @@ -43,7 +43,8 @@ int InetVpnPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, int InetVpnPrefix::FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, InetVpnPrefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label) { + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label) { return FromProtoPrefix(proto_prefix, prefix, label); } diff --git a/src/bgp/l3vpn/inetvpn_address.h b/src/bgp/l3vpn/inetvpn_address.h index 0d6961f8ca1..f1f31fa71ce 100644 --- a/src/bgp/l3vpn/inetvpn_address.h +++ b/src/bgp/l3vpn/inetvpn_address.h @@ -28,7 +28,8 @@ class InetVpnPrefix { static int FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, InetVpnPrefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label); + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label); static InetVpnPrefix FromString(const std::string &str, boost::system::error_code *errorp = NULL); diff --git a/src/bgp/l3vpn/inetvpn_route.cc b/src/bgp/l3vpn/inetvpn_route.cc index 3a4fe00c977..80191d4f17b 100644 --- a/src/bgp/l3vpn/inetvpn_route.cc +++ b/src/bgp/l3vpn/inetvpn_route.cc @@ -58,7 +58,8 @@ void InetVpnRoute::SetKey(const DBRequestKey *reqkey) { void InetVpnRoute::BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr, - uint32_t label) const { + uint32_t label, + uint32_t l3_label) const { prefix_.BuildProtoPrefix(label, prefix); } diff --git a/src/bgp/l3vpn/inetvpn_route.h b/src/bgp/l3vpn/inetvpn_route.h index 960e89d6d2e..bf713c3ea96 100644 --- a/src/bgp/l3vpn/inetvpn_route.h +++ b/src/bgp/l3vpn/inetvpn_route.h @@ -35,7 +35,8 @@ class InetVpnRoute : public BgpRoute { virtual void SetKey(const DBRequestKey *reqkey); virtual void BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr = NULL, - uint32_t label = 0) const; + uint32_t label = 0, + uint32_t l3_label = 0) const; virtual void BuildBgpProtoNextHop(std::vector &nh, IpAddress nexthop) const; diff --git a/src/bgp/rtarget/rtarget_prefix.cc b/src/bgp/rtarget/rtarget_prefix.cc index b2583f1fc50..8c3b625514b 100644 --- a/src/bgp/rtarget/rtarget_prefix.cc +++ b/src/bgp/rtarget/rtarget_prefix.cc @@ -43,7 +43,8 @@ int RTargetPrefix::FromProtoPrefix(const BgpProtoPrefix &proto_prefix, int RTargetPrefix::FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, RTargetPrefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label) { + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label) { return FromProtoPrefix(proto_prefix, prefix); } diff --git a/src/bgp/rtarget/rtarget_prefix.h b/src/bgp/rtarget/rtarget_prefix.h index 9ae7928b64e..b4484f2aae9 100644 --- a/src/bgp/rtarget/rtarget_prefix.h +++ b/src/bgp/rtarget/rtarget_prefix.h @@ -28,7 +28,8 @@ class RTargetPrefix { static int FromProtoPrefix(BgpServer *server, const BgpProtoPrefix &proto_prefix, const BgpAttr *attr, RTargetPrefix *prefix, - BgpAttrPtr *new_attr, uint32_t *label); + BgpAttrPtr *new_attr, uint32_t *label, + uint32_t *l3_label); static RTargetPrefix FromString(const std::string &str, boost::system::error_code *errorp = NULL); diff --git a/src/bgp/rtarget/rtarget_route.cc b/src/bgp/rtarget/rtarget_route.cc index bdb2b81a7f1..df70288ebd9 100644 --- a/src/bgp/rtarget/rtarget_route.cc +++ b/src/bgp/rtarget/rtarget_route.cc @@ -32,7 +32,8 @@ void RTargetRoute::SetKey(const DBRequestKey *reqkey) { void RTargetRoute::BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr, - uint32_t label) const { + uint32_t label, + uint32_t l3_label) const { prefix_.BuildProtoPrefix(prefix); } diff --git a/src/bgp/rtarget/rtarget_route.h b/src/bgp/rtarget/rtarget_route.h index fd2801c83b1..22ef55b364f 100644 --- a/src/bgp/rtarget/rtarget_route.h +++ b/src/bgp/rtarget/rtarget_route.h @@ -32,7 +32,8 @@ class RTargetRoute : public BgpRoute { virtual void SetKey(const DBRequestKey *reqkey); virtual void BuildProtoPrefix(BgpProtoPrefix *prefix, const BgpAttr *attr = NULL, - uint32_t label = 0) const; + uint32_t label = 0, + uint32_t l3_label = 0) const; virtual void BuildBgpProtoNextHop(std::vector &nh, IpAddress nexthop) const;