Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support set-local-pref and set-med #238

Merged
merged 11 commits into from
Aug 25, 2023
30 changes: 30 additions & 0 deletions bgp/ocgobgp.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
package bgp

import (
"fmt"
"strconv"

log "github.com/golang/glog"
"github.com/openconfig/lemming/gnmi/oc"
"github.com/wenovus/gobgp/v3/pkg/bgpconfig"
)
Expand Down Expand Up @@ -45,6 +49,10 @@ func convertPolicyDefinition(policy *oc.RoutingPolicy_PolicyDefinition, neighAdd
for _, comm := range statement.GetActions().BgpActions.GetSetCommunity().GetInline().GetCommunities() {
setCommunitiesList = append(setCommunitiesList, convertCommunity(comm))
}
setmed, err := convertMED(statement.GetActions().GetBgpActions().GetSetMed())
if err != nil {
log.Errorf("MED value not supported: %v", err)
}
statements = append(statements, bgpconfig.Statement{
Name: statement.GetName(),
Conditions: bgpconfig.Conditions{
Expand Down Expand Up @@ -72,6 +80,8 @@ func convertPolicyDefinition(policy *oc.RoutingPolicy_PolicyDefinition, neighAdd
},
Options: statement.GetActions().GetBgpActions().GetSetCommunity().GetOptions().String(),
},
SetLocalPref: statement.GetActions().GetBgpActions().GetSetLocalPref(),
SetMed: bgpconfig.BgpSetMedType(setmed),
},
},
})
Expand Down Expand Up @@ -186,3 +196,23 @@ func convertCommunitySet(occommset map[string]*oc.RoutingPolicy_DefinedSets_BgpD
}
return commsets
}

