add documents
This commit is contained in:
parent
22e62d32ae
commit
1cb687433c
14 changed files with 377 additions and 27 deletions
|
|
@ -1,21 +1,35 @@
|
||||||
defmodule Openflow.Action.DecNwTtl do
|
defmodule Openflow.Action.DecNwTtl do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
|
Decrement IP TTL
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defstruct([])
|
defstruct([])
|
||||||
|
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
|
|
||||||
|
@type t :: %DecNwTtl{}
|
||||||
|
|
||||||
|
@spec ofpat() :: 24
|
||||||
def ofpat, do: 24
|
def ofpat, do: 24
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Create a new dec_nw_ttl action struct
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> %DecNwTtl{} = DecNwTtl.new()
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
@spec new() :: t()
|
||||||
def new do
|
def new do
|
||||||
%DecNwTtl{}
|
%DecNwTtl{}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec to_binary(t()) :: <<_::16, _::_*8>>
|
||||||
def to_binary(%DecNwTtl{}) do
|
def to_binary(%DecNwTtl{}) do
|
||||||
<<24::16, 8::16, 0::size(4)-unit(8)>>
|
<<24::16, 8::16, 0::size(4)-unit(8)>>
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec read(<<_::16, _::_*8>>) :: t()
|
||||||
def read(<<24::16, 8::16, _::size(4)-unit(8)>>) do
|
def read(<<24::16, 8::16, _::size(4)-unit(8)>>) do
|
||||||
%DecNwTtl{}
|
%DecNwTtl{}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,38 @@
|
||||||
defmodule Openflow.Action.Group do
|
defmodule Openflow.Action.Group do
|
||||||
|
@moduledoc """
|
||||||
|
Apply Group
|
||||||
|
"""
|
||||||
|
|
||||||
defstruct(id: 0)
|
defstruct(id: 0)
|
||||||
|
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
|
|
||||||
|
@type t :: %Group{id: 0..0xFFFFFFFF}
|
||||||
|
|
||||||
|
@spec ofpat() :: 22
|
||||||
def ofpat, do: 22
|
def ofpat, do: 22
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Create a new group action struct
|
||||||
|
|
||||||
|
## Options
|
||||||
|
- id: Group identifier
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> %Group{id: 10} = Group.new(10)
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
@spec new(0..0xFFFFFFFF) :: t()
|
||||||
def new(id) do
|
def new(id) do
|
||||||
%Group{id: id}
|
%Group{id: id}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec to_binary(t()) :: <<_::16, _::_*8>>
|
||||||
def to_binary(%Group{id: id}) do
|
def to_binary(%Group{id: id}) do
|
||||||
<<22::16, 8::16, id::32>>
|
<<22::16, 8::16, id::32>>
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec read(<<_::16, _::_*8>>) :: t()
|
||||||
def read(<<22::16, 8::16, id::32>>) do
|
def read(<<22::16, 8::16, id::32>>) do
|
||||||
%Group{id: id}
|
%Group{id: id}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,32 @@
|
||||||
defmodule Openflow.Action.NxRegLoad do
|
defmodule Openflow.Action.NxRegLoad do
|
||||||
|
@moduledoc """
|
||||||
|
Copies value[0:n_bits] to dst[ofs:ofs+n_bits], where a[b:c] denotes the bits
|
||||||
|
within 'a' numbered 'b' through 'c' (not including bit 'c'). Bit numbering
|
||||||
|
starts at 0 for the least-significant bit, 1 for the next most significant
|
||||||
|
bit, and so on.
|
||||||
|
|
||||||
|
'dst' is an nxm_header with nxm_hasmask=0. See the documentation for
|
||||||
|
NXAST_REG_MOVE, above, for the permitted fields and for the side effects of
|
||||||
|
loading them.
|
||||||
|
|
||||||
|
The 'ofs' and 'n_bits' fields are combined into a single 'ofs_nbits' field
|
||||||
|
to avoid enlarging the structure by another 8 bytes. To allow 'n_bits' to
|
||||||
|
take a value between 1 and 64 (inclusive) while taking up only 6 bits, it is
|
||||||
|
also stored as one less than its true value:
|
||||||
|
|
||||||
|
```
|
||||||
|
15 6 5 0
|
||||||
|
+------------------------------+------------------+
|
||||||
|
| ofs | n_bits - 1 |
|
||||||
|
+------------------------------+------------------+
|
||||||
|
```
|
||||||
|
|
||||||
|
The switch will reject actions for which ofs+n_bits is greater than the
|
||||||
|
width of 'dst', or in which any bits in 'value' with value 2n_bits or
|
||||||
|
greater are set to 1, with error type OFPET_BAD_ACTION, code
|
||||||
|
OFPBAC_BAD_ARGUMENT.
|
||||||
|
"""
|
||||||
|
|
||||||
import Bitwise
|
import Bitwise
|
||||||
|
|
||||||
defstruct(
|
defstruct(
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,94 @@
|
||||||
defmodule Openflow.Action.NxRegMove do
|
defmodule Openflow.Action.NxRegMove do
|
||||||
|
@moduledoc """
|
||||||
|
Copies src[src_ofs:src_ofs+n_bits] to dst[dst_ofs:dst_ofs+n_bits], where
|
||||||
|
a[b:c] denotes the bits within 'a' numbered 'b' through 'c' (not including
|
||||||
|
bit 'c'). Bit numbering starts at 0 for the least-significant bit, 1 for
|
||||||
|
the next most significant bit, and so on.
|
||||||
|
|
||||||
|
The following nxm_header values are potentially acceptable as 'src':
|
||||||
|
- `:in_port`
|
||||||
|
- `:eth_dst`
|
||||||
|
- `:eth_src`
|
||||||
|
- `:eth_type`
|
||||||
|
- `:vlan_tci`
|
||||||
|
- `:ip_tos`
|
||||||
|
- `:ip_proto`
|
||||||
|
- `:ip_src`
|
||||||
|
- `:ip_dst`
|
||||||
|
- `:tcp_src`
|
||||||
|
- `:tcp_dst`
|
||||||
|
- `:udp_src`
|
||||||
|
- `:udp_dst`
|
||||||
|
- `:icmp_type`
|
||||||
|
- `:icmp_code`
|
||||||
|
- `:arp_op`
|
||||||
|
- `:arp_spa`
|
||||||
|
- `:arp_tpa`
|
||||||
|
- `:tun_id`
|
||||||
|
- `:arp_sha`
|
||||||
|
- `:arp_tha`
|
||||||
|
- `:icmpv6_type`
|
||||||
|
- `:icmpv6_code`
|
||||||
|
- `:nd_sll`
|
||||||
|
- `:nd_tll`
|
||||||
|
- `:reg(idx)` for idx in the switch's accepted range.
|
||||||
|
- `:pkt_mark`
|
||||||
|
- `:tun_ipv4_src`
|
||||||
|
- `:tun_ipv4_dst`
|
||||||
|
|
||||||
|
The following nxm_header values are potentially acceptable as 'dst':
|
||||||
|
- `:eth_dst`
|
||||||
|
- `:eth_src`
|
||||||
|
- `:ip_tos`
|
||||||
|
- `:ip_src`
|
||||||
|
- `:ip_dst`
|
||||||
|
- `:tcp_src`
|
||||||
|
- `:tcp_dst`
|
||||||
|
- `:udp_src`
|
||||||
|
- `:udp_dst`
|
||||||
|
- `:icmp_type`
|
||||||
|
- `:icmp_code`
|
||||||
|
- `:icmpv6_type`
|
||||||
|
- `:icmpv6_code`
|
||||||
|
- `:arp_sha`
|
||||||
|
- `:arp_tha`
|
||||||
|
- `:arp_op`
|
||||||
|
- `:arp_spa`
|
||||||
|
- `:arp_tpa`
|
||||||
|
|
||||||
|
Modifying any of the above fields changes the corresponding packet header.
|
||||||
|
|
||||||
|
- `:in_port`
|
||||||
|
|
||||||
|
- `:reg(idx)` for idx in the switch's accepted range.
|
||||||
|
|
||||||
|
- `:pkt_mark`
|
||||||
|
|
||||||
|
- `:vlan_tci`. Modifying this field's value has side effects on the
|
||||||
|
packet's 802.1Q header. Setting a value with CFI=0 removes the 802.1Q
|
||||||
|
header (if any), ignoring the other bits. Setting a value with CFI=1
|
||||||
|
adds or modifies the 802.1Q header appropriately, setting the TCI field
|
||||||
|
to the field's new value (with the CFI bit masked out).
|
||||||
|
|
||||||
|
- `:tun_id`, `:tun_ipv4_src`, `:tun_ipv4_dst`. Modifying
|
||||||
|
any of these values modifies the corresponding tunnel header field used
|
||||||
|
for the packet's next tunnel encapsulation, if allowed by the
|
||||||
|
configuration of the output tunnel port.
|
||||||
|
|
||||||
|
A given nxm_header value may be used as 'src' or 'dst' only on a flow whose
|
||||||
|
nx_match satisfies its prerequisites. For example, NXM_OF_IP_TOS may be
|
||||||
|
used only if the flow's nx_match includes an nxm_entry that specifies
|
||||||
|
nxm_type=NXM_OF_ETH_TYPE, nxm_hasmask=0, and nxm_value=0x0800.
|
||||||
|
|
||||||
|
The switch will reject actions for which src_ofs+n_bits is greater than the
|
||||||
|
width of 'src' or dst_ofs+n_bits is greater than the width of 'dst' with
|
||||||
|
error type OFPET_BAD_ACTION, code OFPBAC_BAD_ARGUMENT.
|
||||||
|
|
||||||
|
This action behaves properly when 'src' overlaps with 'dst', that is, it
|
||||||
|
behaves as if 'src' were copied out to a temporary buffer, then the
|
||||||
|
temporary buffer copied to 'dst'.
|
||||||
|
"""
|
||||||
|
|
||||||
defstruct(
|
defstruct(
|
||||||
n_bits: 0,
|
n_bits: 0,
|
||||||
src_offset: 0,
|
src_offset: 0,
|
||||||
|
|
@ -13,6 +103,47 @@ defmodule Openflow.Action.NxRegMove do
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
alias Openflow.Action.Experimenter
|
alias Openflow.Action.Experimenter
|
||||||
|
|
||||||
|
@type t :: %NxRegMove{
|
||||||
|
n_bits: 0..0xFFFF,
|
||||||
|
src_offset: 0..0xFFFF,
|
||||||
|
dst_offset: 0..0xFFFF,
|
||||||
|
src_field: atom(),
|
||||||
|
dst_field: atom()
|
||||||
|
}
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Creates a new reg_move action struct
|
||||||
|
|
||||||
|
## Options:
|
||||||
|
- n_bits: Number of bits
|
||||||
|
- src_offset: Starting bit offset in source
|
||||||
|
- dst_offset: Starting bit offset in destination
|
||||||
|
- src_field: oxm/nxm field name for source field
|
||||||
|
- dst_field: oxm/nxm field name for destination field
|
||||||
|
|
||||||
|
## Example
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
# 1. move:NXM_OF_IN_PORT[]->NXM_OF_VLAN_TCI[]
|
||||||
|
iex> NxRegMove.new(src_field: :nx_in_port, :nx_vlan_tci)
|
||||||
|
|
||||||
|
# 2. move:NXM_NX_TUN_ID[40..57]->NXM_NX_REG1[0..17]
|
||||||
|
iex> NxRegMove.new(
|
||||||
|
iex> src_field: :tun_id,
|
||||||
|
iex> src_offset: 40,
|
||||||
|
iex> dst_field: :reg1
|
||||||
|
iex> dst_offset: 0,
|
||||||
|
iex> n_bits: 18
|
||||||
|
iex> )
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
@spec new(
|
||||||
|
n_bits: 0..0xFFFF,
|
||||||
|
src_offset: 0..0xFFFF,
|
||||||
|
dst_offset: 0..0xFFFF,
|
||||||
|
src_field: atom(),
|
||||||
|
dst_field: atom()
|
||||||
|
) :: t()
|
||||||
def new(options \\ []) do
|
def new(options \\ []) do
|
||||||
src_field = options[:src_field] || raise "src_field must be specified"
|
src_field = options[:src_field] || raise "src_field must be specified"
|
||||||
dst_field = options[:dst_field] || raise "dst_field must be specified"
|
dst_field = options[:dst_field] || raise "dst_field must be specified"
|
||||||
|
|
@ -27,6 +158,7 @@ defmodule Openflow.Action.NxRegMove do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec to_binary(t()) :: binary()
|
||||||
def to_binary(%NxRegMove{} = move) do
|
def to_binary(%NxRegMove{} = move) do
|
||||||
src_field_bin = Openflow.Match.codec_header(move.src_field)
|
src_field_bin = Openflow.Match.codec_header(move.src_field)
|
||||||
dst_field_bin = Openflow.Match.codec_header(move.dst_field)
|
dst_field_bin = Openflow.Match.codec_header(move.dst_field)
|
||||||
|
|
@ -42,6 +174,7 @@ defmodule Openflow.Action.NxRegMove do
|
||||||
>>)
|
>>)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec read(binary()) :: t()
|
||||||
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
def read(<<@experimenter::32, @nxast::16, body::bytes>>) do
|
||||||
<<n_bits::16, src_ofs::16, dst_ofs::16, src_field_bin::4-bytes, dst_field_bin::4-bytes>> =
|
<<n_bits::16, src_ofs::16, dst_ofs::16, src_field_bin::4-bytes, dst_field_bin::4-bytes>> =
|
||||||
body
|
body
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,16 @@
|
||||||
defmodule Openflow.Action.NxResubmit do
|
defmodule Openflow.Action.NxResubmit do
|
||||||
|
@moduledoc """
|
||||||
|
Searches the flow table again, using a flow that is slightly modified from the original lookup:
|
||||||
|
|
||||||
|
Following the lookup, the original in_port is restored.
|
||||||
|
|
||||||
|
If the modified flow matched in the flow table, then the corresponding
|
||||||
|
actions are executed. Afterward, actions following NXAST_RESUBMIT in
|
||||||
|
the original set of actions, if any, are executed; any changes made to
|
||||||
|
the packet (e.g. changes to VLAN) by secondary actions persist when
|
||||||
|
those actions are executed, although the original in_port is restored.
|
||||||
|
"""
|
||||||
|
|
||||||
defstruct(in_port: :in_port)
|
defstruct(in_port: :in_port)
|
||||||
|
|
||||||
@experimenter 0x00002320
|
@experimenter 0x00002320
|
||||||
|
|
@ -7,10 +19,46 @@ defmodule Openflow.Action.NxResubmit do
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
alias Openflow.Action.Experimenter
|
alias Openflow.Action.Experimenter
|
||||||
|
|
||||||
|
@type t :: %{in_port: port_no()}
|
||||||
|
|
||||||
|
@type port_no ::
|
||||||
|
:max
|
||||||
|
| :in_port
|
||||||
|
| :table
|
||||||
|
| :normal
|
||||||
|
| :flood
|
||||||
|
| :all
|
||||||
|
| :controller
|
||||||
|
| :local
|
||||||
|
| :none
|
||||||
|
| 1..0xFFFF
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Creates a new nx_resubmit action struct
|
||||||
|
|
||||||
|
## Options:
|
||||||
|
- in_port: New in_port for checking flow table in the one of the `port_no()` type
|
||||||
|
|
||||||
|
## Note:
|
||||||
|
If the modified flow matchd in the flow table, then the corresponding actions are executed,\\
|
||||||
|
Afterward, actions following the resubmit in the original set of actions, if any, are executed;\\
|
||||||
|
any changes made to the packet by secondary actions persist when those actions are executed,
|
||||||
|
although the original in_port is restored
|
||||||
|
|
||||||
|
## Example:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> %NxResubmit{in_port: :in_port} = NxResubmit.new()
|
||||||
|
iex> %NxResubmit{in_port: 1} = NxResubmit.new(1)
|
||||||
|
```
|
||||||
|
|
||||||
|
"""
|
||||||
|
@spec new(port_no()) :: t()
|
||||||
def new(in_port \\ :in_port) do
|
def new(in_port \\ :in_port) do
|
||||||
%NxResubmit{in_port: in_port}
|
%NxResubmit{in_port: in_port}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec to_binary(t()) :: binary()
|
||||||
def to_binary(%NxResubmit{in_port: in_port}) do
|
def to_binary(%NxResubmit{in_port: in_port}) do
|
||||||
in_port_int = Openflow.Utils.get_enum(in_port, :openflow10_port_no)
|
in_port_int = Openflow.Utils.get_enum(in_port, :openflow10_port_no)
|
||||||
|
|
||||||
|
|
@ -22,6 +70,7 @@ defmodule Openflow.Action.NxResubmit do
|
||||||
>>)
|
>>)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec read(binary()) :: t()
|
||||||
def read(<<@experimenter::32, @nxast::16, in_port_int::16, _::size(4)-unit(8)>>) do
|
def read(<<@experimenter::32, @nxast::16, in_port_int::16, _::size(4)-unit(8)>>) do
|
||||||
in_port = Openflow.Utils.get_enum(in_port_int, :openflow10_port_no)
|
in_port = Openflow.Utils.get_enum(in_port_int, :openflow10_port_no)
|
||||||
%NxResubmit{in_port: in_port}
|
%NxResubmit{in_port: in_port}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
defmodule Openflow.Action.NxSetTunnel do
|
defmodule Openflow.Action.NxSetTunnel do
|
||||||
|
@moduledoc """
|
||||||
|
Set encapsulating tunnel ID.
|
||||||
|
"""
|
||||||
|
|
||||||
defstruct(tunnel_id: 0)
|
defstruct(tunnel_id: 0)
|
||||||
|
|
||||||
@experimenter 0x00002320
|
@experimenter 0x00002320
|
||||||
|
|
@ -7,10 +11,23 @@ defmodule Openflow.Action.NxSetTunnel do
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
alias Openflow.Action.Experimenter
|
alias Openflow.Action.Experimenter
|
||||||
|
|
||||||
|
@type tunnel_id :: 0..0xFFFFFFFF
|
||||||
|
@type t :: %NxSetTunnel{tunnel_id: tunnel_id()}
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Creates a new set_tunnel action struct
|
||||||
|
|
||||||
|
## Example:
|
||||||
|
```elixir
|
||||||
|
iex> %NxSetTunnel{tunnel_id: 1} = NxSetTunnel.new(1)
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
@spec new(tunnel_id()) :: t()
|
||||||
def new(tunnel_id) do
|
def new(tunnel_id) do
|
||||||
%NxSetTunnel{tunnel_id: tunnel_id}
|
%NxSetTunnel{tunnel_id: tunnel_id}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec to_binary(t()) :: binary()
|
||||||
def to_binary(%NxSetTunnel{tunnel_id: tunnel_id}) do
|
def to_binary(%NxSetTunnel{tunnel_id: tunnel_id}) do
|
||||||
Experimenter.pack_exp_header(<<
|
Experimenter.pack_exp_header(<<
|
||||||
@experimenter::32,
|
@experimenter::32,
|
||||||
|
|
@ -20,6 +37,7 @@ defmodule Openflow.Action.NxSetTunnel do
|
||||||
>>)
|
>>)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec read(binary()) :: t()
|
||||||
def read(<<@experimenter::32, @nxast::16, _::16, tunnel_id::32>>) do
|
def read(<<@experimenter::32, @nxast::16, _::16, tunnel_id::32>>) do
|
||||||
%NxSetTunnel{tunnel_id: tunnel_id}
|
%NxSetTunnel{tunnel_id: tunnel_id}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,8 @@ defmodule Openflow.Action.Output do
|
||||||
Create a new output action structure
|
Create a new output action structure
|
||||||
|
|
||||||
## Options:
|
## Options:
|
||||||
- `port_number`: port number that sends a packet from
|
- `port_number`: Output port
|
||||||
- `max_len`: byte length of the packet that sends to the controller
|
- `max_len`: Max length to send to controller
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,6 @@ defmodule Openflow.Action.PopMpls do
|
||||||
Pop the out MPLS label
|
Pop the out MPLS label
|
||||||
|
|
||||||
note: The one of ETH__P_MPLS_* is needed to be specified to eth_type field
|
note: The one of ETH__P_MPLS_* is needed to be specified to eth_type field
|
||||||
|
|
||||||
send_flow_mod_add(
|
|
||||||
datapath_id,
|
|
||||||
match: Match.new(0x8847),
|
|
||||||
instructions: ApplyActions.new(PopMpls.new())
|
|
||||||
)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defstruct(ethertype: 0x8847)
|
defstruct(ethertype: 0x8847)
|
||||||
|
|
@ -25,7 +19,11 @@ defmodule Openflow.Action.PopMpls do
|
||||||
@doc """
|
@doc """
|
||||||
Create a new pop_mpls action struct
|
Create a new pop_mpls action struct
|
||||||
|
|
||||||
0x8847(ETH_P_MPLS_UC) as default value.
|
note: 0x8847(ETH_P_MPLS_UC) as default value.
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> %PopMpls{ethertype: 0x8847} = PopMpls.new()
|
||||||
|
```
|
||||||
"""
|
"""
|
||||||
@spec new() :: t()
|
@spec new() :: t()
|
||||||
@spec new(ethertype :: 0..0xFFFF) :: t()
|
@spec new(ethertype :: 0..0xFFFF) :: t()
|
||||||
|
|
@ -33,10 +31,12 @@ defmodule Openflow.Action.PopMpls do
|
||||||
%PopMpls{ethertype: ethertype}
|
%PopMpls{ethertype: ethertype}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec to_binary(t()) :: <<_::16, _::_*8>>
|
||||||
def to_binary(%PopMpls{ethertype: ethertype}) do
|
def to_binary(%PopMpls{ethertype: ethertype}) do
|
||||||
<<20::16, 8::16, ethertype::16, 0::size(2)-unit(8)>>
|
<<20::16, 8::16, ethertype::16, 0::size(2)-unit(8)>>
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec read(<<_::16, _::_*8>>) :: t()
|
||||||
def read(<<20::16, 8::16, ethertype::16, 0::size(2)-unit(8)>>) do
|
def read(<<20::16, 8::16, ethertype::16, 0::size(2)-unit(8)>>) do
|
||||||
%PopMpls{ethertype: ethertype}
|
%PopMpls{ethertype: ethertype}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,6 @@
|
||||||
defmodule Openflow.Action.PopVlan do
|
defmodule Openflow.Action.PopVlan do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Pop the outer VLAN tag.
|
Pop the outer VLAN tag.
|
||||||
|
|
||||||
note: The one of ETH__P_802_* is needed to be specified to eth_type field
|
|
||||||
send_flow_mod_add(
|
|
||||||
datapath_id,
|
|
||||||
match: Match.new(eth_type: 0x8100),
|
|
||||||
instructions: ApplyActions.new(PopVlan.new())
|
|
||||||
)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defstruct([])
|
defstruct([])
|
||||||
|
|
@ -21,6 +14,10 @@ defmodule Openflow.Action.PopVlan do
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Create a new pop_vlan action struct
|
Create a new pop_vlan action struct
|
||||||
|
|
||||||
|
````elixir
|
||||||
|
iex> %PopVlan{} = PopVlan.new()
|
||||||
|
````
|
||||||
"""
|
"""
|
||||||
@spec new() :: t()
|
@spec new() :: t()
|
||||||
def new do
|
def new do
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
defmodule Openflow.Action.PushMpls do
|
defmodule Openflow.Action.PushMpls do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Push a new MPLS label
|
Push a new MPLS label
|
||||||
|
|
||||||
send_flow_mod_add(
|
|
||||||
datapath_id,
|
|
||||||
match: Match.new(),
|
|
||||||
instruction: ApplyActions.new(PushMpls.new())
|
|
||||||
)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defstruct(ethertype: 0x8847)
|
defstruct(ethertype: 0x8847)
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,6 @@
|
||||||
defmodule Openflow.Action.PushVlan do
|
defmodule Openflow.Action.PushVlan do
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
Push a new VLAN tag
|
Push a new VLAN tag
|
||||||
|
|
||||||
send_flow_mod_add(
|
|
||||||
datapath_id,
|
|
||||||
instructions: ApplyActions.new(PushVlan.new())
|
|
||||||
)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
defstruct(ethertype: 0x8100)
|
defstruct(ethertype: 0x8100)
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,74 @@
|
||||||
defmodule Openflow.Action.SetField do
|
defmodule Openflow.Action.SetField do
|
||||||
|
@moduledoc """
|
||||||
|
Set a header field using OXM TLV format.
|
||||||
|
"""
|
||||||
|
|
||||||
defstruct(field: nil)
|
defstruct(field: nil)
|
||||||
|
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
|
|
||||||
|
@type t :: %SetField{field: Keyword.t()}
|
||||||
|
|
||||||
@set_field_size 8
|
@set_field_size 8
|
||||||
|
|
||||||
def ofpat, do: 25
|
def ofpat, do: 25
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Create a new set_field action struct
|
||||||
|
|
||||||
|
note: The following oxm(nxm)_header values are potentially acceptable as `field`:
|
||||||
|
|
||||||
|
- :tun_id
|
||||||
|
- :tun_ipv4_src
|
||||||
|
- :tun_ipv4_dst
|
||||||
|
- :tun_ipv6_src
|
||||||
|
- :tun_ipv6_dst
|
||||||
|
- :tun_flags
|
||||||
|
- :tun_gbp_id
|
||||||
|
- :tun_gbp_flags
|
||||||
|
- :tun_metadata{0..63}
|
||||||
|
- :in_port
|
||||||
|
- :pkt_mark
|
||||||
|
- :ct_mark
|
||||||
|
- :ct_label
|
||||||
|
- :reg{0..15}
|
||||||
|
- :xreg{0..8}
|
||||||
|
- :xxreg{0..4}
|
||||||
|
- :eth_src
|
||||||
|
- :eth_dst
|
||||||
|
- :vlan_tci
|
||||||
|
- :mpls_ttl
|
||||||
|
- :ip_src
|
||||||
|
- :ip_dst
|
||||||
|
- :ipv6_src
|
||||||
|
- :ipv6_dst
|
||||||
|
- :ipv6_label
|
||||||
|
- :ip_tos
|
||||||
|
- :ip_ecn
|
||||||
|
- :ip_ttl
|
||||||
|
- :arp_op
|
||||||
|
- :arp_spa
|
||||||
|
- :arp_tpa
|
||||||
|
- :arp_sha
|
||||||
|
- :arp_tha
|
||||||
|
- :tcp_src
|
||||||
|
- :tcp_dst
|
||||||
|
- :udp_src
|
||||||
|
- :udp_dst
|
||||||
|
- :icmp_type
|
||||||
|
- :icmp_code
|
||||||
|
- :icmpv6_type
|
||||||
|
- :icmpv6_code
|
||||||
|
- :nd_target
|
||||||
|
- :nd_sll
|
||||||
|
- :nd_tll
|
||||||
|
- :metadata
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> %SetField{field: [reg1: 10]} = SetField.new(reg1: 10)
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
@spec new(Keyword.t()) :: t()
|
||||||
def new([{_field, _value}] = oxm_field) do
|
def new([{_field, _value}] = oxm_field) do
|
||||||
%SetField{field: oxm_field}
|
%SetField{field: oxm_field}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,38 @@
|
||||||
defmodule Openflow.Action.SetNwTtl do
|
defmodule Openflow.Action.SetNwTtl do
|
||||||
|
@moduledoc """
|
||||||
|
Set IP TTL
|
||||||
|
"""
|
||||||
|
|
||||||
defstruct(ttl: 0)
|
defstruct(ttl: 0)
|
||||||
|
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
|
|
||||||
|
@type t :: %SetNwTtl{ttl: 0..0xFF}
|
||||||
|
|
||||||
|
@spec ofpat() :: 23
|
||||||
def ofpat, do: 23
|
def ofpat, do: 23
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Create a new set_nw_ttl action struct
|
||||||
|
|
||||||
|
## Options:
|
||||||
|
- IP TTL
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> %SetNwTtl{ttl: 64} = SetNwTtl.new(_ttl = 64)
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
@spec new(ttl :: 0..0xFF) :: t()
|
||||||
def new(ttl) do
|
def new(ttl) do
|
||||||
%SetNwTtl{ttl: ttl}
|
%SetNwTtl{ttl: ttl}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec to_binary(t()) :: <<_::16, _::_*8>>
|
||||||
def to_binary(%SetNwTtl{ttl: ttl}) do
|
def to_binary(%SetNwTtl{ttl: ttl}) do
|
||||||
<<23::16, 8::16, ttl::8, 0::size(3)-unit(8)>>
|
<<23::16, 8::16, ttl::8, 0::size(3)-unit(8)>>
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec read(<<_::16, _::_*8>>) :: t()
|
||||||
def read(<<23::16, 8::16, ttl::8, _::size(3)-unit(8)>>) do
|
def read(<<23::16, 8::16, ttl::8, _::size(3)-unit(8)>>) do
|
||||||
%SetNwTtl{ttl: ttl}
|
%SetNwTtl{ttl: ttl}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,38 @@
|
||||||
defmodule Openflow.Action.SetQueue do
|
defmodule Openflow.Action.SetQueue do
|
||||||
|
@moduledoc """
|
||||||
|
Set queue id when outputting to a port
|
||||||
|
"""
|
||||||
|
|
||||||
defstruct(id: 0)
|
defstruct(id: 0)
|
||||||
|
|
||||||
alias __MODULE__
|
alias __MODULE__
|
||||||
|
|
||||||
|
@type t :: %SetQueue{id: 0..0xFFFFFFFF}
|
||||||
|
|
||||||
|
@spec ofpat() :: 21
|
||||||
def ofpat, do: 21
|
def ofpat, do: 21
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Create a new set_queue action struct
|
||||||
|
|
||||||
|
## Options:
|
||||||
|
- Queue id for the packets
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
iex> %SetQueue{id: 1} = SetQueue.new(_id = 1)
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
@spec new(id :: 0..0xFFFFFFFF) :: t()
|
||||||
def new(id) do
|
def new(id) do
|
||||||
%SetQueue{id: id}
|
%SetQueue{id: id}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec to_binary(t()) :: <<_::16, _::_*8>>
|
||||||
def to_binary(%SetQueue{id: id}) do
|
def to_binary(%SetQueue{id: id}) do
|
||||||
<<21::16, 8::16, id::32>>
|
<<21::16, 8::16, id::32>>
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec read(<<_::16, _::_*8>>) :: t()
|
||||||
def read(<<21::16, 8::16, id::32>>) do
|
def read(<<21::16, 8::16, id::32>>) do
|
||||||
%SetQueue{id: id}
|
%SetQueue{id: id}
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue