API Usage

In this section, we give some simple examples of using both the netlink raw API, and the higher-level SDN API. An obvious cautionary note: you are modifying your network stack (possibly remotely), so don’t drop your any configuration that would disconnect you (e.g., your control interface, its subnet route(s), and its default route)! These examples use the curl command-line tool, but you could also use wget or fetch.

nlsdn is effectively a netlink wrapper, and the implementation is based on the pyroute2 Netlink Python library. Thus, much of the input data to individual API calls is best defined by the documentation for those APIs. You can find a detailed netlink reference at http://man7.org/linux/man-pages/man7/rtnetlink.7.html ; the pyroute2 documentation is at https://docs.pyroute2.org/iproute.html . Often, it is unnecessary to specify full Netlink attribute names; pyroute2 does a great job expanding unprefixed attribute names to the appropriate prefixed names, given the calling context (e.g., link, address, route, etc.).

All POST/DELETE data is JSON-encoded, and you should specify a Content-type: text/json header in your request. GET calls only accept URL parameters. Successful POST requests return HTTP 2xx and no content.

Unsuccessful requests return an HTTP error code (e.g., 404, 500), and a simple JSON dictionary with a error member that describes the problem.

The curl-based examples in the following sections assume an SSL/TLS-enabled nlsdn server running on localhost:56789, that is configured to accept the admin/admin username and password credentials. We replace the common part of the URL frontmatter for the netlink API endpoint with the $NLSERVER shell variable (and similarly for the $SDNSERVER variable), so make sure to export those variables (and modify as necessary to your config) prior to running the examples:

export NLSERVER=https://localhost:56789/service/nl/v1
export SDNSERVER=https://localhost:56789/service/nlsdn/v1

nl API Endpoint

This subsection defines the raw netlink API. It exposes most of the traditional netlink resources and operations, but not all.

GET requests return lists of dictionaries, each describing a resource (link, address, route, etc). These are defined in the netlink man page (http://man7.org/linux/man-pages/man7/rtnetlink.7.html), but they all follow a common format, containing several top-level keys, and a very detailed, resource-specific list of attributes (in the attrs) key. All GET requests accept several common parameters that allow you to filter the output data, both by the high-level key names, and the lower-level attribute names.

  • _filter: if set to 0, exclude any of the supplied _keys and _attrs. If set to 1, include only the supplied _keys and _attrs.
  • _keys: include or exclude the given keys.
  • _attrs: include or exclude the given attributes. Note that these may be short attribute names (e.g. ifname instead of IFLA_IFNAME), just as for input data to POST or DELETE requests.

nlsdn API Endpoint

This subsection covers the higher-level SDN API. The API is currently quite simple: it supports nlsdn.server.sdn.Match rules that, when match a given flow, perform an nlsdn.server.sdn.Action. Each of these types of objects are created separately, so you must first create an nlsdn.server.sdn.Action, then create a nlsdn.server.sdn.Match that references the nlsdn.server.sdn.Action. Both objects are identified by an alphanumeric ID, returned after creation.

We currently support nlsdn.server.sdn.RuleMatch match objects, which are implemented by ip rule; and nlsdn.server.sdn.RouteAction and nlsdn.server.sdn.Seg6Action actions, both implemented by ip route statements in per-instance routing tables. A matching rule points to a route table containing an action.

nlsdn/match

GET:

Returns a dictionary of nlsdn.server.sdn.Match objects, indexed by number. Each number key points to a dictionary containing the Match keys. For instance, to show all Match objects,

curl -k -u admin:admin "${NLSDNSERVER}/match"

or to show a specific match

curl -k -u admin:admin "${NLSDNSERVER}/match/500"

POST:

Creates a Match object. The type of Match object created is determined based on the value of the type key. For instance, to create a RuleMatch, you would provide a dictionary containing a subset of these keys (nlsdn.server.sdn.RuleMatch.NL_KEYS), like so:

curl -k -u admin:admin -H 'content-type: text/json' -X POST \
    -d '{"type":"rule","priority":500,"src":"127.0.0.1","src_len":32, \
         "sport_range":[56789,56789],"dst":"8.8.8.8","dst_len":32,"oifname":"wlp3s0", \
         "action_id":500}' \
    "${NLSDNSERVER}/match"

(Note that the use of the sport_range attribute currently requires our forked version of pyroute2, available at https://gitlab.flux.utah.edu/safeedge/pyroute2 .)

This would create a rule (nlsdn.server.sdn.RuleMatch) Match object that matches traffic from 127.0.0.1:56789 heading to 8.8.8.8 via wlp3s0, and direct it to the Action with ID 500.

DELETE:

You can delete a Match object by its ID. Note that you must delete Match objects prior to deleting the Actions they reference. For instance, to delete the RuleMatch object created above, you would

curl -k -u admin:admin -H 'content-type: text/json' -X DELETE \
    "${NLSDNSERVER}/match/500" ; echo

nlsdn/action

GET:

Returns a dictionary of nlsdn.server.sdn.Action objects, indexed by number. Each number key points to a dictionary containing the Action keys. For instance, to show all Action objects,

curl -k -u admin:admin "${NLSDNSERVER}/action"

or to show a specific action

curl -k -u admin:admin "${NLSDNSERVER}/action/500"

POST:

curl -k -u admin:admin -H 'content-type: text/json' -X POST \
    -d '{"type":"route","number":500,"dst":"8.8.8.8","dst_len":32, \
         "oif":68}' \
    "${NLSDNSERVER}/action"

DELETE:

You can delete an Action object by its ID. Note that you must delete Match objects prior to deleting the Actions they reference. For instance, to delete the RouteAction object created above, you would

curl -k -u admin:admin -H 'content-type: text/json' -X DELETE \
    "${NLSDNSERVER}/action/500" ; echo