lightedge / lightedge-upfservice

The LightEdge MEC Platform: UPF Service
http://lightedge.github.io/
0 stars 3 forks source link

Click elements

This is a Click external package (built as a dynamic library that can be loaded as a runtime module by Click) providing three new Click elements:

  1. UPFRouter is an element intercepting and routing all traffic between eNodeBs, EPC and VNFs (see section UPFRouter logic below).

    It has three input/output ports working with L3 traffic:

    1. I/O port 0 for all traffic coming from/directed to the EPC. (S1AP traffic, GTPv1U traffic)

    2. I/O port 1 for all traffic coming from/directed to some eNodeB (S1AP traffic, GTPv1U traffic)

    3. I/O port 2 for traffic from/to local processing (i.e. VNFs) (ordinary L3 traffic)

    There is also a fourth optional output port (port 3) for unknown IPv4 traffic neither coming from the EPC nor coming from a eNodeB, and figuring as directed (or coming from) an unknown UE. This traffic can't be reasonably forwarded anywhere, and normally should be dropped.

    Its processing policy is AGNOSTIC for inputs, and PUSH for outputs.

  2. UPFPcapReader is an element logically similar to the standard fromdump Click element, but it is able to properly read a .pcap file containing Ethernet traffic captured via Wireshark or similar tools. It is provided just for testing purposes, and it is able to read both .pcap files containing raw Ethernet frames or LinuxCooked packets.

    It has just one output port, and its processing policy is AGNOSTIC.

  3. UPFPcapWriter is an element logically similar to the standard todump Click element, but it is able to properly write a .pcap file containing Ethernet traffic which can be read back by Wireshark. It is provided just for testing purposes, and it is able to write .pcap files containing raw Ethernet frames.

    It has just one input port, and its processing policy is AGNOSTIC.

Building and installing

You need a working Click installation and the archive version of the UPFlib libraries (and related headers) installed somehwere. By default they are both searched in /usr/local.

If both Click and UPFlib libraries are installed in /usr/local, just use

configure
make
sudo make install

Otherwise, if Click and/or UPFlib are installed elsewhere, use the specific options of configure to specify where they are located. For example:

configure --with-click=<click_install_prefix> --with-upflib=<upflib_install_prefix>
make
make install

By default, the Click package is statically linked with UPFlib libraries, so everything is included in the resulting files (this is possibile as UPFlib archive libraries are compiled with -fPIC -DPIC).

Sample Click configuration for UPFRouter

require(package "upf"); ControlSocket("TCP", 7777);

upfr :: UPFRouter()

kt :: KernelTun(ADDR 10.0.0.2/24, DEVNAME tun0);

s_client :: Socket("UDP", ADDR 10.103.173.254, PORT 5555);

s_server :: Socket("UDP", ADDR 0.0.0.0, PORT 5555);

ktgw :: KernelTun(ADDR 10.90.90.1/24, DEVNAME tun1);

s_server
        -> Print("from s_server[0] to [0]CheckIPHeader", MAXLENGTH 0)
        -> CheckIPHeader()
        -> Print("from CheckIPHeader[0] to [0]Print", MAXLENGTH 0)
        -> IPReassembler()
        -> Print("from Print[0] to [1]upfr", MAXLENGTH 0)
        -> [1]upfr;

kt
        -> Print("from kt[0] to [0]CheckIPHeader", MAXLENGTH 0)
        -> CheckIPHeader()
        -> IPReassembler()
        -> [0]upfr;

upfr[0]
       -> Print("from upfr[0] to [0]kt", MAXLENGTH 0)
       -> IPFragmenter(1000)
       -> kt;

upfr[1]
        -> Print("from upfr[1] to [0]s_client", MAXLENGTH 0)
        -> IPFragmenter(1000)
        -> s_client;

upfr[2]
        -> Print("from upfr[2] to [0]ktgw", MAXLENGTH 0)
        -> IPFragmenter(1000)
        -> ktgw;

ktgw
        -> Print("from ktgw[0] to [2]upfr", MAXLENGTH 0)
        -> [2]upfr;

Sample start script

#!/bin/sh

click myscript.click &

sleep 3
# Setup tun device (ensure env variable $enbs_subnet is set)
ip route add $enbs_subnet dev tun0

Sample commands for UPFRouter read/write handlers

Here we assume that the UPFRouter element is named upfr in Click configuration.

Get UEMap

read upfr.uemap

Insert MatchMap entries into given position

write upfr.matchmapins 0 6-192.168.13.0/24-80

Append MatchMap entries at end (no position)

write upfr.matchmapappend 6-192.168.13.0/24-80

Delete MatchMap entry at given position

write upfr.matchmapdel 0

Get MatchMap

read upfr.matchmap

Disable UDP checksums on encapsulated GTPv1-U traffic

write upfr.enableudpchecksum false

Disable dumping on console of unknown IPv4 traffic

write upfr.enableunknowntrafficdump false

UPFRouter maps and configuration items

  1. UEMap: map of known UE -> GTP tunnel endpoints

    std::unordered_map<IPv4Address, GTPv1UTunnelInfo>

    where a GTPv1UTunnelInfo specifies

    • IPv4Address and TEID of a EPC endpoint;
    • IPv4Address and TEID of a eNodeB endpoint;

    UPFRouter Click element builds it on the fly, intercepting and analyzing S1AP traffic between the eNodeBs and the EPCs.

    Its content can be read via a read handler (see examples below).

  2. MatchMap: a map (actually, a list) of matching rules for GTPv1-U-encapsulated IPv4 traffic between the EPC and a eNodeB that has to be diverted to local processing (instead of being forwarded).

    The matching rule is specified as follows:

    • a protocol number (identifying TCP, UDP, etc.). 0 matches any protocol. Example: 6 = TCP, 17 = UDP, 1 = ICMP, etc.

    • a IPv4 CIDR (address + netmask bits) to be matched against the destination address. '0.0.0.0/0' matches any address. Example: 192.168.3.0/24

    • a TCP/UDP/SCTP/etc. port number (16-bit unsigned integer, to be used only if applicable to the protocol). 0 matches any port number.

    Note: for protocols where port number is not applicable (e.g. ICMP), the port number in the matching rule has to be 0 to match.

    Example of human-readable matching rule: 6-192.168.3.0/24-80

UPFRouter logic

S1AP traffic from port 0 or port 1

The traffic is expected on port 0 and 1 and is analyzed to build the UEMap and keep it up-to-date, but other than that it is forwarded as-is. Traffic coming from port 0 is directed to port 1 and vice-versa.

GTPv1-U IPv4 traffic from a eNodeB (port 1, look in UEMap and MatchMap)

GTPv1-U Traffic coming from port 1 is decapsulated and matched against the MatchMap and, if it matches an entry, it is then matched against the UEMap (for source address)

GTPv1-U IPv4 traffic from the EPC (port 0, look in UEMap and MatchMap)

GTPv1-U Traffic coming from port 0 is decapsulated and matched against the MatchMap and, if it matches an entry, it is then matches against the UEMap (for destination address) to check it is directed to a known UE:

Other L3 traffic from port 0 or from port 1

It's directed unchanged to its matching port (i.e. traffic from port 0 is directed to port 1 and vice-versa).

L3 Traffic coming from port 2

It is matched agains the UEMap for source and for destination address:

Otherwise, if there's no match, the traffic is discarded.