From f77e84806724b7f1bb6874c98a8827f1f50911c7 Mon Sep 17 00:00:00 2001 From: Nischal Sheth Date: Sun, 18 Oct 2015 17:05:20 -0700 Subject: [PATCH] Retain MED when advertising XMPP originated routes to eBGP peers Change-Id: I8ce50449f1f4d2b4d5fe8548856501e8bac9e4d4 Closes-Bug: 1501412 --- src/bgp/bgp_table.cc | 9 +++- src/bgp/test/bgp_table_export_test.cc | 73 +++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/src/bgp/bgp_table.cc b/src/bgp/bgp_table.cc index 707578df3fd..d8f6a666386 100644 --- a/src/bgp/bgp_table.cc +++ b/src/bgp/bgp_table.cc @@ -213,9 +213,14 @@ UpdateInfo *BgpTable::GetUpdateInfo(RibOut *ribout, BgpRoute *route, if (attr->local_pref()) clone->set_local_pref(0); - // Reset Med if the path was not learnt from XMPP. - if (attr->med() && (!peer || peer->PeerType() != BgpProto::XMPP)) + // Reset Med if the path did not originate from an xmpp peer. + // The AS path is NULL if the originating xmpp peer is locally + // connected. It's non-NULL but empty if the originating xmpp + // peer is connected to another bgp speaker in the iBGP mesh. + if (attr->med() && attr->as_path() && + !attr->as_path()->path().path_segments.empty()) { clone->set_med(0); + } // Prepend the local AS to AsPath. as_t local_as = diff --git a/src/bgp/test/bgp_table_export_test.cc b/src/bgp/test/bgp_table_export_test.cc index b7a41d4003b..67c17394114 100644 --- a/src/bgp/test/bgp_table_export_test.cc +++ b/src/bgp/test/bgp_table_export_test.cc @@ -191,6 +191,7 @@ class BgpTableExportTest : public ::testing::Test { if (internal_) { attr_spec.push_back(&path_spec); attr_spec.push_back(&local_pref); + attr_spec.push_back(&med); } else { AsPathSpec::PathSegment *path_seg = new AsPathSpec::PathSegment; path_seg->path_segment_type = AsPathSpec::PathSegment::AS_SEQUENCE; @@ -462,15 +463,14 @@ TEST_P(BgpTableExportParamTest1, CommunityNoExportSubconfed) { // Table : inet.0, bgp.l3vpn.0 // Source: eBGP, iBGP // RibOut: eBGP -// Intent: LocalPref and Med are cleared for eBGP. +// Intent: LocalPref is cleared for eBGP. // -TEST_P(BgpTableExportParamTest1, EBgpNoLocalPrefMed) { +TEST_P(BgpTableExportParamTest1, EBgpNoLocalPref) { CreateRibOut(BgpProto::EBGP, RibExportPolicy::BGP, 300); AddPath(); RunExport(); VerifyExportAccept(); VerifyAttrLocalPref(0); - VerifyAttrMed(0); } // @@ -486,7 +486,6 @@ TEST_P(BgpTableExportParamTest1, EBgpAsPrepend1) { RunExport(); VerifyExportAccept(); VerifyAttrLocalPref(0); - VerifyAttrMed(0); VerifyAttrAsPrepend(); } @@ -504,7 +503,6 @@ TEST_P(BgpTableExportParamTest1, EBgpAsPrepend2) { RunExport(); VerifyExportAccept(); VerifyAttrLocalPref(0); - VerifyAttrMed(0); VerifyAttrAsPrepend(); } @@ -558,6 +556,55 @@ TEST_P(BgpTableExportParamTest2, IBgpSplitHorizon) { VerifyExportReject(); } +// +// Table : inet.0, bgp.l3vpn.0 +// Source: iBGP (effectively XMPP since AsPath is NULL) +// RibOut: eBGP +// Intent: Med is retained if AsPath is NULL. +// +TEST_P(BgpTableExportParamTest2, EBgpRetainMed1) { + CreateRibOut(BgpProto::EBGP, RibExportPolicy::BGP, 300); + ResetAttrAsPath(); + AddPath(); + RunExport(); + VerifyExportAccept(); + VerifyAttrLocalPref(0); + VerifyAttrMed(100); + VerifyAttrAsPrepend(); +} +// +// Table : inet.0, bgp.l3vpn.0 +// Source: iBGP +// RibOut: eBGP +// Intent: Med is retained if AsPath is non-NULL but empty. +// +TEST_P(BgpTableExportParamTest2, EBgpRetainMed2) { + CreateRibOut(BgpProto::EBGP, RibExportPolicy::BGP, 300); + AddPath(); + RunExport(); + VerifyExportAccept(); + VerifyAttrLocalPref(0); + VerifyAttrMed(100); + VerifyAttrAsPrepend(); +} + +// +// Table : inet.0, bgp.l3vpn.0 +// Source: iBGP +// RibOut: eBGP +// Intent: Med is not retained since AsPath is non-empty. +// +TEST_P(BgpTableExportParamTest2, EBgpNoRetainMed) { + CreateRibOut(BgpProto::EBGP, RibExportPolicy::BGP, 300); + SetAttrAsPath(100); + AddPath(); + RunExport(); + VerifyExportAccept(); + VerifyAttrLocalPref(0); + VerifyAttrMed(0); + VerifyAttrAsPrepend(); +} + INSTANTIATE_TEST_CASE_P(Instance, BgpTableExportParamTest2, ::testing::Values("inet.0", "bgp.l3vpn.0")); @@ -688,6 +735,22 @@ TEST_P(BgpTableExportParamTest3, IBgpNoOverwriteMed) { VerifyAttrMed(100); } +// +// Table : inet.0, bgp.l3vpn.0 +// Source: eBGP +// RibOut: eBGP +// Intent: Med is not retained since AsPath is non-empty. +// +TEST_P(BgpTableExportParamTest3, EBgpNoRetainMed) { + CreateRibOut(BgpProto::EBGP, RibExportPolicy::BGP, 300); + AddPath(); + RunExport(); + VerifyExportAccept(); + VerifyAttrLocalPref(0); + VerifyAttrMed(0); + VerifyAttrAsPrepend(); +} + INSTANTIATE_TEST_CASE_P(Instance, BgpTableExportParamTest3, ::testing::Combine( ::testing::Values("inet.0", "bgp.l3vpn.0"),