chiark / gitweb /
61345bce4066b03a0bd9b3e74ba942d46d435087
[elogind.git] / src / libsystemd-rtnl / test-rtnl.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2013 Tom Gundersen <teg@jklm.no>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <linux/rtnetlink.h>
23 #include <netinet/ether.h>
24
25 #include "util.h"
26 #include "macro.h"
27 #include "sd-rtnl.h"
28 #include "socket-util.h"
29 #include "rtnl-util.h"
30
31 static void test_link_configure(sd_rtnl *rtnl, int ifindex) {
32         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *message;
33         uint16_t type;
34         const char *mac = "98:fe:94:3f:c6:18", *name = "test";
35         unsigned int mtu = 1450;
36         void *data;
37
38         /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
39         assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &message) >= 0);
40         assert(sd_rtnl_message_append(message, IFLA_IFNAME, name) >= 0);
41         assert(sd_rtnl_message_append(message, IFLA_ADDRESS, ether_aton(mac)) >= 0);
42         assert(sd_rtnl_message_append(message, IFLA_MTU, &mtu) >= 0);
43
44         assert(sd_rtnl_message_read(message, &type, &data) >= 0);
45         assert(type == IFLA_IFNAME);
46         assert(streq(name, (char *) data));
47
48         assert(sd_rtnl_message_read(message, &type, &data) >= 0);
49         assert(type == IFLA_ADDRESS);
50         assert(streq(mac, ether_ntoa(data)));
51
52         assert(sd_rtnl_message_read(message, &type, &data) >= 0);
53         assert(type == IFLA_MTU);
54         assert(mtu == *(unsigned int *) data);
55
56         assert(sd_rtnl_call(rtnl, message, 0, NULL) == 0);
57 }
58
59 static void test_route(void) {
60         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req;
61         uint32_t addr = htonl(INADDR_LOOPBACK);
62         uint32_t index = 2;
63         uint16_t type;
64         void *data;
65         int r;
66
67         r = sd_rtnl_message_route_new(RTM_NEWROUTE, AF_INET, 0, 0, 0,
68                                       RT_TABLE_MAIN, RT_SCOPE_UNIVERSE, RTPROT_BOOT,
69                                       RTN_UNICAST, 0, &req);
70         if (r < 0) {
71                 log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
72                 return;
73         }
74
75         r = sd_rtnl_message_append(req, RTA_GATEWAY, &addr);
76         if (r < 0) {
77                 log_error("Could not append RTA_GATEWAY attribute: %s", strerror(-r));
78                 return;
79         }
80
81         r = sd_rtnl_message_append(req, RTA_OIF, &index);
82         if (r < 0) {
83                 log_error("Could not append RTA_OIF attribute: %s", strerror(-r));
84                 return;
85         }
86
87         assert(sd_rtnl_message_read(req, &type, &data) > 0);
88         assert(type == RTA_GATEWAY);
89         assert(*(uint32_t *) data == addr);
90
91         assert(sd_rtnl_message_read(req, &type, &data) > 0);
92         assert(type == RTA_OIF);
93         assert(*(uint32_t *) data == index);
94 }
95
96 static void test_multiple(void) {
97         sd_rtnl *rtnl1, *rtnl2;
98
99         assert(sd_rtnl_open(0, &rtnl1) >= 0);
100         assert(sd_rtnl_open(0, &rtnl2) >= 0);
101
102         rtnl1 = sd_rtnl_unref(rtnl1);
103         rtnl2 = sd_rtnl_unref(rtnl2);
104 }
105
106 int main(void) {
107         sd_rtnl *rtnl;
108         sd_rtnl_message *m;
109         sd_rtnl_message *r;
110         void *data;
111         int if_loopback;
112         uint16_t type;
113         unsigned int mtu = 0;
114         unsigned int *mtu_reply;
115
116         test_multiple();
117
118         test_route();
119
120         assert(sd_rtnl_open(0, &rtnl) >= 0);
121         assert(rtnl);
122
123         if_loopback = (int) if_nametoindex("lo");
124         assert(if_loopback > 0);
125
126         test_link_configure(rtnl, if_loopback);
127
128         assert(sd_rtnl_message_link_new(RTM_GETLINK, if_loopback, 0, 0, &m) >= 0);
129         assert(m);
130
131         assert(sd_rtnl_message_get_type(m, &type) >= 0);
132         assert(type == RTM_GETLINK);
133
134         assert(sd_rtnl_message_read(m, &type, &data) == 0);
135
136         assert(sd_rtnl_call(rtnl, m, 0, &r) >= 0);
137         assert(sd_rtnl_message_get_type(r, &type) >= 0);
138         assert(type == RTM_NEWLINK);
139
140         assert(sd_rtnl_message_read(m, &type, &data) == 0);
141         assert((r = sd_rtnl_message_unref(r)) == NULL);
142
143         assert(sd_rtnl_call(rtnl, m, -1, &r) == -EPERM);
144         assert((m = sd_rtnl_message_unref(m)) == NULL);
145         assert((r = sd_rtnl_message_unref(r)) == NULL);
146
147         assert(sd_rtnl_message_link_new(RTM_GETLINK, if_loopback, 0, 0, &m) >= 0);
148         assert(m);
149
150         assert(sd_rtnl_message_append(m, IFLA_MTU, &mtu) >= 0);
151         assert(sd_rtnl_message_read(m, &type, (void **) &mtu_reply) == 1);
152
153         assert(type == IFLA_MTU);
154         assert(*mtu_reply == 0);
155
156         assert(sd_rtnl_message_read(m, &type, &data) == 0);
157
158         assert(sd_rtnl_call(rtnl, m, -1, &r) >= 0);
159         while (sd_rtnl_message_read(r, &type, &data) > 0) {
160                 switch (type) {
161 //                        case IFLA_MTU:
162 //                                assert(*(unsigned int *) data == 65536);
163 //                                break;
164 //                        case IFLA_QDISC:
165 //                                assert(streq((char *) data, "noqueue"));
166 //                                break;
167                         case IFLA_IFNAME:
168                                 assert(streq((char *) data, "lo"));
169                                 break;
170                 }
171         }
172
173         assert((m = sd_rtnl_message_unref(m)) == NULL);
174         assert((r = sd_rtnl_message_unref(r)) == NULL);
175         assert((rtnl = sd_rtnl_unref(rtnl)) == NULL);
176
177         return EXIT_SUCCESS;
178 }