diff --git a/lib/openflow/actions/nx_conjunction.ex b/lib/openflow/actions/nx_conjunction.ex index 5aa65cf..4e073b6 100644 --- a/lib/openflow/actions/nx_conjunction.ex +++ b/lib/openflow/actions/nx_conjunction.ex @@ -13,11 +13,15 @@ defmodule Openflow.Action.NxConjunction do @spec new(Keyword.t()) :: %NxConjunction{} def new(options) do + clause = (options[:clause] || 0) + 1 n_clauses = options[:n_clauses] || raise "n_clauses must be specified" n_clauses >= 2 || raise "n_clauses must be greater than 1" + (1 <= clause and clause <= n_clauses and 2 <= n_clauses and n_clauses <= 64) || + raise "conjunction(id, k/n) must satisfy 1 <= k <= n and 2 <= n <= 64" + %NxConjunction{ - clause: (options[:clause] || 0) + 1, + clause: clause, n_clauses: n_clauses, id: options[:id] || 0 } diff --git a/lib/openflow/echo.ex b/lib/openflow/echo.ex deleted file mode 100644 index d0cea11..0000000 --- a/lib/openflow/echo.ex +++ /dev/null @@ -1,2 +0,0 @@ -defmodule Openflow.Echo do -end diff --git a/lib/openflow/echo/reply.ex b/lib/openflow/echo/reply.ex index 9b0b2d8..f78013a 100644 --- a/lib/openflow/echo/reply.ex +++ b/lib/openflow/echo/reply.ex @@ -11,8 +11,18 @@ defmodule Openflow.Echo.Reply do alias __MODULE__ + @type t :: %Reply{ + version: 4, + xid: 0..0xFFFFFFFF, + data: String.t(), + datapath_id: String.t() | nil, + aux_id: 0..0xFFFF | nil + } + + @spec ofp_type :: 3 def ofp_type, do: 3 + @spec new(xid: 0..0xFFFFFFFF, data: String.t()) :: t() def new(options) when is_list(options) do %Reply{ xid: options[:xid] || 0, @@ -20,15 +30,15 @@ defmodule Openflow.Echo.Reply do } end - def new(data) when is_binary(data) do - %Reply{data: data} - end + @spec new(String.t()) :: t() + def new(data) when is_binary(data), do: %Reply{data: data} - def read(data) do - %Reply{data: data} - end + @spec new() :: t() + def new, do: new([]) - def to_binary(%Reply{data: data}) do - data - end + @spec read(String.t()) :: t() + def read(data), do: %Reply{data: data} + + @spec to_binary(t()) :: String.t() + def to_binary(%Reply{data: data}), do: data end diff --git a/lib/openflow/echo/request.ex b/lib/openflow/echo/request.ex index a1684d6..a433f4f 100644 --- a/lib/openflow/echo/request.ex +++ b/lib/openflow/echo/request.ex @@ -11,8 +11,18 @@ defmodule Openflow.Echo.Request do alias __MODULE__ + @type t :: %Request{ + version: 4, + xid: 0..0xFFFFFFFF, + data: String.t(), + datapath_id: String.t() | nil, + aux_id: 0..0xFFFF | nil + } + + @spec ofp_type :: 2 def ofp_type, do: 2 + @spec new(xid: 0..0xFFFFFFFF, data: String.t()) :: t() def new(options) when is_list(options) do %Request{ xid: options[:xid] || 0, @@ -20,15 +30,15 @@ defmodule Openflow.Echo.Request do } end - def new(data) when is_binary(data) do - %Request{data: data} - end + @spec new(String.t()) :: t() + def new(data) when is_binary(data), do: %Request{data: data} - def read(data) do - %Request{data: data} - end + @spec new() :: t() + def new, do: new([]) - def to_binary(%Request{data: data}) do - data - end + @spec read(String.t()) :: t() + def read(data), do: %Request{data: data} + + @spec to_binary(t()) :: String.t() + def to_binary(%Request{data: data}), do: data end diff --git a/lib/openflow/enum_gen.ex b/lib/openflow/enum_gen.ex deleted file mode 100644 index afeeb11..0000000 --- a/lib/openflow/enum_gen.ex +++ /dev/null @@ -1,1147 +0,0 @@ -defmodule Openflow.EnumGen do - import Bitwise - - @enums [ - openflow_codec: [ - {Openflow.Hello, 0}, - {Openflow.ErrorMsg, 1}, - {Openflow.Echo.Request, 2}, - {Openflow.Echo.Reply, 3}, - {Openflow.Experimenter, 4}, - {Openflow.Features.Request, 5}, - {Openflow.Features.Reply, 6}, - {Openflow.GetConfig.Request, 7}, - {Openflow.GetConfig.Reply, 8}, - {Openflow.SetConfig, 9}, - {Openflow.PacketIn, 10}, - {Openflow.FlowRemoved, 11}, - {Openflow.PortStatus, 12}, - {Openflow.PacketOut, 13}, - {Openflow.FlowMod, 14}, - {Openflow.GroupMod, 15}, - {Openflow.PortMod, 16}, - {Openflow.TableMod, 17}, - {Openflow.Multipart.Request, 18}, - {Openflow.Multipart.Reply, 19}, - {Openflow.Barrier.Request, 20}, - {Openflow.Barrier.Reply, 21}, - {Openflow.Role.Request, 24}, - {Openflow.Role.Reply, 25}, - {Openflow.GetAsync.Request, 26}, - {Openflow.GetAsync.Reply, 27}, - {Openflow.SetAsync, 28}, - {Openflow.MeterMod, 29} - ], - experimenter_id: [ - nicira_ext_message: 0x00002320, - onf_ext_message: 0x4F4E4600 - ], - nicira_ext_message: [ - # {Openflow.NxRole.Request, 10}, /* Openflow 1.3 support role request/reply */ - # {Openflow.NxRole.Reply, 11}, - # {Openflow.NxSetFlowFormat, 12}, /* No special reason for implement this struct codec. */ - # {Openflow.NxFlowMod, 13}, /* Prefer use ofp_flow_mod to nx_flow_mod */ - # {Openflow.NxFlowRemoved, 14}, /* Prefer use ofp_flow_removed to nx_flow_removed */ - # {Openflow.NxSetFlowModTableId, 15}, /* OpenFlow 1.3 support multiple flow table. */ - {Openflow.NxSetPacketInFormat, 16}, - # {Openflow.NxPacketIn, 17}, /* No special reason for implement this struct codec. */ - # {Openflow.NxFlowAge, 18}, /* No special reason for implement this struct codec. */ - # {Openflow.NxSetAsyncConfig, 19}, /* Openflow 1.3 support async config. */ - {Openflow.NxSetControllerId, 20}, - {Openflow.NxFlowMonitor.Cancel, 21}, - {Openflow.NxFlowMonitor.Paused, 22}, - {Openflow.NxFlowMonitor.Resumed, 23}, - {Openflow.NxTLVTableMod, 24}, - {Openflow.NxTLVTable.Request, 25}, - {Openflow.NxTLVTable.Reply, 26}, - {Openflow.NxSetAsyncConfig2, 27}, - {Openflow.NxResume, 28}, - {Openflow.NxCtFlushZone, 29}, - {Openflow.NxPacketIn2, 30} - ], - onf_ext_message: [ - {Openflow.OnfBundleControl, 2300}, - {Openflow.OnfBundleAddMessage, 2301} - ], - multipart_request_flags: [ - more: 1 <<< 0 - ], - multipart_reply_flags: [ - more: 1 <<< 0 - ], - multipart_request_codec: [ - {Openflow.Multipart.Desc.Request, 0}, - {Openflow.Multipart.Flow.Request, 1}, - {Openflow.Multipart.Aggregate.Request, 2}, - {Openflow.Multipart.Table.Request, 3}, - {Openflow.Multipart.PortStats.Request, 4}, - {Openflow.Multipart.Queue.Request, 5}, - {Openflow.Multipart.Group.Request, 6}, - {Openflow.Multipart.GroupDesc.Request, 7}, - {Openflow.Multipart.GroupFeatures.Request, 8}, - {Openflow.Multipart.Meter.Request, 9}, - {Openflow.Multipart.MeterConfig.Request, 10}, - {Openflow.Multipart.MeterFeatures.Request, 11}, - {Openflow.Multipart.TableFeatures.Request, 12}, - {Openflow.Multipart.PortDesc.Request, 13}, - {Openflow.Multipart.Experimenter.Request, 0xFFFF} - ], - multipart_reply_codec: [ - {Openflow.Multipart.Desc.Reply, 0}, - {Openflow.Multipart.Flow.Reply, 1}, - {Openflow.Multipart.Aggregate.Reply, 2}, - {Openflow.Multipart.Table.Reply, 3}, - {Openflow.Multipart.PortStats.Reply, 4}, - {Openflow.Multipart.Queue.Reply, 5}, - {Openflow.Multipart.Group.Reply, 6}, - {Openflow.Multipart.GroupDesc.Reply, 7}, - {Openflow.Multipart.GroupFeatures.Reply, 8}, - {Openflow.Multipart.Meter.Reply, 9}, - {Openflow.Multipart.MeterConfig.Reply, 10}, - {Openflow.Multipart.MeterFeatures.Reply, 11}, - {Openflow.Multipart.TableFeatures.Reply, 12}, - {Openflow.Multipart.PortDesc.Reply, 13}, - {Openflow.Multipart.Experimenter.Reply, 0xFFFF} - ], - nicira_ext_stats: [ - {Openflow.Multipart.NxFlow, 0}, - {Openflow.Multipart.NxAggregate, 1}, - {Openflow.Multipart.NxFlowMonitor, 2}, - {Openflow.Multipart.NxIPFIXBridge, 3}, - {Openflow.Multipart.NxIPFIXFlow, 4} - ], - hello_elem: [ - versionbitmap: 1 - ], - error_type: [ - hello_failed: 0, - bad_request: 1, - bad_action: 2, - bad_instruction: 3, - bad_match: 4, - flow_mod_failed: 5, - group_mod_failed: 6, - port_mod_failed: 7, - table_mod_failed: 8, - queue_op_failed: 9, - switch_config_failed: 10, - role_request_failed: 11, - meter_mod_failed: 12, - table_features_failed: 13, - experimenter: 0xFFFF - ], - hello_failed: [ - inconpatible: 0, - eperm: 1 - ], - bad_request: [ - bad_version: 0, - bad_type: 1, - bad_multipart: 2, - bad_experimeter: 3, - bad_exp_type: 4, - eperm: 5, - bad_len: 6, - buffer_empty: 7, - buffer_unknown: 8, - bad_table_id: 9, - is_slave: 10, - bad_port: 11, - bad_packet: 12, - multipart_buffer_overflow: 13, - nxm_invalid: 256, - nxm_bad_type: 257, - must_be_zero: 515, - bad_reason: 516, - flow_monitor_bad_event: 520, - undecodable_error: 521, - resume_not_supported: 533, - resume_stale: 534 - ], - bad_action: [ - bad_type: 0, - bad_len: 1, - bad_experimeter: 2, - bad_exp_type: 3, - bad_out_port: 4, - bad_argument: 5, - eperm: 6, - too_many: 7, - bad_queue: 8, - bad_out_group: 9, - match_inconsistent: 10, - unsupported_order: 11, - bad_tag: 12, - bad_set_type: 13, - bad_set_len: 14, - bad_set_argument: 15, - must_be_zero: 256, - conntrack_not_supported: 265, - bad_conjunction: 526 - ], - bad_instruction: [ - unknown_instruction: 0, - unsupported_instruction: 1, - bad_table_id: 2, - unsupported_metadata: 3, - unsupported_metadata_mask: 4, - bad_experimeter: 5, - bad_exp_type: 6, - bad_len: 7, - eperm: 8 - ], - bad_match: [ - bad_type: 0, - bad_len: 1, - bad_tag: 2, - bad_dl_addr_mask: 3, - bad_nw_addr_mask: 4, - bad_wildcards: 5, - bad_field: 6, - bad_value: 7, - bad_mask: 8, - bad_prereq: 9, - dup_field: 10, - eperm: 11 - ], - flow_mod_failed: [ - unknown: 0, - table_full: 1, - bad_table_id: 2, - overlap: 3, - eperm: 4, - bad_timeout: 5, - bad_command: 6, - bad_flags: 7 - ], - group_mod_failed: [ - group_exists: 0, - invalid_group: 1, - weight_unsupported: 2, - out_of_groups: 3, - ouf_of_buckets: 4, - chaining_unsupported: 5, - watch_unsupported: 6, - loop: 7, - unknown_group: 8, - chained_group: 9, - bad_type: 10, - bad_command: 11, - bad_bucket: 12, - bad_watch: 13, - eperm: 14 - ], - port_mod_failed: [ - bad_port: 0, - bad_hw_addr: 1, - bad_config: 2, - bad_advertise: 3, - eperm: 4 - ], - table_mod_failed: [ - bad_table: 0, - bad_config: 1, - eperm: 2 - ], - queue_op_failed: [ - bad_port: 0, - bad_queue: 1, - eperm: 2 - ], - switch_config_failed: [ - bad_flags: 0, - bad_len: 1, - eperm: 2 - ], - role_request_failed: [ - stale: 0, - unsup: 1, - bad_role: 2 - ], - meter_mod_failed: [ - unknown: 0, - meter_exists: 1, - invalid_meter: 2, - unknown_meter: 3, - bad_command: 4, - bad_flags: 5, - bad_rate: 6, - bad_burst: 7, - bad_band: 8, - bad_band_value: 9, - out_of_meters: 10, - out_of_bands: 11 - ], - table_features_failed: [ - bad_table: 0, - bad_metadata: 1, - bad_type: 2, - bad_len: 3, - bad_argument: 4, - eperm: 5 - ], - switch_capabilities: [ - flow_stats: 1 <<< 0, - table_stats: 1 <<< 1, - port_stats: 1 <<< 2, - group_stats: 1 <<< 3, - ip_reasm: 1 <<< 5, - queue_stats: 1 <<< 6, - arp_match_ip: 1 <<< 7, - port_blocked: 1 <<< 8 - ], - config_flags: [ - drop: 1 <<< 0, - reasm: 1 <<< 1 - ], - controller_max_len: [ - max: 0xFFE5, - no_buffer: 0xFFFF - ], - experimenter_oxm_vendors: [ - nicira_ext_match: 0x00002320, - hp_ext_match: 0x00002428, - onf_ext_match: 0x4F4E4600 - ], - match_type: [ - standard: 0, - oxm: 1 - ], - oxm_class: [ - nxm_0: 0x0000, - nxm_1: 0x0001, - openflow_basic: 0x8000, - packet_register: 0x8001, - experimenter: 0xFFFF - ], - nxm_0: [ - nx_in_port: 0, - nx_eth_dst: 1, - nx_eth_src: 2, - nx_eth_type: 3, - nx_vlan_tci: 4, - nx_ip_tos: 5, - nx_ip_proto: 6, - nx_ipv4_src: 7, - nx_ipv4_dst: 8, - nx_tcp_src: 9, - nx_tcp_dst: 10, - nx_udp_src: 11, - nx_udp_dst: 12, - nx_icmpv4_type: 13, - nx_icmpv4_code: 14, - nx_arp_op: 15, - nx_arp_spa: 16, - nx_arp_tpa: 17, - nx_tcp_flags: 34 - ], - nxm_1: [ - reg0: 0, - reg1: 1, - reg2: 2, - reg3: 3, - reg4: 4, - reg5: 5, - reg6: 6, - reg7: 7, - reg8: 8, - reg9: 9, - reg10: 10, - reg11: 11, - reg12: 12, - reg13: 13, - reg14: 14, - reg15: 15, - tun_id: 16, - nx_arp_sha: 17, - nx_arp_tha: 18, - nx_ipv6_src: 19, - nx_ipv6_dst: 20, - nx_icmpv6_type: 21, - nx_icmpv6_code: 22, - nx_ipv6_nd_target: 23, - nx_ipv6_nd_sll: 24, - nx_ipv6_nd_tll: 25, - nx_ip_frag: 26, - nx_ipv6_label: 27, - nx_ip_ecn: 28, - nx_ip_ttl: 29, - nx_mpls_ttl: 30, - tun_src: 31, - tun_dst: 32, - pkt_mark: 33, - dp_hash: 35, - recirc_id: 36, - conj_id: 37, - tun_gbp_id: 38, - tun_gbp_flags: 39, - tun_metadata0: 40, - tun_metadata1: 41, - tun_metadata2: 42, - tun_metadata3: 43, - tun_metadata4: 44, - tun_metadata5: 45, - tun_metadata6: 46, - tun_metadata7: 47, - tun_metadata8: 48, - tun_metadata9: 49, - tun_metadata10: 50, - tun_metadata11: 51, - tun_metadata12: 52, - tun_metadata13: 53, - tun_metadata14: 54, - tun_metadata15: 55, - tun_metadata16: 56, - tun_metadata17: 57, - tun_metadata18: 58, - tun_metadata19: 59, - tun_metadata20: 60, - tun_metadata21: 61, - tun_metadata22: 62, - tun_metadata23: 63, - tun_metadata24: 64, - tun_metadata25: 65, - tun_metadata26: 66, - tun_metadata27: 67, - tun_metadata28: 68, - tun_metadata29: 69, - tun_metadata30: 70, - tun_metadata31: 71, - tun_metadata32: 72, - tun_metadata33: 73, - tun_metadata34: 74, - tun_metadata35: 75, - tun_metadata36: 76, - tun_metadata37: 77, - tun_metadata38: 78, - tun_metadata39: 79, - tun_metadata40: 80, - tun_metadata41: 81, - tun_metadata42: 82, - tun_metadata43: 83, - tun_metadata44: 84, - tun_metadata45: 85, - tun_metadata46: 86, - tun_metadata47: 87, - tun_metadata48: 88, - tun_metadata49: 89, - tun_metadata50: 90, - tun_metadata51: 91, - tun_metadata52: 92, - tun_metadata53: 93, - tun_metadata54: 94, - tun_metadata55: 95, - tun_metadata56: 96, - tun_metadata57: 97, - tun_metadata58: 98, - tun_metadata59: 99, - tun_metadata60: 100, - tun_metadata61: 101, - tun_metadata62: 102, - tun_metadata63: 103, - tun_flags: 104, - ct_state: 105, - ct_zone: 106, - ct_mark: 107, - ct_label: 108, - tun_ipv6_src: 109, - tun_ipv6_dst: 110, - xxreg0: 111, - xxreg1: 112, - xxreg2: 113, - xxreg3: 114, - xxreg4: 115, - xxreg5: 116, - xxreg6: 117, - xxreg7: 118, - ct_nw_proto: 119, - ct_nw_src: 120, - ct_nw_dst: 121, - ct_ipv6_src: 122, - ct_ipv6_dst: 123, - ct_tp_src: 124, - ct_tp_dst: 125 - ], - openflow_basic: [ - in_port: 0, - in_phy_port: 1, - metadata: 2, - eth_dst: 3, - eth_src: 4, - eth_type: 5, - vlan_vid: 6, - vlan_pcp: 7, - ip_dscp: 8, - ip_ecn: 9, - ip_proto: 10, - ipv4_src: 11, - ipv4_dst: 12, - tcp_src: 13, - tcp_dst: 14, - udp_src: 15, - udp_dst: 16, - sctp_src: 17, - sctp_dst: 18, - icmpv4_type: 19, - icmpv4_code: 20, - arp_op: 21, - arp_spa: 22, - arp_tpa: 23, - arp_sha: 24, - arp_tha: 25, - ipv6_src: 26, - ipv6_dst: 27, - ipv6_flabel: 28, - icmpv6_type: 29, - icmpv6_code: 30, - ipv6_nd_target: 31, - ipv6_nd_sll: 32, - ipv6_nd_tll: 33, - mpls_label: 34, - mpls_tc: 35, - mpls_bos: 36, - pbb_isid: 37, - tunnel_id: 38, - ipv6_exthdr: 39, - - # Lagopus extended match fields - pbb_uca: 41, - packet_type: 42, - gre_flags: 43, - gre_ver: 44, - gre_protocol: 45, - gre_key: 46, - gre_seqnum: 47, - lisp_flags: 48, - lisp_nonce: 49, - lisp_id: 50, - vxlan_flags: 51, - vxlan_vni: 52, - mpls_data_first_nibble: 53, - mpls_ach_version: 54, - mpls_ach_channel: 55, - mpls_pw_metadata: 56, - mpls_cw_flags: 57, - mpls_cw_fragment: 58, - mpls_cw_len: 59, - mpls_cw_seq_num: 60, - gtpu_flags: 61, - gtpu_ver: 62, - gtpu_msg_type: 63, - gtpu_teid: 64, - gtpu_extn_hdr: 65, - gtpu_extn_udp_port: 66, - gtpu_extn_sci: 67 - ], - vlan_id: [ - present: 0x1000, - none: 0x0000 - ], - ipv6exthdr_flags: [ - nonext: 1 <<< 0, - esp: 1 <<< 1, - auth: 1 <<< 2, - dest: 1 <<< 3, - frag: 1 <<< 4, - router: 1 <<< 5, - hop: 1 <<< 6, - unrep: 1 <<< 7, - unseq: 1 <<< 8 - ], - tcp_flags: [ - fin: 1 <<< 0, - syn: 1 <<< 1, - rst: 1 <<< 2, - psh: 1 <<< 3, - ack: 1 <<< 4, - urg: 1 <<< 5, - ece: 1 <<< 6, - cwr: 1 <<< 7, - ns: 1 <<< 8 - ], - ct_state_flags: [ - # Beginning of a new connection. - new: 1 <<< 0, - # Part of an existing connection. - est: 1 <<< 1, - # Related to an established connection. - rel: 1 <<< 2, - # Flow is in the reply direction. - rep: 1 <<< 3, - # Could not track connection. - inv: 1 <<< 4, - # Conntrack has occurred. - trk: 1 <<< 5, - # Packet's source address/port was mangled by NAT. - snat: 1 <<< 6, - # Packet's destination address/port was mangled by NAT. - dnat: 1 <<< 7 - ], - packet_register: [ - xreg0: 0, - xreg1: 1, - xreg2: 2, - xreg3: 3, - xreg4: 4, - xreg5: 5, - xreg6: 6, - xreg7: 7 - ], - nicira_ext_match: [ - nsh_flags: 1, - nsh_mdtype: 2, - nsh_np: 3, - nsh_spi: 4, - nsh_si: 5, - nsh_c1: 6, - nsh_c2: 7, - nsh_c3: 8, - nsh_c4: 9 - ], - hp_ext_match: [ - hp_udp_src_port_range: 0, - hp_udp_dst_port_range: 1, - hp_tcp_src_port_range: 2, - hp_tcp_dst_port_range: 3, - hp_tcp_flags: 4, - hp_custom_1: 5, - hp_custom_2: 6, - hp_custom_3: 7, - hp_custom_4: 8 - ], - hp_custom_match_type: [ - l2_start: 1, - l3_start: 2, - l4_start: 3 - ], - onf_ext_match: [ - onf_tcp_flags: 42, - onf_actset_output: 43, - onf_pbb_uca: 2560 - ], - buffer_id: [ - no_buffer: 0xFFFFFFFF - ], - port_config: [ - port_down: 1 <<< 0, - no_receive: 1 <<< 2, - no_forward: 1 <<< 5, - no_packet_in: 1 <<< 6 - ], - port_state: [ - link_down: 1 <<< 0, - blocked: 1 <<< 1, - live: 1 <<< 2 - ], - port_features: [ - {:"10mb_hd", 1 <<< 0}, - {:"10mb_fd", 1 <<< 1}, - {:"100mb_hd", 1 <<< 2}, - {:"100mb_fd", 1 <<< 3}, - {:"1gb_hd", 1 <<< 4}, - {:"1gb_fd", 1 <<< 5}, - {:"10gb_fd", 1 <<< 6}, - {:"40gb_fd", 1 <<< 7}, - {:"100gb_fd", 1 <<< 8}, - {:"1tb_fd", 1 <<< 9}, - {:other, 1 <<< 10}, - {:copper, 1 <<< 11}, - {:fiber, 1 <<< 12}, - {:autoneg, 1 <<< 13}, - {:pause, 1 <<< 14}, - {:pause_asym, 1 <<< 15} - ], - openflow10_port_no: [ - max: 0xFF00, - in_port: 0xFFF8, - table: 0xFFF9, - normal: 0xFFFA, - flood: 0xFFFB, - all: 0xFFFC, - controller: 0xFFFD, - local: 0xFFFE, - none: 0xFFFF - ], - openflow13_port_no: [ - max: 0xFFFFFF00, - in_port: 0xFFFFFFF8, - table: 0xFFFFFFF9, - normal: 0xFFFFFFFA, - flood: 0xFFFFFFFB, - all: 0xFFFFFFFC, - controller: 0xFFFFFFFD, - local: 0xFFFFFFFE, - any: 0xFFFFFFFF - ], - packet_in_reason: [ - no_match: 0, - action: 1, - invalid_ttl: 2, - action_set: 3, - group: 4, - packet_out: 5 - ], - flow_mod_command: [ - add: 0, - modify: 1, - modify_strict: 2, - delete: 3, - delete_strict: 4 - ], - flow_mod_flags: [ - send_flow_rem: 1 <<< 0, - check_overlap: 1 <<< 1, - reset_counts: 1 <<< 2, - no_packet_counts: 1 <<< 3, - no_byte_counts: 1 <<< 4 - ], - flow_removed_reason: [ - idle_timeout: 0, - hard_timeout: 1, - delete: 2, - group_delete: 3, - meter_delete: 4, - eviction: 5 - ], - port_reason: [ - add: 0, - delete: 1, - modify: 2 - ], - group_mod_command: [ - add: 0, - modify: 1, - delete: 2 - ], - group_type: [ - all: 0, - select: 1, - indirect: 2, - fast_failover: 3 - ], - group_id: [ - max: 0xFFFFFF00, - all: 0xFFFFFFFC, - any: 0xFFFFFFFF - ], - group_capabilities: [ - select_weight: 1 <<< 0, - select_liveness: 1 <<< 1, - chaining: 1 <<< 2, - chaining_checks: 1 <<< 3 - ], - table_id: [ - max: 0xFE, - all: 0xFF - ], - queue_id: [ - all: 0xFFFFFFFF - ], - meter_mod_command: [ - add: 0, - modify: 1, - delete: 2 - ], - meter_id: [ - max: 0xFFFF0000, - slowpath: 0xFFFFFFFD, - controller: 0xFFFFFFFE, - all: 0xFFFFFFFF - ], - meter_flags: [ - kbps: 1 <<< 0, - pktps: 1 <<< 1, - burst: 1 <<< 2, - stats: 1 <<< 3 - ], - meter_band_type: [ - {Openflow.MeterBand.Drop, 1}, - {Openflow.MeterBand.Remark, 2}, - {Openflow.MeterBand.Experimenter, 0xFFFF} - ], - table_config: [ - table_miss_controller: 0 <<< 0, - table_miss_continue: 1 <<< 0, - table_miss_drop: 2 <<< 0, - table_miss_mask: 3 <<< 0, - eviction: 1 <<< 2, - vacancy_events: 1 <<< 3 - ], - action_type: [ - {Openflow.Action.Output, 0}, - {Openflow.Action.CopyTtlOut, 11}, - {Openflow.Action.CopyTtlIn, 12}, - {Openflow.Action.SetMplsTtl, 15}, - {Openflow.Action.DecMplsTtl, 16}, - {Openflow.Action.PushVlan, 17}, - {Openflow.Action.PopVlan, 18}, - {Openflow.Action.PushMpls, 19}, - {Openflow.Action.PopMpls, 20}, - {Openflow.Action.SetQueue, 21}, - {Openflow.Action.Group, 22}, - {Openflow.Action.SetNwTtl, 23}, - {Openflow.Action.DecNwTtl, 24}, - {Openflow.Action.SetField, 25}, - {Openflow.Action.PushPbb, 26}, - {Openflow.Action.PopPbb, 27}, - {Openflow.Action.Encap, 28}, - {Openflow.Action.Decap, 29}, - {Openflow.Action.SetSequence, 30}, - {Openflow.Action.ValidateSequence, 31}, - {Openflow.Action.Experimenter, 0xFFFF} - ], - action_vendor: [ - nicira_ext_action: 0x00002320, - onf_ext_action: 0x4F4E4600 - ], - onf_ext_action: [ - {Openflow.Action.OnfCopyField, 3200} - ], - nicira_ext_action: [ - {Openflow.Action.NxResubmit, 1}, - {Openflow.Action.NxSetTunnel, 2}, - # {Openflow.Action.NxSetQueue, 4}, Deprecated - # {Openflow.Action.NxPopQueue, 5}, Deprecated - {Openflow.Action.NxRegMove, 6}, - {Openflow.Action.NxRegLoad, 7}, - {Openflow.Action.NxNote, 8}, - {Openflow.Action.NxSetTunnel64, 9}, - {Openflow.Action.NxMultipath, 10}, - {Openflow.Action.NxBundle, 12}, - {Openflow.Action.NxBundleLoad, 13}, - {Openflow.Action.NxResubmitTable, 14}, - {Openflow.Action.NxOutputReg, 15}, - {Openflow.Action.NxLearn, 16}, - {Openflow.Action.NxExit, 17}, - {Openflow.Action.NxDecTtl, 18}, - {Openflow.Action.NxFinTimeout, 19}, - {Openflow.Action.NxController, 20}, - {Openflow.Action.NxDecTtlCntIds, 21}, - {Openflow.Action.NxWriteMetadata, 22}, - # {Openflow.Action.NxPushMpls, 23}, # Deprecated - # {Openflow.Action.NxPopMpls, 24}, # Deprecated - # {Openflow.Action.NxSetMplsTtl, 25}, Deprecated - # {Openflow.Action.NxDecMplsTtl, 26}, Deprecated - {Openflow.Action.NxStackPush, 27}, - {Openflow.Action.NxStackPop, 28}, - {Openflow.Action.NxSample, 29}, - # {Openflow.Action.NxSetMplsLabel, 30}, Deprecated - # {Openflow.Action.NxSetMplsTc, 31}, Deprecated - {Openflow.Action.NxOutputReg2, 32}, - {Openflow.Action.NxRegLoad2, 33}, - {Openflow.Action.NxConjunction, 34}, - {Openflow.Action.NxConntrack, 35}, - {Openflow.Action.NxNat, 36}, - {Openflow.Action.NxController2, 37}, - {Openflow.Action.NxSample2, 38}, - {Openflow.Action.NxOutputTrunc, 39}, - {Openflow.Action.NxGroup, 40}, - {Openflow.Action.NxSample3, 41}, - {Openflow.Action.NxClone, 42}, - {Openflow.Action.NxCtClear, 43}, - {Openflow.Action.NxResubmitTableCt, 44}, - {Openflow.Action.NxLearn2, 45}, - {Openflow.Action.NxEncap, 46}, - {Openflow.Action.NxDecap, 47}, - {Openflow.Action.NxDebugRecirc, 0xFF} - ], - nx_mp_algorithm: [ - modulo_n: 0, - hash_threshold: 1, - highest_random_weight: 2, - iterative_hash: 3 - ], - nx_hash_fields: [ - eth_src: 0, - symmetric_l4: 1, - symmetric_l3l4: 2, - symmetric_l3l4_udp: 3, - nw_src: 4, - nw_dst: 5 - ], - nx_bd_algorithm: [ - active_backup: 0, - highest_random_weight: 1 - ], - nx_learn_flag: [ - send_flow_rem: 1 <<< 0, - delete_learned: 1 <<< 1, - write_result: 1 <<< 2 - ], - nx_conntrack_flags: [ - commit: 1 <<< 0, - force: 1 <<< 1 - ], - nx_nat_flags: [ - src: 1 <<< 0, - dst: 1 <<< 1, - persistent: 1 <<< 2, - protocol_hash: 1 <<< 3, - protocol_random: 1 <<< 4 - ], - nx_nat_range: [ - ipv4_min: 1 <<< 0, - ipv4_max: 1 <<< 1, - ipv6_min: 1 <<< 2, - ipv6_max: 1 <<< 3, - proto_min: 1 <<< 4, - proto_max: 1 <<< 5 - ], - nx_action_controller2_prop_type: [ - max_len: 0, - controller_id: 1, - reason: 2, - userdata: 3, - pause: 4 - ], - nx_action_sample_direction: [ - default: 0, - ingress: 1, - egress: 2 - ], - nx_flow_spec_type: [ - {Openflow.Action.NxFlowSpecMatch, 0}, - {Openflow.Action.NxFlowSpecLoad, 1}, - {Openflow.Action.NxFlowSpecOutput, 2} - ], - instruction_type: [ - {Openflow.Instruction.GotoTable, 1}, - {Openflow.Instruction.WriteMetadata, 2}, - {Openflow.Instruction.WriteActions, 3}, - {Openflow.Instruction.ApplyActions, 4}, - {Openflow.Instruction.ClearActions, 5}, - {Openflow.Instruction.Meter, 6}, - {Openflow.Instruction.Experimenter, 0xFFFF} - ], - controller_role: [ - nochange: 0, - equal: 1, - master: 2, - slave: 3 - ], - nx_role: [ - other: 0, - master: 1, - slave: 2 - ], - packet_in_format: [ - standard: 0, - nxt_packet_in: 1, - nxt_packet_in2: 2 - ], - flow_format: [ - openflow10: 0, - nxm: 1 - ], - packet_in2_prop_type: [ - packet: 0, - full_len: 1, - buffer_id: 2, - table_id: 3, - cookie: 4, - reason: 5, - metadata: 6, - userdata: 7, - continuation: 8 - ], - continuation_prop_type: [ - bridge: 0x8000, - stack: 0x8001, - mirrors: 0x8002, - conntracked: 0x8003, - table_id: 0x8004, - cookie: 0x8005, - actions: 0x8006, - action_set: 0x8007 - ], - flow_monitor_flag: [ - initial: 1 <<< 0, - add: 1 <<< 1, - delete: 1 <<< 2, - modify: 1 <<< 3, - actions: 1 <<< 4, - own: 1 <<< 5 - ], - flow_update_event: [ - added: 0, - deleted: 1, - modified: 2, - abbrev: 3 - ], - tlv_table_mod_command: [ - add: 0, - delete: 1, - clear: 2 - ], - table_feature_prop_type: [ - instructions: 0, - instructions_miss: 1, - next_tables: 2, - next_tables_miss: 3, - write_actions: 4, - write_actions_miss: 5, - apply_actions: 6, - apply_actions_miss: 7, - match: 8, - wildcards: 10, - write_setfield: 12, - write_setfield_miss: 13, - apply_setfield: 14, - apply_setfield_miss: 15, - experimenter: 0xFFFE, - experimenter_miss: 0xFFFF - ], - bundle_ctrl_type: [ - open_request: 0, - open_reply: 1, - close_request: 2, - close_reply: 3, - commit_request: 4, - commit_reply: 5, - discard_request: 6, - discard_reply: 7 - ], - bundle_flags: [ - atomic: 1 <<< 0, - ordered: 1 <<< 1 - ] - ] - - def main(_) do - File.write( - "lib/openflow/enums.ex", - """ - defmodule Openflow.Enums do - @moduledoc "auto generated code"\n - """, - [:binary] - ) - - for {enum_name, enum_def} <- @enums do - to_int_fn_name = :"#{enum_name}_to_int" - - for {key, _value} <- enum_def do - File.write( - "lib/openflow/enums.ex", - """ - def to_int(#{inspect(key)}, :#{enum_name}) do - #{to_int_fn_name}(#{inspect(key)}) - catch - _class, _reason -> #{inspect(key)} - end\n - """, - [:append, :binary] - ) - end - - File.write( - "lib/openflow/enums.ex", - """ - def to_int(_int, :#{enum_name}) do - throw(:bad_enum) - end\n - """, - [:append, :binary] - ) - end - - for {enum_name, enum_def} <- @enums do - to_atom_fn_name = :"#{enum_name}_to_atom" - - for {_key, value} <- enum_def do - File.write( - "lib/openflow/enums.ex", - """ - def to_atom(#{inspect(value, base: :hex)}, :#{enum_name}) do - #{to_atom_fn_name}(#{inspect(value, base: :hex)}) - catch - _class, _reason -> #{value} - end\n - """, - [:append, :binary] - ) - end - - File.write( - "lib/openflow/enums.ex", - """ - def to_atom(_, :#{enum_name}) do - throw(:bad_enum) - end\n - """, - [:append, :binary] - ) - end - - for {enum_name, enum_def} <- @enums do - to_int_fn_name = :"#{enum_name}_to_int" - to_atom_fn_name = :"#{enum_name}_to_atom" - - for {key, value} <- enum_def do - File.write( - "lib/openflow/enums.ex", - " def #{to_int_fn_name}(#{inspect(key)}), do: #{inspect(value, base: :hex)}\n", - [ - :append, - :binary - ] - ) - end - - File.write("lib/openflow/enums.ex", " def #{to_int_fn_name}(_), do: throw(:bad_enum)\n", [ - :append, - :binary - ]) - - for {key, value} <- enum_def do - File.write( - "lib/openflow/enums.ex", - " def #{to_atom_fn_name}(#{inspect(value, base: :hex)}), do: #{inspect(key)}\n", - [ - :append, - :binary - ] - ) - end - - File.write("lib/openflow/enums.ex", " def #{to_atom_fn_name}(_), do: throw(:bad_enum)\n", [ - :append, - :binary - ]) - end - - for {enum_name, _enum_def} <- @enums do - File.write( - "lib/openflow/enums.ex", - """ - def int_to_flags(int, :#{enum_name}) do - Openflow.Utils.int_to_flags([], int, enum_of(:#{enum_name})) - end\n - """, - [:append, :binary] - ) - end - - for {enum_name, _enum_def} <- @enums do - File.write( - "lib/openflow/enums.ex", - """ - def flags_to_int(flags, :#{enum_name}) do - Openflow.Utils.flags_to_int(0, flags, enum_of(:#{enum_name})) - end\n - """, - [:append, :binary] - ) - end - - for {enum_name, enum_def} <- @enums do - File.write( - "lib/openflow/enums.ex", - " defp enum_of(:#{enum_name}), do: #{inspect(enum_def, pretty: true, limit: 100_000)}\n", - [:append, :binary] - ) - end - - File.write("lib/openflow/enums.ex", "end", [:append, :binary]) - end -end diff --git a/lib/openflow/enums.ex b/lib/openflow/enums.ex index 51426c7..11591ad 100644 --- a/lib/openflow/enums.ex +++ b/lib/openflow/enums.ex @@ -727,6 +727,18 @@ defmodule Openflow.Enums do _class, _reason -> :multipart_buffer_overflow end + def to_int(:multipart_request_timeout, :bad_request) do + bad_request_to_int(:multipart_request_timeout) + catch + _class, _reason -> :multipart_request_timeout + end + + def to_int(:multipart_reply_timeout, :bad_request) do + bad_request_to_int(:multipart_reply_timeout) + catch + _class, _reason -> :multipart_reply_timeout + end + def to_int(:nxm_invalid, :bad_request) do bad_request_to_int(:nxm_invalid) catch @@ -881,10 +893,10 @@ defmodule Openflow.Enums do _class, _reason -> :must_be_zero end - def to_int(:conntrack_not_supported, :bad_action) do - bad_action_to_int(:conntrack_not_supported) + def to_int(:conntrack_datapath_support, :bad_action) do + bad_action_to_int(:conntrack_datapath_support) catch - _class, _reason -> :conntrack_not_supported + _class, _reason -> :conntrack_datapath_support end def to_int(:bad_conjunction, :bad_action) do @@ -951,6 +963,12 @@ defmodule Openflow.Enums do _class, _reason -> :eperm end + def to_int(:dup_inst, :bad_instruction) do + bad_instruction_to_int(:dup_inst) + catch + _class, _reason -> :dup_inst + end + def to_int(_int, :bad_instruction) do throw(:bad_enum) end @@ -1027,6 +1045,12 @@ defmodule Openflow.Enums do _class, _reason -> :eperm end + def to_int(:conntrack_datapath_support, :bad_match) do + bad_match_to_int(:conntrack_datapath_support) + catch + _class, _reason -> :conntrack_datapath_support + end + def to_int(_int, :bad_match) do throw(:bad_enum) end @@ -1173,6 +1197,18 @@ defmodule Openflow.Enums do _class, _reason -> :eperm end + def to_int(:unknown_bucket, :group_mod_failed) do + group_mod_failed_to_int(:unknown_bucket) + catch + _class, _reason -> :unknown_bucket + end + + def to_int(:bucket_exists, :group_mod_failed) do + group_mod_failed_to_int(:bucket_exists) + catch + _class, _reason -> :bucket_exists + end + def to_int(_int, :group_mod_failed) do throw(:bad_enum) end @@ -4125,18 +4161,6 @@ defmodule Openflow.Enums do _class, _reason -> Openflow.Action.NxSetTunnel end - def to_int(Openflow.Action.NxSetQueue, :nicira_ext_action) do - nicira_ext_action_to_int(Openflow.Action.NxSetQueue) - catch - _class, _reason -> Openflow.Action.NxSetQueue - end - - def to_int(Openflow.Action.NxPopQueue, :nicira_ext_action) do - nicira_ext_action_to_int(Openflow.Action.NxPopQueue) - catch - _class, _reason -> Openflow.Action.NxPopQueue - end - def to_int(Openflow.Action.NxRegMove, :nicira_ext_action) do nicira_ext_action_to_int(Openflow.Action.NxRegMove) catch @@ -4233,30 +4257,6 @@ defmodule Openflow.Enums do _class, _reason -> Openflow.Action.NxWriteMetadata end - def to_int(Openflow.Action.NxPushMpls, :nicira_ext_action) do - nicira_ext_action_to_int(Openflow.Action.NxPushMpls) - catch - _class, _reason -> Openflow.Action.NxPushMpls - end - - def to_int(Openflow.Action.NxPopMpls, :nicira_ext_action) do - nicira_ext_action_to_int(Openflow.Action.NxPopMpls) - catch - _class, _reason -> Openflow.Action.NxPopMpls - end - - def to_int(Openflow.Action.NxSetMplsTtl, :nicira_ext_action) do - nicira_ext_action_to_int(Openflow.Action.NxSetMplsTtl) - catch - _class, _reason -> Openflow.Action.NxSetMplsTtl - end - - def to_int(Openflow.Action.NxDecMplsTtl, :nicira_ext_action) do - nicira_ext_action_to_int(Openflow.Action.NxDecMplsTtl) - catch - _class, _reason -> Openflow.Action.NxDecMplsTtl - end - def to_int(Openflow.Action.NxStackPush, :nicira_ext_action) do nicira_ext_action_to_int(Openflow.Action.NxStackPush) catch @@ -4275,18 +4275,6 @@ defmodule Openflow.Enums do _class, _reason -> Openflow.Action.NxSample end - def to_int(Openflow.Action.NxSetMplsLabel, :nicira_ext_action) do - nicira_ext_action_to_int(Openflow.Action.NxSetMplsLabel) - catch - _class, _reason -> Openflow.Action.NxSetMplsLabel - end - - def to_int(Openflow.Action.NxSetMplsTc, :nicira_ext_action) do - nicira_ext_action_to_int(Openflow.Action.NxSetMplsTc) - catch - _class, _reason -> Openflow.Action.NxSetMplsTc - end - def to_int(Openflow.Action.NxOutputReg2, :nicira_ext_action) do nicira_ext_action_to_int(Openflow.Action.NxOutputReg2) catch @@ -5895,6 +5883,18 @@ defmodule Openflow.Enums do _class, _reason -> 13 end + def to_atom(0xE, :bad_request) do + bad_request_to_atom(0xE) + catch + _class, _reason -> 14 + end + + def to_atom(0xF, :bad_request) do + bad_request_to_atom(0xF) + catch + _class, _reason -> 15 + end + def to_atom(0x100, :bad_request) do bad_request_to_atom(0x100) catch @@ -6119,6 +6119,12 @@ defmodule Openflow.Enums do _class, _reason -> 8 end + def to_atom(0x100, :bad_instruction) do + bad_instruction_to_atom(0x100) + catch + _class, _reason -> 256 + end + def to_atom(_, :bad_instruction) do throw(:bad_enum) end @@ -6195,6 +6201,12 @@ defmodule Openflow.Enums do _class, _reason -> 11 end + def to_atom(0x108, :bad_match) do + bad_match_to_atom(0x108) + catch + _class, _reason -> 264 + end + def to_atom(_, :bad_match) do throw(:bad_enum) end @@ -6341,6 +6353,18 @@ defmodule Openflow.Enums do _class, _reason -> 14 end + def to_atom(0xF, :group_mod_failed) do + group_mod_failed_to_atom(0xF) + catch + _class, _reason -> 15 + end + + def to_atom(0x10, :group_mod_failed) do + group_mod_failed_to_atom(0x10) + catch + _class, _reason -> 16 + end + def to_atom(_, :group_mod_failed) do throw(:bad_enum) end @@ -9293,18 +9317,6 @@ defmodule Openflow.Enums do _class, _reason -> 2 end - def to_atom(0x4, :nicira_ext_action) do - nicira_ext_action_to_atom(0x4) - catch - _class, _reason -> 4 - end - - def to_atom(0x5, :nicira_ext_action) do - nicira_ext_action_to_atom(0x5) - catch - _class, _reason -> 5 - end - def to_atom(0x6, :nicira_ext_action) do nicira_ext_action_to_atom(0x6) catch @@ -9401,30 +9413,6 @@ defmodule Openflow.Enums do _class, _reason -> 22 end - def to_atom(0x17, :nicira_ext_action) do - nicira_ext_action_to_atom(0x17) - catch - _class, _reason -> 23 - end - - def to_atom(0x18, :nicira_ext_action) do - nicira_ext_action_to_atom(0x18) - catch - _class, _reason -> 24 - end - - def to_atom(0x19, :nicira_ext_action) do - nicira_ext_action_to_atom(0x19) - catch - _class, _reason -> 25 - end - - def to_atom(0x1A, :nicira_ext_action) do - nicira_ext_action_to_atom(0x1A) - catch - _class, _reason -> 26 - end - def to_atom(0x1B, :nicira_ext_action) do nicira_ext_action_to_atom(0x1B) catch @@ -9443,18 +9431,6 @@ defmodule Openflow.Enums do _class, _reason -> 29 end - def to_atom(0x1E, :nicira_ext_action) do - nicira_ext_action_to_atom(0x1E) - catch - _class, _reason -> 30 - end - - def to_atom(0x1F, :nicira_ext_action) do - nicira_ext_action_to_atom(0x1F) - catch - _class, _reason -> 31 - end - def to_atom(0x20, :nicira_ext_action) do nicira_ext_action_to_atom(0x20) catch @@ -10573,6 +10549,8 @@ defmodule Openflow.Enums do def bad_request_to_int(:bad_port), do: 0xB def bad_request_to_int(:bad_packet), do: 0xC def bad_request_to_int(:multipart_buffer_overflow), do: 0xD + def bad_request_to_int(:multipart_request_timeout), do: 0xE + def bad_request_to_int(:multipart_reply_timeout), do: 0xF def bad_request_to_int(:nxm_invalid), do: 0x100 def bad_request_to_int(:nxm_bad_type), do: 0x101 def bad_request_to_int(:must_be_zero), do: 0x203 @@ -10596,6 +10574,8 @@ defmodule Openflow.Enums do def bad_request_to_atom(0xB), do: :bad_port def bad_request_to_atom(0xC), do: :bad_packet def bad_request_to_atom(0xD), do: :multipart_buffer_overflow + def bad_request_to_atom(0xE), do: :multipart_request_timeout + def bad_request_to_atom(0xF), do: :multipart_reply_timeout def bad_request_to_atom(0x100), do: :nxm_invalid def bad_request_to_atom(0x101), do: :nxm_bad_type def bad_request_to_atom(0x203), do: :must_be_zero @@ -10622,7 +10602,7 @@ defmodule Openflow.Enums do def bad_action_to_int(:bad_set_len), do: 0xE def bad_action_to_int(:bad_set_argument), do: 0xF def bad_action_to_int(:must_be_zero), do: 0x100 - def bad_action_to_int(:conntrack_not_supported), do: 0x109 + def bad_action_to_int(:conntrack_datapath_support), do: 0x109 def bad_action_to_int(:bad_conjunction), do: 0x20E def bad_action_to_int(_), do: throw(:bad_enum) def bad_action_to_atom(0x0), do: :bad_type @@ -10642,7 +10622,7 @@ defmodule Openflow.Enums do def bad_action_to_atom(0xE), do: :bad_set_len def bad_action_to_atom(0xF), do: :bad_set_argument def bad_action_to_atom(0x100), do: :must_be_zero - def bad_action_to_atom(0x109), do: :conntrack_not_supported + def bad_action_to_atom(0x109), do: :conntrack_datapath_support def bad_action_to_atom(0x20E), do: :bad_conjunction def bad_action_to_atom(_), do: throw(:bad_enum) def bad_instruction_to_int(:unknown_instruction), do: 0x0 @@ -10654,6 +10634,7 @@ defmodule Openflow.Enums do def bad_instruction_to_int(:bad_exp_type), do: 0x6 def bad_instruction_to_int(:bad_len), do: 0x7 def bad_instruction_to_int(:eperm), do: 0x8 + def bad_instruction_to_int(:dup_inst), do: 0x100 def bad_instruction_to_int(_), do: throw(:bad_enum) def bad_instruction_to_atom(0x0), do: :unknown_instruction def bad_instruction_to_atom(0x1), do: :unsupported_instruction @@ -10664,6 +10645,7 @@ defmodule Openflow.Enums do def bad_instruction_to_atom(0x6), do: :bad_exp_type def bad_instruction_to_atom(0x7), do: :bad_len def bad_instruction_to_atom(0x8), do: :eperm + def bad_instruction_to_atom(0x100), do: :dup_inst def bad_instruction_to_atom(_), do: throw(:bad_enum) def bad_match_to_int(:bad_type), do: 0x0 def bad_match_to_int(:bad_len), do: 0x1 @@ -10677,6 +10659,7 @@ defmodule Openflow.Enums do def bad_match_to_int(:bad_prereq), do: 0x9 def bad_match_to_int(:dup_field), do: 0xA def bad_match_to_int(:eperm), do: 0xB + def bad_match_to_int(:conntrack_datapath_support), do: 0x108 def bad_match_to_int(_), do: throw(:bad_enum) def bad_match_to_atom(0x0), do: :bad_type def bad_match_to_atom(0x1), do: :bad_len @@ -10690,6 +10673,7 @@ defmodule Openflow.Enums do def bad_match_to_atom(0x9), do: :bad_prereq def bad_match_to_atom(0xA), do: :dup_field def bad_match_to_atom(0xB), do: :eperm + def bad_match_to_atom(0x108), do: :conntrack_datapath_support def bad_match_to_atom(_), do: throw(:bad_enum) def flow_mod_failed_to_int(:unknown), do: 0x0 def flow_mod_failed_to_int(:table_full), do: 0x1 @@ -10724,6 +10708,8 @@ defmodule Openflow.Enums do def group_mod_failed_to_int(:bad_bucket), do: 0xC def group_mod_failed_to_int(:bad_watch), do: 0xD def group_mod_failed_to_int(:eperm), do: 0xE + def group_mod_failed_to_int(:unknown_bucket), do: 0xF + def group_mod_failed_to_int(:bucket_exists), do: 0x10 def group_mod_failed_to_int(_), do: throw(:bad_enum) def group_mod_failed_to_atom(0x0), do: :group_exists def group_mod_failed_to_atom(0x1), do: :invalid_group @@ -10740,6 +10726,8 @@ defmodule Openflow.Enums do def group_mod_failed_to_atom(0xC), do: :bad_bucket def group_mod_failed_to_atom(0xD), do: :bad_watch def group_mod_failed_to_atom(0xE), do: :eperm + def group_mod_failed_to_atom(0xF), do: :unknown_bucket + def group_mod_failed_to_atom(0x10), do: :bucket_exists def group_mod_failed_to_atom(_), do: throw(:bad_enum) def port_mod_failed_to_int(:bad_port), do: 0x0 def port_mod_failed_to_int(:bad_hw_addr), do: 0x1 @@ -11755,8 +11743,6 @@ defmodule Openflow.Enums do def onf_ext_action_to_atom(_), do: throw(:bad_enum) def nicira_ext_action_to_int(Openflow.Action.NxResubmit), do: 0x1 def nicira_ext_action_to_int(Openflow.Action.NxSetTunnel), do: 0x2 - def nicira_ext_action_to_int(Openflow.Action.NxSetQueue), do: 0x4 - def nicira_ext_action_to_int(Openflow.Action.NxPopQueue), do: 0x5 def nicira_ext_action_to_int(Openflow.Action.NxRegMove), do: 0x6 def nicira_ext_action_to_int(Openflow.Action.NxRegLoad), do: 0x7 def nicira_ext_action_to_int(Openflow.Action.NxNote), do: 0x8 @@ -11773,15 +11759,9 @@ defmodule Openflow.Enums do def nicira_ext_action_to_int(Openflow.Action.NxController), do: 0x14 def nicira_ext_action_to_int(Openflow.Action.NxDecTtlCntIds), do: 0x15 def nicira_ext_action_to_int(Openflow.Action.NxWriteMetadata), do: 0x16 - def nicira_ext_action_to_int(Openflow.Action.NxPushMpls), do: 0x17 - def nicira_ext_action_to_int(Openflow.Action.NxPopMpls), do: 0x18 - def nicira_ext_action_to_int(Openflow.Action.NxSetMplsTtl), do: 0x19 - def nicira_ext_action_to_int(Openflow.Action.NxDecMplsTtl), do: 0x1A def nicira_ext_action_to_int(Openflow.Action.NxStackPush), do: 0x1B def nicira_ext_action_to_int(Openflow.Action.NxStackPop), do: 0x1C def nicira_ext_action_to_int(Openflow.Action.NxSample), do: 0x1D - def nicira_ext_action_to_int(Openflow.Action.NxSetMplsLabel), do: 0x1E - def nicira_ext_action_to_int(Openflow.Action.NxSetMplsTc), do: 0x1F def nicira_ext_action_to_int(Openflow.Action.NxOutputReg2), do: 0x20 def nicira_ext_action_to_int(Openflow.Action.NxRegLoad2), do: 0x21 def nicira_ext_action_to_int(Openflow.Action.NxConjunction), do: 0x22 @@ -11802,8 +11782,6 @@ defmodule Openflow.Enums do def nicira_ext_action_to_int(_), do: throw(:bad_enum) def nicira_ext_action_to_atom(0x1), do: Openflow.Action.NxResubmit def nicira_ext_action_to_atom(0x2), do: Openflow.Action.NxSetTunnel - def nicira_ext_action_to_atom(0x4), do: Openflow.Action.NxSetQueue - def nicira_ext_action_to_atom(0x5), do: Openflow.Action.NxPopQueue def nicira_ext_action_to_atom(0x6), do: Openflow.Action.NxRegMove def nicira_ext_action_to_atom(0x7), do: Openflow.Action.NxRegLoad def nicira_ext_action_to_atom(0x8), do: Openflow.Action.NxNote @@ -11820,15 +11798,9 @@ defmodule Openflow.Enums do def nicira_ext_action_to_atom(0x14), do: Openflow.Action.NxController def nicira_ext_action_to_atom(0x15), do: Openflow.Action.NxDecTtlCntIds def nicira_ext_action_to_atom(0x16), do: Openflow.Action.NxWriteMetadata - def nicira_ext_action_to_atom(0x17), do: Openflow.Action.NxPushMpls - def nicira_ext_action_to_atom(0x18), do: Openflow.Action.NxPopMpls - def nicira_ext_action_to_atom(0x19), do: Openflow.Action.NxSetMplsTtl - def nicira_ext_action_to_atom(0x1A), do: Openflow.Action.NxDecMplsTtl def nicira_ext_action_to_atom(0x1B), do: Openflow.Action.NxStackPush def nicira_ext_action_to_atom(0x1C), do: Openflow.Action.NxStackPop def nicira_ext_action_to_atom(0x1D), do: Openflow.Action.NxSample - def nicira_ext_action_to_atom(0x1E), do: Openflow.Action.NxSetMplsLabel - def nicira_ext_action_to_atom(0x1F), do: Openflow.Action.NxSetMplsTc def nicira_ext_action_to_atom(0x20), do: Openflow.Action.NxOutputReg2 def nicira_ext_action_to_atom(0x21), do: Openflow.Action.NxRegLoad2 def nicira_ext_action_to_atom(0x22), do: Openflow.Action.NxConjunction @@ -13000,6 +12972,8 @@ defmodule Openflow.Enums do bad_port: 11, bad_packet: 12, multipart_buffer_overflow: 13, + multipart_request_timeout: 14, + multipart_reply_timeout: 15, nxm_invalid: 256, nxm_bad_type: 257, must_be_zero: 515, @@ -13029,7 +13003,7 @@ defmodule Openflow.Enums do bad_set_len: 14, bad_set_argument: 15, must_be_zero: 256, - conntrack_not_supported: 265, + conntrack_datapath_support: 265, bad_conjunction: 526 ] @@ -13043,7 +13017,8 @@ defmodule Openflow.Enums do bad_experimeter: 5, bad_exp_type: 6, bad_len: 7, - eperm: 8 + eperm: 8, + dup_inst: 256 ] defp enum_of(:bad_match), @@ -13059,7 +13034,8 @@ defmodule Openflow.Enums do bad_mask: 8, bad_prereq: 9, dup_field: 10, - eperm: 11 + eperm: 11, + conntrack_datapath_support: 264 ] defp enum_of(:flow_mod_failed), @@ -13090,7 +13066,9 @@ defmodule Openflow.Enums do bad_command: 11, bad_bucket: 12, bad_watch: 13, - eperm: 14 + eperm: 14, + unknown_bucket: 15, + bucket_exists: 16 ] defp enum_of(:port_mod_failed), @@ -13577,8 +13555,6 @@ defmodule Openflow.Enums do do: [ {Openflow.Action.NxResubmit, 1}, {Openflow.Action.NxSetTunnel, 2}, - {Openflow.Action.NxSetQueue, 4}, - {Openflow.Action.NxPopQueue, 5}, {Openflow.Action.NxRegMove, 6}, {Openflow.Action.NxRegLoad, 7}, {Openflow.Action.NxNote, 8}, @@ -13595,15 +13571,9 @@ defmodule Openflow.Enums do {Openflow.Action.NxController, 20}, {Openflow.Action.NxDecTtlCntIds, 21}, {Openflow.Action.NxWriteMetadata, 22}, - {Openflow.Action.NxPushMpls, 23}, - {Openflow.Action.NxPopMpls, 24}, - {Openflow.Action.NxSetMplsTtl, 25}, - {Openflow.Action.NxDecMplsTtl, 26}, {Openflow.Action.NxStackPush, 27}, {Openflow.Action.NxStackPop, 28}, {Openflow.Action.NxSample, 29}, - {Openflow.Action.NxSetMplsLabel, 30}, - {Openflow.Action.NxSetMplsTc, 31}, {Openflow.Action.NxOutputReg2, 32}, {Openflow.Action.NxRegLoad2, 33}, {Openflow.Action.NxConjunction, 34}, diff --git a/lib/openflow/features.ex b/lib/openflow/features.ex deleted file mode 100644 index 43b26b8..0000000 --- a/lib/openflow/features.ex +++ /dev/null @@ -1,2 +0,0 @@ -defmodule Openflow.Features do -end diff --git a/lib/openflow/features/reply.ex b/lib/openflow/features/reply.ex index e104ba8..5d3df0a 100644 --- a/lib/openflow/features/reply.ex +++ b/lib/openflow/features/reply.ex @@ -11,11 +11,38 @@ defmodule Openflow.Features.Reply do alias __MODULE__ + @type t :: %Reply{ + version: 4, + xid: 0..0xFFFFFFFF, + datapath_id: String.t() | nil, + n_buffers: 0..0xFFFFFFFF, + n_tables: 0..0xFF, + aux_id: 0..0xFF, + capabilities: [ + :flow_stats + | :table_stats + | :port_stats + | :group_stats + | :ip_reasm + | :queue_stats + | :arp_match_ip + | :port_blocked + ] + } + + @spec ofp_type :: 6 def ofp_type, do: 6 - def read( - <> - ) do + @spec read(<<_::192>>) :: t() + def read(<< + datapath_id::64-bits, + n_buf::32, + n_tab::8, + aux_id::8, + _pad::16, + caps_int::32, + _rsv::32 + >>) do dpid = Openflow.Utils.to_hex_string(datapath_id) flags = Openflow.Enums.int_to_flags(caps_int, :switch_capabilities) @@ -28,6 +55,7 @@ defmodule Openflow.Features.Reply do } end + @spec to_binary(t()) :: <<_::192>> def to_binary(%Reply{ datapath_id: datapath_id, n_buffers: n_buf, diff --git a/lib/openflow/features/request.ex b/lib/openflow/features/request.ex index 8fb5f4e..8f8f057 100644 --- a/lib/openflow/features/request.ex +++ b/lib/openflow/features/request.ex @@ -10,17 +10,22 @@ defmodule Openflow.Features.Request do alias __MODULE__ + @type t :: %Request{ + version: 4, + xid: 0..0xFFFFFFFF, + datapath_id: String.t() | nil, + aux_id: 0..0xFFFF | nil + } + + @spec ofp_type :: 5 def ofp_type, do: 5 - def new(xid \\ 0) do - %Request{xid: xid} - end + @spec new(0..0xFFFF) :: t() + def new(xid \\ 0), do: %Request{xid: xid} - def read(_) do - %Request{} - end + @spec read(any()) :: t() + def read(_), do: %Request{} - def to_binary(%Request{}) do - <<>> - end + @spec to_binary(t()) :: <<>> + def to_binary(%Request{}), do: <<>> end diff --git a/mix.exs b/mix.exs index 19ea0f6..1da9d4a 100644 --- a/mix.exs +++ b/mix.exs @@ -7,10 +7,12 @@ defmodule Tres.Mixfile do version: "0.1.0", elixir: "~> 1.8", start_permanent: Mix.env() == :prod, - escript: [main_module: Openflow.EnumGen, name: :enum_gen, path: "bin/enum_gen"], compilers: [:erlang] ++ Mix.compilers(), deps: deps(), - aliases: [test: "test --no-start", compile: ["escript.build"]], + aliases: [ + test: "test --no-start", + compile: ["run priv/openflow_enum_gen.exs"] + ], docs: docs(), test_coverage: [tool: ExCoveralls], preferred_cli_env: [ diff --git a/priv/openflow_enum_gen.exs b/priv/openflow_enum_gen.exs new file mode 100644 index 0000000..7666f22 --- /dev/null +++ b/priv/openflow_enum_gen.exs @@ -0,0 +1,1150 @@ +import Bitwise + +enums = [ + openflow_codec: [ + {Openflow.Hello, 0}, + {Openflow.ErrorMsg, 1}, + {Openflow.Echo.Request, 2}, + {Openflow.Echo.Reply, 3}, + {Openflow.Experimenter, 4}, + {Openflow.Features.Request, 5}, + {Openflow.Features.Reply, 6}, + {Openflow.GetConfig.Request, 7}, + {Openflow.GetConfig.Reply, 8}, + {Openflow.SetConfig, 9}, + {Openflow.PacketIn, 10}, + {Openflow.FlowRemoved, 11}, + {Openflow.PortStatus, 12}, + {Openflow.PacketOut, 13}, + {Openflow.FlowMod, 14}, + {Openflow.GroupMod, 15}, + {Openflow.PortMod, 16}, + {Openflow.TableMod, 17}, + {Openflow.Multipart.Request, 18}, + {Openflow.Multipart.Reply, 19}, + {Openflow.Barrier.Request, 20}, + {Openflow.Barrier.Reply, 21}, + {Openflow.Role.Request, 24}, + {Openflow.Role.Reply, 25}, + {Openflow.GetAsync.Request, 26}, + {Openflow.GetAsync.Reply, 27}, + {Openflow.SetAsync, 28}, + {Openflow.MeterMod, 29} + ], + experimenter_id: [ + nicira_ext_message: 0x00002320, + onf_ext_message: 0x4F4E4600 + ], + nicira_ext_message: [ + # {Openflow.NxRole.Request, 10}, /* Openflow 1.3 support role request/reply */ + # {Openflow.NxRole.Reply, 11}, + # {Openflow.NxSetFlowFormat, 12}, /* No special reason for implement this struct codec. */ + # {Openflow.NxFlowMod, 13}, /* Prefer use ofp_flow_mod to nx_flow_mod */ + # {Openflow.NxFlowRemoved, 14}, /* Prefer use ofp_flow_removed to nx_flow_removed */ + # {Openflow.NxSetFlowModTableId, 15}, /* OpenFlow 1.3 support multiple flow table. */ + {Openflow.NxSetPacketInFormat, 16}, + # {Openflow.NxPacketIn, 17}, /* No special reason for implement this struct codec. */ + # {Openflow.NxFlowAge, 18}, /* No special reason for implement this struct codec. */ + # {Openflow.NxSetAsyncConfig, 19}, /* Openflow 1.3 support async config. */ + {Openflow.NxSetControllerId, 20}, + {Openflow.NxFlowMonitor.Cancel, 21}, + {Openflow.NxFlowMonitor.Paused, 22}, + {Openflow.NxFlowMonitor.Resumed, 23}, + {Openflow.NxTLVTableMod, 24}, + {Openflow.NxTLVTable.Request, 25}, + {Openflow.NxTLVTable.Reply, 26}, + {Openflow.NxSetAsyncConfig2, 27}, + {Openflow.NxResume, 28}, + {Openflow.NxCtFlushZone, 29}, + {Openflow.NxPacketIn2, 30} + ], + onf_ext_message: [ + {Openflow.OnfBundleControl, 2300}, + {Openflow.OnfBundleAddMessage, 2301} + ], + multipart_request_flags: [ + more: 1 <<< 0 + ], + multipart_reply_flags: [ + more: 1 <<< 0 + ], + multipart_request_codec: [ + {Openflow.Multipart.Desc.Request, 0}, + {Openflow.Multipart.Flow.Request, 1}, + {Openflow.Multipart.Aggregate.Request, 2}, + {Openflow.Multipart.Table.Request, 3}, + {Openflow.Multipart.PortStats.Request, 4}, + {Openflow.Multipart.Queue.Request, 5}, + {Openflow.Multipart.Group.Request, 6}, + {Openflow.Multipart.GroupDesc.Request, 7}, + {Openflow.Multipart.GroupFeatures.Request, 8}, + {Openflow.Multipart.Meter.Request, 9}, + {Openflow.Multipart.MeterConfig.Request, 10}, + {Openflow.Multipart.MeterFeatures.Request, 11}, + {Openflow.Multipart.TableFeatures.Request, 12}, + {Openflow.Multipart.PortDesc.Request, 13}, + {Openflow.Multipart.Experimenter.Request, 0xFFFF} + ], + multipart_reply_codec: [ + {Openflow.Multipart.Desc.Reply, 0}, + {Openflow.Multipart.Flow.Reply, 1}, + {Openflow.Multipart.Aggregate.Reply, 2}, + {Openflow.Multipart.Table.Reply, 3}, + {Openflow.Multipart.PortStats.Reply, 4}, + {Openflow.Multipart.Queue.Reply, 5}, + {Openflow.Multipart.Group.Reply, 6}, + {Openflow.Multipart.GroupDesc.Reply, 7}, + {Openflow.Multipart.GroupFeatures.Reply, 8}, + {Openflow.Multipart.Meter.Reply, 9}, + {Openflow.Multipart.MeterConfig.Reply, 10}, + {Openflow.Multipart.MeterFeatures.Reply, 11}, + {Openflow.Multipart.TableFeatures.Reply, 12}, + {Openflow.Multipart.PortDesc.Reply, 13}, + {Openflow.Multipart.Experimenter.Reply, 0xFFFF} + ], + nicira_ext_stats: [ + {Openflow.Multipart.NxFlow, 0}, + {Openflow.Multipart.NxAggregate, 1}, + {Openflow.Multipart.NxFlowMonitor, 2}, + {Openflow.Multipart.NxIPFIXBridge, 3}, + {Openflow.Multipart.NxIPFIXFlow, 4} + ], + hello_elem: [ + versionbitmap: 1 + ], + error_type: [ + hello_failed: 0, + bad_request: 1, + bad_action: 2, + bad_instruction: 3, + bad_match: 4, + flow_mod_failed: 5, + group_mod_failed: 6, + port_mod_failed: 7, + table_mod_failed: 8, + queue_op_failed: 9, + switch_config_failed: 10, + role_request_failed: 11, + meter_mod_failed: 12, + table_features_failed: 13, + experimenter: 0xFFFF + ], + hello_failed: [ + inconpatible: 0, + eperm: 1 + ], + bad_request: [ + bad_version: 0, + bad_type: 1, + bad_multipart: 2, + bad_experimeter: 3, + bad_exp_type: 4, + eperm: 5, + bad_len: 6, + buffer_empty: 7, + buffer_unknown: 8, + bad_table_id: 9, + is_slave: 10, + bad_port: 11, + bad_packet: 12, + multipart_buffer_overflow: 13, + multipart_request_timeout: 14, + multipart_reply_timeout: 15, + nxm_invalid: 256, + nxm_bad_type: 257, + must_be_zero: 515, + bad_reason: 516, + flow_monitor_bad_event: 520, + undecodable_error: 521, + resume_not_supported: 533, + resume_stale: 534 + ], + bad_action: [ + bad_type: 0, + bad_len: 1, + bad_experimeter: 2, + bad_exp_type: 3, + bad_out_port: 4, + bad_argument: 5, + eperm: 6, + too_many: 7, + bad_queue: 8, + bad_out_group: 9, + match_inconsistent: 10, + unsupported_order: 11, + bad_tag: 12, + bad_set_type: 13, + bad_set_len: 14, + bad_set_argument: 15, + must_be_zero: 256, + conntrack_datapath_support: 265, + bad_conjunction: 526 + ], + bad_instruction: [ + unknown_instruction: 0, + unsupported_instruction: 1, + bad_table_id: 2, + unsupported_metadata: 3, + unsupported_metadata_mask: 4, + bad_experimeter: 5, + bad_exp_type: 6, + bad_len: 7, + eperm: 8, + dup_inst: 256 + ], + bad_match: [ + bad_type: 0, + bad_len: 1, + bad_tag: 2, + bad_dl_addr_mask: 3, + bad_nw_addr_mask: 4, + bad_wildcards: 5, + bad_field: 6, + bad_value: 7, + bad_mask: 8, + bad_prereq: 9, + dup_field: 10, + eperm: 11, + conntrack_datapath_support: 264 + ], + flow_mod_failed: [ + unknown: 0, + table_full: 1, + bad_table_id: 2, + overlap: 3, + eperm: 4, + bad_timeout: 5, + bad_command: 6, + bad_flags: 7 + ], + group_mod_failed: [ + group_exists: 0, + invalid_group: 1, + weight_unsupported: 2, + out_of_groups: 3, + ouf_of_buckets: 4, + chaining_unsupported: 5, + watch_unsupported: 6, + loop: 7, + unknown_group: 8, + chained_group: 9, + bad_type: 10, + bad_command: 11, + bad_bucket: 12, + bad_watch: 13, + eperm: 14, + unknown_bucket: 15, + bucket_exists: 16 + ], + port_mod_failed: [ + bad_port: 0, + bad_hw_addr: 1, + bad_config: 2, + bad_advertise: 3, + eperm: 4 + ], + table_mod_failed: [ + bad_table: 0, + bad_config: 1, + eperm: 2 + ], + queue_op_failed: [ + bad_port: 0, + bad_queue: 1, + eperm: 2 + ], + switch_config_failed: [ + bad_flags: 0, + bad_len: 1, + eperm: 2 + ], + role_request_failed: [ + stale: 0, + unsup: 1, + bad_role: 2 + ], + meter_mod_failed: [ + unknown: 0, + meter_exists: 1, + invalid_meter: 2, + unknown_meter: 3, + bad_command: 4, + bad_flags: 5, + bad_rate: 6, + bad_burst: 7, + bad_band: 8, + bad_band_value: 9, + out_of_meters: 10, + out_of_bands: 11 + ], + table_features_failed: [ + bad_table: 0, + bad_metadata: 1, + bad_type: 2, + bad_len: 3, + bad_argument: 4, + eperm: 5 + ], + switch_capabilities: [ + flow_stats: 1 <<< 0, + table_stats: 1 <<< 1, + port_stats: 1 <<< 2, + group_stats: 1 <<< 3, + ip_reasm: 1 <<< 5, + queue_stats: 1 <<< 6, + arp_match_ip: 1 <<< 7, + port_blocked: 1 <<< 8 + ], + config_flags: [ + drop: 1 <<< 0, + reasm: 1 <<< 1 + ], + controller_max_len: [ + max: 0xFFE5, + no_buffer: 0xFFFF + ], + experimenter_oxm_vendors: [ + nicira_ext_match: 0x00002320, + hp_ext_match: 0x00002428, + onf_ext_match: 0x4F4E4600 + ], + match_type: [ + standard: 0, + oxm: 1 + ], + oxm_class: [ + nxm_0: 0x0000, + nxm_1: 0x0001, + openflow_basic: 0x8000, + packet_register: 0x8001, + experimenter: 0xFFFF + ], + nxm_0: [ + nx_in_port: 0, + nx_eth_dst: 1, + nx_eth_src: 2, + nx_eth_type: 3, + nx_vlan_tci: 4, + nx_ip_tos: 5, + nx_ip_proto: 6, + nx_ipv4_src: 7, + nx_ipv4_dst: 8, + nx_tcp_src: 9, + nx_tcp_dst: 10, + nx_udp_src: 11, + nx_udp_dst: 12, + nx_icmpv4_type: 13, + nx_icmpv4_code: 14, + nx_arp_op: 15, + nx_arp_spa: 16, + nx_arp_tpa: 17, + nx_tcp_flags: 34 + ], + nxm_1: [ + reg0: 0, + reg1: 1, + reg2: 2, + reg3: 3, + reg4: 4, + reg5: 5, + reg6: 6, + reg7: 7, + reg8: 8, + reg9: 9, + reg10: 10, + reg11: 11, + reg12: 12, + reg13: 13, + reg14: 14, + reg15: 15, + tun_id: 16, + nx_arp_sha: 17, + nx_arp_tha: 18, + nx_ipv6_src: 19, + nx_ipv6_dst: 20, + nx_icmpv6_type: 21, + nx_icmpv6_code: 22, + nx_ipv6_nd_target: 23, + nx_ipv6_nd_sll: 24, + nx_ipv6_nd_tll: 25, + nx_ip_frag: 26, + nx_ipv6_label: 27, + nx_ip_ecn: 28, + nx_ip_ttl: 29, + nx_mpls_ttl: 30, + tun_src: 31, + tun_dst: 32, + pkt_mark: 33, + dp_hash: 35, + recirc_id: 36, + conj_id: 37, + tun_gbp_id: 38, + tun_gbp_flags: 39, + tun_metadata0: 40, + tun_metadata1: 41, + tun_metadata2: 42, + tun_metadata3: 43, + tun_metadata4: 44, + tun_metadata5: 45, + tun_metadata6: 46, + tun_metadata7: 47, + tun_metadata8: 48, + tun_metadata9: 49, + tun_metadata10: 50, + tun_metadata11: 51, + tun_metadata12: 52, + tun_metadata13: 53, + tun_metadata14: 54, + tun_metadata15: 55, + tun_metadata16: 56, + tun_metadata17: 57, + tun_metadata18: 58, +tun_metadata19: 59, +tun_metadata20: 60, +tun_metadata21: 61, +tun_metadata22: 62, +tun_metadata23: 63, +tun_metadata24: 64, +tun_metadata25: 65, +tun_metadata26: 66, +tun_metadata27: 67, +tun_metadata28: 68, +tun_metadata29: 69, +tun_metadata30: 70, +tun_metadata31: 71, +tun_metadata32: 72, +tun_metadata33: 73, +tun_metadata34: 74, +tun_metadata35: 75, +tun_metadata36: 76, +tun_metadata37: 77, +tun_metadata38: 78, +tun_metadata39: 79, +tun_metadata40: 80, +tun_metadata41: 81, +tun_metadata42: 82, +tun_metadata43: 83, +tun_metadata44: 84, +tun_metadata45: 85, +tun_metadata46: 86, +tun_metadata47: 87, +tun_metadata48: 88, +tun_metadata49: 89, +tun_metadata50: 90, +tun_metadata51: 91, +tun_metadata52: 92, +tun_metadata53: 93, +tun_metadata54: 94, +tun_metadata55: 95, +tun_metadata56: 96, +tun_metadata57: 97, +tun_metadata58: 98, +tun_metadata59: 99, +tun_metadata60: 100, +tun_metadata61: 101, +tun_metadata62: 102, +tun_metadata63: 103, +tun_flags: 104, +ct_state: 105, +ct_zone: 106, +ct_mark: 107, +ct_label: 108, +tun_ipv6_src: 109, +tun_ipv6_dst: 110, +xxreg0: 111, +xxreg1: 112, +xxreg2: 113, +xxreg3: 114, +xxreg4: 115, +xxreg5: 116, +xxreg6: 117, +xxreg7: 118, +ct_nw_proto: 119, +ct_nw_src: 120, +ct_nw_dst: 121, +ct_ipv6_src: 122, +ct_ipv6_dst: 123, +ct_tp_src: 124, +ct_tp_dst: 125 + ], + openflow_basic: [ + in_port: 0, + in_phy_port: 1, + metadata: 2, + eth_dst: 3, + eth_src: 4, + eth_type: 5, + vlan_vid: 6, + vlan_pcp: 7, + ip_dscp: 8, + ip_ecn: 9, + ip_proto: 10, + ipv4_src: 11, + ipv4_dst: 12, + tcp_src: 13, + tcp_dst: 14, + udp_src: 15, + udp_dst: 16, + sctp_src: 17, + sctp_dst: 18, + icmpv4_type: 19, + icmpv4_code: 20, + arp_op: 21, + arp_spa: 22, + arp_tpa: 23, + arp_sha: 24, + arp_tha: 25, + ipv6_src: 26, + ipv6_dst: 27, + ipv6_flabel: 28, + icmpv6_type: 29, + icmpv6_code: 30, + ipv6_nd_target: 31, + ipv6_nd_sll: 32, + ipv6_nd_tll: 33, + mpls_label: 34, + mpls_tc: 35, + mpls_bos: 36, + pbb_isid: 37, + tunnel_id: 38, + ipv6_exthdr: 39, + + # Lagopus extended match fields + pbb_uca: 41, + packet_type: 42, + gre_flags: 43, + gre_ver: 44, + gre_protocol: 45, + gre_key: 46, + gre_seqnum: 47, + lisp_flags: 48, + lisp_nonce: 49, + lisp_id: 50, + vxlan_flags: 51, + vxlan_vni: 52, + mpls_data_first_nibble: 53, + mpls_ach_version: 54, + mpls_ach_channel: 55, + mpls_pw_metadata: 56, + mpls_cw_flags: 57, + mpls_cw_fragment: 58, +mpls_cw_len: 59, +mpls_cw_seq_num: 60, +gtpu_flags: 61, +gtpu_ver: 62, +gtpu_msg_type: 63, +gtpu_teid: 64, +gtpu_extn_hdr: 65, +gtpu_extn_udp_port: 66, +gtpu_extn_sci: 67 + ], + vlan_id: [ + present: 0x1000, + none: 0x0000 + ], + ipv6exthdr_flags: [ + nonext: 1 <<< 0, + esp: 1 <<< 1, + auth: 1 <<< 2, + dest: 1 <<< 3, + frag: 1 <<< 4, + router: 1 <<< 5, + hop: 1 <<< 6, + unrep: 1 <<< 7, + unseq: 1 <<< 8 + ], + tcp_flags: [ + fin: 1 <<< 0, + syn: 1 <<< 1, + rst: 1 <<< 2, + psh: 1 <<< 3, + ack: 1 <<< 4, + urg: 1 <<< 5, + ece: 1 <<< 6, + cwr: 1 <<< 7, + ns: 1 <<< 8 + ], + ct_state_flags: [ + # Beginning of a new connection. + new: 1 <<< 0, + # Part of an existing connection. + est: 1 <<< 1, + # Related to an established connection. + rel: 1 <<< 2, + # Flow is in the reply direction. + rep: 1 <<< 3, + # Could not track connection. + inv: 1 <<< 4, + # Conntrack has occurred. + trk: 1 <<< 5, + # Packet's source address/port was mangled by NAT. + snat: 1 <<< 6, + # Packet's destination address/port was mangled by NAT. + dnat: 1 <<< 7 + ], + packet_register: [ + xreg0: 0, + xreg1: 1, + xreg2: 2, + xreg3: 3, + xreg4: 4, + xreg5: 5, + xreg6: 6, + xreg7: 7 + ], + nicira_ext_match: [ + nsh_flags: 1, + nsh_mdtype: 2, + nsh_np: 3, + nsh_spi: 4, + nsh_si: 5, + nsh_c1: 6, + nsh_c2: 7, + nsh_c3: 8, + nsh_c4: 9 + ], + hp_ext_match: [ + hp_udp_src_port_range: 0, + hp_udp_dst_port_range: 1, + hp_tcp_src_port_range: 2, + hp_tcp_dst_port_range: 3, + hp_tcp_flags: 4, + hp_custom_1: 5, + hp_custom_2: 6, + hp_custom_3: 7, + hp_custom_4: 8 + ], + hp_custom_match_type: [ + l2_start: 1, + l3_start: 2, + l4_start: 3 + ], + onf_ext_match: [ + onf_tcp_flags: 42, + onf_actset_output: 43, + onf_pbb_uca: 2560 + ], + buffer_id: [ + no_buffer: 0xFFFFFFFF + ], + port_config: [ + port_down: 1 <<< 0, + no_receive: 1 <<< 2, + no_forward: 1 <<< 5, + no_packet_in: 1 <<< 6 + ], + port_state: [ + link_down: 1 <<< 0, + blocked: 1 <<< 1, + live: 1 <<< 2 + ], + port_features: [ + {:"10mb_hd", 1 <<< 0}, + {:"10mb_fd", 1 <<< 1}, + {:"100mb_hd", 1 <<< 2}, + {:"100mb_fd", 1 <<< 3}, + {:"1gb_hd", 1 <<< 4}, + {:"1gb_fd", 1 <<< 5}, + {:"10gb_fd", 1 <<< 6}, + {:"40gb_fd", 1 <<< 7}, + {:"100gb_fd", 1 <<< 8}, + {:"1tb_fd", 1 <<< 9}, + {:other, 1 <<< 10}, + {:copper, 1 <<< 11}, + {:fiber, 1 <<< 12}, + {:autoneg, 1 <<< 13}, + {:pause, 1 <<< 14}, + {:pause_asym, 1 <<< 15} + ], + openflow10_port_no: [ + max: 0xFF00, + in_port: 0xFFF8, + table: 0xFFF9, + normal: 0xFFFA, + flood: 0xFFFB, + all: 0xFFFC, + controller: 0xFFFD, + local: 0xFFFE, + none: 0xFFFF + ], + openflow13_port_no: [ + max: 0xFFFFFF00, + in_port: 0xFFFFFFF8, + table: 0xFFFFFFF9, + normal: 0xFFFFFFFA, + flood: 0xFFFFFFFB, + all: 0xFFFFFFFC, + controller: 0xFFFFFFFD, + local: 0xFFFFFFFE, + any: 0xFFFFFFFF + ], + packet_in_reason: [ + no_match: 0, + action: 1, + invalid_ttl: 2, + action_set: 3, + group: 4, + packet_out: 5 + ], + flow_mod_command: [ + add: 0, + modify: 1, + modify_strict: 2, + delete: 3, + delete_strict: 4 + ], + flow_mod_flags: [ + send_flow_rem: 1 <<< 0, + check_overlap: 1 <<< 1, + reset_counts: 1 <<< 2, + no_packet_counts: 1 <<< 3, + no_byte_counts: 1 <<< 4 + ], + flow_removed_reason: [ + idle_timeout: 0, + hard_timeout: 1, + delete: 2, + group_delete: 3, + meter_delete: 4, + eviction: 5 + ], + port_reason: [ + add: 0, + delete: 1, + modify: 2 + ], + group_mod_command: [ + add: 0, + modify: 1, + delete: 2 + ], + group_type: [ + all: 0, + select: 1, + indirect: 2, + fast_failover: 3 + ], + group_id: [ + max: 0xFFFFFF00, + all: 0xFFFFFFFC, + any: 0xFFFFFFFF + ], + group_capabilities: [ + select_weight: 1 <<< 0, + select_liveness: 1 <<< 1, + chaining: 1 <<< 2, + chaining_checks: 1 <<< 3 + ], +table_id: [ + max: 0xFE, + all: 0xFF +], +queue_id: [ + all: 0xFFFFFFFF +], +meter_mod_command: [ + add: 0, + modify: 1, + delete: 2 +], +meter_id: [ + max: 0xFFFF0000, + slowpath: 0xFFFFFFFD, + controller: 0xFFFFFFFE, + all: 0xFFFFFFFF +], +meter_flags: [ + kbps: 1 <<< 0, + pktps: 1 <<< 1, + burst: 1 <<< 2, + stats: 1 <<< 3 +], +meter_band_type: [ + {Openflow.MeterBand.Drop, 1}, + {Openflow.MeterBand.Remark, 2}, + {Openflow.MeterBand.Experimenter, 0xFFFF} +], +table_config: [ + table_miss_controller: 0 <<< 0, + table_miss_continue: 1 <<< 0, + table_miss_drop: 2 <<< 0, + table_miss_mask: 3 <<< 0, + eviction: 1 <<< 2, + vacancy_events: 1 <<< 3 +], +action_type: [ + {Openflow.Action.Output, 0}, + {Openflow.Action.CopyTtlOut, 11}, + {Openflow.Action.CopyTtlIn, 12}, + {Openflow.Action.SetMplsTtl, 15}, + {Openflow.Action.DecMplsTtl, 16}, + {Openflow.Action.PushVlan, 17}, + {Openflow.Action.PopVlan, 18}, + {Openflow.Action.PushMpls, 19}, + {Openflow.Action.PopMpls, 20}, + {Openflow.Action.SetQueue, 21}, + {Openflow.Action.Group, 22}, + {Openflow.Action.SetNwTtl, 23}, + {Openflow.Action.DecNwTtl, 24}, + {Openflow.Action.SetField, 25}, + {Openflow.Action.PushPbb, 26}, + {Openflow.Action.PopPbb, 27}, + {Openflow.Action.Encap, 28}, + {Openflow.Action.Decap, 29}, + {Openflow.Action.SetSequence, 30}, + {Openflow.Action.ValidateSequence, 31}, + {Openflow.Action.Experimenter, 0xFFFF} +], +action_vendor: [ + nicira_ext_action: 0x00002320, + onf_ext_action: 0x4F4E4600 +], +onf_ext_action: [ + {Openflow.Action.OnfCopyField, 3200} +], +nicira_ext_action: [ + {Openflow.Action.NxResubmit, 1}, + {Openflow.Action.NxSetTunnel, 2}, + # {Openflow.Action.NxSetQueue, 4}, Deprecated + # {Openflow.Action.NxPopQueue, 5}, Deprecated + {Openflow.Action.NxRegMove, 6}, + {Openflow.Action.NxRegLoad, 7}, + {Openflow.Action.NxNote, 8}, + {Openflow.Action.NxSetTunnel64, 9}, + {Openflow.Action.NxMultipath, 10}, + {Openflow.Action.NxBundle, 12}, + {Openflow.Action.NxBundleLoad, 13}, + {Openflow.Action.NxResubmitTable, 14}, + {Openflow.Action.NxOutputReg, 15}, + {Openflow.Action.NxLearn, 16}, + {Openflow.Action.NxExit, 17}, + {Openflow.Action.NxDecTtl, 18}, + {Openflow.Action.NxFinTimeout, 19}, + {Openflow.Action.NxController, 20}, + {Openflow.Action.NxDecTtlCntIds, 21}, + {Openflow.Action.NxWriteMetadata, 22}, + # {Openflow.Action.NxPushMpls, 23}, # Deprecated + # {Openflow.Action.NxPopMpls, 24}, # Deprecated + # {Openflow.Action.NxSetMplsTtl, 25}, Deprecated + # {Openflow.Action.NxDecMplsTtl, 26}, Deprecated + {Openflow.Action.NxStackPush, 27}, + {Openflow.Action.NxStackPop, 28}, + {Openflow.Action.NxSample, 29}, + # {Openflow.Action.NxSetMplsLabel, 30}, Deprecated + # {Openflow.Action.NxSetMplsTc, 31}, Deprecated + {Openflow.Action.NxOutputReg2, 32}, + {Openflow.Action.NxRegLoad2, 33}, + {Openflow.Action.NxConjunction, 34}, + {Openflow.Action.NxConntrack, 35}, + {Openflow.Action.NxNat, 36}, + {Openflow.Action.NxController2, 37}, + {Openflow.Action.NxSample2, 38}, + {Openflow.Action.NxOutputTrunc, 39}, + {Openflow.Action.NxGroup, 40}, + {Openflow.Action.NxSample3, 41}, + {Openflow.Action.NxClone, 42}, + {Openflow.Action.NxCtClear, 43}, + {Openflow.Action.NxResubmitTableCt, 44}, + {Openflow.Action.NxLearn2, 45}, + {Openflow.Action.NxEncap, 46}, + {Openflow.Action.NxDecap, 47}, + {Openflow.Action.NxDebugRecirc, 0xFF} +], +nx_mp_algorithm: [ + modulo_n: 0, + hash_threshold: 1, + highest_random_weight: 2, + iterative_hash: 3 +], +nx_hash_fields: [ + eth_src: 0, + symmetric_l4: 1, + symmetric_l3l4: 2, + symmetric_l3l4_udp: 3, + nw_src: 4, + nw_dst: 5 +], +nx_bd_algorithm: [ + active_backup: 0, + highest_random_weight: 1 +], +nx_learn_flag: [ + send_flow_rem: 1 <<< 0, + delete_learned: 1 <<< 1, + write_result: 1 <<< 2 +], +nx_conntrack_flags: [ + commit: 1 <<< 0, + force: 1 <<< 1 +], +nx_nat_flags: [ + src: 1 <<< 0, + dst: 1 <<< 1, + persistent: 1 <<< 2, + protocol_hash: 1 <<< 3, + protocol_random: 1 <<< 4 +], +nx_nat_range: [ + ipv4_min: 1 <<< 0, + ipv4_max: 1 <<< 1, + ipv6_min: 1 <<< 2, + ipv6_max: 1 <<< 3, + proto_min: 1 <<< 4, + proto_max: 1 <<< 5 +], +nx_action_controller2_prop_type: [ + max_len: 0, + controller_id: 1, + reason: 2, + userdata: 3, + pause: 4 +], +nx_action_sample_direction: [ + default: 0, + ingress: 1, + egress: 2 +], +nx_flow_spec_type: [ + {Openflow.Action.NxFlowSpecMatch, 0}, + {Openflow.Action.NxFlowSpecLoad, 1}, + {Openflow.Action.NxFlowSpecOutput, 2} +], +instruction_type: [ + {Openflow.Instruction.GotoTable, 1}, + {Openflow.Instruction.WriteMetadata, 2}, + {Openflow.Instruction.WriteActions, 3}, + {Openflow.Instruction.ApplyActions, 4}, + {Openflow.Instruction.ClearActions, 5}, + {Openflow.Instruction.Meter, 6}, + {Openflow.Instruction.Experimenter, 0xFFFF} +], +controller_role: [ + nochange: 0, + equal: 1, + master: 2, + slave: 3 +], +nx_role: [ + other: 0, + master: 1, + slave: 2 +], +packet_in_format: [ + standard: 0, + nxt_packet_in: 1, + nxt_packet_in2: 2 +], +flow_format: [ + openflow10: 0, + nxm: 1 +], +packet_in2_prop_type: [ + packet: 0, + full_len: 1, + buffer_id: 2, + table_id: 3, + cookie: 4, + reason: 5, + metadata: 6, + userdata: 7, + continuation: 8 +], +continuation_prop_type: [ + bridge: 0x8000, + stack: 0x8001, + mirrors: 0x8002, + conntracked: 0x8003, + table_id: 0x8004, + cookie: 0x8005, + actions: 0x8006, + action_set: 0x8007 +], +flow_monitor_flag: [ + initial: 1 <<< 0, + add: 1 <<< 1, + delete: 1 <<< 2, + modify: 1 <<< 3, + actions: 1 <<< 4, + own: 1 <<< 5 +], +flow_update_event: [ + added: 0, + deleted: 1, + modified: 2, + abbrev: 3 +], +tlv_table_mod_command: [ + add: 0, + delete: 1, + clear: 2 +], +table_feature_prop_type: [ + instructions: 0, + instructions_miss: 1, + next_tables: 2, + next_tables_miss: 3, + write_actions: 4, + write_actions_miss: 5, + apply_actions: 6, + apply_actions_miss: 7, + match: 8, + wildcards: 10, + write_setfield: 12, + write_setfield_miss: 13, + apply_setfield: 14, + apply_setfield_miss: 15, + experimenter: 0xFFFE, + experimenter_miss: 0xFFFF +], +bundle_ctrl_type: [ + open_request: 0, + open_reply: 1, + close_request: 2, + close_reply: 3, + commit_request: 4, + commit_reply: 5, + discard_request: 6, + discard_reply: 7 +], +bundle_flags: [ + atomic: 1 <<< 0, + ordered: 1 <<< 1 +] +] + +File.write( + "lib/openflow/enums.ex", + """ + defmodule Openflow.Enums do + @moduledoc "auto generated code"\n + """, + [:binary] +) + +for {enum_name, enum_def} <- enums do + to_int_fn_name = :"#{enum_name}_to_int" + + for {key, _value} <- enum_def do + File.write( + "lib/openflow/enums.ex", + """ + def to_int(#{inspect(key)}, :#{enum_name}) do + #{to_int_fn_name}(#{inspect(key)}) + catch + _class, _reason -> #{inspect(key)} + end\n + """, + [:append, :binary] + ) + end + + File.write( + "lib/openflow/enums.ex", + """ + def to_int(_int, :#{enum_name}) do + throw(:bad_enum) + end\n + """, + [:append, :binary] + ) + end + + for {enum_name, enum_def} <- enums do + to_atom_fn_name = :"#{enum_name}_to_atom" + + for {_key, value} <- enum_def do + File.write( + "lib/openflow/enums.ex", + """ + def to_atom(#{inspect(value, base: :hex)}, :#{enum_name}) do + #{to_atom_fn_name}(#{inspect(value, base: :hex)}) + catch + _class, _reason -> #{value} + end\n + """, + [:append, :binary] + ) + end + + File.write( + "lib/openflow/enums.ex", + """ + def to_atom(_, :#{enum_name}) do + throw(:bad_enum) + end\n + """, + [:append, :binary] + ) + end + + for {enum_name, enum_def} <- enums do + to_int_fn_name = :"#{enum_name}_to_int" + to_atom_fn_name = :"#{enum_name}_to_atom" + + for {key, value} <- enum_def do + File.write( + "lib/openflow/enums.ex", + " def #{to_int_fn_name}(#{inspect(key)}), do: #{inspect(value, base: :hex)}\n", + [ + :append, + :binary + ] + ) + end + + File.write("lib/openflow/enums.ex", " def #{to_int_fn_name}(_), do: throw(:bad_enum)\n", [ + :append, + :binary + ]) + + for {key, value} <- enum_def do + File.write( + "lib/openflow/enums.ex", + " def #{to_atom_fn_name}(#{inspect(value, base: :hex)}), do: #{inspect(key)}\n", + [ + :append, + :binary + ] + ) + end + + File.write("lib/openflow/enums.ex", " def #{to_atom_fn_name}(_), do: throw(:bad_enum)\n", [ + :append, + :binary + ]) + end + + for {enum_name, _enum_def} <- enums do + File.write( + "lib/openflow/enums.ex", + """ + def int_to_flags(int, :#{enum_name}) do + Openflow.Utils.int_to_flags([], int, enum_of(:#{enum_name})) + end\n + """, + [:append, :binary] + ) + end + + for {enum_name, _enum_def} <- enums do + File.write( + "lib/openflow/enums.ex", + """ + def flags_to_int(flags, :#{enum_name}) do + Openflow.Utils.flags_to_int(0, flags, enum_of(:#{enum_name})) + end\n + """, + [:append, :binary] + ) + end + + for {enum_name, enum_def} <- enums do + File.write( + "lib/openflow/enums.ex", + " defp enum_of(:#{enum_name}), do: #{inspect(enum_def, pretty: true, limit: 100_000)}\n", + [:append, :binary] + ) + end + + File.write("lib/openflow/enums.ex", "end", [:append, :binary]) + diff --git a/test/ofp_echo_test.exs b/test/ofp_echo_test.exs index 5e21fed..75d2683 100644 --- a/test/ofp_echo_test.exs +++ b/test/ofp_echo_test.exs @@ -2,6 +2,54 @@ defmodule OfpEchoTest do use ExUnit.Case doctest Openflow + describe "Openflow.Echo.Request" do + test "with xid and data options" do + echo = Openflow.Echo.Request.new(xid: 1, data: "echo") + + echo + |> Openflow.to_binary() + |> Openflow.read() + |> Kernel.elem(1) + |> Kernel.==(echo) + |> assert() + end + + test "with data options" do + echo = Openflow.Echo.Request.new("echo") + + echo + |> Openflow.to_binary() + |> Openflow.read() + |> Kernel.elem(1) + |> Kernel.==(echo) + |> assert() + end + end + + describe "Openflow.Echo.Reply" do + test "with xid and data options" do + echo = Openflow.Echo.Reply.new(xid: 1, data: "echo") + + echo + |> Openflow.to_binary() + |> Openflow.read() + |> Kernel.elem(1) + |> Kernel.==(echo) + |> assert() + end + + test "with data options" do + echo = Openflow.Echo.Reply.new("echo") + + echo + |> Openflow.to_binary() + |> Openflow.read() + |> Kernel.elem(1) + |> Kernel.==(echo) + |> assert() + end + end + describe "Openflow.read/1" do test "with OFP_ECHO_REQUEST packet" do {:ok, %Openflow.Echo.Request{} = echo, ""} = @@ -9,9 +57,11 @@ defmodule OfpEchoTest do |> File.read!() |> Openflow.read() - assert echo.version == 4 - assert echo.xid == 0 - assert echo.data == "" + expect = Openflow.Echo.Request.new() + + assert echo.version == expect.version + assert echo.xid == expect.xid + assert echo.data == expect.data end test "with OFP_ECHO_REPLY packet" do @@ -20,9 +70,11 @@ defmodule OfpEchoTest do |> File.read!() |> Openflow.read() - assert echo.version == 4 - assert echo.xid == 0 - assert echo.data == "" + expect = Openflow.Echo.Reply.new() + + assert echo.version == expect.version + assert echo.xid == expect.xid + assert echo.data == expect.data end end diff --git a/test/ofp_features_test.exs b/test/ofp_features_test.exs index 5d38572..6cb9430 100644 --- a/test/ofp_features_test.exs +++ b/test/ofp_features_test.exs @@ -9,8 +9,10 @@ defmodule OfpFeaturesTest do |> File.read!() |> Openflow.read() - assert features.version == 4 - assert features.xid == 0 + expect = Openflow.Features.Request.new(0) + + assert features.version == expect.version + assert features.xid == expect.xid end test "with OFP_FEATURES_REPLY packet" do