1
- // Copyright (c) 2018 Cisco and/or its affiliates.
1
+ // Copyright (c) 2020 Cisco and/or its affiliates.
2
2
//
3
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
4
// you may not use this file except in compliance with the License.
@@ -32,6 +32,21 @@ import (
32
32
const (
33
33
// ProxyArpDescriptorName is the name of the descriptor.
34
34
ProxyArpDescriptorName = "vpp-proxy-arp"
35
+
36
+ // Dependency labels:
37
+ vrfTableProxyARPDep = "vrf-table-exists"
38
+ )
39
+
40
+ // Validation errors:
41
+ var (
42
+ // ErrMissingIP returned when one of IP fields in ProxyARP range is not set.
43
+ ErrMissingIP = errors .New ("missing IP address" )
44
+ // ErrIPWithMask returned when one of IP fields in ProxyARP range is set with a subnet mask.
45
+ ErrIPWithMask = errors .New ("only one IP must be defined (e.g. \" 192.0.2.1\" ), not a subnet" )
46
+ // ErrInvalidIP returned when one of IP fields in ProxyARP range can not be parsed.
47
+ ErrInvalidIP = errors .New ("invalid IP address" )
48
+ // ErrIPv6NotSupported returned when one of IP fields in ProxyARP range is defined as IPv6.
49
+ ErrIPv6NotSupported = errors .New ("IP address must be IPv4, not IPv6" )
35
50
)
36
51
37
52
// ProxyArpDescriptor teaches KVScheduler how to configure VPP proxy ARPs.
@@ -57,19 +72,73 @@ func NewProxyArpDescriptor(scheduler kvs.KVScheduler,
57
72
ValueTypeName : l3 .ModelProxyARP .ProtoName (),
58
73
KeySelector : l3 .ModelProxyARP .IsKeyValid ,
59
74
ValueComparator : ctx .EquivalentProxyArps ,
75
+ Validate : ctx .Validate ,
60
76
Create : ctx .Create ,
61
77
Update : ctx .Update ,
62
78
Delete : ctx .Delete ,
63
79
Retrieve : ctx .Retrieve ,
80
+ Dependencies : ctx .Dependencies ,
64
81
DerivedValues : ctx .DerivedValues ,
65
82
RetrieveDependencies : []string {ifdescriptor .InterfaceDescriptorName },
66
83
}
67
84
return adapter .NewProxyARPDescriptor (typedDescr )
68
85
}
69
86
70
- // DerivedValues derives l3.ProxyARP_Interface for every interface..
87
+ // Validate validates ProxyARP setup.
88
+ func (d * ProxyArpDescriptor ) Validate (key string , proxyArp * l3.ProxyARP ) error {
89
+ for _ , r := range proxyArp .Ranges {
90
+ if r .FirstIpAddr == "" {
91
+ return kvs .NewInvalidValueError (ErrMissingIP , "ranges.first_ip_addr" )
92
+ }
93
+ if r .LastIpAddr == "" {
94
+ return kvs .NewInvalidValueError (ErrMissingIP , "ranges.last_ip_addr" )
95
+ }
96
+
97
+ if strings .Contains (r .FirstIpAddr , "/" ) {
98
+ return kvs .NewInvalidValueError (ErrIPWithMask , "ranges.first_ip_addr" )
99
+ }
100
+ if strings .Contains (r .LastIpAddr , "/" ) {
101
+ return kvs .NewInvalidValueError (ErrIPWithMask , "ranges.last_ip_addr" )
102
+ }
103
+
104
+ firstIP := net .ParseIP (r .FirstIpAddr )
105
+ if firstIP == nil {
106
+ return kvs .NewInvalidValueError (ErrInvalidIP , "ranges.first_ip_addr" )
107
+ }
108
+ lastIP := net .ParseIP (r .LastIpAddr )
109
+ if lastIP == nil {
110
+ return kvs .NewInvalidValueError (ErrInvalidIP , "ranges.last_ip_addr" )
111
+ }
112
+
113
+ if firstIP .To4 () == nil {
114
+ return kvs .NewInvalidValueError (ErrIPv6NotSupported , "ranges.first_ip_addr" )
115
+ }
116
+ if lastIP .To4 () == nil {
117
+ return kvs .NewInvalidValueError (ErrIPv6NotSupported , "ranges.last_ip_addr" )
118
+ }
119
+ }
120
+ return nil
121
+ }
122
+
123
+ // Dependencies lists dependencies for a VPP Proxy ARP.
124
+ func (d * ProxyArpDescriptor ) Dependencies (key string , proxyArp * l3.ProxyARP ) []kvs.Dependency {
125
+ var dependencies []kvs.Dependency
126
+
127
+ for _ , r := range proxyArp .Ranges {
128
+ if r .VrfId == 0 {
129
+ continue
130
+ }
131
+ dependencies = append (dependencies , kvs.Dependency {
132
+ Label : vrfTableProxyARPDep ,
133
+ Key : l3 .VrfTableKey (r .VrfId , l3 .VrfTable_IPV4 ),
134
+ })
135
+ }
136
+
137
+ return dependencies
138
+ }
139
+
140
+ // DerivedValues derives l3.ProxyARP_Interface for every interface.
71
141
func (d * ProxyArpDescriptor ) DerivedValues (key string , proxyArp * l3.ProxyARP ) (derValues []kvs.KeyValuePair ) {
72
- // IP addresses
73
142
for _ , iface := range proxyArp .Interfaces {
74
143
derValues = append (derValues , kvs.KeyValuePair {
75
144
Key : l3 .ProxyARPInterfaceKey (iface .Name ),
@@ -90,16 +159,12 @@ func (d *ProxyArpDescriptor) EquivalentProxyArps(key string, oldValue, newValue
90
159
91
160
// Create adds VPP Proxy ARP.
92
161
func (d * ProxyArpDescriptor ) Create (key string , value * l3.ProxyARP ) (metadata interface {}, err error ) {
93
- for _ , proxyArpRange := range value .Ranges {
94
- // Prune addresses
95
- firstIP := pruneIP (proxyArpRange .FirstIpAddr )
96
- lastIP := pruneIP (proxyArpRange .LastIpAddr )
97
- // Convert to byte representation
98
- bFirstIP := net .ParseIP (firstIP ).To4 ()
99
- bLastIP := net .ParseIP (lastIP ).To4 ()
100
- // Call VPP API to configure IP range for proxy ARP
101
- if err := d .proxyArpHandler .AddProxyArpRange (bFirstIP , bLastIP ); err != nil {
102
- return nil , errors .Errorf ("failed to add proxy ARP address range %s - %s: %v" , firstIP , lastIP , err )
162
+ for _ , r := range value .Ranges {
163
+ firstIP := net .ParseIP (r .FirstIpAddr ).To4 ()
164
+ lastIP := net .ParseIP (r .LastIpAddr ).To4 ()
165
+
166
+ if err := d .proxyArpHandler .AddProxyArpRange (firstIP , lastIP , r .VrfId ); err != nil {
167
+ return nil , errors .Errorf ("failed to add proxy ARP address range %s - %s (VRF: %d): %v" , firstIP , lastIP , r .VrfId , err )
103
168
}
104
169
}
105
170
return nil , nil
@@ -108,30 +173,22 @@ func (d *ProxyArpDescriptor) Create(key string, value *l3.ProxyARP) (metadata in
108
173
// Update modifies VPP Proxy ARP.
109
174
func (d * ProxyArpDescriptor ) Update (key string , oldValue , newValue * l3.ProxyARP , oldMetadata interface {}) (newMetadata interface {}, err error ) {
110
175
toAdd , toDelete := calculateRngDiff (newValue .Ranges , oldValue .Ranges )
111
- // Remove old ranges
112
- for _ , proxyArpRange := range toDelete {
113
- // Prune addresses
114
- firstIP := pruneIP (proxyArpRange .FirstIpAddr )
115
- lastIP := pruneIP (proxyArpRange .LastIpAddr )
116
- // Convert to byte representation
117
- bFirstIP := net .ParseIP (firstIP ).To4 ()
118
- bLastIP := net .ParseIP (lastIP ).To4 ()
119
- // Call VPP API to configure IP range for proxy ARP
120
- if err := d .proxyArpHandler .DeleteProxyArpRange (bFirstIP , bLastIP ); err != nil {
121
- return nil , errors .Errorf ("failed to delete proxy ARP address range %s - %s: %v" , firstIP , lastIP , err )
122
- }
123
- }
124
- // Add new ranges
125
- for _ , proxyArpRange := range toAdd {
126
- // Prune addresses
127
- firstIP := pruneIP (proxyArpRange .FirstIpAddr )
128
- lastIP := pruneIP (proxyArpRange .LastIpAddr )
129
- // Convert to byte representation
130
- bFirstIP := net .ParseIP (firstIP ).To4 ()
131
- bLastIP := net .ParseIP (lastIP ).To4 ()
132
- // Call VPP API to configure IP range for proxy ARP
133
- if err := d .proxyArpHandler .AddProxyArpRange (bFirstIP , bLastIP ); err != nil {
134
- return nil , errors .Errorf ("failed to add proxy ARP address range %s - %s: %v" , firstIP , lastIP , err )
176
+
177
+ for _ , r := range toDelete {
178
+ firstIP := net .ParseIP (r .FirstIpAddr ).To4 ()
179
+ lastIP := net .ParseIP (r .LastIpAddr ).To4 ()
180
+
181
+ if err := d .proxyArpHandler .DeleteProxyArpRange (firstIP , lastIP , r .VrfId ); err != nil {
182
+ return nil , errors .Errorf ("failed to delete proxy ARP address range %s - %s (VRF: %d): %v" , firstIP , lastIP , r .VrfId , err )
183
+ }
184
+ }
185
+
186
+ for _ , r := range toAdd {
187
+ firstIP := net .ParseIP (r .FirstIpAddr ).To4 ()
188
+ lastIP := net .ParseIP (r .LastIpAddr ).To4 ()
189
+
190
+ if err := d .proxyArpHandler .AddProxyArpRange (firstIP , lastIP , r .VrfId ); err != nil {
191
+ return nil , errors .Errorf ("failed to add proxy ARP address range %s - %s (VRF: %d): %v" , firstIP , lastIP , r .VrfId , err )
135
192
}
136
193
}
137
194
@@ -140,16 +197,12 @@ func (d *ProxyArpDescriptor) Update(key string, oldValue, newValue *l3.ProxyARP,
140
197
141
198
// Delete deletes VPP Proxy ARP.
142
199
func (d * ProxyArpDescriptor ) Delete (key string , value * l3.ProxyARP , metadata interface {}) error {
143
- for _ , proxyArpRange := range value .Ranges {
144
- // Prune addresses
145
- firstIP := pruneIP (proxyArpRange .FirstIpAddr )
146
- lastIP := pruneIP (proxyArpRange .LastIpAddr )
147
- // Convert to byte representation
148
- bFirstIP := net .ParseIP (firstIP ).To4 ()
149
- bLastIP := net .ParseIP (lastIP ).To4 ()
150
- // Call VPP API to configure IP range for proxy ARP
151
- if err := d .proxyArpHandler .DeleteProxyArpRange (bFirstIP , bLastIP ); err != nil {
152
- return errors .Errorf ("failed to delete proxy ARP address range %s - %s: %v" , firstIP , lastIP , err )
200
+ for _ , r := range value .Ranges {
201
+ firstIP := net .ParseIP (r .FirstIpAddr ).To4 ()
202
+ lastIP := net .ParseIP (r .LastIpAddr ).To4 ()
203
+
204
+ if err := d .proxyArpHandler .DeleteProxyArpRange (firstIP , lastIP , r .VrfId ); err != nil {
205
+ return errors .Errorf ("failed to delete proxy ARP address range %s - %s (VRF: %d): %v" , firstIP , lastIP , r .VrfId , err )
153
206
}
154
207
}
155
208
return nil
@@ -186,23 +239,14 @@ func (d *ProxyArpDescriptor) Retrieve(correlate []adapter.ProxyARPKVWithMetadata
186
239
return retrieved , nil
187
240
}
188
241
189
- // Remove IP mask if set
190
- func pruneIP (ip string ) string {
191
- ipParts := strings .Split (ip , "/" )
192
- switch len (ipParts ) {
193
- case 1 , 2 :
194
- return ipParts [0 ]
195
- }
196
- return ip
197
- }
198
-
199
- // Calculate difference between old and new ranges
242
+ // calculateRngDiff calculates difference between old and new ranges.
200
243
func calculateRngDiff (newRngs , oldRngs []* l3.ProxyARP_Range ) (toAdd , toDelete []* l3.ProxyARP_Range ) {
201
- // Find missing ranges
244
+ // Find missing ranges.
202
245
for _ , newRng := range newRngs {
203
246
var found bool
204
247
for _ , oldRng := range oldRngs {
205
- if newRng .FirstIpAddr == oldRng .FirstIpAddr &&
248
+ if newRng .VrfId == oldRng .VrfId &&
249
+ newRng .FirstIpAddr == oldRng .FirstIpAddr &&
206
250
newRng .LastIpAddr == oldRng .LastIpAddr {
207
251
found = true
208
252
break
@@ -212,11 +256,12 @@ func calculateRngDiff(newRngs, oldRngs []*l3.ProxyARP_Range) (toAdd, toDelete []
212
256
toAdd = append (toAdd , newRng )
213
257
}
214
258
}
215
- // Find obsolete interfaces
259
+ // Find obsolete ranges.
216
260
for _ , oldRng := range oldRngs {
217
261
var found bool
218
262
for _ , newRng := range newRngs {
219
- if oldRng .FirstIpAddr == newRng .FirstIpAddr &&
263
+ if oldRng .VrfId == newRng .VrfId &&
264
+ oldRng .FirstIpAddr == newRng .FirstIpAddr &&
220
265
oldRng .LastIpAddr == newRng .LastIpAddr {
221
266
found = true
222
267
break
0 commit comments