pio 0.22.0 → 0.23.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 06006d882906e150385cbe2e7932eb0d741277ee
4
- data.tar.gz: 8b4f1fefee8d39a6e1ce9d173ace7284d5535d9f
3
+ metadata.gz: 964cf85acbc8d40d637ae0ade92ba7902871f763
4
+ data.tar.gz: 8b2030596db8463f4e96c58130c7f95789d518d1
5
5
  SHA512:
6
- metadata.gz: 0e70773ffec96c1647cccc8b2a93b262f9655e3c3294e1ca6ee911385279a2fdb293357402eb5abb7f25e462785499b775cb82424fa4bb32859f71a257273aaf
7
- data.tar.gz: d3c9c2353d742e752924726a77f9f91ab24c1dfdfe5870b651409c1b990eb75723ace6a39289316032571407a4edaca75c8ecfe6bd38ce3cb6c5e6b1f8833af1
6
+ metadata.gz: 256528fa1737e893e938f12f332e5e5e485e86b11dfdea88fb103ff646d83ad1e0a3c6e0526c22edcef3c06c47a08494ad7fd1a0291d43ee45a24ccf2489f8e4
7
+ data.tar.gz: 0ef1cd6a8a24b77b854f21c79362418db441ccd953e0e664eb09d1a69d901bbbabca6e9580e35ed8c680dfcf8a5a4a209f3c02b71cdfa660e43880aea72a1909
data/CHANGELOG.md CHANGED
@@ -3,6 +3,13 @@
3
3
  ## develop (unreleased)
4
4
 
5
5
 
