Lucet compiler has to “compile” the wiring connections needed for a OpenFlow-SDN distributed machine. The "compilation" happens on two levels:
- the topology representation in Dobby,
- configuration files for Xen and LINCX.
Table of Contents
Lucet has the following options that can be adjusted in the sys.config
:
Parameter | Description | Example |
---|---|---|
dobby_node | Erlang node name that runs Dobby | 'dobby@127.0.0.1' |
To build and run Lucet invoke make && make run
.
lucet:wire(SrcId, DstId)
Creates bound_to
path between SrcId
and DstId
in Dobby. SrcId
and DstId
are binaries for identifiers' names.
If SrcId
or the path doesn't exist an error is returned.
A bound_to
path can only consist of:
- OpenFlow Port identifiers (lm_of_port),
- Virtual Port identifiers (lm_vp),
- Physical Port identifiers (lm_pp),
- Endpoint identifiers (endpoint),
- Patch Panel identifiers (lm_patchp).
When a bound_to
link is created between two ports, A and B, the wires
meta-data
on their Patch Panel is updated (they have to be attached to the same Patch Panel).
Two entries are added to the wires
meta-data map: A => B, B => A.
Each bound_to
link between Physical Port and Virtual Port
has its corresponding xen bridge (xenbr{X} where X is a number). Before
wiring occurs, Physical Port is assumed to be linked to the bridge
as part of
. The wiring process is responsible for creating a part of
link between the bridge and VP.
Each bound_to
link between two Virtual Ports has its corresponding
xen bridge. The wiring process is responsible for creating an
identifier for the xen bridge and its part of
links to the Virtual Ports.
The bridge name is inbr_vif{X}_vif{Y}
where X and Y are vif interfaces'
numbers associated with VPs that are linked.
lucet:generate_vh_domain_config(PhysicalHost, VirtualHostNo, MgmtIfMac)
Generates domain config file for Virtual Hosts (not necessarily those
with LINCX). This function is intended to be called after wiring is done
by lucet:wire/2
.
The VirtualHost
is a name for VH identifier as string or binary
(or list of names). The MgmtIfMac
is the MAC address of the Management
Interface that will be set for the first bridge.
Below is an example call:
lucet:generate_vh_domain_config(<<"PH1">>, 1, "00:01:02:03:04:05").
vif = ['mac=00:01:02:03:04:05,bridge=xenbr0',
'bridge=inbr_vif1.2_vif2.1',
'bridge=xenbr1']
Lucet comes with a JSON topology generator for Dobby. It can be run like:
./utils/appfest_gen -out appfest.json -physical_ports 10 -physical_hosts 4 \
-ofp_ports 4 -virtual_hosts 1
The script takes the following options:
Options | Description | Default |
---|---|---|
out | The output file | "out.json" |
physical_hosts | Number of physical hosts (ph) | 2 |
physical_ports | Number of physical ports (pp) per ph | 4 |
virtual hosts | Number of virtual hosts (vp) with endpoints (ep) | 1 |
ofp_ports | Number of OpenFlow ports per vh with OpenFlow switch (ofs) | 4 |
Note that the virtual_hosts
parameter does not take into account Virtual Host
no 1 which is always assumed to be VH with OFS.
To see larger pictures open them as
raw
github content.
This example illustrates how to use Lucet to wire a topology generated with the following command:
./utils/appfest_gen -out topo.json -physical_ports 1 -ofp_ports 2 -virtual_hosts 1 -physical_hosts 2
A picture below shows the topology in the Dobby Visualizer tool:
After the wiring we expect that:
- Port 1 of OpenFlow Switch 1 on Physical Host 1 (PH1/VH1/OFS1/OFP1)
will be bound to Port 1 of OpenFlow Switch 1 on Physical Host 2 (PH2/VH1/OFS1/OFP1).
This indicates that:
- On Physical Host 1, Port 1 of OpenFlow Switch 1 (PH1/VH1/OFS1/OFP1) will be bound to Physical Port 1 (PH1/PP1),
- On Physical Host 2, Port 1 of OpenFlow Switch 1 (PH2/VH1/OFS1/OFP1) will be bound to Physical Port 1 (PH2/PP1).
- On Physical Host 1, Port 2 of OpenFlow Switch 1 (PH1/VH1/OFS1/OFP2) will be bound to Endpoint1 on Virtual Host 2.
- On Physical Host 1, Port 2 of OpenFlow Switch 1 (PH2/VH1/OFS1/OFP2) will be bound to Endpoint1 on Virtual Host 2.
Start the Dobby service and import the topology json file:
dby_bulk:import(json, "{PATH}/out.json").
Verify that the topology is imported:
3> dby:links(<<"PH1">>).
[{<<"PH1/PP1">>,
#{<<"type">> => #{publisher_id => <<"lucet">>,
timestamp => <<"2015-05-26T16:22:02Z">>,
value => <<"part_of">>}}}]
Before calling Lucet API make sure that it is connected to Dobby. Calling
nodes()
in Lucet shell should return something like ['dobby@127.0.0.1']
.
lucet:wire(<<"PH1/VH1/OFS1/OFP1">>, <<"PH1/PP1">>).
lucet:wire(<<"PH1/PP1">>, <<"PH2/PP1">>).
lucet:wire(<<"PH2/VH1/OFS1/OFP1">>, <<"PH2/PP1">>).
Now, the topology representation should look like on the picture below:
In comparison to the initial picture there are 2 new identifiers:
- Xen bridge between
PH1/PP1
andPH1/VP1.1
calledPH1/xenbr1
. The bridge number is taken from the interface metadata ofPH1/PP1
. - Similar bridge between
PH2/PP1
andPH2/VP1.1
calledPH2/xenbr1
.
There are also 9 new links:
- A
part_of
link betweenPH1/xenbr1
andPH1/PP1
. - A
part_of
link betweenPH1/xenbr1
andPH1/VP1.1
. - A
bound_to
link betweenPH1/PP1
andPH1/VP1.1
. - A
connected_to
link betweenPH/PP1
andPH1/VH1/OFS1/OFP1
. - 4 analogous links to 1. 2. 3. and 4. for
PH2
. - A
connected_to
link betweenPH1/PP1
andPH2/PP1
.
We cannot do it with
lucet:wire(<<"PH1/VH1/OFS1/OFP1">>, <<"PH2/VH1/OFS1/OFP1">>)
because Lucet wouldn't know which PPs to use (for example it could choose that PP1/PP1 will be connected to PH2/PP3). However, if we want to have a
connected_to
link between the OpenFlow Ports we can call
lucet:wire(<<"PH1/VH1/OFS1/OFP1">>, <<"PH2/VH1/OFS1/OFP1">>).
after all the above commands.
lucet:wire(<<"PH1/VH1/OFS1/OFP2">>, <<"PH1/VH2/EP1">>).
lucet:wire(<<"PH2/VH1/OFS1/OFP2">>, <<"PH2/VH2/EP1">>).
After this call the topology will change into this:
In comparison to the previous state it has 2 new identifiers, and 8 new links. The identifiers are:
- Xen bridge between Virtual Ports of Virtual Host 1 and 2 on Physical
Host 1:
PH1/inbr_vif1.2_vif2.1
- Xen bridge between Virtual Ports of Virtual Host 1 and 2 on Physical
Host 2:
PH2/inbr_vif1.2_vif2.1
.
And the links:
- A
part_of
link betweenPH1/inbr_vif1.2_vif2.1
andPH1/VP1.2
. - A
part_of
link betweenPH1/inbr_vif1.2_vif2.1
andPH1/VP2.1
. - A
bound_to
link betweenPH1/VP1.2
andPH1/VP2.1
. - A
connected_to
link betweenPH1/VH1/OFS1/OFP2
andPH1/VH2/EP1
. - 4 analogous links to the above but for
PH2
.
For PH1/VH1
:
lucet:generate_vh_domain_config(<<"PH1">>, 1, "00:01:02:03:04:05").
vif = ['mac=00:01:02:03:04:05,bridge=xenbr0',
'bridge=inbr_vif1.2_vif2.1',
'bridge=xenbr1']
For PH1/VH2
:
lucet:generate_vh_domain_config(<<"PH1">>, 2, "00:01:02:03:04:05").
vif = ['mac=00:01:02:03:04:05,bridge=xenbr0',
'bridge=inbr_vif1.2_vif2.1']
And analogously for the PH2
Virtual Hosts.