summaryrefslogtreecommitdiffstats
path: root/src/test/test-netlink-manual.c
blob: 8c1b0d407e36c0275ab00ef72ce76220e61b79c6 (plain)
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
/* SPDX-License-Identifier: LGPL-2.1-or-later */

/* Make sure the net/if.h header is included before any linux/ one */
#include <net/if.h>
#include <arpa/inet.h>
#include <linux/if_tunnel.h>
#include <linux/ip.h>
#include <sys/types.h>
#include <unistd.h>

#include "sd-netlink.h"

#include "macro.h"
#include "module-util.h"
#include "tests.h"

static int load_module(const char *mod_name) {
        _cleanup_(sym_kmod_unrefp) struct kmod_ctx *ctx = NULL;
        _cleanup_(sym_kmod_module_unref_listp) struct kmod_list *list = NULL;
        struct kmod_list *l;
        int r;

        r = dlopen_libkmod();
        if (r < 0)
                return log_error_errno(r, "Failed to load libkmod: %m");

        ctx = sym_kmod_new(NULL, NULL);
        if (!ctx)
                return log_oom();

        r = sym_kmod_module_new_from_lookup(ctx, mod_name, &list);
        if (r < 0)
                return r;

        sym_kmod_list_foreach(l, list) {
                _cleanup_(sym_kmod_module_unrefp) struct kmod_module *mod = NULL;

                mod = sym_kmod_module_get_module(l);

                r = sym_kmod_module_probe_insert_module(mod, 0, NULL, NULL, NULL, NULL);
                if (r > 0)
                        r = -EINVAL;
        }

        return r;
}

static int test_tunnel_configure(sd_netlink *rtnl) {
        int r;
        sd_netlink_message *m, *n;
        struct in_addr local, remote;

        /* skip test if module cannot be loaded */
        r = load_module("ipip");
        if (r < 0)
                return log_tests_skipped_errno(r, "failed to load module 'ipip'");

        r = load_module("sit");
        if (r < 0)
                return log_tests_skipped_errno(r, "failed to load module 'sit'");

        if (getuid() != 0)
                return log_tests_skipped("not root");

        /* IPIP tunnel */
        assert_se(sd_rtnl_message_new_link(rtnl, &m, RTM_NEWLINK, 0) >= 0);
        assert_se(m);

        assert_se(sd_netlink_message_append_string(m, IFLA_IFNAME, "ipip-tunnel") >= 0);
        assert_se(sd_netlink_message_append_u32(m, IFLA_MTU, 1234)>= 0);

        assert_se(sd_netlink_message_open_container(m, IFLA_LINKINFO) >= 0);

        assert_se(sd_netlink_message_open_container_union(m, IFLA_INFO_DATA, "ipip") >= 0);

        inet_pton(AF_INET, "192.168.21.1", &local.s_addr);
        assert_se(sd_netlink_message_append_u32(m, IFLA_IPTUN_LOCAL, local.s_addr) >= 0);

        inet_pton(AF_INET, "192.168.21.2", &remote.s_addr);
        assert_se(sd_netlink_message_append_u32(m, IFLA_IPTUN_REMOTE, remote.s_addr) >= 0);

        assert_se(sd_netlink_message_close_container(m) >= 0);
        assert_se(sd_netlink_message_close_container(m) >= 0);

        assert_se(sd_netlink_call(rtnl, m, -1, 0) == 1);

        ASSERT_NULL((m = sd_netlink_message_unref(m)));

        /* sit */
        assert_se(sd_rtnl_message_new_link(rtnl, &n, RTM_NEWLINK, 0) >= 0);
        assert_se(n);

        assert_se(sd_netlink_message_append_string(n, IFLA_IFNAME, "sit-tunnel") >= 0);
        assert_se(sd_netlink_message_append_u32(n, IFLA_MTU, 1234)>= 0);

        assert_se(sd_netlink_message_open_container(n, IFLA_LINKINFO) >= 0);

        assert_se(sd_netlink_message_open_container_union(n, IFLA_INFO_DATA, "sit") >= 0);

        assert_se(sd_netlink_message_append_u8(n, IFLA_IPTUN_PROTO, IPPROTO_IPIP) >= 0);

        inet_pton(AF_INET, "192.168.21.3", &local.s_addr);
        assert_se(sd_netlink_message_append_u32(n, IFLA_IPTUN_LOCAL, local.s_addr) >= 0);

        inet_pton(AF_INET, "192.168.21.4", &remote.s_addr);
        assert_se(sd_netlink_message_append_u32(n, IFLA_IPTUN_REMOTE, remote.s_addr) >= 0);

        assert_se(sd_netlink_message_close_container(n) >= 0);
        assert_se(sd_netlink_message_close_container(n) >= 0);

        assert_se(sd_netlink_call(rtnl, n, -1, 0) == 1);

        ASSERT_NULL((n = sd_netlink_message_unref(n)));

        return EXIT_SUCCESS;
}

int main(int argc, char *argv[]) {
        sd_netlink *rtnl;
        int r;

        test_setup_logging(LOG_INFO);

        assert_se(sd_netlink_open(&rtnl) >= 0);
        assert_se(rtnl);

        r = test_tunnel_configure(rtnl);

        ASSERT_NULL((rtnl = sd_netlink_unref(rtnl)));

        return r;
}