summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packet/bgp.go19
-rw-r--r--table/policy.go38
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)
}