pio 0.20.0 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/Rakefile +2 -2
- data/features/open_flow13/match.feature +370 -0
- data/features/open_flow13/oxm_ether_destination_field.raw +0 -0
- data/features/open_flow13/oxm_ether_source_field.raw +0 -0
- data/features/open_flow13/oxm_ether_type_field.raw +0 -0
- data/features/open_flow13/oxm_in_phy_port_field.raw +0 -0
- data/features/open_flow13/oxm_in_port_field.raw +0 -0
- data/features/open_flow13/oxm_ipv4_destination_field.raw +0 -0
- data/features/open_flow13/oxm_ipv4_source_field.raw +0 -0
- data/features/open_flow13/oxm_ipv6_destination_field.raw +0 -0
- data/features/open_flow13/oxm_ipv6_source_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ether_destination_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ether_source_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ipv4_destination_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ipv4_source_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ipv6_destination_field.raw +0 -0
- data/features/open_flow13/oxm_masked_ipv6_source_field.raw +0 -0
- data/features/open_flow13/oxm_metadata_field.raw +0 -0
- data/features/open_flow13/oxm_metadata_masked_field.raw +0 -0
- data/features/open_flow13/oxm_no_fields.raw +0 -0
- data/features/open_flow13/oxm_tcp_destination_field.raw +0 -0
- data/features/open_flow13/oxm_tcp_field.raw +0 -0
- data/features/open_flow13/oxm_tcp_source_field.raw +0 -0
- data/features/open_flow13/oxm_udp_destination_field.raw +0 -0
- data/features/open_flow13/oxm_udp_field.raw +0 -0
- data/features/open_flow13/oxm_udp_source_field.raw +0 -0
- data/lib/pio/ipv4_header.rb +0 -2
- data/lib/pio/open_flow/message.rb +18 -54
- data/lib/pio/open_flow10/packet_in.rb +1 -1
- data/lib/pio/open_flow13/match.rb +452 -0
- data/lib/pio/open_flow13.rb +7 -0
- data/lib/pio/type/ipv6_address.rb +21 -0
- data/lib/pio/version.rb +1 -1
- data/pio.gemspec +8 -8
- data/spec/pio/mac_spec.rb +2 -2
- data/spec/pio/open_flow13/match_spec.rb +387 -0
- data/spec/pio/packet_out_spec.rb +1 -2
- metadata +73 -19
@@ -0,0 +1,452 @@
|
|
1
|
+
require 'bindata'
|
2
|
+
require 'pio/type/ip_address'
|
3
|
+
require 'pio/type/ipv6_address'
|
4
|
+
require 'pio/type/mac_address'
|
5
|
+
|
6
|
+
# Base module.
|
7
|
+
module Pio
|
8
|
+
# OpenFlow 1.3.
|
9
|
+
module OpenFlow13
|
10
|
+
# OFPMT_OXM
|
11
|
+
MATCH_TYPE_OXM = 1
|
12
|
+
|
13
|
+
# OpenFlow eXtensible Match (OXM)
|
14
|
+
class Match
|
15
|
+
OXM_CLASS_OPENFLOW_BASIC = 0x8000
|
16
|
+
|
17
|
+
# The value of OXM_OF_IN_PORT match field.
|
18
|
+
class InPort < BinData::Record
|
19
|
+
OXM_FIELD = 0
|
20
|
+
|
21
|
+
endian :big
|
22
|
+
|
23
|
+
uint32 :in_port
|
24
|
+
|
25
|
+
def length
|
26
|
+
4
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# The value of OXM_OF_ETH_DST match field.
|
31
|
+
class EtherDestinationAddress < BinData::Record
|
32
|
+
OXM_FIELD = 3
|
33
|
+
|
34
|
+
endian :big
|
35
|
+
|
36
|
+
mac_address :ether_destination_address
|
37
|
+
|
38
|
+
def length
|
39
|
+
6
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# The value of OXM_OF_ETH_SRC match field.
|
44
|
+
class EtherSourceAddress < BinData::Record
|
45
|
+
OXM_FIELD = 4
|
46
|
+
|
47
|
+
endian :big
|
48
|
+
|
49
|
+
mac_address :ether_source_address
|
50
|
+
|
51
|
+
def length
|
52
|
+
6
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Masked OXM_OF_ETH_DST match field.
|
57
|
+
class MaskedEtherDestinationAddress < BinData::Record
|
58
|
+
endian :big
|
59
|
+
|
60
|
+
mac_address :ether_destination_address
|
61
|
+
mac_address :ether_destination_address_mask
|
62
|
+
|
63
|
+
def length
|
64
|
+
12
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
# Masked OXM_OF_ETH_SRC match field.
|
69
|
+
class MaskedEtherSourceAddress < BinData::Record
|
70
|
+
endian :big
|
71
|
+
|
72
|
+
mac_address :ether_source_address
|
73
|
+
mac_address :ether_source_address_mask
|
74
|
+
|
75
|
+
def length
|
76
|
+
12
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# The value of OXM_OF_ETH_TYPE match field.
|
81
|
+
class EtherType < BinData::Record
|
82
|
+
OXM_FIELD = 5
|
83
|
+
|
84
|
+
endian :big
|
85
|
+
|
86
|
+
uint16 :ether_type
|
87
|
+
|
88
|
+
def length
|
89
|
+
2
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# The value of OXM_OF_IP_PROTO
|
94
|
+
class IpProtocol < BinData::Record
|
95
|
+
OXM_FIELD = 10
|
96
|
+
|
97
|
+
endian :big
|
98
|
+
|
99
|
+
uint8 :ip_protocol
|
100
|
+
|
101
|
+
def length
|
102
|
+
1
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# The value of OXM_OF_IPV4_SRC
|
107
|
+
class Ipv4SourceAddress < BinData::Record
|
108
|
+
OXM_FIELD = 11
|
109
|
+
|
110
|
+
endian :big
|
111
|
+
|
112
|
+
ip_address :ipv4_source_address
|
113
|
+
|
114
|
+
def length
|
115
|
+
4
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# The value of masked OXM_OF_IPV4_SRC
|
120
|
+
class MaskedIpv4SourceAddress < BinData::Record
|
121
|
+
OXM_FIELD = 11
|
122
|
+
|
123
|
+
endian :big
|
124
|
+
ip_address :ipv4_source_address
|
125
|
+
ip_address :ipv4_source_address_mask
|
126
|
+
|
127
|
+
def length
|
128
|
+
8
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# The value of OXM_OF_IPV4_DST
|
133
|
+
class Ipv4DestinationAddress < BinData::Record
|
134
|
+
OXM_FIELD = 12
|
135
|
+
|
136
|
+
endian :big
|
137
|
+
|
138
|
+
ip_address :ipv4_destination_address
|
139
|
+
|
140
|
+
def length
|
141
|
+
4
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# The value of masked OXM_OF_IPV4_DST
|
146
|
+
class MaskedIpv4DestinationAddress < BinData::Record
|
147
|
+
OXM_FIELD = 12
|
148
|
+
|
149
|
+
endian :big
|
150
|
+
ip_address :ipv4_destination_address
|
151
|
+
ip_address :ipv4_destination_address_mask
|
152
|
+
|
153
|
+
def length
|
154
|
+
8
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
# The value of OXM_OF_TCP_SRC
|
159
|
+
class TcpSourcePort < BinData::Record
|
160
|
+
OXM_FIELD = 13
|
161
|
+
|
162
|
+
endian :big
|
163
|
+
|
164
|
+
uint16 :tcp_source_port
|
165
|
+
|
166
|
+
def length
|
167
|
+
16
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# The value of OXM_OF_TCP_DST
|
172
|
+
class TcpDestinationPort < BinData::Record
|
173
|
+
OXM_FIELD = 14
|
174
|
+
|
175
|
+
endian :big
|
176
|
+
|
177
|
+
uint16 :tcp_destination_port
|
178
|
+
|
179
|
+
def length
|
180
|
+
16
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# The value of OXM_OF_UDP_SRC
|
185
|
+
class UdpSourcePort < BinData::Record
|
186
|
+
OXM_FIELD = 15
|
187
|
+
|
188
|
+
endian :big
|
189
|
+
|
190
|
+
uint16 :udp_source_port
|
191
|
+
|
192
|
+
def length
|
193
|
+
16
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
# The value of OXM_OF_UDP_SRC
|
198
|
+
class UdpDestinationPort < BinData::Record
|
199
|
+
OXM_FIELD = 16
|
200
|
+
|
201
|
+
endian :big
|
202
|
+
|
203
|
+
uint16 :udp_destination_port
|
204
|
+
|
205
|
+
def length
|
206
|
+
16
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# The value of OXM_OF_IPV6_SRC
|
211
|
+
class Ipv6SourceAddress < BinData::Record
|
212
|
+
OXM_FIELD = 26
|
213
|
+
|
214
|
+
endian :big
|
215
|
+
|
216
|
+
ipv6_address :ipv6_source_address
|
217
|
+
|
218
|
+
def length
|
219
|
+
128
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# The value of masked OXM_OF_IPV6_SRC
|
224
|
+
class MaskedIpv6SourceAddress < BinData::Record
|
225
|
+
OXM_FIELD = 26
|
226
|
+
|
227
|
+
endian :big
|
228
|
+
|
229
|
+
ipv6_address :ipv6_source_address
|
230
|
+
ipv6_address :ipv6_source_address_mask
|
231
|
+
|
232
|
+
def length
|
233
|
+
256
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# The value of OXM_OF_IPV6_DST
|
238
|
+
class Ipv6DestinationAddress < BinData::Record
|
239
|
+
OXM_FIELD = 27
|
240
|
+
|
241
|
+
endian :big
|
242
|
+
|
243
|
+
ipv6_address :ipv6_destination_address
|
244
|
+
|
245
|
+
def length
|
246
|
+
128
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# The value of OXM_OF_IPV6_DST
|
251
|
+
class MaskedIpv6DestinationAddress < BinData::Record
|
252
|
+
OXM_FIELD = 27
|
253
|
+
|
254
|
+
endian :big
|
255
|
+
|
256
|
+
ipv6_address :ipv6_destination_address
|
257
|
+
ipv6_address :ipv6_destination_address_mask
|
258
|
+
|
259
|
+
def length
|
260
|
+
256
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
# OXM format
|
265
|
+
class Format < BinData::Record
|
266
|
+
# OXM match field.
|
267
|
+
class MatchField < BinData::Record
|
268
|
+
endian :big
|
269
|
+
|
270
|
+
uint16 :oxm_class, value: OXM_CLASS_OPENFLOW_BASIC
|
271
|
+
bit7 :oxm_field
|
272
|
+
bit1 :oxm_hasmask
|
273
|
+
uint8 :oxm_length, value: -> { tlv_value.length }
|
274
|
+
choice :tlv_value,
|
275
|
+
read_length: :oxm_length,
|
276
|
+
selection: :choose_tlv_value do
|
277
|
+
in_port InPort
|
278
|
+
ether_destination_address EtherDestinationAddress
|
279
|
+
masked_ether_destination_address MaskedEtherDestinationAddress
|
280
|
+
ether_source_address EtherSourceAddress
|
281
|
+
masked_ether_source_address MaskedEtherSourceAddress
|
282
|
+
ether_type EtherType
|
283
|
+
ipv4_source_address Ipv4SourceAddress
|
284
|
+
masked_ipv4_source_address MaskedIpv4SourceAddress
|
285
|
+
ipv4_destination_address Ipv4DestinationAddress
|
286
|
+
masked_ipv4_destination_address MaskedIpv4DestinationAddress
|
287
|
+
ip_protocol IpProtocol
|
288
|
+
tcp_source_port TcpSourcePort
|
289
|
+
tcp_destination_port TcpDestinationPort
|
290
|
+
udp_source_port UdpSourcePort
|
291
|
+
udp_destination_port UdpDestinationPort
|
292
|
+
ipv6_source_address Ipv6SourceAddress
|
293
|
+
masked_ipv6_source_address MaskedIpv6SourceAddress
|
294
|
+
ipv6_destination_address Ipv6DestinationAddress
|
295
|
+
masked_ipv6_destination_address MaskedIpv6DestinationAddress
|
296
|
+
end
|
297
|
+
|
298
|
+
def length
|
299
|
+
tlv_value.length + 4
|
300
|
+
end
|
301
|
+
|
302
|
+
def masked?
|
303
|
+
oxm_hasmask == 1
|
304
|
+
end
|
305
|
+
|
306
|
+
def method_missing(method, *args, &block)
|
307
|
+
tlv_value.__send__ method, *args, &block
|
308
|
+
end
|
309
|
+
|
310
|
+
private
|
311
|
+
|
312
|
+
# rubocop:disable MethodLength
|
313
|
+
# rubocop:disable CyclomaticComplexity
|
314
|
+
# rubocop:disable PerceivedComplexity
|
315
|
+
# rubocop:disable AbcSize
|
316
|
+
def choose_tlv_value
|
317
|
+
case oxm_field
|
318
|
+
when InPort::OXM_FIELD
|
319
|
+
InPort
|
320
|
+
when EtherDestinationAddress::OXM_FIELD
|
321
|
+
masked? ? MaskedEtherDestinationAddress : EtherDestinationAddress
|
322
|
+
when EtherSourceAddress::OXM_FIELD
|
323
|
+
masked? ? MaskedEtherSourceAddress : EtherSourceAddress
|
324
|
+
when EtherType::OXM_FIELD
|
325
|
+
EtherType
|
326
|
+
when Ipv4SourceAddress::OXM_FIELD
|
327
|
+
masked? ? MaskedIpv4SourceAddress : Ipv4SourceAddress
|
328
|
+
when Ipv4DestinationAddress::OXM_FIELD
|
329
|
+
masked? ? MaskedIpv4DestinationAddress : Ipv4DestinationAddress
|
330
|
+
when IpProtocol::OXM_FIELD
|
331
|
+
IpProtocol
|
332
|
+
when TcpSourcePort::OXM_FIELD
|
333
|
+
TcpSourcePort
|
334
|
+
when TcpDestinationPort::OXM_FIELD
|
335
|
+
TcpDestinationPort
|
336
|
+
when UdpSourcePort::OXM_FIELD
|
337
|
+
UdpSourcePort
|
338
|
+
when UdpDestinationPort::OXM_FIELD
|
339
|
+
UdpDestinationPort
|
340
|
+
when Ipv6SourceAddress::OXM_FIELD
|
341
|
+
masked? ? MaskedIpv6SourceAddress : Ipv6SourceAddress
|
342
|
+
when Ipv6DestinationAddress::OXM_FIELD
|
343
|
+
masked? ? MaskedIpv6DestinationAddress : Ipv6DestinationAddress
|
344
|
+
else
|
345
|
+
fail "Unknown OXM field value: #{oxm_field}"
|
346
|
+
end
|
347
|
+
end
|
348
|
+
# rubocop:enable MethodLength
|
349
|
+
# rubocop:enable CyclomaticComplexity
|
350
|
+
# rubocop:enable PerceivedComplexity
|
351
|
+
# rubocop:enable AbcSize
|
352
|
+
end
|
353
|
+
|
354
|
+
endian :big
|
355
|
+
|
356
|
+
uint16 :match_type, value: MATCH_TYPE_OXM
|
357
|
+
uint16 :match_length, initial_value: -> { 4 + tlv_total_length }
|
358
|
+
array(:match_fields,
|
359
|
+
type: :match_field,
|
360
|
+
read_until: -> { tlv_length_left <= 5 },
|
361
|
+
onlyif: -> { match_length > 4 })
|
362
|
+
string :padding, length: :padding_length
|
363
|
+
hide :padding
|
364
|
+
|
365
|
+
def method_missing(method, *args, &block)
|
366
|
+
match_fields.each do |each|
|
367
|
+
next unless each.tlv_value.respond_to?(method)
|
368
|
+
return each.tlv_value.__send__(method, *args, &block)
|
369
|
+
end
|
370
|
+
fail NoMethodError, method.to_s
|
371
|
+
end
|
372
|
+
|
373
|
+
private
|
374
|
+
|
375
|
+
def tlv_length_left
|
376
|
+
match_length - tlv_total_length
|
377
|
+
end
|
378
|
+
|
379
|
+
def tlv_total_length
|
380
|
+
if match_fields.size > 0
|
381
|
+
match_fields.map(&:length).inject(&:+)
|
382
|
+
else
|
383
|
+
0
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
def padding_length
|
388
|
+
(match_length + 7) / 8 * 8 - match_length
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
# Match.new option parser.
|
393
|
+
class Options
|
394
|
+
# rubocop:disable MethodLength
|
395
|
+
# rubocop:disable AbcSize
|
396
|
+
def initialize(user_attrs)
|
397
|
+
@match_fields = []
|
398
|
+
|
399
|
+
[:in_port, :ether_type, :ip_protocol,
|
400
|
+
:tcp_source_port, :tcp_destination_port,
|
401
|
+
:udp_source_port, :udp_destination_port].each do |each|
|
402
|
+
next unless user_attrs.key?(each)
|
403
|
+
klass = Match.const_get(each.to_s.split('_').map(&:capitalize).join)
|
404
|
+
@match_fields << { oxm_field: klass.const_get(:OXM_FIELD),
|
405
|
+
tlv_value: { each => user_attrs.fetch(each) } }
|
406
|
+
end
|
407
|
+
|
408
|
+
[:ether_destination_address, :ether_source_address,
|
409
|
+
:ipv4_source_address, :ipv4_destination_address,
|
410
|
+
:ipv6_source_address, :ipv6_destination_address].each do |each|
|
411
|
+
next unless user_attrs.key?(each)
|
412
|
+
klass = Match.const_get(each.to_s.split('_').map(&:capitalize).join)
|
413
|
+
mask_key = "#{each}_mask".to_sym
|
414
|
+
@match_fields <<
|
415
|
+
{ oxm_field: klass.const_get(:OXM_FIELD),
|
416
|
+
oxm_hasmask: user_attrs.key?(mask_key) ? 1 : 0,
|
417
|
+
tlv_value: { each => user_attrs[each],
|
418
|
+
mask_key => user_attrs[mask_key] } }
|
419
|
+
end
|
420
|
+
end
|
421
|
+
# rubocop:enable MethodLength
|
422
|
+
# rubocop:enable AbcSize
|
423
|
+
|
424
|
+
def to_hash
|
425
|
+
{ match_fields: @match_fields }
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
def self.read(raw_data)
|
430
|
+
allocate.tap do |message|
|
431
|
+
message.instance_variable_set(:@format, Format.read(raw_data))
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
def initialize(user_attrs = {})
|
436
|
+
@format = if user_attrs.empty?
|
437
|
+
Format.new
|
438
|
+
else
|
439
|
+
Format.new(Options.new(user_attrs).to_hash)
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
def length
|
444
|
+
@format.to_binary_s.length
|
445
|
+
end
|
446
|
+
|
447
|
+
def method_missing(method, *args, &block)
|
448
|
+
@format.__send__ method, *args, &block
|
449
|
+
end
|
450
|
+
end
|
451
|
+
end
|
452
|
+
end
|
data/lib/pio/open_flow13.rb
CHANGED
@@ -10,3 +10,10 @@ require 'pio/open_flow13/echo'
|
|
10
10
|
require 'pio/open_flow13/features_reply'
|
11
11
|
require 'pio/open_flow13/features_request'
|
12
12
|
require 'pio/open_flow13/hello'
|
13
|
+
require 'pio/open_flow13/match'
|
14
|
+
|
15
|
+
# Base module.
|
16
|
+
module Pio
|
17
|
+
remove_const :Match
|
18
|
+
Match = OpenFlow13::Match
|
19
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bindata'
|
2
|
+
require 'ipaddr'
|
3
|
+
|
4
|
+
module Pio
|
5
|
+
module Type
|
6
|
+
# IPv6 address
|
7
|
+
class Ipv6Address < BinData::Primitive
|
8
|
+
endian :big
|
9
|
+
|
10
|
+
uint128 :ipv6_address
|
11
|
+
|
12
|
+
def set(value)
|
13
|
+
self.ipv6_address = IPAddr.new(value, Socket::Constants::AF_INET6)
|
14
|
+
end
|
15
|
+
|
16
|
+
def get
|
17
|
+
IPAddr.new(ipv6_address, Socket::Constants::AF_INET6).to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/pio/version.rb
CHANGED
data/pio.gemspec
CHANGED
@@ -31,33 +31,33 @@ Gem::Specification.new do |gem|
|
|
31
31
|
gem.add_dependency 'bindata', '~> 2.1.0'
|
32
32
|
|
33
33
|
gem.add_development_dependency 'rake'
|
34
|
-
gem.add_development_dependency 'bundler', '~> 1.
|
34
|
+
gem.add_development_dependency 'bundler', '~> 1.10.3'
|
35
35
|
gem.add_development_dependency 'pry', '~> 0.10.1'
|
36
36
|
|
37
37
|
# Guard
|
38
|
-
gem.add_development_dependency 'guard', '~> 2.12.
|
38
|
+
gem.add_development_dependency 'guard', '~> 2.12.6'
|
39
39
|
gem.add_development_dependency 'guard-bundler', '~> 2.1.0'
|
40
40
|
gem.add_development_dependency 'guard-cucumber', '~> 1.6.0'
|
41
|
-
gem.add_development_dependency 'guard-rspec', '~> 4.5.
|
41
|
+
gem.add_development_dependency 'guard-rspec', '~> 4.5.2'
|
42
42
|
gem.add_development_dependency 'guard-rubocop', '~> 1.2.0'
|
43
43
|
gem.add_development_dependency 'rb-fchange', '~> 0.0.6'
|
44
|
-
gem.add_development_dependency 'rb-fsevent', '~> 0.9.
|
44
|
+
gem.add_development_dependency 'rb-fsevent', '~> 0.9.5'
|
45
45
|
gem.add_development_dependency 'rb-inotify', '~> 0.9.5'
|
46
46
|
gem.add_development_dependency 'terminal-notifier-guard', '~> 1.6.4'
|
47
47
|
|
48
48
|
# Docs
|
49
|
-
gem.add_development_dependency 'inch', '~> 0.
|
49
|
+
gem.add_development_dependency 'inch', '~> 0.6.2'
|
50
50
|
gem.add_development_dependency 'relish', '~> 0.7.1'
|
51
51
|
gem.add_development_dependency 'yard', '~> 0.8.7.6'
|
52
52
|
|
53
53
|
# Test
|
54
54
|
gem.add_development_dependency 'codeclimate-test-reporter', '~> 0.4.7'
|
55
|
-
gem.add_development_dependency 'coveralls', '~> 0.8.
|
55
|
+
gem.add_development_dependency 'coveralls', '~> 0.8.1'
|
56
56
|
gem.add_development_dependency 'cucumber', '~> 2.0.0'
|
57
57
|
gem.add_development_dependency 'flay', '~> 2.6.1'
|
58
58
|
gem.add_development_dependency 'flog', '~> 4.3.2'
|
59
|
-
gem.add_development_dependency 'reek', '~> 2.1
|
59
|
+
gem.add_development_dependency 'reek', '~> 2.2.1'
|
60
60
|
gem.add_development_dependency 'rspec', '~> 3.2.0'
|
61
61
|
gem.add_development_dependency 'rspec-given', '~> 3.7.0'
|
62
|
-
gem.add_development_dependency 'rubocop', '~> 0.
|
62
|
+
gem.add_development_dependency 'rubocop', '~> 0.32.0'
|
63
63
|
end
|
data/spec/pio/mac_spec.rb
CHANGED
@@ -142,9 +142,9 @@ describe Pio::Mac do
|
|
142
142
|
context 'with reserved address' do
|
143
143
|
(0x0..0xf).each do |each|
|
144
144
|
octet = format('%02x', each)
|
145
|
-
reserved_address = "01:80:c2:00:00:#{
|
145
|
+
reserved_address = "01:80:c2:00:00:#{octet}"
|
146
146
|
|
147
|
-
context "when #{
|
147
|
+
context "when #{reserved_address}" do
|
148
148
|
let(:value) { reserved_address }
|
149
149
|
|
150
150
|
describe '#reserved?' do
|