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