go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/aclplugin/aclidx/aclidx.go (about) 1 // Copyright (c) 2018 Cisco and/or its affiliates. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package aclidx 16 17 import ( 18 "time" 19 20 "go.ligato.io/cn-infra/v2/idxmap" 21 "go.ligato.io/cn-infra/v2/logging" 22 23 "go.ligato.io/vpp-agent/v3/pkg/idxvpp" 24 ) 25 26 // ACLMetadataIndex provides read-only access to mapping between ACL indices (used internally in VPP) 27 // and ACL names. 28 type ACLMetadataIndex interface { 29 // LookupIdx looks up previously stored item identified by index in mapping. 30 LookupByName(name string) (metadata *ACLMetadata, exists bool) 31 32 // LookupName looks up previously stored item identified by name in mapping. 33 LookupByIndex(idx uint32) (name string, metadata *ACLMetadata, exists bool) 34 35 // WatchAcls 36 WatchAcls(subscriber string, channel chan<- ACLMetadataDto) 37 } 38 39 // ACLMetadataIndexRW is mapping between ACL indices (used internally in VPP) and ACL names. 40 type ACLMetadataIndexRW interface { 41 ACLMetadataIndex 42 idxmap.NamedMappingRW 43 } 44 45 // ACLMetadata represents metadata for ACL. 46 type ACLMetadata struct { 47 Index uint32 48 L2 bool 49 } 50 51 // GetIndex returns index of the ACL. 52 func (m *ACLMetadata) GetIndex() uint32 { 53 return m.Index 54 } 55 56 // ACLMetadataDto represents an item sent through watch channel in aclIndex. 57 type ACLMetadataDto struct { 58 idxmap.NamedMappingEvent 59 Metadata *ACLMetadata 60 } 61 62 type aclMetadataIndex struct { 63 idxmap.NamedMappingRW 64 65 log logging.Logger 66 nameToIndex idxvpp.NameToIndex 67 } 68 69 // NewACLIndex creates new instance of aclMetadataIndex. 70 func NewACLIndex(logger logging.Logger, title string) ACLMetadataIndexRW { 71 mapping := idxvpp.NewNameToIndex(logger, title, indexMetadata) 72 return &aclMetadataIndex{ 73 NamedMappingRW: mapping, 74 log: logger, 75 nameToIndex: mapping, 76 } 77 } 78 79 // LookupByName looks up previously stored item identified by index in mapping. 80 func (aclIdx *aclMetadataIndex) LookupByName(name string) (metadata *ACLMetadata, exists bool) { 81 meta, found := aclIdx.GetValue(name) 82 if found { 83 if typedMeta, ok := meta.(*ACLMetadata); ok { 84 return typedMeta, found 85 } 86 } 87 return nil, false 88 } 89 90 // LookupByIndex looks up previously stored item identified by name in mapping. 91 func (aclIdx *aclMetadataIndex) LookupByIndex(idx uint32) (name string, metadata *ACLMetadata, exists bool) { 92 var item idxvpp.WithIndex 93 name, item, exists = aclIdx.nameToIndex.LookupByIndex(idx) 94 if exists { 95 var isIfaceMeta bool 96 metadata, isIfaceMeta = item.(*ACLMetadata) 97 if !isIfaceMeta { 98 exists = false 99 } 100 } 101 return 102 } 103 104 // WatchAcls ... 105 func (aclIdx *aclMetadataIndex) WatchAcls(subscriber string, channel chan<- ACLMetadataDto) { 106 watcher := func(dto idxmap.NamedMappingGenericEvent) { 107 typedMeta, ok := dto.Value.(*ACLMetadata) 108 if !ok { 109 return 110 } 111 msg := ACLMetadataDto{ 112 NamedMappingEvent: dto.NamedMappingEvent, 113 Metadata: typedMeta, 114 } 115 select { 116 case channel <- msg: 117 case <-time.After(idxmap.DefaultNotifTimeout): 118 aclIdx.log.Warn("Unable to deliver notification") 119 } 120 } 121 if err := aclIdx.Watch(subscriber, watcher); err != nil { 122 aclIdx.log.Error(err) 123 } 124 } 125 126 // indexMetadata is an index function used for ACL metadata. 127 func indexMetadata(metaData interface{}) map[string][]string { 128 indexes := make(map[string][]string) 129 130 ifMeta, ok := metaData.(*ACLMetadata) 131 if !ok || ifMeta == nil { 132 return indexes 133 } 134 135 return indexes 136 }