xref: /aosp_15_r20/external/toybox/toys/pending/brctl.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
1*cf5a6c84SAndroid Build Coastguard Worker /* brctl.c - ethernet bridge control
2*cf5a6c84SAndroid Build Coastguard Worker  *
3*cf5a6c84SAndroid Build Coastguard Worker  * Copyright 2013 Ashwini Kumar <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker  * Copyright 2013 Kyungwan Han <[email protected]>
5*cf5a6c84SAndroid Build Coastguard Worker  *
6*cf5a6c84SAndroid Build Coastguard Worker  * No Standard
7*cf5a6c84SAndroid Build Coastguard Worker 
8*cf5a6c84SAndroid Build Coastguard Worker USE_BRCTL(NEWTOY(brctl, "<1", TOYFLAG_USR|TOYFLAG_SBIN))
9*cf5a6c84SAndroid Build Coastguard Worker 
10*cf5a6c84SAndroid Build Coastguard Worker config BRCTL
11*cf5a6c84SAndroid Build Coastguard Worker   bool "brctl"
12*cf5a6c84SAndroid Build Coastguard Worker   default n
13*cf5a6c84SAndroid Build Coastguard Worker   help
14*cf5a6c84SAndroid Build Coastguard Worker     usage: brctl COMMAND [BRIDGE [INTERFACE]]
15*cf5a6c84SAndroid Build Coastguard Worker 
16*cf5a6c84SAndroid Build Coastguard Worker     Manage ethernet bridges
17*cf5a6c84SAndroid Build Coastguard Worker 
18*cf5a6c84SAndroid Build Coastguard Worker     Commands:
19*cf5a6c84SAndroid Build Coastguard Worker     show                  Show a list of bridges
20*cf5a6c84SAndroid Build Coastguard Worker     addbr BRIDGE          Create BRIDGE
21*cf5a6c84SAndroid Build Coastguard Worker     delbr BRIDGE          Delete BRIDGE
22*cf5a6c84SAndroid Build Coastguard Worker     addif BRIDGE IFACE    Add IFACE to BRIDGE
23*cf5a6c84SAndroid Build Coastguard Worker     delif BRIDGE IFACE    Delete IFACE from BRIDGE
24*cf5a6c84SAndroid Build Coastguard Worker     setageing BRIDGE TIME Set ageing time
25*cf5a6c84SAndroid Build Coastguard Worker     setfd BRIDGE TIME     Set bridge forward delay
26*cf5a6c84SAndroid Build Coastguard Worker     sethello BRIDGE TIME  Set hello time
27*cf5a6c84SAndroid Build Coastguard Worker     setmaxage BRIDGE TIME Set max message age
28*cf5a6c84SAndroid Build Coastguard Worker     setpathcost BRIDGE PORT COST   Set path cost
29*cf5a6c84SAndroid Build Coastguard Worker     setportprio BRIDGE PORT PRIO   Set port priority
30*cf5a6c84SAndroid Build Coastguard Worker     setbridgeprio BRIDGE PRIO      Set bridge priority
31*cf5a6c84SAndroid Build Coastguard Worker     stp BRIDGE [1/yes/on|0/no/off] STP on/off
32*cf5a6c84SAndroid Build Coastguard Worker */
33*cf5a6c84SAndroid Build Coastguard Worker 
34*cf5a6c84SAndroid Build Coastguard Worker #define FOR_brctl
35*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
36*cf5a6c84SAndroid Build Coastguard Worker #include <linux/if_bridge.h>
37*cf5a6c84SAndroid Build Coastguard Worker 
GLOBALS(int sockfd;)38*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
39*cf5a6c84SAndroid Build Coastguard Worker     int sockfd;
40*cf5a6c84SAndroid Build Coastguard Worker )
41*cf5a6c84SAndroid Build Coastguard Worker #define MAX_BRIDGES 1024 //same is no of ports supported
42*cf5a6c84SAndroid Build Coastguard Worker 
43*cf5a6c84SAndroid Build Coastguard Worker static void get_ports(char *bridge, int *indices)
44*cf5a6c84SAndroid Build Coastguard Worker {
45*cf5a6c84SAndroid Build Coastguard Worker   struct ifreq ifr;
46*cf5a6c84SAndroid Build Coastguard Worker   int ifindices[MAX_BRIDGES];
47*cf5a6c84SAndroid Build Coastguard Worker   unsigned long args[4] = { BRCTL_GET_PORT_LIST,
48*cf5a6c84SAndroid Build Coastguard Worker     (unsigned long) ifindices, MAX_BRIDGES, 0 };
49*cf5a6c84SAndroid Build Coastguard Worker 
50*cf5a6c84SAndroid Build Coastguard Worker   memset(ifindices, 0, MAX_BRIDGES);
51*cf5a6c84SAndroid Build Coastguard Worker   args[1] = (unsigned long)ifindices;
52*cf5a6c84SAndroid Build Coastguard Worker   xstrncpy(ifr.ifr_name, bridge, IFNAMSIZ);
53*cf5a6c84SAndroid Build Coastguard Worker   ifr.ifr_data = (char *)args;
54*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCDEVPRIVATE, &ifr);
55*cf5a6c84SAndroid Build Coastguard Worker   if (indices) memcpy(indices, ifindices, sizeof(ifindices));
56*cf5a6c84SAndroid Build Coastguard Worker }
57*cf5a6c84SAndroid Build Coastguard Worker 
get_br_info(char * bridge,struct __bridge_info * info)58*cf5a6c84SAndroid Build Coastguard Worker void get_br_info(char *bridge, struct __bridge_info *info)
59*cf5a6c84SAndroid Build Coastguard Worker {
60*cf5a6c84SAndroid Build Coastguard Worker   struct ifreq ifr;
61*cf5a6c84SAndroid Build Coastguard Worker   unsigned long args[4] = { BRCTL_GET_BRIDGE_INFO,
62*cf5a6c84SAndroid Build Coastguard Worker     (unsigned long) info, 0, 0 };
63*cf5a6c84SAndroid Build Coastguard Worker 
64*cf5a6c84SAndroid Build Coastguard Worker   memset(info, 0, sizeof(*info));
65*cf5a6c84SAndroid Build Coastguard Worker   xstrncpy(ifr.ifr_name, bridge, IFNAMSIZ);
66*cf5a6c84SAndroid Build Coastguard Worker   ifr.ifr_data = (char *)args;
67*cf5a6c84SAndroid Build Coastguard Worker 
68*cf5a6c84SAndroid Build Coastguard Worker   if (ioctl(TT.sockfd, SIOCDEVPRIVATE, &ifr) < 0) {
69*cf5a6c84SAndroid Build Coastguard Worker     perror_msg("%s: can't get info %s\n", bridge, strerror(errno));
70*cf5a6c84SAndroid Build Coastguard Worker     return;
71*cf5a6c84SAndroid Build Coastguard Worker   }
72*cf5a6c84SAndroid Build Coastguard Worker }
73*cf5a6c84SAndroid Build Coastguard Worker 
br_show(char ** argv)74*cf5a6c84SAndroid Build Coastguard Worker void br_show(char **argv)
75*cf5a6c84SAndroid Build Coastguard Worker {
76*cf5a6c84SAndroid Build Coastguard Worker   struct __bridge_info info;
77*cf5a6c84SAndroid Build Coastguard Worker   int num, cnt, i, j, ifindices[MAX_BRIDGES], pindices[MAX_BRIDGES];
78*cf5a6c84SAndroid Build Coastguard Worker   unsigned long args[4] = { BRCTL_GET_BRIDGES,
79*cf5a6c84SAndroid Build Coastguard Worker     (unsigned long)ifindices, MAX_BRIDGES,0 };
80*cf5a6c84SAndroid Build Coastguard Worker   char br[IF_NAMESIZE], ifn[IF_NAMESIZE];
81*cf5a6c84SAndroid Build Coastguard Worker 
82*cf5a6c84SAndroid Build Coastguard Worker   num = ioctl(TT.sockfd, SIOCGIFBR, args); //ret is num of bridges found
83*cf5a6c84SAndroid Build Coastguard Worker   if (num < 0) error_exit("get bridges fail");
84*cf5a6c84SAndroid Build Coastguard Worker   printf("bridge name\tbridge id\t\tSTP enabled\tinterfaces\n");
85*cf5a6c84SAndroid Build Coastguard Worker 
86*cf5a6c84SAndroid Build Coastguard Worker   for (i = 0; i < num; i++) {
87*cf5a6c84SAndroid Build Coastguard Worker     unsigned char *id;
88*cf5a6c84SAndroid Build Coastguard Worker 
89*cf5a6c84SAndroid Build Coastguard Worker     if (!if_indextoname(ifindices[i], br)) perror_exit("interface not found");
90*cf5a6c84SAndroid Build Coastguard Worker     get_br_info(br, &info);
91*cf5a6c84SAndroid Build Coastguard Worker     id = (unsigned char*)&(info.bridge_id);
92*cf5a6c84SAndroid Build Coastguard Worker     printf("%s\t\t",br);
93*cf5a6c84SAndroid Build Coastguard Worker     printf("%.2x%.2x.%.2x%.2x%.2x%.2x%.2x%.2x", id[0], id[1],
94*cf5a6c84SAndroid Build Coastguard Worker         id[2], id[3], id[4], id[5], id[6], id[7]);
95*cf5a6c84SAndroid Build Coastguard Worker     printf("\t%s\t\t",(info.stp_enabled)?"yes" : "no");
96*cf5a6c84SAndroid Build Coastguard Worker 
97*cf5a6c84SAndroid Build Coastguard Worker     memset(pindices, 0, sizeof(pindices));
98*cf5a6c84SAndroid Build Coastguard Worker     get_ports(br, pindices);
99*cf5a6c84SAndroid Build Coastguard Worker     for (j = 0, cnt = 0; j < MAX_BRIDGES; j++) {
100*cf5a6c84SAndroid Build Coastguard Worker       if (!pindices[j]) continue;
101*cf5a6c84SAndroid Build Coastguard Worker       if (!if_indextoname(pindices[j], ifn)) {
102*cf5a6c84SAndroid Build Coastguard Worker         error_msg("no name for index :%d", pindices[j]);
103*cf5a6c84SAndroid Build Coastguard Worker         continue;
104*cf5a6c84SAndroid Build Coastguard Worker       }
105*cf5a6c84SAndroid Build Coastguard Worker       if (cnt) printf("\n\t\t\t\t\t\t\t");
106*cf5a6c84SAndroid Build Coastguard Worker       printf("%s", ifn);
107*cf5a6c84SAndroid Build Coastguard Worker       cnt++;
108*cf5a6c84SAndroid Build Coastguard Worker     }
109*cf5a6c84SAndroid Build Coastguard Worker     xputc('\n');
110*cf5a6c84SAndroid Build Coastguard Worker   }
111*cf5a6c84SAndroid Build Coastguard Worker }
112*cf5a6c84SAndroid Build Coastguard Worker 
br_addbr(char ** argv)113*cf5a6c84SAndroid Build Coastguard Worker void br_addbr(char **argv)
114*cf5a6c84SAndroid Build Coastguard Worker {
115*cf5a6c84SAndroid Build Coastguard Worker   char br[IFNAMSIZ];
116*cf5a6c84SAndroid Build Coastguard Worker   unsigned long args[4] = {BRCTL_ADD_BRIDGE, (unsigned long) br, 0, 0};
117*cf5a6c84SAndroid Build Coastguard Worker 
118*cf5a6c84SAndroid Build Coastguard Worker #ifdef SIOCBRADDBR
119*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCBRADDBR, argv[0]);
120*cf5a6c84SAndroid Build Coastguard Worker #else
121*cf5a6c84SAndroid Build Coastguard Worker   xstrncpy(br, argv[0], IFNAMSIZ);
122*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCSIFBR, args);
123*cf5a6c84SAndroid Build Coastguard Worker #endif
124*cf5a6c84SAndroid Build Coastguard Worker }
125*cf5a6c84SAndroid Build Coastguard Worker 
br_delbr(char ** argv)126*cf5a6c84SAndroid Build Coastguard Worker void br_delbr(char **argv)
127*cf5a6c84SAndroid Build Coastguard Worker {
128*cf5a6c84SAndroid Build Coastguard Worker   char br[IFNAMSIZ];
129*cf5a6c84SAndroid Build Coastguard Worker   unsigned long args[4] = {BRCTL_DEL_BRIDGE, (unsigned long) br, 0, 0};
130*cf5a6c84SAndroid Build Coastguard Worker 
131*cf5a6c84SAndroid Build Coastguard Worker #ifdef SIOCBRDELBR
132*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCBRDELBR, argv[0]);
133*cf5a6c84SAndroid Build Coastguard Worker #else
134*cf5a6c84SAndroid Build Coastguard Worker   xstrncpy(br, argv[0], IFNAMSIZ);
135*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCSIFBR, args);
136*cf5a6c84SAndroid Build Coastguard Worker #endif
137*cf5a6c84SAndroid Build Coastguard Worker }
138*cf5a6c84SAndroid Build Coastguard Worker 
br_addif(char ** argv)139*cf5a6c84SAndroid Build Coastguard Worker void br_addif(char **argv)
140*cf5a6c84SAndroid Build Coastguard Worker {
141*cf5a6c84SAndroid Build Coastguard Worker   int index;
142*cf5a6c84SAndroid Build Coastguard Worker   struct ifreq ifr;
143*cf5a6c84SAndroid Build Coastguard Worker   unsigned long args[4] = {BRCTL_ADD_IF, 0, 0, 0};
144*cf5a6c84SAndroid Build Coastguard Worker 
145*cf5a6c84SAndroid Build Coastguard Worker   if (!(index = if_nametoindex(argv[1]))) perror_exit("interface %s", argv[1]);
146*cf5a6c84SAndroid Build Coastguard Worker   xstrncpy(ifr.ifr_name, argv[0], IFNAMSIZ);
147*cf5a6c84SAndroid Build Coastguard Worker #ifdef SIOCBRADDIF
148*cf5a6c84SAndroid Build Coastguard Worker   ifr.ifr_ifindex = index;
149*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCBRADDIF, &ifr);
150*cf5a6c84SAndroid Build Coastguard Worker #else
151*cf5a6c84SAndroid Build Coastguard Worker   args[1] = index;
152*cf5a6c84SAndroid Build Coastguard Worker   ifr.ifr_data = (char *)args;
153*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCDEVPRIVATE, &ifr);
154*cf5a6c84SAndroid Build Coastguard Worker #endif
155*cf5a6c84SAndroid Build Coastguard Worker }
156*cf5a6c84SAndroid Build Coastguard Worker 
br_delif(char ** argv)157*cf5a6c84SAndroid Build Coastguard Worker void br_delif(char **argv)
158*cf5a6c84SAndroid Build Coastguard Worker {
159*cf5a6c84SAndroid Build Coastguard Worker   int index;
160*cf5a6c84SAndroid Build Coastguard Worker   struct ifreq ifr;
161*cf5a6c84SAndroid Build Coastguard Worker   unsigned long args[4] = {BRCTL_DEL_IF, 0, 0, 0};
162*cf5a6c84SAndroid Build Coastguard Worker 
163*cf5a6c84SAndroid Build Coastguard Worker   if (!(index = if_nametoindex(argv[1]))) perror_exit("interface %s",argv[1]);
164*cf5a6c84SAndroid Build Coastguard Worker   xstrncpy(ifr.ifr_name, argv[0], IFNAMSIZ);
165*cf5a6c84SAndroid Build Coastguard Worker #ifdef SIOCBRDELIF
166*cf5a6c84SAndroid Build Coastguard Worker   ifr.ifr_ifindex = index;
167*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCBRDELIF, &ifr);
168*cf5a6c84SAndroid Build Coastguard Worker #else
169*cf5a6c84SAndroid Build Coastguard Worker   args[1] = index;
170*cf5a6c84SAndroid Build Coastguard Worker   ifr.ifr_data = (char *)args;
171*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCDEVPRIVATE, &ifr);
172*cf5a6c84SAndroid Build Coastguard Worker #endif
173*cf5a6c84SAndroid Build Coastguard Worker }
174*cf5a6c84SAndroid Build Coastguard Worker 
strtotimeval(struct timeval * tv,char * time)175*cf5a6c84SAndroid Build Coastguard Worker static void strtotimeval(struct timeval *tv, char *time)
176*cf5a6c84SAndroid Build Coastguard Worker {
177*cf5a6c84SAndroid Build Coastguard Worker   double secs;
178*cf5a6c84SAndroid Build Coastguard Worker 
179*cf5a6c84SAndroid Build Coastguard Worker   if (sscanf(time, "%lf", &secs) != 1) error_exit("time format not proper");
180*cf5a6c84SAndroid Build Coastguard Worker   tv->tv_sec = secs;
181*cf5a6c84SAndroid Build Coastguard Worker   tv->tv_usec = 1000000 * (secs - tv->tv_sec);
182*cf5a6c84SAndroid Build Coastguard Worker }
183*cf5a6c84SAndroid Build Coastguard Worker 
tv_to_jify(struct timeval * tv)184*cf5a6c84SAndroid Build Coastguard Worker static unsigned long tv_to_jify(struct timeval *tv)
185*cf5a6c84SAndroid Build Coastguard Worker {
186*cf5a6c84SAndroid Build Coastguard Worker   unsigned long long jify;
187*cf5a6c84SAndroid Build Coastguard Worker 
188*cf5a6c84SAndroid Build Coastguard Worker   jify = 1000000ULL * tv->tv_sec + tv->tv_usec;
189*cf5a6c84SAndroid Build Coastguard Worker   return (jify/10000);
190*cf5a6c84SAndroid Build Coastguard Worker }
191*cf5a6c84SAndroid Build Coastguard Worker 
set_time(char * br,unsigned long cmd,unsigned long val)192*cf5a6c84SAndroid Build Coastguard Worker void set_time(char *br, unsigned long cmd, unsigned long val)
193*cf5a6c84SAndroid Build Coastguard Worker {
194*cf5a6c84SAndroid Build Coastguard Worker   struct ifreq ifr;
195*cf5a6c84SAndroid Build Coastguard Worker   unsigned long args[4] = {cmd, val, 0, 0};
196*cf5a6c84SAndroid Build Coastguard Worker 
197*cf5a6c84SAndroid Build Coastguard Worker   xstrncpy(ifr.ifr_name, br, IFNAMSIZ);
198*cf5a6c84SAndroid Build Coastguard Worker   ifr.ifr_data = (char *)args;
199*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCDEVPRIVATE, &ifr);
200*cf5a6c84SAndroid Build Coastguard Worker }
201*cf5a6c84SAndroid Build Coastguard Worker 
br_set_ageing_time(char ** argv)202*cf5a6c84SAndroid Build Coastguard Worker void br_set_ageing_time(char **argv)
203*cf5a6c84SAndroid Build Coastguard Worker {
204*cf5a6c84SAndroid Build Coastguard Worker   struct timeval tv;
205*cf5a6c84SAndroid Build Coastguard Worker 
206*cf5a6c84SAndroid Build Coastguard Worker   strtotimeval(&tv, argv[1]);
207*cf5a6c84SAndroid Build Coastguard Worker   set_time(argv[0], BRCTL_SET_AGEING_TIME, tv_to_jify(&tv));
208*cf5a6c84SAndroid Build Coastguard Worker }
209*cf5a6c84SAndroid Build Coastguard Worker 
br_set_fwd_delay(char ** argv)210*cf5a6c84SAndroid Build Coastguard Worker void br_set_fwd_delay(char **argv)
211*cf5a6c84SAndroid Build Coastguard Worker {
212*cf5a6c84SAndroid Build Coastguard Worker   struct timeval tv;
213*cf5a6c84SAndroid Build Coastguard Worker 
214*cf5a6c84SAndroid Build Coastguard Worker   strtotimeval(&tv, argv[1]);
215*cf5a6c84SAndroid Build Coastguard Worker   set_time(argv[0], BRCTL_SET_BRIDGE_FORWARD_DELAY, tv_to_jify(&tv));
216*cf5a6c84SAndroid Build Coastguard Worker }
217*cf5a6c84SAndroid Build Coastguard Worker 
br_set_hello_time(char ** argv)218*cf5a6c84SAndroid Build Coastguard Worker void br_set_hello_time(char **argv)
219*cf5a6c84SAndroid Build Coastguard Worker {
220*cf5a6c84SAndroid Build Coastguard Worker   struct timeval tv;
221*cf5a6c84SAndroid Build Coastguard Worker 
222*cf5a6c84SAndroid Build Coastguard Worker   strtotimeval(&tv, argv[1]);
223*cf5a6c84SAndroid Build Coastguard Worker   set_time(argv[0], BRCTL_SET_BRIDGE_HELLO_TIME, tv_to_jify(&tv));
224*cf5a6c84SAndroid Build Coastguard Worker }
225*cf5a6c84SAndroid Build Coastguard Worker 
br_set_max_age(char ** argv)226*cf5a6c84SAndroid Build Coastguard Worker void br_set_max_age(char **argv)
227*cf5a6c84SAndroid Build Coastguard Worker {
228*cf5a6c84SAndroid Build Coastguard Worker   struct timeval tv;
229*cf5a6c84SAndroid Build Coastguard Worker 
230*cf5a6c84SAndroid Build Coastguard Worker   strtotimeval(&tv, argv[1]);
231*cf5a6c84SAndroid Build Coastguard Worker   set_time(argv[0], BRCTL_SET_BRIDGE_MAX_AGE, tv_to_jify(&tv));
232*cf5a6c84SAndroid Build Coastguard Worker }
233*cf5a6c84SAndroid Build Coastguard Worker 
br_set_bridge_prio(char ** argv)234*cf5a6c84SAndroid Build Coastguard Worker void br_set_bridge_prio(char **argv)
235*cf5a6c84SAndroid Build Coastguard Worker {
236*cf5a6c84SAndroid Build Coastguard Worker   int prio;
237*cf5a6c84SAndroid Build Coastguard Worker 
238*cf5a6c84SAndroid Build Coastguard Worker   if (sscanf(argv[1], "%i", &prio) != 1) error_exit("prio not proper");
239*cf5a6c84SAndroid Build Coastguard Worker   set_time(argv[0], BRCTL_SET_BRIDGE_PRIORITY, prio);
240*cf5a6c84SAndroid Build Coastguard Worker }
241*cf5a6c84SAndroid Build Coastguard Worker 
br_set_stp(char ** argv)242*cf5a6c84SAndroid Build Coastguard Worker void br_set_stp(char **argv)
243*cf5a6c84SAndroid Build Coastguard Worker {
244*cf5a6c84SAndroid Build Coastguard Worker   int i;
245*cf5a6c84SAndroid Build Coastguard Worker   struct stp {
246*cf5a6c84SAndroid Build Coastguard Worker     char *n;
247*cf5a6c84SAndroid Build Coastguard Worker     int set;
248*cf5a6c84SAndroid Build Coastguard Worker   } ss[] = {{"1", 1}, {"yes", 1},{"on", 1},
249*cf5a6c84SAndroid Build Coastguard Worker     {"0", 0}, {"no", 0},{"off", 0}};
250*cf5a6c84SAndroid Build Coastguard Worker 
251*cf5a6c84SAndroid Build Coastguard Worker   for (i = 0; i < ARRAY_LEN(ss); i++) {
252*cf5a6c84SAndroid Build Coastguard Worker     if (!strcmp(ss[i].n, argv[1])) break;
253*cf5a6c84SAndroid Build Coastguard Worker   }
254*cf5a6c84SAndroid Build Coastguard Worker   if (i >= ARRAY_LEN(ss)) error_exit("invalid stp state");
255*cf5a6c84SAndroid Build Coastguard Worker   set_time(argv[0], BRCTL_SET_BRIDGE_STP_STATE, ss[i].set);
256*cf5a6c84SAndroid Build Coastguard Worker }
257*cf5a6c84SAndroid Build Coastguard Worker 
set_cost_prio(char * br,char * port,unsigned long cmd,unsigned long val)258*cf5a6c84SAndroid Build Coastguard Worker void set_cost_prio(char *br, char *port, unsigned long cmd, unsigned long val)
259*cf5a6c84SAndroid Build Coastguard Worker {
260*cf5a6c84SAndroid Build Coastguard Worker   struct ifreq ifr;
261*cf5a6c84SAndroid Build Coastguard Worker   int i, index, pindices[MAX_BRIDGES];
262*cf5a6c84SAndroid Build Coastguard Worker   unsigned long args[4] = {cmd, 0, val, 0};
263*cf5a6c84SAndroid Build Coastguard Worker 
264*cf5a6c84SAndroid Build Coastguard Worker   if (!(index = if_nametoindex(port))) error_exit("invalid port");
265*cf5a6c84SAndroid Build Coastguard Worker 
266*cf5a6c84SAndroid Build Coastguard Worker   memset(pindices, 0, sizeof(pindices));
267*cf5a6c84SAndroid Build Coastguard Worker   get_ports(br, pindices);
268*cf5a6c84SAndroid Build Coastguard Worker   for (i = 0; i < MAX_BRIDGES; i++) {
269*cf5a6c84SAndroid Build Coastguard Worker     if (index == pindices[i]) break;
270*cf5a6c84SAndroid Build Coastguard Worker   }
271*cf5a6c84SAndroid Build Coastguard Worker   if (i >= MAX_BRIDGES) error_exit("%s not in bridge", port);
272*cf5a6c84SAndroid Build Coastguard Worker   args[1] = i;
273*cf5a6c84SAndroid Build Coastguard Worker   xstrncpy(ifr.ifr_name, br, IFNAMSIZ);
274*cf5a6c84SAndroid Build Coastguard Worker   ifr.ifr_data = (char *)args;
275*cf5a6c84SAndroid Build Coastguard Worker   xioctl(TT.sockfd, SIOCDEVPRIVATE, &ifr);
276*cf5a6c84SAndroid Build Coastguard Worker }
277*cf5a6c84SAndroid Build Coastguard Worker 
br_set_path_cost(char ** argv)278*cf5a6c84SAndroid Build Coastguard Worker void br_set_path_cost(char **argv)
279*cf5a6c84SAndroid Build Coastguard Worker {
280*cf5a6c84SAndroid Build Coastguard Worker   int cost;
281*cf5a6c84SAndroid Build Coastguard Worker 
282*cf5a6c84SAndroid Build Coastguard Worker   cost = atolx_range(argv[2], 0, INT_MAX);
283*cf5a6c84SAndroid Build Coastguard Worker   set_cost_prio(argv[0], argv[1], BRCTL_SET_PATH_COST, cost);
284*cf5a6c84SAndroid Build Coastguard Worker }
285*cf5a6c84SAndroid Build Coastguard Worker 
br_set_port_prio(char ** argv)286*cf5a6c84SAndroid Build Coastguard Worker void br_set_port_prio(char **argv)
287*cf5a6c84SAndroid Build Coastguard Worker {
288*cf5a6c84SAndroid Build Coastguard Worker   int prio;
289*cf5a6c84SAndroid Build Coastguard Worker 
290*cf5a6c84SAndroid Build Coastguard Worker   prio = atolx_range(argv[2], 0, INT_MAX);
291*cf5a6c84SAndroid Build Coastguard Worker   set_cost_prio(argv[0], argv[1], BRCTL_SET_PORT_PRIORITY, prio);
292*cf5a6c84SAndroid Build Coastguard Worker 
293*cf5a6c84SAndroid Build Coastguard Worker }
294*cf5a6c84SAndroid Build Coastguard Worker 
brctl_main(void)295*cf5a6c84SAndroid Build Coastguard Worker void brctl_main(void)
296*cf5a6c84SAndroid Build Coastguard Worker {
297*cf5a6c84SAndroid Build Coastguard Worker   int i;
298*cf5a6c84SAndroid Build Coastguard Worker   struct cmds {
299*cf5a6c84SAndroid Build Coastguard Worker     char *cmd;
300*cf5a6c84SAndroid Build Coastguard Worker     int nargs;
301*cf5a6c84SAndroid Build Coastguard Worker     void (*f)(char **argv);
302*cf5a6c84SAndroid Build Coastguard Worker   } cc[] = {{"show", 0, br_show},
303*cf5a6c84SAndroid Build Coastguard Worker     {"addbr", 1, br_addbr}, {"delbr", 1, br_delbr},
304*cf5a6c84SAndroid Build Coastguard Worker     {"addif", 2, br_addif}, {"delif", 2, br_delif},
305*cf5a6c84SAndroid Build Coastguard Worker     {"setageing", 2, br_set_ageing_time},
306*cf5a6c84SAndroid Build Coastguard Worker     {"setfd", 2, br_set_fwd_delay},
307*cf5a6c84SAndroid Build Coastguard Worker     {"sethello", 2, br_set_hello_time},
308*cf5a6c84SAndroid Build Coastguard Worker     {"setmaxage", 2, br_set_max_age},
309*cf5a6c84SAndroid Build Coastguard Worker     {"setpathcost", 3, br_set_path_cost},
310*cf5a6c84SAndroid Build Coastguard Worker     {"setportprio", 3, br_set_port_prio},
311*cf5a6c84SAndroid Build Coastguard Worker     {"setbridgeprio", 2, br_set_bridge_prio},
312*cf5a6c84SAndroid Build Coastguard Worker     {"stp", 2, br_set_stp},
313*cf5a6c84SAndroid Build Coastguard Worker   };
314*cf5a6c84SAndroid Build Coastguard Worker 
315*cf5a6c84SAndroid Build Coastguard Worker   TT.sockfd = xsocket(AF_INET, SOCK_STREAM, 0);
316*cf5a6c84SAndroid Build Coastguard Worker   while (*toys.optargs) {
317*cf5a6c84SAndroid Build Coastguard Worker     for (i = 0; i < ARRAY_LEN(cc); i++) {
318*cf5a6c84SAndroid Build Coastguard Worker       struct cmds *t = cc + i;
319*cf5a6c84SAndroid Build Coastguard Worker 
320*cf5a6c84SAndroid Build Coastguard Worker       if (strcmp(t->cmd, *toys.optargs)) continue;
321*cf5a6c84SAndroid Build Coastguard Worker 
322*cf5a6c84SAndroid Build Coastguard Worker       toys.optargs++, toys.optc--;
323*cf5a6c84SAndroid Build Coastguard Worker       if (toys.optc < t->nargs) help_exit("check args");
324*cf5a6c84SAndroid Build Coastguard Worker       t->f(toys.optargs);
325*cf5a6c84SAndroid Build Coastguard Worker       toys.optargs += t->nargs;
326*cf5a6c84SAndroid Build Coastguard Worker       toys.optc -= t->nargs;
327*cf5a6c84SAndroid Build Coastguard Worker       break;
328*cf5a6c84SAndroid Build Coastguard Worker     }
329*cf5a6c84SAndroid Build Coastguard Worker 
330*cf5a6c84SAndroid Build Coastguard Worker     if (i == ARRAY_LEN(cc)) help_exit("invalid option '%s'", *toys.optargs);
331*cf5a6c84SAndroid Build Coastguard Worker   }
332*cf5a6c84SAndroid Build Coastguard Worker   xclose(TT.sockfd);
333*cf5a6c84SAndroid Build Coastguard Worker }
334