File: README.md

package info (click to toggle)
nlinline 0.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid, trixie
  • size: 136 kB
  • sloc: ansic: 560; makefile: 17
file content (177 lines) | stat: -rw-r--r-- 7,206 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# nlinline
A quick and clean API for NetLink networking configuring.

NLINLINE (netlink inline) is a *library* of inline functions providing C programmers with very handy functions to configure network stacks. NLINLINE is entirely implemented in a header file, nlinline.h.

NLinline provides the following functions:

* `nlinline_if_nametoindex(const char *ifname);` return the index of the network interface whose name is `ifname`

* `int nlinline_iplink_add(const char *ifname, unsigned int ifindex, const char *type, const char *data);` add a (virtual) link

* `int nlinline_iplink_del(const char *ifname, unsigned int ifindex);` remove a link

* `int nlinline_linksetupdown(unsigned int ifindex, int updown);` turn the interface `ifindex` up (`updown == 1`) or down (`updown == 0`).

* `int nlinline_ipaddr_add(int family, void *addr, int prefixlen, int ifindex)` add an IP address to the interface `ifindex`. It supports IPv4 (`family == AF_INET`) and IPv6 `(family == AF_INET6)`.

* `int nlinline_ipaddr_del(int family, void *addr, int prefixlen, int ifindex)` remove the IP address from the interface `ifindex`. It supports IPv4 (`family == AF_INET`) and IPv6 `(family == AF_INET6)`.

* `int nlinline_iproute_add(int family, void *dst_addr, int dst_prefixlen, void *gw_addr, int ifindex);` add a static route to `dst_addr`/`dst_prefixlen` network through the gateway `gw_addr`. If `dst_addr == NULL` it adds a default route. `ifindex` must be specified when `gw_addr` is an IPv6 link local address.

* `int nlinline_iproute_del(int family, void *dst_addr, int dst_prefixlen, void *gw_addr, int ifindex);` remove the static route to `dst_addr`/`dst_prefixlen` network through the gateway `gw_addr`.

* `int nlinline_linksetaddr(unsigned int ifindex, void *macaddr);` set the MAC address of the interface `ifindex`.

* `int nlinline_linkgetaddr(unsigned int ifindex, void *macaddr);` get the MAC address of the interface `ifindex`.

* `int nlinline_linksetmtu(unsigned int ifindex, unsigned int mtu);` set the MTU of the interface `ifindex`.

IP addresses are `void *` arguments, any sequence of 4 or 16 bytes (in network byte order) is a legal IPv4 or IPv6 address respectively.

### Netlink + inline

* NLINLINE is a simple way to configure networking for network namespaces and *Internet of Threads* programs.
* NLINLINE do not add dependencies at run-time. It is useful for security critical applications (like PAM modules)
* NLINLINE uses netlink only, it does not depends on the obsolete netdevice (ioctl) API.
* Only the code of referenced inline functions enters in the object and executable code.

### Example

```C
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <nlinline.h>

int main(int argc, char *argv[]) {
  uint8_t ipv4addr[] = {192,168,2,2};
  uint8_t ipv4gw[] = {192,168,2,1};
  uint8_t ipv6addr[16] = {0x20, 0x01, 0x07, 0x60, [15] = 0x02};
  uint8_t ipv6gw[16] = {0x20, 0x01, 0x07, 0x60, [15] = 0x01};

  int ifindex = nlinline_if_nametoindex(argv[1]);
  if (ifindex > 0)
    printf("%d\n", ifindex);
  else {
    perror("nametoindex");
    return 1;
  }

  if (nlinline_linksetupdown(ifindex, 1) < 0)
    perror("link up");
  if (nlinline_ipaddr_add(AF_INET, ipv4addr, 24, ifindex) < 0)
    perror("addr ipv4");
  if (nlinline_iproute_add(AF_INET, NULL, 0, ipv4gw) < 0)
    perror("addr ipv6");
  if (nlinline_ipaddr_add(AF_INET6, ipv6addr, 64, ifindex) < 0)
    perror("route ipv4");
  if (nlinline_iproute_add(AF_INET6, NULL, 0, ipv6gw, 0) < 0)
    perror("route ipv6");
  return 0;
}
```

