]> git.proxmox.com Git - mirror_iproute2.git/blame - ip/iplink_bridge_slave.c
misc/ss: tcp cwnd should be unsigned
[mirror_iproute2.git] / ip / iplink_bridge_slave.c
CommitLineData
8c39db39
JP
1/*
2 * iplink_bridge_slave.c Bridge slave device support
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * Authors: Jiri Pirko <jiri@resnulli.us>
10 */
11
12#include <stdio.h>
13#include <sys/socket.h>
14#include <netinet/in.h>
15#include <linux/if_link.h>
16#include <linux/if_bridge.h>
17
18#include "rt_names.h"
19#include "utils.h"
20#include "ip_common.h"
21
a560d850 22static void print_explain(FILE *f)
8c39db39 23{
a560d850 24 fprintf(f,
8c39db39
JP
25 "Usage: ... bridge_slave [ state STATE ] [ priority PRIO ] [cost COST ]\n"
26 " [ guard {on | off} ]\n"
56f5daac 27 " [ hairpin {on | off} ]\n"
8c39db39
JP
28 " [ fastleave {on | off} ]\n"
29 " [ root_block {on | off} ]\n"
30 " [ learning {on | off} ]\n"
31 " [ flood {on | off} ]\n"
f6e615de 32 " [ proxy_arp {on | off} ]\n"
38b31a78 33 " [ proxy_arp_wifi {on | off} ]\n"
10759a90 34 " [ mcast_router MULTICAST_ROUTER ]\n"
478a8e59 35 " [ mcast_fast_leave {on | off} ]\n"
8c39db39
JP
36 );
37}
38
a560d850
ZS
39static void explain(void)
40{
41 print_explain(stderr);
42}
43
8c39db39
JP
44static const char *port_states[] = {
45 [BR_STATE_DISABLED] = "disabled",
46 [BR_STATE_LISTENING] = "listening",
47 [BR_STATE_LEARNING] = "learning",
48 [BR_STATE_FORWARDING] = "forwarding",
49 [BR_STATE_BLOCKING] = "blocking",
50};
51
52static void print_portstate(FILE *f, __u8 state)
53{
54 if (state <= BR_STATE_BLOCKING)
55 fprintf(f, "state %s ", port_states[state]);
56 else
57 fprintf(f, "state (%d) ", state);
58}
59
60static void print_onoff(FILE *f, char *flag, __u8 val)
61{
62 fprintf(f, "%s %s ", flag, val ? "on" : "off");
63}
64
65static void bridge_slave_print_opt(struct link_util *lu, FILE *f,
66 struct rtattr *tb[])
67{
68 if (!tb)
69 return;
70
71 if (tb[IFLA_BRPORT_STATE])
72 print_portstate(f, rta_getattr_u8(tb[IFLA_BRPORT_STATE]));
73
74 if (tb[IFLA_BRPORT_PRIORITY])
75 fprintf(f, "priority %d ",
76 rta_getattr_u16(tb[IFLA_BRPORT_PRIORITY]));
77
78 if (tb[IFLA_BRPORT_COST])
79 fprintf(f, "cost %d ",
80 rta_getattr_u32(tb[IFLA_BRPORT_COST]));
81
82 if (tb[IFLA_BRPORT_MODE])
83 print_onoff(f, "hairpin",
84 rta_getattr_u8(tb[IFLA_BRPORT_MODE]));
85
86 if (tb[IFLA_BRPORT_GUARD])
87 print_onoff(f, "guard",
88 rta_getattr_u8(tb[IFLA_BRPORT_GUARD]));
89
90 if (tb[IFLA_BRPORT_PROTECT])
91 print_onoff(f, "root_block",
92 rta_getattr_u8(tb[IFLA_BRPORT_PROTECT]));
93
94 if (tb[IFLA_BRPORT_FAST_LEAVE])
95 print_onoff(f, "fastleave",
96 rta_getattr_u8(tb[IFLA_BRPORT_FAST_LEAVE]));
97
98 if (tb[IFLA_BRPORT_LEARNING])
99 print_onoff(f, "learning",
100 rta_getattr_u8(tb[IFLA_BRPORT_LEARNING]));
101
102 if (tb[IFLA_BRPORT_UNICAST_FLOOD])
103 print_onoff(f, "flood",
104 rta_getattr_u8(tb[IFLA_BRPORT_UNICAST_FLOOD]));
3069539f
NA
105
106 if (tb[IFLA_BRPORT_ID])
107 fprintf(f, "port_id 0x%x ",
108 rta_getattr_u16(tb[IFLA_BRPORT_ID]));
109
110 if (tb[IFLA_BRPORT_NO])
111 fprintf(f, "port_no 0x%x ",
112 rta_getattr_u16(tb[IFLA_BRPORT_NO]));
113
114 if (tb[IFLA_BRPORT_DESIGNATED_PORT])
115 fprintf(f, "designated_port %u ",
116 rta_getattr_u16(tb[IFLA_BRPORT_DESIGNATED_PORT]));
117
118 if (tb[IFLA_BRPORT_DESIGNATED_COST])
119 fprintf(f, "designated_cost %u ",
120 rta_getattr_u16(tb[IFLA_BRPORT_DESIGNATED_COST]));
121
122 if (tb[IFLA_BRPORT_BRIDGE_ID]) {
123 char bridge_id[32];
124
125 br_dump_bridge_id(RTA_DATA(tb[IFLA_BRPORT_BRIDGE_ID]),
126 bridge_id, sizeof(bridge_id));
127 fprintf(f, "designated_bridge %s ", bridge_id);
128 }
129
130 if (tb[IFLA_BRPORT_ROOT_ID]) {
131 char root_id[32];
132
133 br_dump_bridge_id(RTA_DATA(tb[IFLA_BRPORT_ROOT_ID]),
134 root_id, sizeof(root_id));
135 fprintf(f, "designated_root %s ", root_id);
136 }
137
138 if (tb[IFLA_BRPORT_HOLD_TIMER]) {
139 struct timeval tv;
140 __u64 htimer;
141
142 htimer = rta_getattr_u64(tb[IFLA_BRPORT_HOLD_TIMER]);
143 __jiffies_to_tv(&tv, htimer);
144 fprintf(f, "hold_timer %4i.%.2i ", (int)tv.tv_sec,
145 (int)tv.tv_usec/10000);
146 }
147
148 if (tb[IFLA_BRPORT_MESSAGE_AGE_TIMER]) {
149 struct timeval tv;
150 __u64 agetimer;
151
152 agetimer = rta_getattr_u64(tb[IFLA_BRPORT_MESSAGE_AGE_TIMER]);
153 __jiffies_to_tv(&tv, agetimer);
154 fprintf(f, "message_age_timer %4i.%.2i ", (int)tv.tv_sec,
155 (int)tv.tv_usec/10000);
156 }
157
158 if (tb[IFLA_BRPORT_FORWARD_DELAY_TIMER]) {
159 struct timeval tv;
160 __u64 fwdtimer;
161
162 fwdtimer = rta_getattr_u64(tb[IFLA_BRPORT_FORWARD_DELAY_TIMER]);
163 __jiffies_to_tv(&tv, fwdtimer);
164 fprintf(f, "forward_delay_timer %4i.%.2i ", (int)tv.tv_sec,
165 (int)tv.tv_usec/10000);
166 }
167
168 if (tb[IFLA_BRPORT_TOPOLOGY_CHANGE_ACK])
169 fprintf(f, "topology_change_ack %u ",
170 rta_getattr_u8(tb[IFLA_BRPORT_TOPOLOGY_CHANGE_ACK]));
171
172 if (tb[IFLA_BRPORT_CONFIG_PENDING])
173 fprintf(f, "config_pending %u ",
174 rta_getattr_u8(tb[IFLA_BRPORT_CONFIG_PENDING]));
f6e615de
NA
175 if (tb[IFLA_BRPORT_PROXYARP])
176 print_onoff(f, "proxy_arp",
177 rta_getattr_u8(tb[IFLA_BRPORT_PROXYARP]));
38b31a78
NA
178
179 if (tb[IFLA_BRPORT_PROXYARP_WIFI])
180 print_onoff(f, "proxy_arp_wifi",
181 rta_getattr_u8(tb[IFLA_BRPORT_PROXYARP_WIFI]));
10759a90
NA
182
183 if (tb[IFLA_BRPORT_MULTICAST_ROUTER])
184 fprintf(f, "mcast_router %u ",
185 rta_getattr_u8(tb[IFLA_BRPORT_MULTICAST_ROUTER]));
478a8e59
NA
186
187 if (tb[IFLA_BRPORT_FAST_LEAVE])
188 print_onoff(f, "mcast_fast_leave",
189 rta_getattr_u8(tb[IFLA_BRPORT_FAST_LEAVE]));
8c39db39
JP
190}
191
192static void bridge_slave_parse_on_off(char *arg_name, char *arg_val,
193 struct nlmsghdr *n, int type)
194{
195 __u8 val;
196
197 if (strcmp(arg_val, "on") == 0)
198 val = 1;
199 else if (strcmp(arg_val, "off") == 0)
200 val = 0;
201 else
202 invarg("should be \"on\" or \"off\"", arg_name);
203
204 addattr8(n, 1024, type, val);
205}
206
207static int bridge_slave_parse_opt(struct link_util *lu, int argc, char **argv,
208 struct nlmsghdr *n)
209{
210 __u8 state;
211 __u16 priority;
212 __u32 cost;
213
214 while (argc > 0) {
215 if (matches(*argv, "state") == 0) {
216 NEXT_ARG();
217 if (get_u8(&state, *argv, 0))
218 invarg("state is invalid", *argv);
219 addattr8(n, 1024, IFLA_BRPORT_STATE, state);
220 } else if (matches(*argv, "priority") == 0) {
221 NEXT_ARG();
222 if (get_u16(&priority, *argv, 0))
223 invarg("priority is invalid", *argv);
224 addattr16(n, 1024, IFLA_BRPORT_PRIORITY, priority);
225 } else if (matches(*argv, "cost") == 0) {
226 NEXT_ARG();
227 if (get_u32(&cost, *argv, 0))
228 invarg("cost is invalid", *argv);
229 addattr32(n, 1024, IFLA_BRPORT_COST, cost);
230 } else if (matches(*argv, "hairpin") == 0) {
231 NEXT_ARG();
232 bridge_slave_parse_on_off("hairpin", *argv, n,
233 IFLA_BRPORT_MODE);
234 } else if (matches(*argv, "guard") == 0) {
235 NEXT_ARG();
236 bridge_slave_parse_on_off("guard", *argv, n,
237 IFLA_BRPORT_GUARD);
238 } else if (matches(*argv, "root_block") == 0) {
239 NEXT_ARG();
240 bridge_slave_parse_on_off("root_block", *argv, n,
241 IFLA_BRPORT_PROTECT);
242 } else if (matches(*argv, "fastleave") == 0) {
243 NEXT_ARG();
244 bridge_slave_parse_on_off("fastleave", *argv, n,
245 IFLA_BRPORT_FAST_LEAVE);
246 } else if (matches(*argv, "learning") == 0) {
247 NEXT_ARG();
248 bridge_slave_parse_on_off("learning", *argv, n,
249 IFLA_BRPORT_LEARNING);
250 } else if (matches(*argv, "flood") == 0) {
251 NEXT_ARG();
252 bridge_slave_parse_on_off("flood", *argv, n,
253 IFLA_BRPORT_UNICAST_FLOOD);
f6e615de
NA
254 } else if (matches(*argv, "proxy_arp") == 0) {
255 NEXT_ARG();
256 bridge_slave_parse_on_off("proxy_arp", *argv, n,
257 IFLA_BRPORT_PROXYARP);
38b31a78
NA
258 } else if (matches(*argv, "proxy_arp_wifi") == 0) {
259 NEXT_ARG();
260 bridge_slave_parse_on_off("proxy_arp_wifi", *argv, n,
261 IFLA_BRPORT_PROXYARP_WIFI);
10759a90
NA
262 } else if (matches(*argv, "mcast_router") == 0) {
263 __u8 mcast_router;
264
265 NEXT_ARG();
266 if (get_u8(&mcast_router, *argv, 0))
267 invarg("invalid mcast_router", *argv);
268 addattr8(n, 1024, IFLA_BRPORT_MULTICAST_ROUTER,
269 mcast_router);
478a8e59
NA
270 } else if (matches(*argv, "mcast_fast_leave") == 0) {
271 NEXT_ARG();
272 bridge_slave_parse_on_off("mcast_fast_leave", *argv, n,
273 IFLA_BRPORT_FAST_LEAVE);
8c39db39
JP
274 } else if (matches(*argv, "help") == 0) {
275 explain();
276 return -1;
277 } else {
278 fprintf(stderr, "bridge_slave: unknown option \"%s\"?\n",
279 *argv);
280 explain();
281 return -1;
282 }
283 argc--, argv++;
284 }
285
286 return 0;
287}
288
a560d850
ZS
289static void bridge_slave_print_help(struct link_util *lu, int argc, char **argv,
290 FILE *f)
291{
292 print_explain(f);
293}
294
8c39db39
JP
295struct link_util bridge_slave_link_util = {
296 .id = "bridge",
297 .maxattr = IFLA_BRPORT_MAX,
298 .print_opt = bridge_slave_print_opt,
299 .parse_opt = bridge_slave_parse_opt,
a560d850 300 .print_help = bridge_slave_print_help,
8c39db39
JP
301 .slave = true,
302};