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 to0
, exclude any of the supplied_keys
and_attrs
. If set to1
, 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 ofIFLA_IFNAME
), just as for input data toPOST
orDELETE
requests.
nl/links
¶
GET
:
Returns a list of dictionaries, each corresponding to a struct
ifinfomsg
returned by a RTM_GETLINK
netlink request. You may
specify URL parameters that correspond to struct ifinfomsg
(or to
its pyroute2
short names and short attribute names), such as
family
, ifindex
, ifname
, etc. Instead of searching for a
specific device by ifindex
, you could also simply using the
nl/links/<ifindex>
URL; or the nl/links/<ifname>
URL instead of
ifname
.
To return all information about all links:
curl -k -u admin:admin "${NLSERVER}/links"
To only return some of the information about the lo
device:
curl -k -u admin:admin \
"${NLSERVER}/links?ifname=lo&_filter=1&_keys=family,attrs&_attrs=ifname"
POST
:
Creates a new link according to the JSON dictionary specified as the
input data (e.g., the RTM_NEWLINK
netlink message).
For instance, to create a link named dummy1
using the dummy
driver:
curl -k -u admin:admin -H 'content-type: text/json' -X POST \
-d '{"ifname":"dummy1","kind":"dummy"}' \
"${NLSERVER}/links"
DELETE
:
Deletes one or more links according to the JSON dictionary specified as the
input data (e.g., the RTM_DELLINK
netlink message).
For instance, to delete the dummy1
link we previously created:
curl -k -u admin:admin -H 'content-type: text/json' -X DELETE \
-d '{"ifname":"dummy1","kind":"dummy"}' \
"${NLSERVER}/links"
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