This program takes the name of an interface from the command line. It turns that interface up and
sets the interface IPv4 and IPv6 addresses and default routes.

## nlinline extended to user-mode stacks: nlinline+

The header file `nlinline+.h` implements an extended version of nlinline providing the support for user-mode networking stacks available as libraries.

`nlinline+.h` basically provides the same function as `nlinline.h` in a more flexible implementation. `nlinline+.h` includes a set of macro which define the same inline functions as nlinkine for library-based networking stacks.

```
NLINLINE_LIB(mystack)
``` 
defines the functions 
`mystack_if_nametoindex`, `mystack_linksetupdown`... using `mystack_socket` instead of `socket`, `mystack_bind` instead of `bind` etc.

```
NLINLINE_LIBCOMP(yourstack)
```
is similar to `NLINLINE_LIB`: it defines `yourstack_if_nametoindex`, `yourstack_linksetupdown`... 
but it uses only `yourstack_socket` instead of `socket`, while `bind`, `close`, `recv`, `send` are the standard system calls.

```
NLINLINE_LIBMULTI(hisstack)
```
is for librariesproviding multi-stack support. The functions `hisstack_if_nametoindex`,
`hisstack_linksetupdown` have one more (leading) argument: a generic pointer used as stack identifier. These functions use `hisstack_bind`, `hisstack_recv`...
Instead of `socket`, `hisstack_msocket` is used: it has one more (leading) argument which is the stack identifier.

```
NLINLINE_LIBMULTICOMP(herstack)
```
combines the characteristics of `NLINLINE_LIBCOMP` and those of `NLINLINE_LIBMULTI`, it is for libraries providing multi-stack support whose file descriptors are compatible with standard system calls. All the function generated by `NLINLINE_LIBMULTICOMP` have one more argument as in `NLINLINE_LIBMULTI`, `herstack_msocket` is used instead of `socket`,  while `bind`, `close`, `recv`, `send` are the standard system calls.

### Example

As an example of usage, programs using the [libvdestack](https://github.com/rd235/libvdestack) library can have nlinline support:

```
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <stdint.h>
#include <unistd.h>
#include <vdestack.h>
#include <nlinline+.h>

NLINLINE_LIBMULTICOMP(vde_)

int main(int argc, char *argv[]) {
  int rv;
    uint8_t ipv4addr[] = {192,168,2,2};
  uint8_t ipv4gw[] = {192,168,2,1};
  uint8_t ipv6addr[16] = {0x20, 0x01, 0x07, 0x60, [15] = 0x02};
  uint8_t ipv6gw[16] = {0x20, 0x01, 0x07, 0x60, [15] = 0x01};

  struct vdestack *stack = vde_addstack(argv[1], NULL);

  int ifindex = vde_if_nametoindex(stack, "vde0");
  if (ifindex > 0)
    printf("%d\n", ifindex);
  else {
    perror("nametoindex");
    return 1;
  }

  if (vde_linksetupdown(stack, ifindex, 1) < 0)
    perror("link up");
  if (vde_ipaddr_add(stack, AF_INET, ipv4addr, 24, ifindex) < 0)
    perror("addr ipv4");
  if (vde_iproute_add(stack, AF_INET, NULL, 0, ipv4gw) < 0)
    perror("addr ipv6");
  if (vde_ipaddr_add(stack, AF_INET6, ipv6addr, 64, ifindex) < 0)
    perror("route ipv4");
  if (vde_iproute_add(stack, AF_INET6, NULL, 0, ipv6gw, 0) < 0)
    perror("route ipv6");

  /* use the stack */

  vde_delstack(stack);
}

```

Functions like `vde_linksetupdown`, `vde_if_nametoindex`,... have been defined by
`NLINLINE_LIBMULTICOMP`.

## how to install nlinline

Just put `nlinline.h` (and `nlinline+.h`) where you need it and that's all.
```
cp nlinline.h nlinline+.h /usr/local/include
```
or
```
cp nlinline.h /usr/include
```

In case you are lazy and you like standard install methods and tools, there is a trivial CMake support. 
The standard cmake install sequence applies:
```
$ cmake .
$ sudo make install
```