// compare extended community in the message's attribute with // the one in the condition. func (c *ExtCommunityCondition) evaluate(path *table.Path) bool { makeAs4Str := func(ec *ExtCommunityElement) string { t := ec.ecType str := fmt.Sprintf("%d", ec.localAdmin) switch t { case bgp.EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC: str = fmt.Sprintf("%d:%s", ec.globalAdmin.(uint16), str) case bgp.EC_TYPE_TRANSITIVE_IP4_SPECIFIC: str = fmt.Sprintf("%s:%s", ec.globalAdmin.(net.IP).String(), str) case bgp.EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC: ga := ec.globalAdmin.(uint32) upper := strconv.FormatUint(uint64(ga&0xFFFF0000>>16), 10) lower := strconv.FormatUint(uint64(ga&0x0000FFFF), 10) str = fmt.Sprintf("%s.%s:%s", upper, lower, str) } return str } makeTypeSubStr := func(st bgp.ExtendedCommunityAttrSubType) string { subStr := "" switch st { case bgp.EC_SUBTYPE_ROUTE_TARGET: subStr = "RT" case bgp.EC_SUBTYPE_ROUTE_ORIGIN: subStr = "SoO" } return subStr } eCommunities := path.GetExtCommunities() if len(eCommunities) == 0 || c == nil { return false } matched := false matchStr := "" for _, member := range c.ExtCommunityList { for _, eCommunity := range eCommunities { ec := eCommunity.(bgp.ExtendedCommunityInterface) t, st := ec.GetTypes() if member.isRegExp { ecString := fmt.Sprintf("%s:%s", makeTypeSubStr(st), ec.String()) if member.regExp.MatchString(ecString) { matched = true log.WithFields(log.Fields{ "Topic": "Policy", "RegExp": member.regExp.String(), }).Debug("extended community regexp used") matchStr = ec.String() break } } else if member.ecType == t && member.ecSubType == st { if makeAs4Str(member) == ec.String() { matched = true matchStr = ec.String() break } } } if matched { log.WithFields(log.Fields{ "Topic": "Policy", "Condition": "Extended Community", "Extended Community": matchStr, }).Debug("condition matched") return true } } return false }