Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/net/ynl/samples/rt-link.c
26285 views
1
// SPDX-License-Identifier: GPL-2.0
2
#include <stdio.h>
3
#include <string.h>
4
5
#include <ynl.h>
6
7
#include <arpa/inet.h>
8
#include <net/if.h>
9
10
#include "rt-link-user.h"
11
12
static void rt_link_print(struct rt_link_getlink_rsp *r)
13
{
14
unsigned int i;
15
16
printf("%3d: ", r->_hdr.ifi_index);
17
18
if (r->_len.ifname)
19
printf("%16s: ", r->ifname);
20
21
if (r->_present.mtu)
22
printf("mtu %5d ", r->mtu);
23
24
if (r->linkinfo._len.kind)
25
printf("kind %-8s ", r->linkinfo.kind);
26
else
27
printf(" %8s ", "");
28
29
if (r->prop_list._count.alt_ifname) {
30
printf("altname ");
31
for (i = 0; i < r->prop_list._count.alt_ifname; i++)
32
printf("%s ", r->prop_list.alt_ifname[i]->str);
33
printf(" ");
34
}
35
36
if (r->linkinfo._present.data && r->linkinfo.data._present.netkit) {
37
struct rt_link_linkinfo_netkit_attrs *netkit;
38
const char *name;
39
40
netkit = &r->linkinfo.data.netkit;
41
printf("primary %d ", netkit->primary);
42
43
name = NULL;
44
if (netkit->_present.policy)
45
name = rt_link_netkit_policy_str(netkit->policy);
46
if (name)
47
printf("policy %s ", name);
48
}
49
50
printf("\n");
51
}
52
53
static int rt_link_create_netkit(struct ynl_sock *ys)
54
{
55
struct rt_link_getlink_ntf *ntf_gl;
56
struct rt_link_newlink_req *req;
57
struct ynl_ntf_base_type *ntf;
58
int ret;
59
60
req = rt_link_newlink_req_alloc();
61
if (!req) {
62
fprintf(stderr, "Can't alloc req\n");
63
return -1;
64
}
65
66
/* rtnetlink doesn't provide info about the created object.
67
* It expects us to set the ECHO flag and the dig the info out
68
* of the notifications...
69
*/
70
rt_link_newlink_req_set_nlflags(req, NLM_F_CREATE | NLM_F_ECHO);
71
72
rt_link_newlink_req_set_linkinfo_kind(req, "netkit");
73
74
/* Test error messages */
75
rt_link_newlink_req_set_linkinfo_data_netkit_policy(req, 10);
76
ret = rt_link_newlink(ys, req);
77
if (ret) {
78
printf("Testing error message for policy being bad:\n\t%s\n", ys->err.msg);
79
} else {
80
fprintf(stderr, "Warning: unexpected success creating netkit with bad attrs\n");
81
goto created;
82
}
83
84
rt_link_newlink_req_set_linkinfo_data_netkit_policy(req, NETKIT_DROP);
85
86
ret = rt_link_newlink(ys, req);
87
created:
88
rt_link_newlink_req_free(req);
89
if (ret) {
90
fprintf(stderr, "YNL: %s\n", ys->err.msg);
91
return -1;
92
}
93
94
if (!ynl_has_ntf(ys)) {
95
fprintf(stderr,
96
"Warning: interface created but received no notification, won't delete the interface\n");
97
return 0;
98
}
99
100
ntf = ynl_ntf_dequeue(ys);
101
if (ntf->cmd != RTM_NEWLINK) {
102
fprintf(stderr,
103
"Warning: unexpected notification type, won't delete the interface\n");
104
return 0;
105
}
106
ntf_gl = (void *)ntf;
107
ret = ntf_gl->obj._hdr.ifi_index;
108
ynl_ntf_free(ntf);
109
110
return ret;
111
}
112
113
static void rt_link_del(struct ynl_sock *ys, int ifindex)
114
{
115
struct rt_link_dellink_req *req;
116
117
req = rt_link_dellink_req_alloc();
118
if (!req) {
119
fprintf(stderr, "Can't alloc req\n");
120
return;
121
}
122
123
req->_hdr.ifi_index = ifindex;
124
if (rt_link_dellink(ys, req))
125
fprintf(stderr, "YNL: %s\n", ys->err.msg);
126
else
127
fprintf(stderr,
128
"Trying to delete a Netkit interface (ifindex %d)\n",
129
ifindex);
130
131
rt_link_dellink_req_free(req);
132
}
133
134
int main(int argc, char **argv)
135
{
136
struct rt_link_getlink_req_dump *req;
137
struct rt_link_getlink_list *rsp;
138
struct ynl_error yerr;
139
struct ynl_sock *ys;
140
int created = 0;
141
142
ys = ynl_sock_create(&ynl_rt_link_family, &yerr);
143
if (!ys) {
144
fprintf(stderr, "YNL: %s\n", yerr.msg);
145
return 1;
146
}
147
148
if (argc > 1) {
149
fprintf(stderr, "Trying to create a Netkit interface\n");
150
created = rt_link_create_netkit(ys);
151
if (created < 0)
152
goto err_destroy;
153
}
154
155
req = rt_link_getlink_req_dump_alloc();
156
if (!req)
157
goto err_del_ifc;
158
159
rsp = rt_link_getlink_dump(ys, req);
160
rt_link_getlink_req_dump_free(req);
161
if (!rsp)
162
goto err_close;
163
164
if (ynl_dump_empty(rsp))
165
fprintf(stderr, "Error: no links reported\n");
166
ynl_dump_foreach(rsp, link)
167
rt_link_print(link);
168
rt_link_getlink_list_free(rsp);
169
170
if (created)
171
rt_link_del(ys, created);
172
173
ynl_sock_destroy(ys);
174
return 0;
175
176
err_close:
177
fprintf(stderr, "YNL: %s\n", ys->err.msg);
178
err_del_ifc:
179
if (created)
180
rt_link_del(ys, created);
181
err_destroy:
182
ynl_sock_destroy(ys);
183
return 2;
184
}
185
186