• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include "rt_names.h"
18 #include "utils.h"
19 #include "ip_common.h"
20 
print_explain(FILE * f)21 static void print_explain(FILE *f)
22 {
23 	fprintf(f,
24 		"Usage: ... bridge [ forward_delay FORWARD_DELAY ]\n"
25 		"                  [ hello_time HELLO_TIME ]\n"
26 		"                  [ max_age MAX_AGE ]\n"
27 		"                  [ ageing_time AGEING_TIME ]\n"
28 		"                  [ stp_state STP_STATE ]\n"
29 		"                  [ priority PRIORITY ]\n"
30 		"                  [ vlan_filtering VLAN_FILTERING ]\n"
31 		"                  [ vlan_protocol VLAN_PROTOCOL ]\n"
32 		"\n"
33 		"Where: VLAN_PROTOCOL := { 802.1Q | 802.1ad }\n"
34 	);
35 }
36 
explain(void)37 static void explain(void)
38 {
39 	print_explain(stderr);
40 }
41 
bridge_parse_opt(struct link_util * lu,int argc,char ** argv,struct nlmsghdr * n)42 static 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();
50 			if (get_u32(&val, *argv, 0))
51 				invarg("invalid forward_delay", *argv);
52 
53 			addattr32(n, 1024, IFLA_BR_FORWARD_DELAY, val);
54 		} else if (matches(*argv, "hello_time") == 0) {
55 			NEXT_ARG();
56 			if (get_u32(&val, *argv, 0))
57 				invarg("invalid hello_time", *argv);
58 
59 			addattr32(n, 1024, IFLA_BR_HELLO_TIME, val);
60 		} else if (matches(*argv, "max_age") == 0) {
61 			NEXT_ARG();
62 			if (get_u32(&val, *argv, 0))
63 				invarg("invalid max_age", *argv);
64 
65 			addattr32(n, 1024, IFLA_BR_MAX_AGE, val);
66 		} else if (matches(*argv, "ageing_time") == 0) {
67 			NEXT_ARG();
68 			if (get_u32(&val, *argv, 0))
69 				invarg("invalid ageing_time", *argv);
70 
71 			addattr32(n, 1024, IFLA_BR_AGEING_TIME, val);
72 		} else if (matches(*argv, "stp_state") == 0) {
73 			NEXT_ARG();
74 			if (get_u32(&val, *argv, 0))
75 				invarg("invalid stp_state", *argv);
76 
77 			addattr32(n, 1024, IFLA_BR_STP_STATE, val);
78 		} else if (matches(*argv, "priority") == 0) {
79 			__u16 prio;
80 
81 			NEXT_ARG();
82 			if (get_u16(&prio, *argv, 0))
83 				invarg("invalid priority", *argv);
84 
85 			addattr16(n, 1024, IFLA_BR_PRIORITY, prio);
86 		} 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);
95 		} 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);
104 		} 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 
bridge_print_opt(struct link_util * lu,FILE * f,struct rtattr * tb[])118 static 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]));
134 
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]));
146 
147 	if (tb[IFLA_BR_VLAN_FILTERING])
148 		fprintf(f, "vlan_filtering %u ",
149 			rta_getattr_u8(tb[IFLA_BR_VLAN_FILTERING]));
150 
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 	}
158 }
159 
bridge_print_help(struct link_util * lu,int argc,char ** argv,FILE * f)160 static void bridge_print_help(struct link_util *lu, int argc, char **argv,
161 		FILE *f)
162 {
163 	print_explain(f);
164 }
165 
166 struct 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,
171 	.print_help     = bridge_print_help,
172 };
173