func convertMED(med oc.RoutingPolicy_PolicyDefinition_Statement_Actions_BgpActions_SetMed_Union) (string, error) {
if med == nil {
return "", nil
}
switch c := med.(type) {
case oc.UnionString:
return string(c), nil
case oc.UnionUint32:
return strconv.FormatUint(uint64(c), 10), nil
case oc.E_BgpActions_SetMed:
switch c {
case oc.BgpActions_SetMed_IGP:
// TODO(wenbli): Find IGP cost to return.
}
return "", fmt.Errorf("unsupported value for MED: (%T, %v)", med, med)
default:
return "", fmt.Errorf("unrecognized value for MED: (%T, %v)", med, med)
}
}
2 changes: 1 addition & 1 deletion bgp/tests/local_tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go_test(
name = "local_tests_test",
size = "large",
srcs = [
"community_set_test.go",
"attributes_test.go",
"policy_test.go",
"prefix_set_test.go",
"route_propagation_test.go",
Expand Down
218 changes: 218 additions & 0 deletions bgp/tests/local_tests/attributes_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package local_test

import (
"fmt"
"testing"

"github.com/openconfig/lemming/bgp"
"github.com/openconfig/lemming/gnmi/oc"
"github.com/openconfig/lemming/gnmi/oc/ocpath"
"github.com/openconfig/ygot/ygot"

valpb "github.com/openconfig/lemming/bgp/tests/proto/policyval"
)

const (
acceptedCommunitySet = oc.UnionString("23456:23456")
rejectedCommunitySet = oc.UnionString("12345:12345")
lowerLocalPref = 41
higherLocalPref = 42
lowerMED = oc.UnionUint32(10)
higherMED = oc.UnionUint32(11)
)

// TestAttributes tests BGP attributes.
// - set-community and community set.
// - set-local-pref and local pref.
//
// DUT2's import policy from DUT1 sets the attribute values.
// DUT2's export policy to DUT3 filters the prefix with the attribute value.
func TestAttributes(t *testing.T) {
routeList := []string{
"10.1.0.0/16",
"10.2.0.0/16",
"10.10.0.0/16",
"10.11.0.0/16",
"10.12.0.0/16",
}
testPolicy(t, PolicyTestCase{
spec: &valpb.PolicyTestCase{
Description: "Test that one NLRI gets accepted and the otheris rejected via various attribute values.",
RouteTests: []*valpb.RouteTestCase{{
Description: "Accepted route with no attributes",
Input: &valpb.TestRoute{
ReachPrefix: routeList[0],
},
ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT,
ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT,
}, {
Description: "Accepted route with some attributes",
Input: &valpb.TestRoute{
ReachPrefix: routeList[1],
},
ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT,
ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT,
}, {
Description: "Rejected route due to community set",
Input: &valpb.TestRoute{
ReachPrefix: routeList[2],
},
ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT,
ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_DISCARD,
}, {
Description: "Unpreferred route due to local-pref",
Input: &valpb.TestRoute{
ReachPrefix: routeList[3],
},
ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT,
ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_NOT_PREFERRED,
}, {
Description: "Unpreferred route due to MED",
Input: &valpb.TestRoute{
ReachPrefix: routeList[4],
},
ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT,
ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_NOT_PREFERRED,
}},
LongerPathRouteTests: []*valpb.RouteTestCase{{
Description: "Accepted route due to higher local-pref",
Input: &valpb.TestRoute{
ReachPrefix: routeList[3],
},
ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_NOT_PREFERRED,
ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT,
}},
AlternatePathRouteTests: []*valpb.RouteTestCase{{
Description: "Accepted route due to lower MED",
Input: &valpb.TestRoute{
ReachPrefix: routeList[4],
},
ExpectedResultBeforePolicy: valpb.RouteTestResult_ROUTE_TEST_RESULT_NOT_PREFERRED,
ExpectedResult: valpb.RouteTestResult_ROUTE_TEST_RESULT_ACCEPT,
}},
},
installPolicies: func(t *testing.T, dut1, dut2, dut3, dut4, dut5 *Device) {
if debug {
fmt.Println("Installing test policies")
}

dut1PolicyName := "set-attributes-dut1"
dut1Policy := &oc.RoutingPolicy_PolicyDefinition_Statement_OrderedMap{}
dut5PolicyName := "set-attributes-dut5"
dut5Policy := &oc.RoutingPolicy_PolicyDefinition_Statement_OrderedMap{}
rejectPolicyName := "export-policy"
rejectPolicy := &oc.RoutingPolicy_PolicyDefinition_Statement_OrderedMap{}

for i, route := range routeList {
// Create prefix set
prefixSetName := "accept-" + route
prefixPath := ocpath.Root().RoutingPolicy().DefinedSets().PrefixSet(prefixSetName).Prefix(route, "exact").IpPrefix()
Replace(t, dut1, prefixPath.Config(), route)
Replace(t, dut5, prefixPath.Config(), route)

var installDut1Stmt bool
dut1Stmt := &oc.RoutingPolicy_PolicyDefinition_Statement{Name: ygot.String(route + "-setattr-policy-dut1")}
dut1Stmt.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetPrefixSet(prefixSetName)
dut1Stmt.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY)

var installDut5Stmt bool
dut5Stmt := &oc.RoutingPolicy_PolicyDefinition_Statement{Name: ygot.String(route + "-setattr-policy-dut5")}
dut5Stmt.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetPrefixSet(prefixSetName)
dut5Stmt.GetOrCreateConditions().GetOrCreateMatchPrefixSet().SetMatchSetOptions(oc.RoutingPolicy_MatchSetOptionsRestrictedType_ANY)

var installRejectStmt bool
rejectStmt := &oc.RoutingPolicy_PolicyDefinition_Statement{Name: ygot.String(route + "-reject-policy")}

// Create the corresponding set and filter policies for each test route.
switch i {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't very clear. i don't see why i == 1 means set communites

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment. Each index refers to an input test route, and each one has its corresponding policies that applies to it. Each one is essentially a subtest that re-uses the topology.

case 1:
// Set communities
installDut1Stmt = true
dut1Stmt.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetCommunity().SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD)
dut1Stmt.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetCommunity().GetOrCreateInline().SetCommunities(
[]oc.RoutingPolicy_PolicyDefinition_Statement_Actions_BgpActions_SetCommunity_Inline_Communities_Union{
acceptedCommunitySet,
},
)

dut1Stmt.GetOrCreateActions().GetOrCreateBgpActions().SetSetLocalPref(higherLocalPref)
case 2:
// Set communities
installDut1Stmt = true
dut1Stmt.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetCommunity().SetOptions(oc.BgpPolicy_BgpSetCommunityOptionType_ADD)
dut1Stmt.GetOrCreateActions().GetOrCreateBgpActions().GetOrCreateSetCommunity().GetOrCreateInline().SetCommunities(
[]oc.RoutingPolicy_PolicyDefinition_Statement_Actions_BgpActions_SetCommunity_Inline_Communities_Union{
rejectedCommunitySet,
},
)

// Create community set
installRejectStmt = true
rejectCommSetName := "reject-community-set"
rejCommMemberPath := ocpath.Root().RoutingPolicy().DefinedSets().BgpDefinedSets().CommunitySet(rejectCommSetName).CommunityMember()
Replace(t, dut2, rejCommMemberPath.Config(), []oc.RoutingPolicy_DefinedSets_BgpDefinedSets_CommunitySet_CommunityMember_Union{
rejectedCommunitySet,
})
Replace(t, dut2, ocpath.Root().RoutingPolicy().DefinedSets().BgpDefinedSets().CommunitySet(rejectCommSetName).MatchSetOptions().Config(), oc.RoutingPolicy_MatchSetOptionsType_ANY)

// Match on given list of community set members.
rejectStmt.GetOrCreateConditions().GetOrCreateBgpConditions().SetCommunitySet(rejectCommSetName)
case 3:
// Set local-pref
installDut1Stmt = true
dut1Stmt.GetOrCreateActions().GetOrCreateBgpActions().SetSetLocalPref(lowerLocalPref)

installDut5Stmt = true
dut5Stmt.GetOrCreateActions().GetOrCreateBgpActions().SetSetLocalPref(higherLocalPref)
case 4:
// Set MED
installDut1Stmt = true
dut1Stmt.GetOrCreateActions().GetOrCreateBgpActions().SetSetMed(higherMED)

installDut5Stmt = true
dut5Stmt.GetOrCreateActions().GetOrCreateBgpActions().SetSetMed(lowerMED)
}
if installDut1Stmt {
dut1Stmt.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE)
if err := dut1Policy.Append(dut1Stmt); err != nil {
t.Fatalf("Cannot append new BGP policy statement: %v", err)
}
}
if installDut5Stmt {
dut5Stmt.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_ACCEPT_ROUTE)
if err := dut5Policy.Append(dut5Stmt); err != nil {
t.Fatalf("Cannot append new BGP policy statement: %v", err)
}
}
if installRejectStmt {
rejectStmt.GetOrCreateActions().SetPolicyResult(oc.RoutingPolicy_PolicyResultType_REJECT_ROUTE)
if err := rejectPolicy.Append(rejectStmt); err != nil {
t.Fatalf("Cannot append new BGP policy statement: %v", err)
}
}
}
// Install export policies
Replace(t, dut1, ocpath.Root().RoutingPolicy().PolicyDefinition(dut1PolicyName).Config(), &oc.RoutingPolicy_PolicyDefinition{Name: ygot.String(dut1PolicyName), Statement: dut1Policy})
Replace(t, dut1, bgp.BGPPath.Neighbor(dut2.RouterID).ApplyPolicy().ExportPolicy().Config(), []string{dut1PolicyName})
Replace(t, dut5, ocpath.Root().RoutingPolicy().PolicyDefinition(dut5PolicyName).Config(), &oc.RoutingPolicy_PolicyDefinition{Name: ygot.String(dut5PolicyName), Statement: dut5Policy})
Replace(t, dut5, bgp.BGPPath.Neighbor(dut2.RouterID).ApplyPolicy().ExportPolicy().Config(), []string{dut5PolicyName})
// Install import policies
Replace(t, dut2, ocpath.Root().RoutingPolicy().PolicyDefinition(rejectPolicyName).Config(), &oc.RoutingPolicy_PolicyDefinition{Name: ygot.String(rejectPolicyName), Statement: rejectPolicy})
Replace(t, dut2, bgp.BGPPath.Neighbor(dut1.RouterID).ApplyPolicy().ImportPolicy().Config(), []string{rejectPolicyName})
},
})
}
Loading