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.
@@ -1,48 +1,10 @@
1
1
  require 'bindata'
2
2
  require 'forwardable'
3
+ require 'pio/open_flow13/actions'
3
4
 
4
5
  module Pio
5
6
  # An instruction to apply a list of actions to a packet in-order.
6
7
  class Apply
7
- # Actions not yet implemented.
8
- class UnsupportedAction < BinData::Record
9
- endian :big
10
-
11
- uint16 :action_type
12
- uint16 :action_length
13
- end
14
-
15
- # Actions list of actions-apply instruction.
16
- class Actions < BinData::Primitive
17
- mandatory_parameter :length
18
-
19
- endian :big
20
-
21
- string :binary, read_length: :length
22
-
23
- def set(value)
24
- self.binary = [value].flatten.map(&:to_binary).join
25
- end
26
-
27
- # rubocop:disable MethodLength
28
- def get
29
- actions = []
30
- tmp = binary
31
- while tmp.length > 0
32
- action = case BinData::Uint16be.read(tmp)
33
- when 0
34
- SendOutPort.read(tmp)
35
- else
36
- UnsupportedAction.read(tmp)
37
- end
38
- tmp = tmp[action.action_length..-1]
39
- actions << action
40
- end
41
- actions
42
- end
43
- # rubocop:enable MethodLength
44
- end
45
-
46
8
  # OpenFlow 1.3.4 OFPIT_APPLY_ACTIONS instruction format.
47
9
  class Format < BinData::Record
48
10
  endian :big
@@ -0,0 +1,17 @@
1
+ module Pio
2
+ # Buffered packet to apply to, or :no_buffer.
3
+ class BufferId < BinData::Primitive
4
+ NO_BUFFER = 0xffffffff
5
+
6
+ endian :big
7
+ uint32 :buffer_id, initial_value: NO_BUFFER
8
+
9
+ def get
10
+ (buffer_id == NO_BUFFER) ? :no_buffer : buffer_id
11
+ end
12
+
13
+ def set(value)
14
+ self.buffer_id = (value == :no_buffer ? NO_BUFFER : value)
15
+ end
16
+ end
17
+ end
@@ -1,5 +1,6 @@
1
1
  require 'forwardable'
2
2
  require 'pio/open_flow'
3
+ require 'pio/open_flow13/buffer_id'
3
4
  require 'pio/open_flow13/match'
4
5
 
5
6
  # Base module.
@@ -29,22 +30,6 @@ module Pio
29
30
  end
30
31
  end
31
32
 
32
- # Buffered packet to apply to, or :no_buffer.
33
- class BufferId < BinData::Primitive
34
- NO_BUFFER = 0xffffffff
35
-
36
- endian :big
37
- uint32 :buffer_id, initial_value: NO_BUFFER
38
-
39
- def get
40
- (buffer_id == NO_BUFFER) ? :no_buffer : buffer_id
41
- end
42
-
43
- def set(value)
44
- self.buffer_id = (value == :no_buffer ? NO_BUFFER : value)
45
- end
46
- end
47
-
48
33
  # For delete commands, require matching entries to include this as
49
34
  # an output port.
50
35
  class OutPort < BinData::Primitive
@@ -348,6 +348,125 @@ module Pio
348
348
  end
349
349
  end
350
350
 
351
+ # The value of OXM_OF_ARP_OP
352
+ class ArpOp < BinData::Record
353
+ OXM_FIELD = 21
354
+
355
+ endian :big
356
+
357
+ uint16 :arp_op
358
+
359
+ def length
360
+ 2
361
+ end
362
+ end
363
+
364
+ # The value of OXM_OF_ARP_SPA
365
+ class ArpSenderProtocolAddress < BinData::Record
366
+ OXM_FIELD = 22
367
+
368
+ endian :big
369
+
370
+ ip_address :arp_sender_protocol_address
371
+
372
+ def length
373
+ 4
374
+ end
375
+ end
376
+
377
+ # The value of masked OXM_OF_ARP_SPA
378
+ class MaskedArpSenderProtocolAddress < BinData::Record
379
+ OXM_FIELD = 22
380
+
381
+ endian :big
382
+ ip_address :arp_sender_protocol_address
383
+ ip_address :arp_sender_protocol_address_mask
384
+
385
+ def length
386
+ 8
387
+ end
388
+ end
389
+
390
+ # The value of OXM_OF_ARP_TPA
391
+ class ArpTargetProtocolAddress < BinData::Record
392
+ OXM_FIELD = 23
393
+
394
+ endian :big
395
+
396
+ ip_address :arp_target_protocol_address
397
+
398
+ def length
399
+ 4
400
+ end
401
+ end
402
+
403
+ # The value of masked OXM_OF_ARP_TPA
404
+ class MaskedArpTargetProtocolAddress < BinData::Record
405
+ OXM_FIELD = 23
406
+
407
+ endian :big
408
+ ip_address :arp_target_protocol_address
409
+ ip_address :arp_target_protocol_address_mask
410
+
411
+ def length
412
+ 8
413
+ end
414
+ end
415
+
416
+ # The value of OXM_OF_ARP_SHA match field.
417
+ class ArpSenderHardwareAddress < BinData::Record
418
+ OXM_FIELD = 24
419
+
420
+ endian :big
421
+
422
+ mac_address :arp_sender_hardware_address
423
+
424
+ def length
425
+ 6
426
+ end
427
+ end
428
+
429
+ # Masked OXM_OF_ARP_SHA match field.
430
+ class MaskedArpSenderHardwareAddress < BinData::Record
431
+ OXM_FIELD = 24
432
+
433
+ endian :big
434
+
435
+ mac_address :arp_sender_hardware_address
436
+ mac_address :arp_sender_hardware_address_mask
437
+
438
+ def length
439
+ 12
440
+ end
441
+ end
442
+
443
+ # The value of OXM_OF_ARP_THA match field.
444
+ class ArpTargetHardwareAddress < BinData::Record
445
+ OXM_FIELD = 25
446
+
447
+ endian :big
448
+
449
+ mac_address :arp_target_hardware_address
450
+
451
+ def length
452
+ 6
453
+ end
454
+ end
455
+
456
+ # Masked OXM_OF_ARP_THA match field.
457
+ class MaskedArpTargetHardwareAddress < BinData::Record
458
+ OXM_FIELD = 25
459
+
460
+ endian :big
461
+
462
+ mac_address :arp_target_hardware_address
463
+ mac_address :arp_target_hardware_address_mask
464
+
465
+ def length
466
+ 12
467
+ end
468
+ end
469
+
351
470
  # The value of OXM_OF_IPV6_SRC
352
471
  class Ipv6SourceAddress < BinData::Record
353
472
  OXM_FIELD = 26
@@ -402,9 +521,35 @@ module Pio
402
521
  end
403
522
  end
404
523
 
524
+ # The value of OXM_OF_TUNNEL_ID match field
525
+ class TunnelId < BinData::Record
526
+ OXM_FIELD = 38
527
+
528
+ endian :big
529
+
530
+ uint64 :tunnel_id
531
+
532
+ def length
533
+ 8
534
+ end
535
+ end
536
+
537
+ # Masked OXM_OF_TUNNEL_ID match field
538
+ class MaskedTunnelId < BinData::Record
539
+ endian :big
540
+
541
+ uint64 :tunnel_id
542
+ uint64 :tunnel_id_mask
543
+
544
+ def length
545
+ 16
546
+ end
547
+ end
548
+
405
549
  # OXM format
406
550
  class Oxm < BinData::Record
407
551
  # OXM match field.
552
+ # rubocop:disable ClassLength
408
553
  class MatchField < BinData::Record
409
554
  endian :big
410
555
 
@@ -438,12 +583,23 @@ module Pio
438
583
  udp_destination_port UdpDestinationPort
439
584
  sctp_source_port SctpSourcePort
440
585
  sctp_destination_port SctpDestinationPort
