pio 0.22.0 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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