chiark / gitweb /
2d2b2373b6a6b5f18f8fdefa52a19167cc36a945
[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 <netinet/ether.h>
23
24 #include "util.h"
25 #include "macro.h"
26 #include "sd-rtnl.h"
27 #include "socket-util.h"
28
29 static void test_link_configure(sd_rtnl *rtnl, int ifindex) {
30         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *message;
31         uint16_t type;
32         const char *mac = "98:fe:94:3f:c6:18", *name = "test";
33         unsigned int mtu = 1450;
34         void *data;
35
36         /* we'd really like to test NEWLINK, but let's not mess with the running kernel */
37         assert(sd_rtnl_message_link_new(RTM_GETLINK, ifindex, 0, 0, &message) >= 0);
38         assert(sd_rtnl_message_append(message, IFLA_IFNAME, name) >= 0);
39         assert(sd_rtnl_message_append(message, IFLA_ADDRESS, ether_aton(mac)) >= 0);
40         assert(sd_rtnl_message_append(message, IFLA_MTU, &mtu) >= 0);
41
42         assert(sd_rtnl_message_read(message, &type, &data) >= 0);
43         assert(type == IFLA_IFNAME);
44         assert(streq(name, (char *) data));
45
46         assert(sd_rtnl_message_read(message, &type, &data) >= 0);
47         assert(type == IFLA_ADDRESS);
48         assert(streq(mac, ether_ntoa(data)));
49
50         assert(sd_rtnl_message_read(message, &type, &data) >= 0);
51         assert(type == IFLA_MTU);
52         assert(mtu == *(unsigned int *) data);
53
54         assert(sd_rtnl_send_with_reply_and_block(rtnl, message, 0, NULL) == 0);
55 }
56
57 static void test_route(void) {
58         _cleanup_sd_rtnl_message_unref_ sd_rtnl_message *req;
59         uint32_t addr = htonl(INADDR_LOOPBACK);
60         uint32_t index = 2;
61         uint16_t type;
62         void *data;
63         int r;
64
65         r = sd_rtnl_message_route_new(RTM_NEWROUTE, AF_INET, 0, 0, 0,
66                                       RT_TABLE_MAIN, RT_SCOPE_UNIVERSE, RTPROT_BOOT,
67                                       RTN_UNICAST, 0, &req);
68         if (r < 0) {
69                 log_error("Could not create RTM_NEWROUTE message: %s", strerror(-r));
70                 return;
71         }
72
73         r = sd_rtnl_message_append(req, RTA_GATEWAY, &addr);
74         if (r < 0) {
75                 log_error("Could not append RTA_GATEWAY attribute: %s", strerror(-r));
76                 return;
77         }
78
79         r = sd_rtnl_message_append(req, RTA_OIF, &index);
80         if (r < 0) {
81                 log_error("Could not append RTA_OIF attribute: %s", strerror(-r));
82                 return;
83         }
84
85         assert(sd_rtnl_message_read(req, &type, &data) > 0);
86         assert(type == RTA_GATEWAY);
87         assert(*(uint32_t *) data == addr);
88
89         assert(sd_rtnl_message_read(req, &type, &data) > 0);
90         assert(type == RTA_OIF);
91         assert(*(uint32_t *) data == index);
92 }
93
94 static void test_multiple(void) {
95         sd_rtnl *rtnl1, *rtnl2;
96
97         assert(sd_rtnl_open(0, &rtnl1) >= 0);
98         assert(sd_rtnl_open(0, &rtnl2) >= 0);
99
100         rtnl1 = sd_rtnl_unref(rtnl1);
101         rtnl2 = sd_rtnl_unref(rtnl2);
102 }
103
104 int main(void) {
105         sd_rtnl *rtnl;
106         sd_rtnl_message *m;
107         sd_rtnl_message *r;
108         void *data;
109         int if_loopback;
110         uint16_t type;
111         unsigned int mtu = 0;
112         unsigned int *mtu_reply;
113
114         test_multiple();
115
116         test_route();
117
118         assert(sd_rtnl_open(0, &rtnl) >= 0);
119         assert(rtnl);
120
121         if_loopback = (int) if_nametoindex("lo");
122         assert(if_loopback > 0);
123
124         test_link_configure(rtnl, if_loopback);
125
126         assert(sd_rtnl_message_link_new(RTM_GETLINK, if_loopback, 0, 0, &m) >= 0);
127         assert(m);
128
129         assert(sd_rtnl_message_get_type(m, &type) >= 0);
130         assert(type == RTM_GETLINK);
131
132         assert(sd_rtnl_message_read(m, &type, &data) == 0);
133
134         assert(sd_rtnl_send_with_reply_and_block(rtnl, m, 0, &r) >= 0);
135         assert(sd_rtnl_message_get_type(r, &type) >= 0);
136         assert(type == RTM_NEWLINK);
137
138         assert(sd_rtnl_message_read(m, &type, data) == 0);
139         assert((r = sd_rtnl_message_unref(r)) == NULL);
140
141         assert(sd_rtnl_send_with_reply_and_block(rtnl, m, -1, &r) == -EPERM);
142         assert((m = sd_rtnl_message_unref(m)) == NULL);
143         assert((r = sd_rtnl_message_unref(r)) == NULL);
144
145         assert(sd_rtnl_message_link_new(RTM_GETLINK, if_loopback, 0, 0, &m) >= 0);
146         assert(m);
147
148         assert(sd_rtnl_message_append(m, IFLA_MTU, &mtu) >= 0);
149         assert(sd_rtnl_message_read(m, &type, (void **) &mtu_reply) == 1);
150
151         assert(type == IFLA_MTU);
152         assert(*mtu_reply == 0);
153
154         assert(sd_rtnl_message_read(m, &type, data) == 0);
155
156         assert(sd_rtnl_send_with_reply_and_block(rtnl, m, -1, &r) >= 0);
157         while (sd_rtnl_message_read(r, &type, &data) > 0) {
158                 switch (type) {
159 //                        case IFLA_MTU:
160 //                                assert(*(unsigned int *) data == 65536);
161 //                                break;
162 //                        case IFLA_QDISC:
163 //                                assert(streq((char *) data, "noqueue"));
164 //                                break;
165                         case IFLA_IFNAME:
166                                 assert(streq((char *) data, "lo"));
167                                 break;
168                 }
169         }
170
171         assert((m = sd_rtnl_message_unref(m)) == NULL);
172         assert((r = sd_rtnl_message_unref(r)) == NULL);
173         assert((rtnl = sd_rtnl_unref(rtnl)) == NULL);
174
175         return EXIT_SUCCESS;
176 }