586
+ arp_op ArpOp
587
+ arp_sender_protocol_address ArpSenderProtocolAddress
588
+ masked_arp_sender_protocol_address MaskedArpSenderProtocolAddress
589
+ arp_target_protocol_address ArpTargetProtocolAddress
590
+ masked_arp_target_protocol_address MaskedArpTargetProtocolAddress
591
+ arp_sender_hardware_address ArpSenderHardwareAddress
592
+ masked_arp_sender_hardware_address MaskedArpSenderHardwareAddress
593
+ arp_target_hardware_address ArpTargetHardwareAddress
594
+ masked_arp_target_hardware_address MaskedArpTargetHardwareAddress
441
595
  icmpv4_type Icmpv4Type
442
596
  icmpv4_code Icmpv4Code
443
597
  ipv6_source_address Ipv6SourceAddress
444
598
  masked_ipv6_source_address MaskedIpv6SourceAddress
445
599
  ipv6_destination_address Ipv6DestinationAddress
446
600
  masked_ipv6_destination_address MaskedIpv6DestinationAddress
601
+ tunnel_id TunnelId
602
+ masked_tunnel_id MaskedTunnelId
447
603
  end
448
604
 
449
605
  def length
@@ -506,10 +662,42 @@ module Pio
506
662
  Icmpv4Type
507
663
  when Icmpv4Code::OXM_FIELD
508
664
  Icmpv4Code
665
+ when ArpOp::OXM_FIELD
666
+ ArpOp
667
+ when ArpSenderProtocolAddress::OXM_FIELD
668
+ if masked?
669
+ MaskedArpSenderProtocolAddress
670
+ else
671
+ ArpSenderProtocolAddress
672
+ end
673
+ when ArpTargetProtocolAddress::OXM_FIELD
674
+ if masked?
675
+ MaskedArpTargetProtocolAddress
676
+ else
677
+ ArpTargetProtocolAddress
678
+ end
679
+ when ArpSenderHardwareAddress::OXM_FIELD
680
+ if masked?
681
+ MaskedArpSenderHardwareAddress
682
+ else
683
+ ArpSenderHardwareAddress
684
+ end
685
+ when ArpTargetHardwareAddress::OXM_FIELD
686
+ if masked?
687
+ MaskedArpTargetHardwareAddress
688
+ else
689
+ ArpTargetHardwareAddress
690
+ end
509
691
  when Ipv6SourceAddress::OXM_FIELD
510
- masked? ? MaskedIpv6SourceAddress : Ipv6SourceAddress
692
+ if masked?
693
+ MaskedIpv6SourceAddress
694
+ else
695
+ Ipv6SourceAddress
696
+ end
511
697
  when Ipv6DestinationAddress::OXM_FIELD
512
698
  masked? ? MaskedIpv6DestinationAddress : Ipv6DestinationAddress
699
+ when TunnelId::OXM_FIELD
700
+ masked? ? MaskedTunnelId : TunnelId
513
701
  else
514
702
  fail "Unknown OXM field value: #{oxm_field}"
515
703
  end
@@ -519,6 +707,7 @@ module Pio
519
707
  # rubocop:enable PerceivedComplexity
520
708
  # rubocop:enable AbcSize
521
709
  end
710
+ # rubocop:enable MethodLength
522
711
 
523
712
  endian :big
524
713
 
@@ -571,8 +760,9 @@ module Pio
571
760
 
572
761
  [:in_port, :ether_type, :ip_protocol, :vlan_vid, :vlan_pcp,
573
762
  :ip_dscp, :ip_ecn, :tcp_source_port, :tcp_destination_port,
574
- :udp_source_port, :udp_destination_port, :sctp_source_port,
575
- :sctp_destination_port, :icmpv4_type, :icmpv4_code].each do |each|
763
+ :udp_source_port, :udp_destination_port,
764
+ :sctp_source_port, :sctp_destination_port,
765
+ :icmpv4_type, :icmpv4_code, :arp_op].each do |each|
576
766
  next unless user_attrs.key?(each)
