Skip to content

Commit

Permalink
apps.vlan: use config parser, update README
Browse files Browse the repository at this point in the history
Also check the validity of the tag configuration option.
  • Loading branch information
alexandergall committed Jul 27, 2017
1 parent 47aee50 commit f094f74
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 37 deletions.
86 changes: 60 additions & 26 deletions src/apps/vlan/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,83 @@ can multiplex and demultiplex packets to different output ports based on tag.

## Tagger (apps.vlan.vlan)

The `Tagger` app adds a VLAN tag, with the configured value, to packets
received on its `input` port and transmits them on its `output` port.
The `Tagger` app adds a VLAN tag, with the configured value and
encapsulation, to packets received on its `input` port and transmits
them on its `output` port.

### Configuration

— Key **tag**
— Key **encapsulation**

*Optional*. The Ethertype to use as encapsulation for the
VLAN. Permitted values are the strings _"dot1q"_ and _"dot1ad"_ or a
number to select an arbitrary Ethertype. _"dot1q"_ and _"dot1ad"_
correspond to the Ethertypes 0x8100 and 0x88a8, respectively,
according to the IEEE standards 802.1Q and 802.1ad.

*Required*. VLAN tag to add or remove from the packet.
If a number is given, it is truncated to 16 bits. This feature is
intended to allow interoperation with vendors that do not use one of
the standard encapsulations (a prominent example being the value
0x9100, which can still be found in practice for double-tagging
instead of 0x88a8).

The default is _"dot1q"_.

— Key **tag**

*Required*. VLAN tag to add or remove from the packet. The value must
be a number in the range 1-4094 (inclusive).

## Untagger (apps.vlan.vlan)

The `Untagger` app checks packets received on its `input` port for a VLAN tag,
removes it if it matches with the configured VLAN tag and transmits them on its
`output` port. Packets with other VLAN tags than the configured tag will be
dropped.
The `Untagger` app checks packets received on its `input` port for a
VLAN tag, removes it if it matches with the configured VLAN tag and
transmits them on its `output` port. Packets with other VLAN tags than
the configured tag are dropped.

### Configuration

— Key **tag**
— Key **encapsulation**

*Optional*. See above.

*Required*. VLAN tag to add or remove from the packet.
— Key **tag**

*Required*. VLAN tag to add or remove from the packet. The value must
be a number in the range 1-4094 (inclusive).

## VlanMux (apps.vlan.vlan)

Despite the name, the `VlanMux` app can act both as a multiplexer, i.e. receive
packets from multiple different input ports, add a VLAN tag and transmit them
out onto one, as well as receiving packets from its `trunk` port and
demultiplex it over many output ports based on the VLAN tag of the received
packet.
Despite the name, the `VlanMux` app can act both as a multiplexer,
i.e. receive packets from multiple different input ports, add a VLAN
tag and transmit them out onto one, as well as receiving packets from
its `trunk` port and demultiplex it over many output ports based on
the VLAN tag of the received packet. It supports the notion of a
"native VLAN" by mapping untagged frames on the trunk port to a
dedicated output port.

A packet received on its `trunk` input port must either be untagged or
tagged with the encapsulation as specified with the **encapsulation**
configuration option. Otherwise, the packet is dropped.

If the Ethernet frame is tagged, the VLAN ID is extracted and the
packet is transmitted on the port named `vlan<vid>`, where `<vid>` is
the decimal representation of the VLAN ID. If no such port exists,
the packet is dropped.

If the Ethernet frame is untagged, it is transmitted on the port named
`native` or dropped if no such port exists.

Packets received on its `trunk` input port with Ethernet type 0x8100 are
inspected for the VLAN tag and transmitted on an output port `vlanX` where *X*
is the VLAN tag parsed from the packet. If no such output port exists the
packet is dropped. Received packets with an Ethernet type other than 0x8100 are
transmitted on its `native` output port,
A packet received on a port named `vlan<vid>` is tagged with the VLAN
ID `<vid>` according to the configured encapsulation and transmitted
on the trunk port.

A packet received on the port named `native` is transmitted as is on
the trunk port.

### Configuration

Packets received on its `native` input port are transmitted verbatim on its
`trunk` output port.
— Key **encapsulation**

Packets received on input ports named `vlanX`, where *X* is a VLAN tag, will
have the VLAN tag *X* added and then be transmitted on its `trunk` output port.
*Optional*. See above.

There is no configuration for the `VlanMux` app, simply connect it to your
other apps and it will base its actions on the name of the ports.
41 changes: 30 additions & 11 deletions src/apps/vlan/vlan.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,24 @@ local cast = ffi.cast
local htons, htonl = lib.htons, lib.htonl
local ntohs, ntohl = htons, htonl

Tagger = {}
Untagger = {}
VlanMux = {}
local default_encap = { default = "dot1q" }
Tagger = {
config = {
encapsulation = default_encap,
tag = { required = true }
}
}
Untagger = {
config = {
encapsulation = default_encap,
tag = { required = true }
}
}
VlanMux = {
config = {
encapsulation = default_encap,
}
}

local tpids = { dot1q = 0x8100, dot1ad = 0x88A8 }
local o_ethernet_ethertype = 12
Expand Down Expand Up @@ -59,22 +74,26 @@ function tci_to_vid (tci)
end

function new_aux (self, conf)
local encap = (conf and conf.encapsulation) or "dot1q"
self.tpid = encap
local encap = conf.encapsulation
if (type(encap) == "string") then
local tpid = tpids[encap]
assert(tpid)
self.tpid = tpid
self.tpid = tpids[encap]
assert(self.tpid, "Unsupported encapsulation type "..encap)
else
assert(type(encap) == "number")
self.tpid = encap
end
return self
end

function check_tag (tag)
assert(tag > 0 and tag < 4095, "VLAN tag "..tag.." out of range")
return tag
end

function Tagger:new (conf)
local o = setmetatable({}, {__index=Tagger})
new_aux(o, conf)
o.tag = build_tag(assert(conf.tag), o.tpid)
o.tag = build_tag(check_tag(conf.tag), o.tpid)
return(o)
end

Expand All @@ -91,7 +110,7 @@ end
function Untagger:new (conf)
local o = setmetatable({}, {__index=Untagger})
new_aux(o, conf)
o.tag = build_tag(assert(conf.tag), o.tpid)
o.tag = build_tag(check_tag(conf.tag), o.tpid)
return(o)
end

Expand Down Expand Up @@ -121,7 +140,7 @@ function VlanMux:link ()
local from_vlans, to_vlans = {}, {}
for name, l in pairs(self.input) do
if string.match(name, "vlan%d+") then
local vid = tonumber(string.sub(name, 5))
local vid = check_tag(tonumber(string.sub(name, 5)))
to_vlans[vid] = self.output[name]
table.insert(from_vlans, { link = l, vid = vid })
elseif name == "native" then
Expand Down

0 comments on commit f094f74

Please sign in to comment.