diff options
-rw-r--r-- | packet/bgp.go | 19 | ||||
-rw-r--r-- | table/policy.go | 38 |
2 files changed, 47 insertions, 10 deletions
diff --git a/packet/bgp.go b/packet/bgp.go index 1d7b65cc..d47e3b65 100644 --- a/packet/bgp.go +++ b/packet/bgp.go @@ -4559,6 +4559,25 @@ func NewFourOctetAsSpecificExtended(subtype ExtendedCommunityAttrSubType, as uin } func ParseExtendedCommunity(subtype ExtendedCommunityAttrSubType, com string) (ExtendedCommunityInterface, error) { + if subtype == EC_SUBTYPE_ORIGIN_VALIDATION { + var value ValidationState + switch com { + case VALIDATION_STATE_VALID.String(): + value = VALIDATION_STATE_VALID + case VALIDATION_STATE_NOT_FOUND.String(): + value = VALIDATION_STATE_NOT_FOUND + case VALIDATION_STATE_INVALID.String(): + value = VALIDATION_STATE_INVALID + default: + return nil, fmt.Errorf("invalid validation state") + } + return &OpaqueExtended{ + SubType: EC_SUBTYPE_ORIGIN_VALIDATION, + Value: &ValidationExtended{ + Value: value, + }, + }, nil + } elems, err := parseRdAndRt(com) if err != nil { return nil, err diff --git a/table/policy.go b/table/policy.go index 675c46b2..be9ba5ad 100644 --- a/table/policy.go +++ b/table/policy.go @@ -843,19 +843,33 @@ func ParseCommunity(arg string) (uint32, error) { func ParseExtCommunity(arg string) (bgp.ExtendedCommunityInterface, error) { var subtype bgp.ExtendedCommunityAttrSubType + var value string elems := strings.SplitN(arg, ":", 2) - if len(elems) < 2 { - return nil, fmt.Errorf("invalid ext-community format([rt|soo]:<value>)") + + isValidationState := func(s string) bool { + s = strings.ToLower(s) + r := s == bgp.VALIDATION_STATE_VALID.String() + r = r || s == bgp.VALIDATION_STATE_NOT_FOUND.String() + return r || s == bgp.VALIDATION_STATE_INVALID.String() } - switch strings.ToLower(elems[0]) { - case "rt": - subtype = bgp.EC_SUBTYPE_ROUTE_TARGET - case "soo": - subtype = bgp.EC_SUBTYPE_ROUTE_ORIGIN - default: - return nil, fmt.Errorf("unknown ext-community subtype. rt, soo is supported") + if len(elems) < 2 && (len(elems) < 1 && !isValidationState(elems[0])) { + return nil, fmt.Errorf("invalid ext-community (rt|soo):<value> | valid | not-found | invalid") + } + if isValidationState(elems[0]) { + subtype = bgp.EC_SUBTYPE_ORIGIN_VALIDATION + value = elems[0] + } else { + switch strings.ToLower(elems[0]) { + case "rt": + subtype = bgp.EC_SUBTYPE_ROUTE_TARGET + case "soo": + subtype = bgp.EC_SUBTYPE_ROUTE_ORIGIN + default: + return nil, fmt.Errorf("invalid ext-community (rt|soo):<value> | valid | not-found | invalid") + } + value = elems[1] } - return bgp.ParseExtendedCommunity(subtype, elems[1]) + return bgp.ParseExtendedCommunity(subtype, value) } func ParseCommunityRegexp(arg string) (*regexp.Regexp, error) { @@ -942,6 +956,8 @@ func (s *ExtCommunitySet) ToApiStruct() *api.DefinedSet { return fmt.Sprintf("rt:%s", arg) case bgp.EC_SUBTYPE_ROUTE_ORIGIN: return fmt.Sprintf("soo:%s", arg) + case bgp.EC_SUBTYPE_ORIGIN_VALIDATION: + return arg default: return fmt.Sprintf("%d:%s", s.subtypeList[idx], arg) } @@ -1807,6 +1823,8 @@ func (a *ExtCommunityAction) ToApiStruct() *api.CommunityAction { return fmt.Sprintf("rt:%s", arg) case bgp.EC_SUBTYPE_ROUTE_ORIGIN: return fmt.Sprintf("soo:%s", arg) + case bgp.EC_SUBTYPE_ORIGIN_VALIDATION: + return arg default: return fmt.Sprintf("%d:%s", a.subtypeList[idx], arg) } |