577
767
  klass = Match.const_get(each.to_s.split('_').map(&:capitalize).join)
578
768
  @match_fields << { oxm_field: klass.const_get(:OXM_FIELD),
@@ -581,7 +771,10 @@ module Pio
581
771
 
582
772
  [:metadata, :ether_destination_address, :ether_source_address,
583
773
  :ipv4_source_address, :ipv4_destination_address,
584
- :ipv6_source_address, :ipv6_destination_address].each do |each|
774
+ :arp_sender_protocol_address, :arp_target_protocol_address,
775
+ :arp_sender_hardware_address, :arp_target_hardware_address,
776
+ :ipv6_source_address, :ipv6_destination_address,
777
+ :tunnel_id].each do |each|
585
778
  next unless user_attrs.key?(each)
586
779
  klass = Match.const_get(each.to_s.split('_').map(&:capitalize).join)
587
780
  mask_key = "#{each}_mask".to_sym
@@ -0,0 +1,90 @@
1
+ require 'bindata'
2
+ require 'pio/open_flow13/actions'
3
+ require 'pio/open_flow13/buffer_id'
4
+
5
+ # Base module.
6
+ module Pio
7
+ remove_const :PacketOut
8
+
9
+ # OpenFlow 1.3 PacketOut message parser and generator
10
+ class PacketOut
11
+ # Packet's input port or :controller
12
+ class InPort < BinData::Primitive
13
+ CONTROLLER = 0xfffffffd
14
+
15
+ endian :big
16
+ uint32 :in_port
17
+
18
+ def get
19
+ (in_port == CONTROLLER) ? :controller : in_port
20
+ end
21
+
22
+ def set(value)
23
+ self.in_port = (value == :controller ? NO_CONTROLLER : value)
24
+ end
25
+ end
26
+
27
+ # OpenFlow 1.3 PacketOut message body
28
+ class Body < BinData::Record
29
+ endian :big
30
+
31
+ buffer_id :buffer_id
32
+ in_port :in_port
33
+ uint16 :actions_length, initial_value: -> { actions.binary.length }
34
+ string :padding, length: 6
35
+ actions :actions, length: :actions_length
36
+ string :raw_data, read_length: -> { message_length - 24 - actions_length }
37
+
38
+ def length
39
+ 10 + padding.length + actions_length + raw_data.length
40
+ end
41
+
42
+ def data
43
+ @data ||= Pio::Parser.read(raw_data)
44
+ end
45
+
46
+ def method_missing(method, *args)
47
+ data.__send__(method, *args).snapshot
48
+ end
49
+ end
50
+
51
+ # OpenFlow 1.3 PacketOut message body
52
+ class Format < BinData::Record
53
+ extend Forwardable
54
+
55
+ endian :big
56
+
57
+ open_flow_header :open_flow_header,
58
+ ofp_version_value: 4, message_type_value: 13
59
+ body :body
60
+
61
+ def_delegators :open_flow_header, :ofp_version
62
+ def_delegators :open_flow_header, :message_type
63
+ def_delegators :open_flow_header, :message_length
64
+ def_delegators :open_flow_header, :transaction_id
65
+ def_delegator :open_flow_header, :transaction_id, :xid
66
+
67
+ def method_missing(method, *args, &block)
68
+ body.__send__ method, *args, &block
69
+ end
70
+ end
71
+
72
+ def self.read(raw_data)
73
+ allocate.tap do |message|
74
+ message.instance_variable_set(:@format, Format.read(raw_data))
75
+ end
76
+ end
77
+
78
+ def initialize(user_attrs = {})
79
+ header_attrs = OpenFlowHeader::Options.parse(user_attrs)
80
+ body_attrs = { actions: user_attrs[:actions],
81
+ raw_data: user_attrs[:raw_data] }
82
+ @format = Format.new(open_flow_header: header_attrs,
83
+ body: body_attrs)
84
+ end
85
+
86
+ def method_missing(method, *args, &block)
87
+ @format.__send__ method, *args, &block
88
+ end
89
+ end
90
+ end