diff --git a/src/bgp/bgp_attr.cc b/src/bgp/bgp_attr.cc index 1340d7ab50d..1321aa908ba 100644 --- a/src/bgp/bgp_attr.cc +++ b/src/bgp/bgp_attr.cc @@ -212,12 +212,12 @@ std::string PmsiTunnelSpec::ToString() const { return oss.str(); } -uint32_t PmsiTunnelSpec::GetLabel() const { - return label >> 4; +uint32_t PmsiTunnelSpec::GetLabel(bool is_vni) const { + return (is_vni ? label : (label >> 4)); } -void PmsiTunnelSpec::SetLabel(uint32_t in_label) { - label = in_label << 4 | 0x01; +void PmsiTunnelSpec::SetLabel(uint32_t in_label, bool is_vni) { + label = (is_vni ? in_label : (in_label << 4 | 0x01)); } Ip4Address PmsiTunnelSpec::GetIdentifier() const { @@ -293,7 +293,7 @@ PmsiTunnel::PmsiTunnel(PmsiTunnelDB *pmsi_tunnel_db, refcount_ = 0; tunnel_flags = pmsi_spec_.tunnel_flags; tunnel_type = pmsi_spec_.tunnel_type; - label = pmsi_spec_.GetLabel(); + label = pmsi_spec_.label; identifier = pmsi_spec_.GetIdentifier(); } diff --git a/src/bgp/bgp_attr.h b/src/bgp/bgp_attr.h index 3e2bc165d29..7e5fd3b01c1 100644 --- a/src/bgp/bgp_attr.h +++ b/src/bgp/bgp_attr.h @@ -212,8 +212,8 @@ struct PmsiTunnelSpec : public BgpAttribute { virtual void ToCanonical(BgpAttr *attr); virtual std::string ToString() const; - uint32_t GetLabel() const; - void SetLabel(uint32_t label); + uint32_t GetLabel(bool is_vni = false) const; + void SetLabel(uint32_t label, bool is_vni = false); Ip4Address GetIdentifier() const; void SetIdentifier(Ip4Address identifier); @@ -237,6 +237,9 @@ class PmsiTunnel { } const PmsiTunnelSpec &pmsi_tunnel() const { return pmsi_spec_; } + uint32_t GetLabel(bool is_vni = false) const { + return (is_vni ? label : label >> 4); + } friend std::size_t hash_value(const PmsiTunnel &pmsi_tunnel) { size_t hash = 0; @@ -246,7 +249,6 @@ class PmsiTunnel { uint8_t tunnel_flags; uint8_t tunnel_type; - uint32_t label; Ip4Address identifier; private: @@ -254,6 +256,7 @@ class PmsiTunnel { friend int intrusive_ptr_del_ref(const PmsiTunnel *cpmsi_tunnel); friend void intrusive_ptr_release(const PmsiTunnel *cpmsi_tunnel); + uint32_t label; mutable tbb::atomic refcount_; PmsiTunnelDB *pmsi_tunnel_db_; PmsiTunnelSpec pmsi_spec_; diff --git a/src/bgp/bgp_route.cc b/src/bgp/bgp_route.cc index b8c3e486f8e..e9754624beb 100644 --- a/src/bgp/bgp_route.cc +++ b/src/bgp/bgp_route.cc @@ -338,13 +338,13 @@ static void FillOriginVnPathInfo(const OriginVnPath *ovnpath, } } -static void FillPmsiTunnelInfo(const PmsiTunnel *pmsi_tunnel, +static void FillPmsiTunnelInfo(const PmsiTunnel *pmsi_tunnel, bool label_is_vni, ShowRoutePath *show_path) { ShowPmsiTunnel spt; spt.set_type(pmsi_tunnel->pmsi_tunnel().GetTunnelTypeString()); spt.set_ar_type(pmsi_tunnel->pmsi_tunnel().GetTunnelArTypeString()); spt.set_identifier(pmsi_tunnel->identifier.to_string()); - spt.set_label(pmsi_tunnel->label); + spt.set_label(pmsi_tunnel->GetLabel(label_is_vni)); spt.set_flags(pmsi_tunnel->pmsi_tunnel().GetTunnelFlagsStrings()); show_path->set_pmsi_tunnel(spt); } @@ -413,7 +413,9 @@ void BgpRoute::FillRouteInfo(const BgpTable *table, FillOriginVnPathInfo(attr->origin_vn_path(), &srp); } if (attr->pmsi_tunnel()) { - FillPmsiTunnelInfo(attr->pmsi_tunnel(), &srp); + const ExtCommunity *extcomm = attr->ext_community(); + bool label_is_vni = extcomm && extcomm->ContainsTunnelEncapVxlan(); + FillPmsiTunnelInfo(attr->pmsi_tunnel(), label_is_vni, &srp); } show_route_paths.push_back(srp); } diff --git a/src/bgp/bgp_xmpp_channel.cc b/src/bgp/bgp_xmpp_channel.cc index ccaf00c5185..751ba641e46 100644 --- a/src/bgp/bgp_xmpp_channel.cc +++ b/src/bgp/bgp_xmpp_channel.cc @@ -1510,6 +1510,7 @@ bool BgpXmppChannel::ProcessEnetItem(string vrf_name, IpAddress nh_address(Ip4Address(0)); uint32_t label = 0; uint32_t flags = 0; + bool label_is_vni = false; if (add_change) { req.oper = DBRequest::DB_ENTRY_ADD_CHANGE; @@ -1552,6 +1553,8 @@ bool BgpXmppChannel::ProcessEnetItem(string vrf_name, TunnelEncap tun_encap(*it); if (tun_encap.tunnel_encap() == TunnelEncapType::UNSPEC) continue; + if (tun_encap.tunnel_encap() == TunnelEncapType::VXLAN) + label_is_vni = true; no_valid_tunnel_encap = false; if (i == 0) { ext.communities.push_back( @@ -1648,7 +1651,7 @@ bool BgpXmppChannel::ProcessEnetItem(string vrf_name, } pmsi_spec.SetIdentifier(nh_address.to_v4()); } - pmsi_spec.SetLabel(label); + pmsi_spec.SetLabel(label, label_is_vni); attrs.push_back(&pmsi_spec); } diff --git a/src/bgp/evpn/evpn_route.cc b/src/bgp/evpn/evpn_route.cc index 6930801c351..f1e8178c709 100644 --- a/src/bgp/evpn/evpn_route.cc +++ b/src/bgp/evpn/evpn_route.cc @@ -15,10 +15,10 @@ using std::vector; const EvpnPrefix EvpnPrefix::kNullPrefix; -const uint32_t EvpnPrefix::kInvalidLabel = 0x100000; +const uint32_t EvpnPrefix::kInvalidLabel = 0x00100000; const uint32_t EvpnPrefix::kNullTag = 0; const uint32_t EvpnPrefix::kMaxTag = 0xFFFFFFFF; -const uint32_t EvpnPrefix::kMaxVni = 0xFFFFFF; +const uint32_t EvpnPrefix::kMaxVni = 0x00FFFFFF; const size_t EvpnPrefix::kRdSize = RouteDistinguisher::kSize; const size_t EvpnPrefix::kEsiSize = EthernetSegmentId::kSize; @@ -213,7 +213,16 @@ int EvpnPrefix::FromProtoPrefix(BgpServer *server, (pmsi_tunnel->tunnel_type == PmsiTunnelSpec::IngressReplication || pmsi_tunnel->tunnel_type == PmsiTunnelSpec::AssistedReplicationContrail)) { - *label = pmsi_tunnel->label; + const ExtCommunity *extcomm = attr ? attr->ext_community() : NULL; + if (extcomm && extcomm->ContainsTunnelEncapVxlan()) { + if (prefix->tag_ && prefix->tag_ <= kMaxVni) { + *label = prefix->tag_; + } else { + *label = pmsi_tunnel->GetLabel(true); + } + } else { + *label = pmsi_tunnel->GetLabel(false); + } } break; } diff --git a/src/bgp/evpn/test/evpn_prefix_test.cc b/src/bgp/evpn/test/evpn_prefix_test.cc index 95c6380ecb0..01cbc02ece3 100644 --- a/src/bgp/evpn/test/evpn_prefix_test.cc +++ b/src/bgp/evpn/test/evpn_prefix_test.cc @@ -1657,6 +1657,8 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, ParsePrefix_Error6) { EXPECT_NE(0, ec.value()); } +// Build and parse BgpProtoPrefix for reach, w/ ipv4. +// Encap is not VXLAN, so label should be honored. TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix1) { string temp1("3-10.1.1.1:65535-"); string temp2("-192.1.1.1"); @@ -1667,9 +1669,15 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix1) { EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); - BgpAttr attr1; + BgpAttrSpec attr_spec; + PmsiTunnelSpec pmsi_spec; + pmsi_spec.tunnel_type = PmsiTunnelSpec::IngressReplication; + pmsi_spec.SetLabel(10000, false); + attr_spec.push_back(&pmsi_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(&attr1, 0, &proto_prefix); + prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 4) * 8, proto_prefix.prefixlen); @@ -1677,19 +1685,20 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix1) { 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(attr_out2->esi().IsZero()); - EXPECT_EQ(attr_in2.get(), attr_out2.get()); - EXPECT_EQ(0, label2); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(10000, label2); } } +// Build and parse BgpProtoPrefix for reach, w/ ipv6. +// Encap is not VXLAN, so label should be honored. TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix2) { string temp1("3-10.1.1.1:65535-"); string temp2("-2001:db8:0:9::1"); @@ -1700,9 +1709,15 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix2) { EvpnPrefix prefix1(EvpnPrefix::FromString(prefix_str, &ec)); EXPECT_EQ(0, ec.value()); - BgpAttr attr1; + BgpAttrSpec attr_spec; + PmsiTunnelSpec pmsi_spec; + pmsi_spec.tunnel_type = PmsiTunnelSpec::IngressReplication; + pmsi_spec.SetLabel(10000, false); + attr_spec.push_back(&pmsi_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + BgpProtoPrefix proto_prefix; - prefix1.BuildProtoPrefix(&attr1, 0, &proto_prefix); + prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 16) * 8, proto_prefix.prefixlen); @@ -1710,16 +1725,281 @@ TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix2) { 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(attr_out2->esi().IsZero()); - EXPECT_EQ(attr_in2.get(), attr_out2.get()); - EXPECT_EQ(0, label2); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(10000, label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. +// Tag is not 0, so label should be ignored. +TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix3) { + string temp1("3-10.1.1.1:65535-"); + string temp2("-192.1.1.1"); + uint32_t tag_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + boost::system::error_code ec; + string prefix_str = temp1 + integerToString(tag) + temp2; + 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); + PmsiTunnelSpec pmsi_spec; + pmsi_spec.tunnel_type = PmsiTunnelSpec::IngressReplication; + pmsi_spec.SetLabel(10000, true); + attr_spec.push_back(&pmsi_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); + EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 4) * 8, + proto_prefix.prefixlen); + EXPECT_EQ(EvpnPrefix::kMinInclusiveMulticastRouteSize + 4, + 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(attr_out2->esi().IsZero()); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(tag, label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. +// Tag is 0, so label should be honored. +TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix4) { + string temp1("3-10.1.1.1:65535-"); + string temp2("-192.1.1.1"); + uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t label, label_list) { + boost::system::error_code ec; + string prefix_str = temp1 + integerToString(0) + temp2; + 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); + PmsiTunnelSpec pmsi_spec; + pmsi_spec.tunnel_type = PmsiTunnelSpec::IngressReplication; + pmsi_spec.SetLabel(label, true); + attr_spec.push_back(&pmsi_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); + EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 4) * 8, + proto_prefix.prefixlen); + EXPECT_EQ(EvpnPrefix::kMinInclusiveMulticastRouteSize + 4, + 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(attr_out2->esi().IsZero()); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(label, label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv4. +// Tag is greater than kMaxVni, so label should be honored. +TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix5) { + string temp1("3-10.1.1.1:65535-"); + string temp2("-192.1.1.1"); + uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t label, label_list) { + boost::system::error_code ec; + string prefix_str = + temp1 + integerToString(EvpnPrefix::kMaxVni + 1) + temp2; + 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); + PmsiTunnelSpec pmsi_spec; + pmsi_spec.tunnel_type = PmsiTunnelSpec::IngressReplication; + pmsi_spec.SetLabel(label, true); + attr_spec.push_back(&pmsi_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); + EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 4) * 8, + proto_prefix.prefixlen); + EXPECT_EQ(EvpnPrefix::kMinInclusiveMulticastRouteSize + 4, + 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(attr_out2->esi().IsZero()); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(label, label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. +// Tag is not 0, so label should be ignored. +TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix6) { + string temp1("3-10.1.1.1:65535-"); + string temp2("-2001:db8:0:9::1"); + uint32_t tag_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t tag, tag_list) { + boost::system::error_code ec; + string prefix_str = temp1 + integerToString(tag) + temp2; + 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); + PmsiTunnelSpec pmsi_spec; + pmsi_spec.tunnel_type = PmsiTunnelSpec::IngressReplication; + pmsi_spec.SetLabel(10000, true); + attr_spec.push_back(&pmsi_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); + EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 16) * 8, + proto_prefix.prefixlen); + EXPECT_EQ(EvpnPrefix::kMinInclusiveMulticastRouteSize + 16, + 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(attr_out2->esi().IsZero()); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(tag, label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. +// Tag is 0, so label should be honored. +TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix7) { + string temp1("3-10.1.1.1:65535-"); + string temp2("-2001:db8:0:9::1"); + uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t label, label_list) { + boost::system::error_code ec; + string prefix_str = temp1 + integerToString(0) + temp2; + 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); + PmsiTunnelSpec pmsi_spec; + pmsi_spec.tunnel_type = PmsiTunnelSpec::IngressReplication; + pmsi_spec.SetLabel(label, true); + attr_spec.push_back(&pmsi_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); + EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 16) * 8, + proto_prefix.prefixlen); + EXPECT_EQ(EvpnPrefix::kMinInclusiveMulticastRouteSize + 16, + 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(attr_out2->esi().IsZero()); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(label, label2); + } +} + +// Build and parse BgpProtoPrefix for reach with VXLAN encap, w/ ipv6. +// Tag is greater than kMaxVni, so label should be honored. +TEST_F(EvpnInclusiveMulticastPrefixTest, FromProtoPrefix8) { + string temp1("3-10.1.1.1:65535-"); + string temp2("-2001:db8:0:9::1"); + uint32_t label_list[] = { 32, 10000, 1048575, 16777215 }; + BOOST_FOREACH(uint32_t label, label_list) { + boost::system::error_code ec; + string prefix_str = + temp1 + integerToString(EvpnPrefix::kMaxVni + 1) + temp2; + 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); + PmsiTunnelSpec pmsi_spec; + pmsi_spec.tunnel_type = PmsiTunnelSpec::IngressReplication; + pmsi_spec.SetLabel(label, true); + attr_spec.push_back(&pmsi_spec); + BgpAttrPtr attr = bs_->attr_db()->Locate(attr_spec); + + BgpProtoPrefix proto_prefix; + prefix1.BuildProtoPrefix(attr.get(), 0, &proto_prefix); + EXPECT_EQ(EvpnPrefix::InclusiveMulticastRoute, proto_prefix.type); + EXPECT_EQ((EvpnPrefix::kMinInclusiveMulticastRouteSize + 16) * 8, + proto_prefix.prefixlen); + EXPECT_EQ(EvpnPrefix::kMinInclusiveMulticastRouteSize + 16, + 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(attr_out2->esi().IsZero()); + EXPECT_EQ(attr.get(), attr_out2.get()); + EXPECT_EQ(label, label2); } } diff --git a/src/bgp/test/bgp_attr_test.cc b/src/bgp/test/bgp_attr_test.cc index aa0d6a9dd5a..33d22b64c68 100644 --- a/src/bgp/test/bgp_attr_test.cc +++ b/src/bgp/test/bgp_attr_test.cc @@ -14,6 +14,7 @@ #include "base/test/task_test_util.h" #include "bgp/bgp_log.h" #include "bgp/bgp_server.h" +#include "bgp/evpn/evpn_route.h" #include "bgp/extended-community/mac_mobility.h" #include "bgp/origin-vn/origin_vn.h" #include "control-node/control_node.h" @@ -958,7 +959,7 @@ TEST_F(BgpAttrTest, PmsiTunnel3) { EXPECT_EQ("10.1.1.1", pmsi_spec2.GetIdentifier().to_string()); } -TEST_F(BgpAttrTest, PmsiTunnel4) { +TEST_F(BgpAttrTest, PmsiTunnel4a) { BgpAttrSpec attr_spec; PmsiTunnelSpec pmsi_spec; pmsi_spec.tunnel_flags = PmsiTunnelSpec::EdgeReplicationSupported; @@ -975,7 +976,28 @@ TEST_F(BgpAttrTest, PmsiTunnel4) { pmsi_tunnel->tunnel_flags); EXPECT_EQ(PmsiTunnelSpec::IngressReplication, pmsi_tunnel->tunnel_type); - EXPECT_EQ(10000, pmsi_tunnel->label); + EXPECT_EQ(10000, pmsi_tunnel->GetLabel()); + EXPECT_EQ("10.1.1.1", pmsi_tunnel->identifier.to_string()); +} + +TEST_F(BgpAttrTest, PmsiTunnel4b) { + BgpAttrSpec attr_spec; + PmsiTunnelSpec pmsi_spec; + pmsi_spec.tunnel_flags = PmsiTunnelSpec::EdgeReplicationSupported; + pmsi_spec.tunnel_type = PmsiTunnelSpec::IngressReplication; + pmsi_spec.SetLabel(EvpnPrefix::kMaxVni, true); + error_code ec; + pmsi_spec.SetIdentifier(Ip4Address::from_string("10.1.1.1", ec)); + attr_spec.push_back(&pmsi_spec); + BgpAttrPtr attr = attr_db_->Locate(attr_spec); + EXPECT_EQ(1, attr_db_->Size()); + + const PmsiTunnel *pmsi_tunnel = attr->pmsi_tunnel(); + EXPECT_EQ(PmsiTunnelSpec::EdgeReplicationSupported, + pmsi_tunnel->tunnel_flags); + EXPECT_EQ(PmsiTunnelSpec::IngressReplication, + pmsi_tunnel->tunnel_type); + EXPECT_EQ(EvpnPrefix::kMaxVni, pmsi_tunnel->GetLabel(true)); EXPECT_EQ("10.1.1.1", pmsi_tunnel->identifier.to_string()); } diff --git a/src/bgp/test/bgp_evpn_manager_test.cc b/src/bgp/test/bgp_evpn_manager_test.cc index 81db1822747..5de9181b3f8 100644 --- a/src/bgp/test/bgp_evpn_manager_test.cc +++ b/src/bgp/test/bgp_evpn_manager_test.cc @@ -483,7 +483,7 @@ class BgpEvpnManagerTest : public ::testing::TestWithParam { pmsi_tunnel->tunnel_flags); TASK_UTIL_EXPECT_EQ(PmsiTunnelSpec::IngressReplication, pmsi_tunnel->tunnel_type); - TASK_UTIL_EXPECT_EQ(peer->label(), pmsi_tunnel->label); + TASK_UTIL_EXPECT_EQ(peer->label(), pmsi_tunnel->GetLabel()); TASK_UTIL_EXPECT_EQ(peer->address(), pmsi_tunnel->identifier); TASK_UTIL_EXPECT_EQ(peer->address(), attr->nexthop().to_v4()); TASK_UTIL_EXPECT_EQ(peer->address(), attr->originator_id()); @@ -1100,7 +1100,7 @@ class BgpEvpnManagerTest : public ::testing::TestWithParam { TASK_UTIL_EXPECT_EQ(PmsiTunnelSpec::ARLeaf, pmsi_tunnel->tunnel_flags); TASK_UTIL_EXPECT_EQ(PmsiTunnelSpec::AssistedReplicationContrail, pmsi_tunnel->tunnel_type); - TASK_UTIL_EXPECT_EQ(peer->label(), pmsi_tunnel->label); + TASK_UTIL_EXPECT_EQ(peer->label(), pmsi_tunnel->GetLabel()); TASK_UTIL_EXPECT_EQ(peer->replicator_address(), pmsi_tunnel->identifier); TASK_UTIL_EXPECT_EQ(peer->address(), attr->nexthop().to_v4()); @@ -1269,7 +1269,7 @@ class BgpEvpnManagerTest : public ::testing::TestWithParam { TASK_UTIL_EXPECT_EQ(tunnel_flags, pmsi_tunnel->tunnel_flags); TASK_UTIL_EXPECT_EQ(PmsiTunnelSpec::IngressReplication, pmsi_tunnel->tunnel_type); - TASK_UTIL_EXPECT_EQ(peer->label(), pmsi_tunnel->label); + TASK_UTIL_EXPECT_EQ(peer->label(), pmsi_tunnel->GetLabel()); TASK_UTIL_EXPECT_EQ(peer->address(), pmsi_tunnel->identifier); TASK_UTIL_EXPECT_EQ(peer->address(), attr->nexthop().to_v4()); TASK_UTIL_EXPECT_EQ(peer->address(), attr->originator_id());