== LISP Flow Mapping User Guide === Overview ==== Locator/ID Separation Protocol http://tools.ietf.org/html/rfc6830[Locator/ID Separation Protocol (LISP)] is a technology that provides a flexible map-and-encap framework that can be used for overlay network applications such as data center network virtualization and Network Function Virtualization (NFV). LISP provides the following name spaces: * http://tools.ietf.org/html/rfc6830#page-6[Endpoint Identifiers (EIDs)] * http://tools.ietf.org/html/rfc6830#section-3[Routing Locators (RLOCs)] In a virtualization environment EIDs can be viewed as virtual address space and RLOCs can be viewed as physical network address space. The LISP framework decouples network control plane from the forwarding plane by providing: * A data plane that specifies how the virtualized network addresses are encapsulated in addresses from the underlying physical network. * A control plane that stores the mapping of the virtual-to-physical address spaces, the associated forwarding policies and serves this information to the data plane on demand. Network programmability is achieved by programming forwarding policies such as transparent mobility, service chaining, and traffic engineering in the mapping system; where the data plane elements can fetch these policies on demand as new flows arrive. This chapter describes the LISP Flow Mapping project in OpenDaylight and how it can be used to enable advanced SDN and NFV use cases. LISP data plane Tunnel Routers are available at http://LISPmob.org/[LISPmob.org] in the open source community on the following platforms: * Linux * Android * OpenWRT For more details and support for LISP data plane software please visit http://LISPmob.org/[the LISPmob web site]. ==== LISP Flow Mapping Service The LISP Flow Mapping service provides LISP Mapping System services. This includes LISP Map-Server and LISP Map-Resolver services to store and serve mapping data to data plane nodes as well as to OpenDaylight applications. Mapping data can include mapping of virtual addresses to physical network address where the virtual nodes are reachable or hosted at. Mapping data can also include a variety of routing policies including traffic engineering and load balancing. To leverage this service, OpenDaylight applications and services can use the northbound REST API to define the mappings and policies in the LISP Mapping Service. Data plane devices capable of LISP control protocol can leverage this service through a southbound LISP plugin. LISP-enabled devices must be configured to use this OpenDaylight service as their Map Server and/or Map Resolver. The southbound LISP plugin supports the LISP control protocol (Map-Register, Map-Request, Map-Reply messages), and can also be used to register mappings in the OpenDaylight mapping service. === LISP Flow Mapping Architecture The following figure shows the various LISP Flow Mapping modules. .LISP Mapping Service Internal Architecture image::lispflow-technical-arch-overview-helium.jpg["LISP Mapping Service Internal Architecture", width=460] A brief description of each module is as follows: * *DAO (Data Access Object):* This layer separates the LISP logic from the database, so that we can separate the map server and map resolver from the specific implementation of the mapping database. Currently we have an implementation of this layer with an in-memory HashMap, but it can be switched to any other key/value store and you only need to implement the ILispDAO interface. * *Map Server:* This module processes the adding or registration of authentication tokens (keys) and mappings. For a detailed specification of LISP Map Server, see http://tools.ietf.org/search/rfc6830[LISP]. * *Map Resolver:* This module receives and processes the mapping lookup queries and provides the mappings to requester. For a detailed specification of LISP Map Server, see http://tools.ietf.org/search/rfc6830[LISP]. * *Northbound API:* This is part of the OpenDaylight northbound API. This module enables defining key-EID associations as well as adding mapping information through the Map Server. Key-EID associations can also be queried via this API. The northbound API also provides capability of querying the mapping information for an EID prefix. * *Neutron:* This module implements the OpenDaylight Neutron Service APIs. It provides integration between the LISP service and the OpenDaylight Neutron service, and thus OpenStack. * *NETCONF:* This module enables the LISP service to communicate to NETCONF-enabled devices through OpenDaylight's NETCONF plugin. * *Java API:* The API module exposes the Map Server and Map Resolver capabilities via a Java API. * *LISP Southbound Plugin:* This plugin enables data plane devices that support LISP control plane protocol (see see http://tools.ietf.org/search/rfc6830[LISP]) to register and query mappings to the LISP Flow Mapping via the LISP control plane protocol. === Configuring LISP Flow Mapping In order to use the LISP mapping service for registering EID to RLOC mappings from northbound or southbound, keys have to be defined for the EID prefixes first. Once a key is defined for an EID prefix, it can be used to add mappings for that EID prefix multiple times. If the service is going to be used to process Map-Register messages from the southbound LISP plugin, the same key must be used by the data plane device to create the authentication data in the Map-Register messages for the associated EID prefix. The +etc/custom.properties+ file in the Karaf distribution allows configuration of several OpenDaylight parameters. The LISP service has two properties that can be adjusted: +lisp.mappingOverwrite+ and +lisp.smr+. *lisp.mappingOverwrite* (default: 'true'):: Configures handling of mapping updates. When set to 'true' (default) a mapping update (either through the southbound plugin via a Map-Register message or through a northbound API PUT REST call) the existing RLOC set associated to an EID prefix is overwritten. When set to 'false', the RLOCs of the update are merged to the existing set. *lisp.smr* (default: 'false'):: Enables/disables the http://tools.ietf.org/html/rfc6830#section-6.6.2[Solicit-Map-Request (SMR)] functionality. SMR is a method to notify changes in an EID-to-RLOC mapping to "subscribers". The LISP service considers all Map-Request's source RLOC as a subscriber to the requested EID prefix, and will send an SMR control message to that RLOC if the mapping changes. *lisp.elpPolicy* (default: 'default'):: Configures how to build a Map-Reply southbound message from a mapping containing an Explicit Locator Path (ELP) RLOC. It is used for compatibility with dataplane devices that don't understand the ELP LCAF format. The 'default' setting doesn't alter the mapping, returning all RLOCs unmodified. The 'both' setting adds a new RLOC to the mapping, with a lower priority than the ELP, that is the next hop in the service chain. To determine the next hop, it searches the source RLOC of the Map-Request in the ELP, and chooses the next hop, if it exists, otherwise it chooses the first hop. The 'replace' setting adds a new RLOC using the same algorithm as the 'both' setting, but using the origin priority of the ELP RLOC, which is removed from the mapping. === Textual Conventions for LISP Address Formats In addition to the more common IPv4, IPv6 and MAC address data types, the LISP control plane supports arbitrary http://www.iana.org/assignments/address-family-numbers[Address Family Identifiers] assigned by IANA, and in addition to those the https://tools.ietf.org/html/draft-ietf-lisp-lcaf[LISP Canoncal Address Format (LCAF)]. The LISP Flow Mapping project in OpenDaylight implements support for many of these different address formats, the full list being summarized in the following table. While some of the address formats have well defined and widely used textual representation, many don't. It became necessary to define a convention to use for text rendering of all implemented address types in logs, URLs, input fields, etc. The below table lists the supported formats, along with their AFI number and LCAF type, including the prefix used for disambiguation of potential overlap, and examples output. .LISP Address Formats [align="right",options="header",cols=",>,<,192.0.2.2\|lps->192.0.2.3} | Source/Destination Key | 16387 | 12 | srcdst: | 192.0.2.1/32\|192.0.2.2/32 | Key/Value Address Pair | 16387 | 15 | kv: | 192.0.2.1=>192.0.2.2 |===== Please note that the forward slash character `/` typically separating IPv4 and IPv6 addresses from the mask length is transformed into `%2f` when used in a URL. === Karaf commands In this section we will discuss two types of Karaf commands: built-in, and LISP specific. Some built-in commands are quite useful, and are needed for the tutorial, so they will be discussed here. A reference of all LISP specific commands, added by the LISP Flow Mapping project is also included. They are useful mostly for debugging. ==== Useful built-in commands +help+:: Lists all available command, with a short description of each. +help +:: Show detailed help about a specific command. +feature:list [-i]+:: Show all locally available features in the Karaf container. The `-i` option lists only features that are currently installed. It is possible to use `| grep` to filter the output (for all commands, not just this one). +feature:install +:: Install feature `feature_name`. +log:set +:: Set the log level for `class` to `level`. The default log level for all classes is INFO. For debugging, or learning about LISP internals it is useful to run `log:set TRACE org.opendaylight.lispflowmapping` right after Karaf starts up. +log:display+:: Outputs the log file to the console, and returns control to the user. +log:tail+:: Continuously shows log output, requires `Ctrl+C` to return to the console. ==== LISP specific commands The available lisp commands can always be obtained by `help mappingservice`. Currently they are: +mappingservice:addkey+:: Add the default password `password` for the IPv4 EID prefix 0.0.0.0/0 (all addresses). This is useful when experimenting with southbound devices, and using the REST interface would be combersome for whatever reason. +mappingservice:mappings+:: Show the list of all mappings stored in the internal non-persistent data store (the DAO), listing the full data structure. The output is not human friendly, but can be used for debugging. === Tutorials This section provides a tutorial demonstrating various features in this service. ==== Creating a LISP overlay This section provides instructions to set up a LISP network of three nodes (one "client" node and two "server" nodes) using LISPmob as data plane LISP nodes and the LISP Flow Mapping project from OpenDaylight as the LISP programmable mapping system for the LISP network. ===== Overview The steps shown below will demonstrate setting up a LISP network between a client and two servers, then performing a failover between the two "server" nodes. ===== Prerequisites * *OpenDaylight Beryllium* * *The Postman Chrome App*: the most convenient way to follow along this tutorial is to use the https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop?hl=en[Postman Chrome App] to edit and send the requests. The project git repository hosts a collection of the requests that are used in this tutorial in the +resources/tutorial/Beryllium_Tutorial.json.postman_collection+ file. You can import this file to Postman by clicking 'Import' at the top, choosing 'Download from link' and then entering the following URL: +https://git.opendaylight.org/gerrit/gitweb?p=lispflowmapping.git;a=blob_plain;f=resources/tutorial/Beryllium_Tutorial.json.postman_collection;hb=refs/heads/master+. Alternatively, you can save the file on your machine, or if you have the repository checked out, you can import from there. You will need to create a new Postman Environment and define some variables within: +controllerHost+ set to the hostname or IP address of the machine running the ODL instance, and +restconfPort+ to 8181, if you didn't modify the default controller settings. * *LISPmob version 0.5.x* At the time of this writing this version has not been reelased yet, but it is available in the 'experimental' branch in the project's https://github.com/LISPmob/lispmob/tree/experimental[Git repository]. The README.md lists the dependencies needed to build it from source. * *A virtualization platform* ===== Target Environment The three LISP data plane nodes and the LISP mapping system are assumed to be running in Linux virtual machines, which have the +eth0+ interface in NAT mode to allow outside internet access and +eth1+ connected to a host-only network, with the following IP addresses (please adjust configuration files, JSON examples, etc. accordingly if you're using another addressing scheme): .Nodes in the tutorial [align="right",options="header"] |=== | Node | Node Type | IP Address | *controller* | OpenDaylight | 192.168.16.11 | *client* | LISPmob | 192.168.16.30 | *server1* | LISPmob | 192.168.16.31 | *server2* | LISPmob | 192.168.16.32 | *service-node* | LISPmob | 192.168.16.33 |=== NOTE: While the tutorial uses LISPmob as the data plane, it could be any LISP-enabled hardware or software router (commercial/open source). ===== Instructions The below steps use the command line tool cURL to talk to the LISP Flow Mapping RPC REST API. This is so that you can see the actual request URLs and body content on the page. . Install and run OpenDaylight Beryllium release on the controller VM. Please follow the general OpenDaylight Beryllium Installation Guide for this step. Once the OpenDaylight controller is running install the 'odl-openflowplugin-msmr' feature from the Karaf CLI: feature:install odl-lispflowmapping-msmr + It takes quite a while to load and initialize all features and their dependencies. It's worth running the command +log:tail+ in the Karaf console to see when the log output is winding down, and continue with the tutorial after that. . Install LISPmob on the *client*, *server1*, *server2*, and *service-node* VMs following the installation instructions https://github.com/LISPmob/lispmob#software-prerequisites[from the LISPmob README file]. . Configure the LISPmob installations from the previous step. Starting from the +lispd.conf.example+ file in the distribution, set the EID in each +lispd.conf+ file from the IP address space selected for your virtual/LISP network. In this tutorial the EID of the *client* is set to 1.1.1.1/32, and that of *server1* and *server2* to 2.2.2.2/32. . Set the RLOC interface to +eth1+ in each +lispd.conf+ file. LISP will determine the RLOC (IP address of the corresponding VM) based on this interface. . Set the Map-Resolver address to the IP address of the *controller*, and on the *client* the Map-Server too. On *server1* and *server2* set the Map-Server to something else, so that it doesn't interfere with the mappings on the controller, since we're going to program them manually. . Modify the "key" parameter in each +lispd.conf+ file to a key/password of your choice ('password' in this tutorial). + NOTE: The +resources/tutorial+ directory in the 'stable/beryllium' branch of the project git repository has the files used in the tutorial https://git.opendaylight.org/gerrit/gitweb?p=lispflowmapping.git;a=tree;f=resources/tutorial;hb=refs/heads/stable/beryllium[checked in], so you can just copy the files to +/root/lispd.conf+ on the respective VMs. You will also find the JSON files referenced below in the same directory. + . Define a key and EID prefix association in OpenDaylight using the RPC REST API for the *client* EID (1.1.1.1/32) to allow registration from the southbound. Since the mappings for the server EID will be configured from the REST API, no such association is necessary. Run the below command on the *controller* (or any machine that can reach *controller*, by replacing 'localhost' with the IP address of *controller*). curl -u "admin":"admin" -H "Content-type: application/json" -X POST \ http://localhost:8181/restconf/operations/mappingservice:add-key \ --data @add-key.json + where the content of the 'add-key.json' file is the following: + [source,json] ---- { "input": { "LispAddressContainer": { "Ipv4Address": { "afi": 1, "Ipv4Address": "1.1.1.1" } }, "mask-length": 32, "key-type": 1, "authkey": "password" } } ---- . Verify that the key is added properly by requesting the following URL: curl -u "admin":"admin" -H "Content-type: application/json" -X POST \ http://localhost:8181/restconf/operations/mappingservice:get-key \ --data @get1.json + where the content of the 'get1.json' file can be derived from the 'add-key.json' file by removing the 'key-type' and 'authkey' fields. The output the above invocation should look like this: {"output":{"authkey":"password"}} . Run the +lispd+ LISPmob daemon on all VMs: lispd -f /root/lispd.conf . The *client* LISPmob node should now register its EID-to-RLOC mapping in OpenDaylight. To verify you can lookup the corresponding EIDs via the REST API curl -u "admin":"admin" -H "Content-type: application/json" -X POST \ http://localhost:8181/restconf/operations/mappingservice:get-mapping \ --data @get1.json + An alternative way for retrieving mappings from ODL using the southbound interface is using the https://github.com/davidmeyer/lig[+lig+] open source tool. . Register the EID-to-RLOC mapping of the server EID 2.2.2.2/32 to the controller, pointing to *server1* and *server2* with a higher priority for *server1* curl -u "admin":"admin" -H "Content-type: application/json" -X POST \ http://localhost:8181/restconf/operations/mappingservice:add-mapping \ --data @mapping.json + where the 'mapping.json' file looks like this: + [source,json] ---- { "input": { "recordTtl": 1440, "maskLength": 32, "authoritative": true, "LispAddressContainer": { "Ipv4Address": { "afi": 1, "Ipv4Address": "2.2.2.2" } }, "LocatorRecord": [ { "name": "server1", "priority": 1, "weight": 1, "multicastPriority": 255, "multicastWeight": 0, "localLocator": true, "rlocProbed": false, "routed": false, "LispAddressContainer": { "Ipv4Address": { "afi": 1, "Ipv4Address": "192.168.16.31" } } }, { "name": "server2", "priority": 2, "weight": 1, "multicastPriority": 255, "multicastWeight": 0, "localLocator": true, "rlocProbed": false, "routed": false, "LispAddressContainer": { "Ipv4Address": { "afi": 1, "Ipv4Address": "192.168.16.32" } } } ] } } ---- + Here the priority of the second RLOC (192.168.16.32 - *server2*) is 2, a higher numeric value than the priority of 192.168.16.31, which is 1. This policy is saying that *server1* is preferred to *server2* for reaching EID 2.2.2.2/32. Note that lower priority value has higher preference in LISP. . Verify the correct registration of the 2.2.2.2/32 EID: curl -u "admin":"admin" -H "Content-type: application/json" -X POST \ http://localhost:8181/restconf/operations/mappingservice:get-mapping \ --data @get2.json + where 'get2.json' can be derived from 'get1.json' by changing the content of the 'Ipv4Address' field from '1.1.1.1' to '2.2.2.2'. . Now the LISP network is up. To verify, log into the *client* VM and ping the server EID: ping 2.2.2.2 . Let's test fail-over now. Suppose you had a service on *server1* which became unavailable, but *server1* itself is still reachable. LISP will not automatically fail over, even if the mapping for 2.2.2.2/32 has two locators, since both locators are still reachable and uses the one with the higher priority (lowest priority value). To force a failover, we need to set the priority of *server2* to a lower value. Using the file mapping.json above, swap the priority values between the two locators (lines 15 and 31 in 'mapping.json') and repeat the request from step 11. You can also repeat step 12 to see if the mapping is correctly registered. If you leave the ping on, and monitor the traffic using wireshark, you can see that the ping traffic to 2.2.2.2 will be diverted from the *server1* RLOC to the *server2* RLOC. + With the default OpenDaylight configuration the failover should be near instantaneous (we observed 3 lost pings in the worst case), because of the LISP http://tools.ietf.org/html/rfc6830#section-6.6.2[Solicit-Map-Request (SMR) mechanism] that can ask a LISP data plane element to update its mapping for a certain EID (enabled by default). It is controlled by the +lisp.smr+ variable in +etc/custom.porperties+. When enabled, any mapping change from the RPC interface will trigger an SMR packet to all data plane elements that have requested the mapping in the last 15 minutes. If disabled, ITRs keep their mappings until the TTL specified in the Map-Reply expires. . To add a service chain into the path from the client to the server, we can use an Explicit Locator Path, specifying the *service-node* as the first hop and *server1* (or *server2*) as the second hop. The following will achieve that: curl -u "admin":"admin" -H "Content-type: application/json" -X POST \ http://localhost:8181/restconf/operations/mappingservice:add-mapping \ --data @elp.json + where the 'elp.json' file is as follows: + [source,json] ---- { "input": { "recordTtl": 1440, "maskLength": 32, "authoritative": true, "LispAddressContainer": { "Ipv4Address": { "afi": 1, "Ipv4Address": "2.2.2.2" } }, "LocatorRecord": [ { "name": "ELP", "priority": 1, "weight": 1, "multicastPriority": 255, "multicastWeight": 0, "localLocator": true, "rlocProbed": false, "routed": false, "LispAddressContainer": { "LcafTrafficEngineeringAddr": { "afi": 16387, "lcafType": 10, "Hops": [ { "name": "service-node", "lookup": false, "RLOCProbe": false, "strict": true, "hop": { "Ipv4Address": { "afi": 1, "Ipv4Address": "192.168.16.33" } } }, { "name": "server1", "lookup": false, "RLOCProbe": false, "strict": true, "hop": { "Ipv4Address": { "afi": 1, "Ipv4Address": "192.168.16.31" } } } ] } } } ] } } ---- + After the mapping for 2.2.2.2/32 is updated with the above, the ICMP traffic from *client* to *server1* will flow through the *service-node*. You can confirm this in the LISPmob logs, or by sniffing the traffic on either the *service-node* or *server1*. Note that service chains are unidirectional, so unless another ELP mapping is added for the return traffic, packets will go from *server1* to *client* directly. . Suppose the *service-node* is actually a firewall, and traffic is diverted there to support access control lists (ACLs). In this tutorial that can be emulated by using +iptables+ firewall rules in the *service-node* VM. To deny traffic on the service chain defined above, the following rule can be added: iptables -A OUTPUT --dst 192.168.16.31 -j DROP + The ping from the *client* should now have stopped. + In this case the ACL is done on the destination RLOC. There is an effort underway in the LISPmob community to allow filtering on EIDs, which is the more logical place to apply ACLs. . To delete the rule and restore connectivity on the service chain, delete the ACL by issuing the following command: iptables -D OUTPUT --dst 192.168.16.31 -j DROP + which should restore connectivity. === LISP Flow Mapping Support For support the lispflowmapping project can be reached by emailing the developer mailing list: lispflowmapping-dev@lists.opendaylight.org or on the #opendaylight-lispflowmapping IRC channel on irc.freenode.net. Additional information is also available on the https://wiki.opendaylight.org/view/OpenDaylight_Lisp_Flow_Mapping:Main[Lisp Flow Mapping wiki]