go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/aclplugin/descriptor/acl_to_interface.go (about) 1 package descriptor 2 3 import ( 4 "github.com/pkg/errors" 5 "go.ligato.io/cn-infra/v2/logging" 6 "google.golang.org/protobuf/proto" 7 8 kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" 9 "go.ligato.io/vpp-agent/v3/plugins/vpp/aclplugin/aclidx" 10 "go.ligato.io/vpp-agent/v3/plugins/vpp/aclplugin/vppcalls" 11 acl "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/acl" 12 interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" 13 ) 14 15 const ( 16 // ACLToInterfaceDescriptorName is name for descriptor 17 ACLToInterfaceDescriptorName = "vpp-acl-to-interface" 18 19 // dependency labels 20 interfaceDep = "interface-exists" 21 ) 22 23 // ACLToInterfaceDescriptor represents assignment of ACL to interface. 24 type ACLToInterfaceDescriptor struct { 25 log logging.Logger 26 aclHandler vppcalls.ACLVppAPI 27 aclIndex aclidx.ACLMetadataIndex 28 } 29 30 // NewACLToInterfaceDescriptor returns new ACLInterface descriptor 31 func NewACLToInterfaceDescriptor(aclIndex aclidx.ACLMetadataIndex, aclHandler vppcalls.ACLVppAPI, 32 log logging.PluginLogger) *ACLToInterfaceDescriptor { 33 return &ACLToInterfaceDescriptor{ 34 log: log, 35 aclIndex: aclIndex, 36 aclHandler: aclHandler, 37 } 38 } 39 40 // GetDescriptor returns descriptor suitable for registration with the KVScheduler. 41 func (d *ACLToInterfaceDescriptor) GetDescriptor() *kvs.KVDescriptor { 42 return &kvs.KVDescriptor{ 43 Name: ACLToInterfaceDescriptorName, 44 KeySelector: d.IsACLInterfaceKey, 45 Create: d.Create, 46 Delete: d.Delete, 47 Dependencies: d.Dependencies, 48 } 49 } 50 51 // IsACLInterfaceKey returns true if the key is identifying ACL interface (derived value) 52 func (d *ACLToInterfaceDescriptor) IsACLInterfaceKey(key string) bool { 53 _, _, _, isACLToInterfaceKey := acl.ParseACLToInterfaceKey(key) 54 return isACLToInterfaceKey 55 } 56 57 // Create binds interface to ACL. 58 func (d *ACLToInterfaceDescriptor) Create(key string, emptyVal proto.Message) (metadata kvs.Metadata, err error) { 59 aclName, ifName, flow, _ := acl.ParseACLToInterfaceKey(key) 60 61 aclMeta, found := d.aclIndex.LookupByName(aclName) 62 if !found { 63 err = errors.Errorf("failed to obtain metadata for ACL %s", aclName) 64 d.log.Error(err) 65 return nil, err 66 } 67 68 if aclMeta.L2 { 69 // MACIP ACL (L2) 70 if err := d.aclHandler.AddMACIPACLToInterface(aclMeta.Index, ifName); err != nil { 71 d.log.Error(err) 72 return nil, err 73 } 74 } else { 75 // ACL (L3/L4) 76 if flow == acl.IngressFlow { 77 if err := d.aclHandler.AddACLToInterfaceAsIngress(aclMeta.Index, ifName); err != nil { 78 d.log.Error(err) 79 return nil, err 80 } 81 } else if flow == acl.EgressFlow { 82 if err := d.aclHandler.AddACLToInterfaceAsEgress(aclMeta.Index, ifName); err != nil { 83 d.log.Error(err) 84 return nil, err 85 } 86 } 87 } 88 89 return nil, nil 90 } 91 92 // Delete unbinds interface from ACL. 93 func (d *ACLToInterfaceDescriptor) Delete(key string, emptyVal proto.Message, metadata kvs.Metadata) error { 94 aclName, ifName, flow, _ := acl.ParseACLToInterfaceKey(key) 95 96 aclMeta, found := d.aclIndex.LookupByName(aclName) 97 if !found { 98 err := errors.Errorf("failed to obtain metadata for ACL %s", aclName) 99 d.log.Error(err) 100 return err 101 } 102 103 if aclMeta.L2 { 104 // MACIP ACL (L2) 105 if err := d.aclHandler.DeleteMACIPACLFromInterface(aclMeta.Index, ifName); err != nil { 106 d.log.Error(err) 107 return err 108 } 109 } else { 110 // ACL (L3/L4) 111 if flow == acl.IngressFlow { 112 if err := d.aclHandler.DeleteACLFromInterfaceAsIngress(aclMeta.Index, ifName); err != nil { 113 d.log.Error(err) 114 return err 115 } 116 } else if flow == acl.EgressFlow { 117 if err := d.aclHandler.DeleteACLFromInterfaceAsEgress(aclMeta.Index, ifName); err != nil { 118 d.log.Error(err) 119 return err 120 } 121 } 122 } 123 124 return nil 125 } 126 127 // Dependencies lists the interface as the only dependency for the binding. 128 func (d *ACLToInterfaceDescriptor) Dependencies(key string, emptyVal proto.Message) []kvs.Dependency { 129 _, ifName, _, _ := acl.ParseACLToInterfaceKey(key) 130 return []kvs.Dependency{ 131 { 132 Label: interfaceDep, 133 Key: interfaces.InterfaceKey(ifName), 134 }, 135 } 136 }