Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
goldenrye committed Jun 8, 2020
2 parents f5b09bf + 178fe6e commit 3e11482
Show file tree
Hide file tree
Showing 103 changed files with 3,390 additions and 1,382 deletions.
7 changes: 7 additions & 0 deletions Documentation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ pip install -r requirements.txt
Documentation is created in the ReSTructured text format.
A nice document listing important commands is the [Restructured Text (reST) and Sphinx CheatSheet](https://thomas-cokelaer.info/tutorials/sphinx/rest_syntax.html).

Please note that you have mostly two ways to create a link to another location of the documentation:

- use an explicit reference to the target location (e.g., ```:ref:`sec-updating-linux-kernel` ```), which must declare a 'label' (e.g., ```.. _sec-updating-linux-kernel:``` followed by an empty line);

- use the ```:doc:`polycubectl CLI <polycubectl/polycubectl>` ``` primitive, which enables to refer to a specific file and allows to specify the text to be written in the link.

- use the ```:scm_web:``` macro, which avoids to declare the entire path of the linked document when this refers to the github repository (e.g., ``` :scm_web:`Nat <src/services/pcn-nat/src/Nat_dp.c>` ```)

### Build it

Expand Down
60 changes: 29 additions & 31 deletions Documentation/developers/dataplane.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,31 @@ Writing the eBPF datapath
The Polycube architecture leverages the software abstraction provided by `BCC <https://github.com/iovisor/bcc/>`_, which is further extended in this project particular with respect to eBPF features that are useful for networking services.
In order to get more information about how to use the maps in BCC please read the `BCC reference guide <https://github.com/iovisor/bcc/blob/master/docs/reference_guide.md>`_, additionally there is a list of the `available eBPF helpers <https://github.com/iovisor/bcc/blob/master/docs/kernel-versions.md>`_.

Polycube architecture adds a wrapper around the user's code, this wrapper calls the `handle_rx` function with the following parameters:
Polycube architecture adds a wrapper around the user's code, this wrapper calls the ``handle_rx`` function with the following parameters:

1. **ctx**: Packet to be processed
2. **md**: packet's metadata:
- **ctx**: packet to be processed
- **md**: packet metadata
- **in_port**: integer that identifies the ingress port of the packet.

- **in_port**: integer that identifies the ingress port of the packet.
Polycube provides a set of functions to handle the packets, the return value of the ``handle_rx`` function should be the result of calling one of these functions.

``polycube`` provides a set of functions to handle the packets, the return value of the `handle_rx` function should be the result of calling one of these functions.
- **pcn_pkt_redirect(struct __sk_buff *skb, struct pkt_metadata *md, u16 port);**: sends the packet through an the ``ifc`` port. :scm_web:`Example: Helloworld service <src/services/pcn-helloworld/src/Helloworld_dp_ingress.c#L96>`.

- **pcn_pkt_redirect(struct __sk_buff *skb, struct pkt_metadata *md, u16 port);**: sends the packet through an the ``ifc`` port. [Example](services/pcn-helloworld/src/Helloworld_dp.h#L86)
- **pcn_pkt_drop(struct __sk_buff *skb, struct pkt_metadata *md);**: drops the packet. It is the same that just returning `RX_DROP`. :scm_web:`Example: Helloworld service <src/services/pcn-helloworld/src/Helloworld_dp_ingress.c#L80>`.

- **pcn_pkt_drop(struct __sk_buff *skb, struct pkt_metadata *md);**: drops the packet. It is the same that just returning `RX_DROP`. [Example](services/pcn-helloworld/src/Helloworld_dp.h#L78)
- **pcn_pkt_redirect_ns(struct __sk_buff *skb, struct pkt_metadata *md, u16 port)**: (available only for *shadow* services) sends the packet to the namespace if it comes from the port indicated as parameter.

- **pcn_pkt_controller(struct __sk_buff *skb, struct pkt_metadata *md, u16 reason)**: sends the packet to the control path controller. Reason can be used to indicate why the packet is being sent to the custom code running in the control path. If there is not any reason `RX_CONTROLLER` could be directly returned. [Example](services/pcn-helloworld/src/Helloworld_dp.h#L82)
Processing packets in the slowpath
**********************************

- **pcn_pkt_controller_with_metadata(struct __sk_buff *skb, struct pkt_metadata *md, u16 reason, u32 metadata[3])**: Sends the packet to the custom code running in the control path. In addition to the reason the user can also send some additional medatada.
A copy of the packet can be sent to the controller to be processed by the slowpath using the following helpers:

- **pcn_pkt_redirect_ns(struct __sk_buff *skb, struct pkt_metadata *md, u16 port)**: (it is only available for shadow services) sends the packet to the namespace as if it came from the port indicated as parameter
- **pcn_pkt_controller(struct __sk_buff *skb, struct pkt_metadata *md, u16 reason)**: sends a copy of the packet to the controller. Reason can be used to indicate why the packet is being sent to the custom code running in the control path.
:scm_web:`Example: Helloworld service <src/services/pcn-helloworld/src/Helloworld_dp_ingress.c#L79>`.

- **pcn_pkt_controller_with_metadata(struct __sk_buff *skb, struct pkt_metadata *md, u16 reason, u32 metadata[3])**: sends a copy of the packet to the custom code running in the control path. In addition to the reason the user can also send some additional metadata.

The packet will be processed by the ``packet_in`` method of the controller.

Checksum calculation
********************
Expand All @@ -31,38 +38,29 @@ The L3 (IP) and L4 (TCP, UDP) checksums has to be updated when fields in the pac
``polycube`` provides a set of wrappers of the eBPF helpers to do it:

- **pcn_csum_diff()**: wrapper of `BPF_FUNC_csum_diff <https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7d672345ed295b1356a5d9f7111da1d1d7d65867>`_

Note: For XDP cubes and kernels version prior to 4.16 this function supports only 4 bytes arguments.
Note that in case of XDP cubes and kernels version prior to 4.16 this function supports only 4 bytes arguments.

- **pcn_l3_csum_replace()**: wrapper of `BPF_FUNC_l3_csum_replace <https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=91bc4822c3d61b9bb7ef66d3b77948a4f9177954>`_

- **pcn_l4_csum_replace()**: wrapper of `BPF_FUNC_l4_csum_replace <https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=91bc4822c3d61b9bb7ef66d3b77948a4f9177954>`_

Services as :scm_web:`nat <src/services/pcn-nat/src/Nat_dp.c>` and :scm_web:`nat <src/services/pcn-loadbalancer-rp/src/Lbrp_dp.c>` show how to use these functions.
Services as :scm_web:`NAT <src/services/pcn-nat/src/Nat_dp.c>` and :scm_web:`Load Balancer <src/services/pcn-loadbalancer-rp/src/Lbrp_dp.c>` show how to use these functions.

Vlan Support
VLAN Support
************

The vlan handling in TC and XDP eBPF programs is a little bit different, so polycube includes a set of helpers to uniform this accross.

- bool pcn_is_vlan_present(struct CTXTYPE* pkt)

- int pcn_get_vlan_id(struct CTXTYPE* pkt, uint16_t* vlan_id, uint16_t* eth_proto);

- uint8_t pcn_vlan_pop_tag(struct CTXTYPE* pkt);

- uint8_t pcn_vlan_push_tag(struct CTXTYPE* pkt, u16 eth_proto, u32 vlan_id);


Known limitations:
******************
- It is not possible to send a packet through multiple ports, then multicast, broadcast of any similar functionality has to be implemented in the control path.
The VLAN handling in TC and XDP eBPF programs is a little bit different, so polycube includes a set of helpers to uniform this accross.

- bool **pcn_is_vlan_present** (struct CTXTYPE* pkt)
- int **pcn_get_vlan_id** (struct CTXTYPE* pkt, uint16_t* vlan_id, uint16_t* eth_proto);
- uint8_t **pcn_vlan_pop_tag** (struct CTXTYPE* pkt);
- uint8_t **pcn_vlan_push_tag** (struct CTXTYPE* pkt, u16 eth_proto, u32 vlan_id);

TODO:
*****

- Document support for multiple eBPF programs
Known limitations
*****************
- Since you cannot send a packet on multiple ports, multicast, broadcast or any similar functionality has to be implemented in the control path.
- The support for multiple eBPF programs is not yet documented.


Debugging the data plane
Expand Down
145 changes: 145 additions & 0 deletions Documentation/developers/hateoas.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
Hateoas
=======

Polycube supports the Hateoas standard.
Thanks to this feature the daemon (:doc:`polycubed<../polycubed/polycubed>`) is able to provide the list
of valid endpoints to the client that can be used to make requests to the server.
The endpoints provided are those of the level just after the one requested.
From the :doc:`polycubed<../polycubed/polycubed>` root you can explore the service through the Hateoas standard.


What can Hateoas be used for?
-----------------------------

The Hateoas standard can be used to explore endpoints that can be used in Polycube.
In this way a client will be able to access Polycube resources and thus cubes independently.
This feature can also be useful in case you want to implement an alternative client to :doc:`polycubectl<../polycubectl/polycubectl>`.


How to use Hateoas
------------------
This feature can be used by observing the json of :doc:`polycubed<../polycubed/polycubed>` responses.
You can use an http client (e.g. Postman) to execute requests to the Polycube daemon.



Example
-------

In this example if the client request is

::

GET -> localhost:9000/polycube/v1/simplebridge/sb1/

then the server response will include all endpoints a of the level just after the simplebridge name (sb1).

::

{
"name": "sb1",
"uuid": "d138da68-f6f4-4ee9-8238-34e9ab1df156",
"service-name": "simplebridge",
"type": "TC",
"loglevel": "INFO",
"ports": [
{
"name": "tovethe1",
"uuid": "b2d6ebcb-163c-4ee8-a943-ba46b5fa4bda",
"status": "UP",
"peer": "veth1"
},
{
"name": "tovethe2",
"uuid": "e760a44d-5e9f-47e9-85d9-38e144400e83",
"status": "UP",
"peer": "veth2"
}
],
"shadow": false,
"span": false,
"fdb": {
"aging-time": 300,
"entry": [
{
"address": "da:55:44:5a:b1:b1",
"port": "tovethe1",
"age": 29
},
{
"address": "11:ff:fe:80:00:00",
"port": "tovethe2",
"age": 26
},
{
"address": "ee:c9:0e:19:c7:2a",
"port": "tovethe2",
"age": 1
}
]
},
"_links": [
{
"rel": "self",
"href": "//127.0.0.1:9000/polycube/v1/simplebridge/sb1/"
},
{
"rel": "uuid",
"href": "//127.0.0.1:9000/polycube/v1/simplebridge/sb1/uuid/"
},
{
"rel": "type",
"href": "//127.0.0.1:9000/polycube/v1/simplebridge/sb1/type/"
},
{
"rel": "service-name",
"href": "//127.0.0.1:9000/polycube/v1/simplebridge/sb1/service-name/"
},
{
"rel": "loglevel",
"href": "//127.0.0.1:9000/polycube/v1/simplebridge/sb1/loglevel/"
},
{
"rel": "ports",
"href": "//127.0.0.1:9000/polycube/v1/simplebridge/sb1/ports/"
},
{
"rel": "shadow",
"href": "//127.0.0.1:9000/polycube/v1/simplebridge/sb1/shadow/"
},
{
"rel": "span",
"href": "//127.0.0.1:9000/polycube/v1/simplebridge/sb1/span/"
},
{
"rel": "fdb",
"href": "//127.0.0.1:9000/polycube/v1/simplebridge/sb1/fdb/"
}
]

}

As we can see from this answer json, the "_links" section contains all the endpoints
that the client can use to contact :doc:`polycubed<../polycubed/polycubed>` starting from the service name (sb1).

In this way a client can explore the service level by level.



How to know endpoints without hateoas?
--------------------------------------
Well, there is an alternative (harder) way to know the endpoints of a cube that can be used in a Polycube.
The swaggerfile must be produced from the yang datamodel of a service (option **-s** in swagger-codegen_).

To do this you have to provide the datamodel of a service as input to the swagger codegen (**-i** option).
The swaggerfile is a large and not very understandable json.
How can we study it in order to know APIs?
We have to use the swagger-editor_ that can accept the swaggerfile generated and
provides a more user friendly way to observe api's of a service.
Swagger editor allows you to view endpoints and verbs that can be used to interact with a Polycube.

Note: using this method you will only know the endpoints of a cube and not all the endpoints offered by :doc:`polycubed<../polycubed/polycubed>`.


.. _swagger-codegen: https://github.com/polycube-network/polycube-codegen#full-installation-from-sources
.. _swagger-editor: https://editor.swagger.io/
105 changes: 103 additions & 2 deletions Documentation/developers/hints.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,106 @@
Some hints for programmers
--------------------------
Hints for programmers
---------------------

Compiling a Polycube service
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Polycube services can be compiled in two ways:

- together with the entire Polycube source code
- as stand-alone services that can be loaded into Polycube at runtime

Compiling together with the Polycube source code
************************************************
1. Place the service into the :SCM_WEB:`src/services <src/services>` folder;

2. Update the :SCM_WEB:`src/services/CMakeLists.txt <src/services/CMakeLists.txt>` file adding a new `cmake` instruction:

::

add_service(service_name service_folder)

where the first argument is the service name used in the Polycube REST API, while second argument is the folder name of the service.

**Note**: the service folder name must follow the ``pcn-service_name`` naming convention (E.g. pcn-bridge, pcn-router).

3. Compile and re-install Polycube:

::

# having Polycube root folder as working directory
mkdir build && cd build
cmake ..
make -j $(getconf _NPROCESSORS_ONLN)
sudo make install

.. _stand_alone_compilation:

Compiling a stand-alone service
*******************************
1. create a `build` folder in the root folder of the service and set it as working directory:

::

mkdir build && cd build

2. generate a Makefile:

::

cmake ..

3. compile the service to build a shared library object:

::

make -j $(getconf _NPROCESSORS_ONLN)

At this point the service has been compiled and the built shared library object can be found into the ``build/src`` folder named as ``libpcn-service_name.so``

The compiled service, completely encapsulated in the .so file, is now ready to be loaded by the Polycube daemon.

Loading/unloading Polycube services at runtime
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In order to load a new service at runtime, we should provide to Polycube daemon the shared library object (.so) we compiled before.

Loading a service
*****************
In order to load a new service into Polycube a shared library object must be provided.
Please see :ref:`stand_alone_compilation` to generate this object.

To load a service into a running Polycube instance use:

::

polycubectl services add type=lib uri=/absolute/path/to/libpcn-service_name.so name=service_name

- the ``uri`` parameter indicates the absolute path to the shared library object of the service;
- the ``name`` parameter indicates the name that will be use in the Polycube rest API for the service.

After having loaded the service, it can be instantiated as a normal service using ``polycubectl``.

To verify the service has been loaded correctly and is ready to be instantiated:

::

# show available services list; the loaded service should be present
polycubectl services show

# create an instance of the service
polycubectl service_name add instance_name

# dump the service
polycubectl instance_name show


Unloading a service
*******************
To unload a service from a running Polycube instance use:

::

polycubectl services del service_name

where ``service_name`` indicates the name used by the Polycube rest API for the service (E.g. bridge, router)


Install the provided git-hooks
Expand Down
1 change: 1 addition & 0 deletions Documentation/developers/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ This guide represents an initial starting point for developers that want to impl
debugging
profiler
hints
hateoas



Expand Down
Loading

0 comments on commit 3e11482

Please sign in to comment.