From 0aff30a74216f499b8abfabc50016b041b319749 Mon Sep 17 00:00:00 2001 From: Thomas Rosenstein Date: Sun, 18 Oct 2020 21:34:36 +0200 Subject: fix #2289: improve regex to give expected results --- cmd/gobgp/policy.go | 58 +++------------------------------------ internal/pkg/table/policy.go | 2 +- internal/pkg/table/policy_test.go | 29 ++++++++++++++++++++ 3 files changed, 34 insertions(+), 55 deletions(-) diff --git a/cmd/gobgp/policy.go b/cmd/gobgp/policy.go index 710fdb38..f90b68b0 100644 --- a/cmd/gobgp/policy.go +++ b/cmd/gobgp/policy.go @@ -31,65 +31,15 @@ import ( api "github.com/osrg/gobgp/api" "github.com/osrg/gobgp/internal/pkg/config" + table "github.com/osrg/gobgp/internal/pkg/table" "github.com/osrg/gobgp/pkg/packet/bgp" ) var ( _regexpCommunity = regexp.MustCompile(`\^\^(\S+)\$\$`) - repexpCommunity = regexp.MustCompile(`(\d+.)*\d+:\d+`) - regexpLargeCommunity = regexp.MustCompile(`\d+:\d+:\d+`) regexpCommunityString = regexp.MustCompile(`[\^\$]`) ) -func parseCommunityRegexp(arg string) (*regexp.Regexp, error) { - i, err := strconv.ParseUint(arg, 10, 32) - if err == nil { - return regexp.Compile(fmt.Sprintf("^%d:%d$", i>>16, i&0x0000ffff)) - } - if repexpCommunity.MatchString(arg) { - return regexp.Compile(fmt.Sprintf("^%s$", arg)) - } - for i, v := range bgp.WellKnownCommunityNameMap { - if strings.Replace(strings.ToLower(arg), "_", "-", -1) == v { - return regexp.Compile(fmt.Sprintf("^%d:%d$", i>>16, i&0x0000ffff)) - } - } - exp, err := regexp.Compile(arg) - if err != nil { - return nil, fmt.Errorf("invalid community format: %s", arg) - } - return exp, nil -} - -func parseExtCommunityRegexp(arg string) (bgp.ExtendedCommunityAttrSubType, *regexp.Regexp, error) { - var subtype bgp.ExtendedCommunityAttrSubType - elems := strings.SplitN(arg, ":", 2) - if len(elems) < 2 { - return subtype, nil, fmt.Errorf("invalid ext-community format([rt|soo]:)") - } - switch strings.ToLower(elems[0]) { - case "rt": - subtype = bgp.EC_SUBTYPE_ROUTE_TARGET - case "soo": - subtype = bgp.EC_SUBTYPE_ROUTE_ORIGIN - default: - return subtype, nil, fmt.Errorf("unknown ext-community subtype. rt, soo is supported") - } - exp, err := parseCommunityRegexp(elems[1]) - return subtype, exp, err -} - -func parseLargeCommunityRegexp(arg string) (*regexp.Regexp, error) { - if regexpLargeCommunity.MatchString(arg) { - return regexp.Compile(fmt.Sprintf("^%s$", arg)) - } - exp, err := regexp.Compile(arg) - if err != nil { - return nil, fmt.Errorf("invalid large-community format: %s", arg) - } - return exp, nil -} - func routeTypePrettyString(s api.Conditions_RouteType) string { switch s { case api.Conditions_ROUTE_TYPE_EXTERNAL: @@ -370,7 +320,7 @@ func parseCommunitySet(args []string) (*api.DefinedSet, error) { name := args[0] args = args[1:] for _, arg := range args { - if _, err := parseCommunityRegexp(arg); err != nil { + if _, err := table.ParseCommunityRegexp(arg); err != nil { return nil, err } } @@ -388,7 +338,7 @@ func parseExtCommunitySet(args []string) (*api.DefinedSet, error) { name := args[0] args = args[1:] for _, arg := range args { - if _, _, err := parseExtCommunityRegexp(arg); err != nil { + if _, _, err := table.ParseExtCommunityRegexp(arg); err != nil { return nil, err } } @@ -406,7 +356,7 @@ func parseLargeCommunitySet(args []string) (*api.DefinedSet, error) { name := args[0] args = args[1:] for _, arg := range args { - if _, err := parseLargeCommunityRegexp(arg); err != nil { + if _, err := table.ParseLargeCommunityRegexp(arg); err != nil { return nil, err } } diff --git a/internal/pkg/table/policy.go b/internal/pkg/table/policy.go index 08636991..d2e4f5ef 100644 --- a/internal/pkg/table/policy.go +++ b/internal/pkg/table/policy.go @@ -1135,7 +1135,7 @@ func ParseExtCommunity(arg string) (bgp.ExtendedCommunityInterface, error) { return bgp.ParseExtendedCommunity(subtype, value) } -var _regexpCommunity2 = regexp.MustCompile(`(\d+.)*\d+:\d+`) +var _regexpCommunity2 = regexp.MustCompile(`^(\d+.)*\d+:\d+$`) func ParseCommunityRegexp(arg string) (*regexp.Regexp, error) { i, err := strconv.ParseUint(arg, 10, 32) diff --git a/internal/pkg/table/policy_test.go b/internal/pkg/table/policy_test.go index 7c2d7a64..9f74f32c 100644 --- a/internal/pkg/table/policy_test.go +++ b/internal/pkg/table/policy_test.go @@ -2771,6 +2771,35 @@ func TestParseCommunityRegexp(t *testing.T) { assert.Equal(t, nil, err) assert.Equal(t, true, exp.MatchString("65000:1")) assert.Equal(t, false, exp.MatchString("65000:100")) + + // test if the parseCommunityRegexp function behaves as expected + + l1 := "6830:24370$" + r1, _ := ParseCommunityRegexp("6830:24370$") + + l2 := "^6830:24370$" + r2, _ := ParseCommunityRegexp("^6830:24370$") + + l3 := "^65001:100$" + r3, _ := ParseCommunityRegexp("65001:100") + + l4 := "^65001:400$" + r4, _ := ParseCommunityRegexp("4259905936") + + l5 := "^[0-9]*:300$" + r5, _ := ParseCommunityRegexp("^[0-9]*:300$") + + l6 := "^" + strconv.Itoa(int(bgp.COMMUNITY_INTERNET)) + ":" + strconv.Itoa(int(bgp.COMMUNITY_INTERNET)) + "$" + r6, _ := ParseCommunityRegexp("INTERNET") + + fmt.Printf("%v %v", l2, r2) + + assert.Equal(t, l1, r1.String()) + assert.Equal(t, l2, r2.String()) + assert.Equal(t, l3, r3.String()) + assert.Equal(t, l4, r4.String()) + assert.Equal(t, l5, r5.String()) + assert.Equal(t, l6, r6.String()) } func TestLocalPrefAction(t *testing.T) { -- cgit v1.2.3