blob: 00804093dcb5358656cfe7ecd38c08343f2792d4 [file] [log] [blame]
Jiri Pirko28d84b42014-09-28 16:33:29 -07001/*
2 * iplink_bridge.c Bridge 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 <stdlib.h>
14#include <string.h>
15#include <linux/if_link.h>
16
Toshiaki Makita1eea5c42015-08-31 18:48:46 +090017#include "rt_names.h"
Jiri Pirko28d84b42014-09-28 16:33:29 -070018#include "utils.h"
19#include "ip_common.h"
20
Zhang Shengju43367ef2015-08-12 06:03:23 +000021static void print_explain(FILE *f)
Jiri Pirko28d84b42014-09-28 16:33:29 -070022{
Zhang Shengju43367ef2015-08-12 06:03:23 +000023 fprintf(f,
Jiri Pirko28d84b42014-09-28 16:33:29 -070024 "Usage: ... bridge [ forward_delay FORWARD_DELAY ]\n"
25 " [ hello_time HELLO_TIME ]\n"
26 " [ max_age MAX_AGE ]\n"
Nikolay Aleksandrov6c99fb62015-06-16 13:38:47 +030027 " [ ageing_time AGEING_TIME ]\n"
Nikolay Aleksandrovdab04962015-06-16 13:38:48 +030028 " [ stp_state STP_STATE ]\n"
Nikolay Aleksandrovb0197a02015-06-16 13:38:49 +030029 " [ priority PRIORITY ]\n"
Nikolay Aleksandrove4d456f2015-08-12 09:19:06 -070030 " [ vlan_filtering VLAN_FILTERING ]\n"
Toshiaki Makita1eea5c42015-08-31 18:48:46 +090031 " [ vlan_protocol VLAN_PROTOCOL ]\n"
32 "\n"
33 "Where: VLAN_PROTOCOL := { 802.1Q | 802.1ad }\n"
Jiri Pirko28d84b42014-09-28 16:33:29 -070034 );
35}
36
Zhang Shengju43367ef2015-08-12 06:03:23 +000037static void explain(void)
38{
39 print_explain(stderr);
40}
41
Jiri Pirko28d84b42014-09-28 16:33:29 -070042static int bridge_parse_opt(struct link_util *lu, int argc, char **argv,
43 struct nlmsghdr *n)
44{
45 __u32 val;
46
47 while (argc > 0) {
48 if (matches(*argv, "forward_delay") == 0) {
49 NEXT_ARG();
Zhang Shengju6a9ce302015-08-13 07:48:15 +000050 if (get_u32(&val, *argv, 0))
Jiri Pirko28d84b42014-09-28 16:33:29 -070051 invarg("invalid forward_delay", *argv);
Zhang Shengju6a9ce302015-08-13 07:48:15 +000052
Jiri Pirko28d84b42014-09-28 16:33:29 -070053 addattr32(n, 1024, IFLA_BR_FORWARD_DELAY, val);
54 } else if (matches(*argv, "hello_time") == 0) {
55 NEXT_ARG();
Zhang Shengju6a9ce302015-08-13 07:48:15 +000056 if (get_u32(&val, *argv, 0))
Jiri Pirko28d84b42014-09-28 16:33:29 -070057 invarg("invalid hello_time", *argv);
Zhang Shengju6a9ce302015-08-13 07:48:15 +000058
Jiri Pirko28d84b42014-09-28 16:33:29 -070059 addattr32(n, 1024, IFLA_BR_HELLO_TIME, val);
60 } else if (matches(*argv, "max_age") == 0) {
61 NEXT_ARG();
Zhang Shengju6a9ce302015-08-13 07:48:15 +000062 if (get_u32(&val, *argv, 0))
Jiri Pirko28d84b42014-09-28 16:33:29 -070063 invarg("invalid max_age", *argv);
Zhang Shengju6a9ce302015-08-13 07:48:15 +000064
Jiri Pirko28d84b42014-09-28 16:33:29 -070065 addattr32(n, 1024, IFLA_BR_MAX_AGE, val);
Nikolay Aleksandrov6c99fb62015-06-16 13:38:47 +030066 } else if (matches(*argv, "ageing_time") == 0) {
67 NEXT_ARG();
Zhang Shengju6a9ce302015-08-13 07:48:15 +000068 if (get_u32(&val, *argv, 0))
Nikolay Aleksandrov6c99fb62015-06-16 13:38:47 +030069 invarg("invalid ageing_time", *argv);
Zhang Shengju6a9ce302015-08-13 07:48:15 +000070
Nikolay Aleksandrov6c99fb62015-06-16 13:38:47 +030071 addattr32(n, 1024, IFLA_BR_AGEING_TIME, val);
Nikolay Aleksandrovdab04962015-06-16 13:38:48 +030072 } else if (matches(*argv, "stp_state") == 0) {
73 NEXT_ARG();
Zhang Shengju6a9ce302015-08-13 07:48:15 +000074 if (get_u32(&val, *argv, 0))
Nikolay Aleksandrovdab04962015-06-16 13:38:48 +030075 invarg("invalid stp_state", *argv);
Zhang Shengju6a9ce302015-08-13 07:48:15 +000076
Nikolay Aleksandrovdab04962015-06-16 13:38:48 +030077 addattr32(n, 1024, IFLA_BR_STP_STATE, val);
Nikolay Aleksandrovb0197a02015-06-16 13:38:49 +030078 } else if (matches(*argv, "priority") == 0) {
79 __u16 prio;
80
81 NEXT_ARG();
Zhang Shengju6a9ce302015-08-13 07:48:15 +000082 if (get_u16(&prio, *argv, 0))
Nikolay Aleksandrovb0197a02015-06-16 13:38:49 +030083 invarg("invalid priority", *argv);
Zhang Shengju6a9ce302015-08-13 07:48:15 +000084
Nikolay Aleksandrovb0197a02015-06-16 13:38:49 +030085 addattr16(n, 1024, IFLA_BR_PRIORITY, prio);
Nikolay Aleksandrove4d456f2015-08-12 09:19:06 -070086 } else if (matches(*argv, "vlan_filtering") == 0) {
87 __u8 vlan_filter;
88
89 NEXT_ARG();
90 if (get_u8(&vlan_filter, *argv, 0)) {
91 invarg("invalid vlan_filtering", *argv);
92 return -1;
93 }
94 addattr8(n, 1024, IFLA_BR_VLAN_FILTERING, vlan_filter);
Toshiaki Makita1eea5c42015-08-31 18:48:46 +090095 } else if (matches(*argv, "vlan_protocol") == 0) {
96 __u16 vlan_proto;
97
98 NEXT_ARG();
99 if (ll_proto_a2n(&vlan_proto, *argv)) {
100 invarg("invalid vlan_protocol", *argv);
101 return -1;
102 }
103 addattr16(n, 1024, IFLA_BR_VLAN_PROTOCOL, vlan_proto);
Jiri Pirko28d84b42014-09-28 16:33:29 -0700104 } else if (matches(*argv, "help") == 0) {
105 explain();
106 return -1;
107 } else {
108 fprintf(stderr, "bridge: unknown command \"%s\"?\n", *argv);
109 explain();
110 return -1;
111 }
112 argc--, argv++;
113 }
114
115 return 0;
116}
117
118static void bridge_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
119{
120 if (!tb)
121 return;
122
123 if (tb[IFLA_BR_FORWARD_DELAY])
124 fprintf(f, "forward_delay %u ",
125 rta_getattr_u32(tb[IFLA_BR_FORWARD_DELAY]));
126
127 if (tb[IFLA_BR_HELLO_TIME])
128 fprintf(f, "hello_time %u ",
129 rta_getattr_u32(tb[IFLA_BR_HELLO_TIME]));
130
131 if (tb[IFLA_BR_MAX_AGE])
132 fprintf(f, "max_age %u ",
133 rta_getattr_u32(tb[IFLA_BR_MAX_AGE]));
Nikolay Aleksandrovfdba0512015-08-12 09:11:30 -0700134
135 if (tb[IFLA_BR_AGEING_TIME])
136 fprintf(f, "ageing_time %u ",
137 rta_getattr_u32(tb[IFLA_BR_AGEING_TIME]));
138
139 if (tb[IFLA_BR_STP_STATE])
140 fprintf(f, "stp_state %u ",
141 rta_getattr_u32(tb[IFLA_BR_STP_STATE]));
142
143 if (tb[IFLA_BR_PRIORITY])
144 fprintf(f, "priority %u ",
145 rta_getattr_u16(tb[IFLA_BR_PRIORITY]));
Nikolay Aleksandrove4d456f2015-08-12 09:19:06 -0700146
147 if (tb[IFLA_BR_VLAN_FILTERING])
148 fprintf(f, "vlan_filtering %u ",
149 rta_getattr_u8(tb[IFLA_BR_VLAN_FILTERING]));
Toshiaki Makita1eea5c42015-08-31 18:48:46 +0900150
151 if (tb[IFLA_BR_VLAN_PROTOCOL]) {
152 SPRINT_BUF(b1);
153
154 fprintf(f, "vlan_protocol %s ",
155 ll_proto_n2a(rta_getattr_u16(tb[IFLA_BR_VLAN_PROTOCOL]),
156 b1, sizeof(b1)));
157 }
Jiri Pirko28d84b42014-09-28 16:33:29 -0700158}
159
Zhang Shengju43367ef2015-08-12 06:03:23 +0000160static void bridge_print_help(struct link_util *lu, int argc, char **argv,
161 FILE *f)
162{
163 print_explain(f);
164}
165
Jiri Pirko28d84b42014-09-28 16:33:29 -0700166struct link_util bridge_link_util = {
167 .id = "bridge",
168 .maxattr = IFLA_BR_MAX,
169 .parse_opt = bridge_parse_opt,
170 .print_opt = bridge_print_opt,
Zhang Shengju43367ef2015-08-12 06:03:23 +0000171 .print_help = bridge_print_help,
Jiri Pirko28d84b42014-09-28 16:33:29 -0700172};