diff options
-rw-r--r-- | policy/policy.go | 92 | ||||
-rw-r--r-- | policy/policy_test.go | 8 |
2 files changed, 31 insertions, 69 deletions
diff --git a/policy/policy.go b/policy/policy.go index b0f0880a..1fd2f017 100644 --- a/policy/policy.go +++ b/policy/policy.go @@ -38,13 +38,6 @@ const ( ROUTE_TYPE_REJECT ) -type MaskLengthRangeType int - -const ( - MASK_LENGTH_RANGE_MIN MaskLengthRangeType = iota - MASK_LENGTH_RANGE_MAX -) - type AttributeComparison int const ( @@ -1313,23 +1306,18 @@ func (a *AsPathPrependAction) apply(path *table.Path) *table.Path { } type Prefix struct { - Address net.IP - AddressFamily bgp.RouteFamily - Masklength uint8 - MasklengthRange map[MaskLengthRangeType]uint8 + Prefix *net.IPNet + AddressFamily bgp.RouteFamily + MasklengthRangeMax uint8 + MasklengthRangeMin uint8 } func NewPrefix(prefixStr string, maskRange string) (Prefix, error) { p := Prefix{} - mlr := make(map[MaskLengthRangeType]uint8) addr, ipPref, e := net.ParseCIDR(prefixStr) - if e != nil { return p, e } - maskLength, _ := ipPref.Mask.Size() - p.Address = addr - p.Masklength = uint8(maskLength) if ipv4Family := addr.To4(); ipv4Family != nil { p.AddressFamily, _ = bgp.GetRouteFamily("ipv4-unicast") @@ -1339,33 +1327,30 @@ func NewPrefix(prefixStr string, maskRange string) (Prefix, error) { return p, fmt.Errorf("can not determine the address family.") } - // TODO: validate mask length by using regexp + p.Prefix = ipPref - idx := strings.Index(maskRange, "..") - if idx == -1 { - log.WithFields(log.Fields{ - "Topic": "Policy", - "Type": "Prefix", - "MaskRangeFormat": maskRange, - }).Warn("mask length range format is invalid. mask range was skipped.") - return p, nil - } - - if idx != 0 { - min, e := strconv.ParseUint(maskRange[:idx], 10, 8) - if e != nil { - return p, e - } - mlr[MASK_LENGTH_RANGE_MIN] = uint8(min) - } - if idx != len(maskRange)-1 { - max, e := strconv.ParseUint(maskRange[idx+2:], 10, 8) - if e != nil { - return p, e - } - mlr[MASK_LENGTH_RANGE_MAX] = uint8(max) + if maskRange == "" { + l, _ := ipPref.Mask.Size() + maskLength := uint8(l) + p.MasklengthRangeMax = maskLength + p.MasklengthRangeMin = maskLength + } else { + exp := regexp.MustCompile("(\\d+)\\.\\.(\\d+)") + elems := exp.FindStringSubmatch(maskRange) + if len(elems) != 3 { + log.WithFields(log.Fields{ + "Topic": "Policy", + "Type": "Prefix", + "MaskRangeFormat": maskRange, + }).Warn("mask length range format is invalid.") + return p, fmt.Errorf("mask length range format is invalid") + } + // we've already checked the range is sane by regexp + min, _ := strconv.Atoi(elems[1]) + max, _ := strconv.Atoi(elems[2]) + p.MasklengthRangeMin = uint8(min) + p.MasklengthRangeMax = uint8(max) } - p.MasklengthRange = mlr return p, nil } @@ -1422,30 +1407,7 @@ func ipPrefixCalculate(path *table.Path, cPrefix Prefix) bool { return false } - cp := fmt.Sprintf("%s/%d", cPrefix.Address, cPrefix.Masklength) - rMin, okMin := cPrefix.MasklengthRange[MASK_LENGTH_RANGE_MIN] - rMax, okMax := cPrefix.MasklengthRange[MASK_LENGTH_RANGE_MAX] - if !okMin && !okMax { - if pAddr.Equal(cPrefix.Address) && pMasklen == cPrefix.Masklength { - return true - } else { - return false - } - } - - _, ipNet, e := net.ParseCIDR(cp) - if e != nil { - log.WithFields(log.Fields{ - "Topic": "Policy", - "Prefix": ipNet, - "Error": e, - }).Error("failed to parse the prefix of condition") - return false - } - if ipNet.Contains(pAddr) && (rMin <= pMasklen && pMasklen <= rMax) { - return true - } - return false + return cPrefix.Prefix.Contains(pAddr) && (cPrefix.MasklengthRangeMin <= pMasklen && pMasklen <= cPrefix.MasklengthRangeMax) } const ( diff --git a/policy/policy_test.go b/policy/policy_test.go index b0406f47..981d1723 100644 --- a/policy/policy_test.go +++ b/policy/policy_test.go @@ -45,16 +45,16 @@ func TestPrefixCalcurateNoRange(t *testing.T) { nexthop := bgp.NewPathAttributeNextHop("10.0.0.1") med := bgp.NewPathAttributeMultiExitDisc(0) pathAttributes := []bgp.PathAttributeInterface{origin, aspath, nexthop, med} - nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.101")} + nlri := []*bgp.IPAddrPrefix{bgp.NewIPAddrPrefix(24, "10.10.0.0")} updateMsg := bgp.NewBGPUpdateMessage(nil, pathAttributes, nlri) path := table.ProcessMessage(updateMsg, peer)[0] // test pl1, _ := NewPrefix("10.10.0.0/24", "") match1 := ipPrefixCalculate(path, pl1) - assert.Equal(t, false, match1) - pl2, _ := NewPrefix("10.10.0.101/24", "") + assert.Equal(t, true, match1) + pl2, _ := NewPrefix("10.10.0.0/23", "") match2 := ipPrefixCalculate(path, pl2) - assert.Equal(t, true, match2) + assert.Equal(t, false, match2) pl3, _ := NewPrefix("10.10.0.0/16", "21..24") match3 := ipPrefixCalculate(path, pl3) assert.Equal(t, true, match3) |