6
+ ## 0.23.0 (6/29/2015)
7
+ ### New features
8
+ * [#183](https://github.com/trema/pio/pull/183): Add new class `Pio::PacketIn` (OpenFlow1.3).
9
+ * [#185](https://github.com/trema/pio/pull/185): Add new classes `Pio::Match::TunnelId` and `Pio::Match::MaskedTunnelId`
10
+ * [#184](https://github.com/trema/pio/pull/184): Add new classes `Pio::Match::ArpOp`, `Pio::Match::ArpSenderProtocolAddress`, `Pio::Match::ArpTargetProtocolAddress`, `Pio::Match::ArpSenderHardwareAddress`, `Pio::Match::ArpTargetHardwareAddress`, `Pio::Match::MaskedArpSenderProtocolAddress`,`Pio::Match::MaskedArpTargetProtocolAddress`, `Pio::Match::MaskedArpSenderHardwareAddress` and `Pio::Match::MaskedArpTargetHardwareAddress`
11
+
12
+
6
13
  ## 0.22.0 (6/25/2015)
7
14
  ### New features
8
15
  * [#177](https://github.com/trema/pio/pull/177): Add new class `Pio::PacketIn` (OpenFlow1.3).
data/README.md CHANGED
@@ -36,6 +36,7 @@ supports the following packet formats:
36
36
  - [Features Request](https://relishapp.com/trema/pio/docs/open-flow13/pio-features-request)
37
37
  - [Features Reply](https://relishapp.com/trema/pio/docs/open-flow13/pio-features-reply)
38
38
  - [Packet In](https://relishapp.com/trema/pio/docs/open-flow13/pio-packetin)
39
+ - [Packet Out](https://relishapp.com/trema/pio/docs/open-flow13/pio-packetout)
39
40
  - [Flow Mod](https://relishapp.com/trema/pio/docs/open-flow13/pio-flowmod)
40
41
 
41
42
  ## Features Overview
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'bundler/gem_tasks'
2
2
 
3
3
  RELISH_PROJECT = 'trema/pio'
4
- FLAY_THRESHOLD = 398
4
+ FLAY_THRESHOLD = 452
5
5
 
6
6
  task default: :travis
7
7
  task test: [:spec, :cucumber]
@@ -280,6 +280,109 @@ Feature: Pio::Match
280
280
  | ip_protocol | 1 |
281
281
  | icmpv4_code | 0 |
282
282
 
283
+ Scenario: new(eth_type: 2054, arp_op: 1)
284
+ When I try to create an OpenFlow message with:
285
+ """
286
+ Pio::Match.new(ether_type: 2054, arp_op: 1)
287
+ """
288
+ Then it should finish successfully
289
+ And the message have the following fields and values:
290
+ | field | value |
291
+ | ether_type | 2054 |
292
+ | arp_op | 1 |
293
+
294
+ Scenario: new(eth_type: 2054, arp_sender_protocol_address: '1.2.3.4')
295
+ When I try to create an OpenFlow message with:
296
+ """
297
+ Pio::Match.new(ether_type: 2054, arp_sender_protocol_address: '1.2.3.4')
298
+ """
299
+ Then it should finish successfully
300
+ And the message have the following fields and values:
301
+ | field | value |
302
+ | ether_type | 2054 |
303
+ | arp_sender_protocol_address | 1.2.3.4 |
304
+
305
+ Scenario: new(eth_type: 2054, arp_sender_protocol_address: '1.2.3.4', arp_sender_protocol_address_mask: '255.255.0.0')
306
+ When I try to create an OpenFlow message with:
307
+ """
308
+ Pio::Match.new(ether_type: 2054, arp_sender_protocol_address: '1.2.3.4', arp_sender_protocol_address_mask: '255.255.0.0')
309
+ """
310
+ Then it should finish successfully
311
+ And the message have the following fields and values:
312
+ | field | value |
313
+ | ether_type | 2054 |
314
+ | arp_sender_protocol_address | 1.2.3.4 |
315
+ | arp_sender_protocol_address_mask | 255.255.0.0 |
316
+
317
+ Scenario: new(eth_type: 2054, arp_target_protocol_address: '1.2.3.4')
318
+ When I try to create an OpenFlow message with:
319
+ """
320
+ Pio::Match.new(ether_type: 2054, arp_target_protocol_address: '1.2.3.4')
321
+ """
322
+ Then it should finish successfully
323
+ And the message have the following fields and values:
324
+ | field | value |
325
+ | ether_type | 2054 |
326
+ | arp_target_protocol_address | 1.2.3.4 |
327
+
328
+ Scenario: new(eth_type: 2054, arp_target_protocol_address: '1.2.3.4', arp_target_protocol_address_mask: '255.255.0.0')
329
+ When I try to create an OpenFlow message with:
330
+ """
331
+ Pio::Match.new(ether_type: 2054, arp_target_protocol_address: '1.2.3.4', arp_target_protocol_address_mask: '255.255.0.0')
332
+ """
333
+ Then it should finish successfully
334
+ And the message have the following fields and values:
335
+ | field | value |
336
+ | ether_type | 2054 |
337
+ | arp_target_protocol_address | 1.2.3.4 |
338
+ | arp_target_protocol_address_mask | 255.255.0.0 |
339
+
340
+ Scenario: new(eth_type: 2054, arp_sender_hardware_address: '11:22:33:44:55:66')
341
+ When I try to create an OpenFlow message with:
342
+ """
343
+ Pio::Match.new(ether_type: 2054, arp_sender_hardware_address: '11:22:33:44:55:66')
344
+ """
345
+ Then it should finish successfully
346
+ And the message have the following fields and values:
347
+ | field | value |
348
+ | ether_type | 2054 |
349
+ | arp_sender_hardware_address | 11:22:33:44:55:66 |
350
+
351
+ Scenario: new(eth_type: 2054, arp_sender_hardware_address: '11:22:33:44:55:66', arp_sender_hardware_address_mask: 'ff:ff:ff:00:00:00')
352
+ When I try to create an OpenFlow message with:
353
+ """
354
+ Pio::Match.new(ether_type: 2054, arp_sender_hardware_address: '11:22:33:44:55:66', arp_sender_hardware_address_mask: 'ff:ff:ff:00:00:00')
355
+ """
356
+ Then it should finish successfully
357
+ And the message have the following fields and values:
358
+ | field | value |
359
+ | ether_type | 2054 |
360
+ | arp_sender_hardware_address | 11:22:33:44:55:66 |
361
+ | arp_sender_hardware_address_mask | ff:ff:ff:00:00:00 |
362
+
363
+ Scenario: new(eth_type: 2054, arp_target_hardware_address: '11:22:33:44:55:66')
364
+ When I try to create an OpenFlow message with:
365
+ """
366
+ Pio::Match.new(ether_type: 2054, arp_target_hardware_address: '11:22:33:44:55:66')
367
+ """
368
+ Then it should finish successfully
369
+ And the message have the following fields and values:
370
+ | field | value |
371
+ | ether_type | 2054 |
372
+ | arp_target_hardware_address | 11:22:33:44:55:66 |
373
+
374
+ Scenario: new(eth_type: 2054, arp_target_hardware_address: '11:22:33:44:55:66', arp_target_hardware_address_mask: 'ff:ff:ff:00:00:00')
375
+ When I try to create an OpenFlow message with:
376
+ """
377
+ Pio::Match.new(ether_type: 2054, arp_target_hardware_address: '11:22:33:44:55:66', arp_target_hardware_address_mask: 'ff:ff:ff:00:00:00')
378
+ """
379
+ Then it should finish successfully
380
+ And the message have the following fields and values:
381
+ | field | value |
382
+ | ether_type | 2054 |
383
+ | arp_target_hardware_address | 11:22:33:44:55:66 |
384
+ | arp_target_hardware_address_mask | ff:ff:ff:00:00:00 |
385
+
283
386
  Scenario: new(ether_type: 0x86dd, ipv6_source_address: '2001:db8:bd05:1d2:288a:1fc0:1:10ee')
284
387
  When I try to create an OpenFlow message with:
285
388
  """
@@ -326,6 +429,27 @@ Feature: Pio::Match
326
429
  | ipv6_destination_address | 2001:db8:bd05:1d2:288a:1fc0:1:10ee |
327
430
  | ipv6_destination_address_mask | ffff:ffff:ffff:ffff:: |
328
431
 
432
+ Scenario: new(tunnel_id: 1)
433
+ When I try to create an OpenFlow message with:
434
+ """
435
+ Pio::Match.new(tunnel_id: 1)
436
+ """
437
+ Then it should finish successfully
438
+ And the message have the following fields and values:
439
+ | field | value |
440
+ | tunnel_id | 1 |
441
+
442
+ Scenario: new(tunnel_id: 1, tunnel_id_mask: 9223372036854775808)
443
+ When I try to create an OpenFlow message with:
444
+ """
445
+ Pio::Match.new(tunnel_id: 1, tunnel_id_mask: 9223372036854775808)
446
+ """
447
+ Then it should finish successfully
448
+ And the message have the following fields and values:
449
+ | field | value |
450
+ | tunnel_id | 1 |
451
+ | tunnel_id_mask | 9223372036854775808 |
452
+
329
453
  Scenario: read (file: open_flow13/oxm_no_fields.raw)
330
454
  When I try to parse a file named "open_flow13/oxm_no_fields.raw" with "Pio::Match" class
331
455
  Then it should finish successfully
@@ -529,6 +653,82 @@ Feature: Pio::Match
529
653
  | ip_protocol | 1 |
530
654
  | icmpv4_code | 0 |
531
655
 
656
+ Scenario: read (file: open_flow13/oxm_arp_op_field.raw)
657
+ When I try to parse a file named "open_flow13/oxm_arp_op_field.raw" with "Pio::Match" class
658
+ Then it should finish successfully
659
+ And the message have the following fields and values:
660
+ | field | value |
661
+ | ether_type | 2054 |
662
+ | arp_op | 1 |
663
+
664
+ Scenario: read (file: open_flow13/oxm_arp_spa_field.raw)
665
+ When I try to parse a file named "open_flow13/oxm_arp_spa_field.raw" with "Pio::Match" class
666
+ Then it should finish successfully
667
+ And the message have the following fields and values:
668
+ | field | value |
669
+ | ether_type | 2054 |
670
+ | arp_sender_protocol_address | 1.2.3.4 |
671
+
672
+ Scenario: read (file: open_flow13/oxm_masked_arp_spa_field.raw)
673
+ When I try to parse a file named "open_flow13/oxm_masked_arp_spa_field.raw" with "Pio::Match" class
674
+ Then it should finish successfully
675
+ And the message have the following fields and values:
676
+ | field | value |
677
+ | ether_type | 2054 |
678
+ | arp_sender_protocol_address | 1.2.3.4 |
679
+ | arp_sender_protocol_address_mask | 255.255.0.0 |
680
+
681
+ Scenario: read (file: open_flow13/oxm_arp_tpa_field.raw)
682
+ When I try to parse a file named "open_flow13/oxm_arp_tpa_field.raw" with "Pio::Match" class
683
+ Then it should finish successfully
684
+ And the message have the following fields and values:
685
+ | field | value |
686
+ | ether_type | 2054 |
687
+ | arp_target_protocol_address | 1.2.3.4 |
688
+
689
+ Scenario: read (file: open_flow13/oxm_masked_arp_tpa_field.raw)
690
+ When I try to parse a file named "open_flow13/oxm_masked_arp_tpa_field.raw" with "Pio::Match" class
691
+ Then it should finish successfully
692
+ And the message have the following fields and values:
693
+ | field | value |
694
+ | ether_type | 2054 |
695
+ | arp_target_protocol_address | 1.2.3.4 |
696
+ | arp_target_protocol_address_mask | 255.255.0.0 |
697
+
698
+ Scenario: read (file: open_flow13/oxm_arp_sha_field.raw)
699
+ When I try to parse a file named "open_flow13/oxm_arp_sha_field.raw" with "Pio::Match" class
700
+ Then it should finish successfully
701
+ And the message have the following fields and values:
702
+ | field | value |
703
+ | ether_type | 2054 |
704
+ | arp_sender_hardware_address | 11:22:33:44:55:66 |
705
+
706
+ Scenario: read (file: open_flow13/oxm_masked_arp_sha_field.raw)
707
+ When I try to parse a file named "open_flow13/oxm_masked_arp_sha_field.raw" with "Pio::Match" class
708
+ Then it should finish successfully
709
+ And the message have the following fields and values:
710
+ | field | value |
711
+ | ether_type | 2054 |
712
+ | arp_sender_hardware_address | 11:22:33:44:55:66 |
713
+ | arp_sender_hardware_address_mask | ff:ff:ff:ff:ff:ff |
714
+
715
+ Scenario: read (file: open_flow13/oxm_arp_tha_field.raw)
716
+ When I try to parse a file named "open_flow13/oxm_arp_tha_field.raw" with "Pio::Match" class
717
+ Then it should finish successfully
718
+ And the message have the following fields and values:
719
+ | field | value |
720
+ | ether_type | 2054 |
721
+ | arp_target_hardware_address | 11:22:33:44:55:66 |
722
+
723
+ Scenario: read (file: open_flow13/oxm_masked_arp_tha_field.raw)
724
+ When I try to parse a file named "open_flow13/oxm_masked_arp_tha_field.raw" with "Pio::Match" class
725
+ Then it should finish successfully
726
+ And the message have the following fields and values:
727
+ | field | value |
728
+ | ether_type | 2054 |
729
+ | arp_target_hardware_address | 11:22:33:44:55:66 |
730
+ | arp_target_hardware_address_mask | ff:ff:ff:ff:ff:ff |
731
+
532
732
  Scenario: read (file: open_flow13/oxm_ipv6_source_field.raw)
533
733
  When I try to parse a file named "open_flow13/oxm_ipv6_source_field.raw" with "Pio::Match" class
534
734
  Then it should finish successfully
@@ -562,3 +762,18 @@ Feature: Pio::Match
562
762
  | ether_type | 34525 |
563
763
  | ipv6_destination_address | 2001:db8:bd05:1d2:288a:1fc0:1:10ee |
564
764
  | ipv6_destination_address_mask | ffff:ffff:ffff:ffff:: |
765
+
766
+ Scenario: read (file: open_flow13/oxm_tunnel_id_field.raw)
767
+ When I try to parse a file named "open_flow13/oxm_tunnel_id_field.raw" with "Pio::Match" class
768
+ Then it should finish successfully
769
+ And the message have the following fields and values:
770
+ | field | value |
771
+ | tunnel_id | 1 |
772
+
773
+ Scenario: read (file: open_flow13/oxm_masked_tunnel_id_field.raw)
774
+ When I try to parse a file named "open_flow13/oxm_masked_tunnel_id_field.raw" with "Pio::Match" class
775
+ Then it should finish successfully
776
+ And the message have the following fields and values:
777
+ | field | value |
778
+ | tunnel_id | 1 |
779
+ | tunnel_id_mask | 9223372036854775808 |
@@ -0,0 +1,96 @@
1
+ Feature: Pio::PacketOut
2
+ Background:
3
+ Given I use OpenFlow 1.3
4
+
5
+ Scenario: new
6
+ When I try to create an OpenFlow message with:
7
+ """
8
+ Pio::PacketOut.new
9
+ """
10
+ Then it should finish successfully
11
+ And the message have the following fields and values:
12
+ | field | value |
13
+ | class | Pio::PacketOut |
14
+ | ofp_version | 4 |
15
+ | message_type | 13 |
16
+ | message_length | 24 |
17
+ | transaction_id | 0 |
18
+ | xid | 0 |
19
+ | buffer_id | :no_buffer |
20
+ | in_port | 0 |
21
+ | actions_length | 0 |
22
+ | raw_data.length | 0 |
23
+
24
+ Scenario: new (actions = SendOutPort(1), raw_data = ARP Request)
25
+ When I try to create an OpenFlow message with:
26
+ """
27
+ data_dump = [
28
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xac, 0x5d, 0x10, 0x31, 0x37,
29
+ 0x79, 0x08, 0x06, 0x00, 0x01, 0x08, 0x00, 0x06, 0x04, 0x00, 0x01,
30
+ 0xac, 0x5d, 0x10, 0x31, 0x37, 0x79, 0xc0, 0xa8, 0x02, 0xfe, 0xff,
31
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0xa8, 0x02, 0x05, 0x00, 0x00,
32
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33
+ 0x00, 0x00, 0x00, 0x00, 0x00
34
+ ].pack('C*')
35
+
36
+ Pio::PacketOut.new(raw_data: data_dump, actions: Pio::SendOutPort.new(1))
37
+ """
38
+ Then it should finish successfully
39
+ And the message have the following fields and values:
40
+ | field | value |
41
+ | class | Pio::PacketOut |
42
+ | ofp_version | 4 |
43
+ | message_type | 13 |
44
+ | message_length | 100 |
45
+ | transaction_id | 0 |
46
+ | xid | 0 |
47
+ | buffer_id | :no_buffer |
48
+ | in_port | 0 |
49
+ | actions_length | 16 |
50
+ | raw_data.length | 60 |
51
+ | data.class | Pio::Arp::Request |
52
+ | destination_mac | ff:ff:ff:ff:ff:ff |
53
+ | source_mac | ac:5d:10:31:37:79 |
54
+ | ether_type | 2054 |
55
+ | hardware_type | 1 |
56
+ | protocol_type | 2048 |
57
+ | hardware_length | 6 |
58
+ | protocol_length | 4 |
59
+ | operation | 1 |
60
+ | sender_hardware_address | ac:5d:10:31:37:79 |
61
+ | sender_protocol_address | 192.168.2.254 |
62
+ | target_hardware_address | ff:ff:ff:ff:ff:ff |
63
+ | target_protocol_address | 192.168.2.5 |
64
+
65
+ Scenario: read
66
+ When I try to parse a file named "open_flow13/packet_out.raw" with "PacketOut" class
67
+ Then it should finish successfully
68
+ And the message have the following fields and values:
69
+ | field | value |
70
+ | class | Pio::PacketOut |
71
+ | ofp_version | 4 |
72
+ | message_type | 13 |
73
+ | message_length | 100 |
74
+ | transaction_id | 123 |
75
+ | xid | 123 |
76
+ | buffer_id | :no_buffer |
77
+ | in_port | :controller |
78
+ | actions_length | 16 |
79
+ | actions.first.class | Pio::SendOutPort |
80
+ | actions.first.port | 1 |
81
+ | actions.first.max_length | :no_buffer |
82
+ | raw_data.length | 60 |
83
+ | data.class | Pio::Arp::Request |
84
+ | destination_mac | ff:ff:ff:ff:ff:ff |
85
+ | source_mac | ac:5d:10:31:37:79 |
86
+ | ether_type | 2054 |
87
+ | hardware_type | 1 |
88
+ | protocol_type | 2048 |
89
+ | hardware_length | 6 |
90
+ | protocol_length | 4 |
91
+ | operation | 1 |
92
+ | sender_hardware_address | ac:5d:10:31:37:79 |
93
+ | sender_protocol_address | 192.168.2.254 |
94
+ | target_hardware_address | ff:ff:ff:ff:ff:ff |
95
+ | target_protocol_address | 192.168.2.5 |
96
+
@@ -16,6 +16,7 @@ require 'pio/open_flow13/hello'
16
16
  require 'pio/open_flow13/match'
17
17
  require 'pio/open_flow13/meter'
18
18
  require 'pio/open_flow13/packet_in'
19
+ require 'pio/open_flow13/packet_out'
19
20
  require 'pio/open_flow13/send_out_port'
20
21
  require 'pio/open_flow13/write_metadata'
21
22
 
@@ -0,0 +1,42 @@
1
+ require 'bindata'
2
+
3
+ module Pio
4
+ # Actions not yet implemented.
5
+ class UnsupportedAction < BinData::Record
6
+ endian :big
7
+
8
+ uint16 :action_type
9
+ uint16 :action_length
10
+ end
11
+
12
+ # Actions list of actions-apply instruction.
13
+ class Actions < BinData::Primitive
14
+ mandatory_parameter :length
15
+
16
+ endian :big
17
+
18
+ string :binary, read_length: :length
19
+
20
+ def set(value)
21
+ self.binary = [value].flatten.map(&:to_binary).join
22
+ end
23
+
24
+ # rubocop:disable MethodLength
25
+ def get
26
+ actions = []
27
+ tmp = binary
28
+ while tmp.length > 0
29
+ action = case BinData::Uint16be.read(tmp)
30
+ when 0
31
+ SendOutPort.read(tmp)
32
+ else
33
+ UnsupportedAction.read(tmp)
34
+ end
35
+ tmp = tmp[action.action_length..-1]
36
+ actions << action
37
+ end
38
+ actions
39
+ end
40
+ # rubocop:enable MethodLength
41
+ end
42
+ end