2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
25 * - add and remove interfaces from a bond interface
29 * Modification History:
31 * July 14, 2004 Dieter Siegmund (dieter@apple.com)
35 #include <sys/param.h>
36 #include <sys/ioctl.h>
37 #include <sys/socket.h>
42 #include <net/ethernet.h>
44 #include <net/if_var.h>
45 #include <net/if_bond_var.h>
47 #include <net/route.h>
58 extern int bond_details
;
60 #define EA_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x"
61 #define EA_CH(e, i) ((u_char)((u_char *)(e))[(i)])
62 #define EA_LIST(ea) EA_CH(ea,0),EA_CH(ea,1),EA_CH(ea,2),EA_CH(ea,3),EA_CH(ea,4),EA_CH(ea,5)
64 static __inline__
const char *
65 selected_state_string(u_char s
)
67 static const char * names
[] = { "unselected", "selected", "standby" };
69 if (s
<= IF_BOND_STATUS_SELECTED_STATE_STANDBY
) {
76 bond_print_details(struct if_bond_status
* ibs_p
, int count
)
80 struct if_bond_status
* scan_p
= ibs_p
;
82 for (i
= 0; i
< count
; i
++, scan_p
++) {
83 struct if_bond_partner_state
* ps
;
84 ps
= &scan_p
->ibs_partner_state
;
85 printf("\tbond interface: %s priority: 0x%04x "
86 "state: 0x%02x partner system: 0x%04x,"
88 "key: 0x%04x port: 0x%04x priority: 0x%04x "
90 scan_p
->ibs_if_name
, scan_p
->ibs_port_priority
,
91 scan_p
->ibs_state
, ps
->ibps_system_priority
,
92 EA_LIST(&ps
->ibps_system
), ps
->ibps_key
,
93 ps
->ibps_port
, ps
->ibps_port_priority
,
100 bond_status(int s
, struct rt_addrinfo
* info __unused
)
103 struct if_bond_req ibr
;
104 struct if_bond_status
* ibs_p
;
105 struct if_bond_status_req
* ibsr_p
;
107 bzero((char *)&ibr
, sizeof(ibr
));
108 ibr
.ibr_op
= IF_BOND_OP_GET_STATUS
;
109 ibsr_p
= &ibr
.ibr_ibru
.ibru_status
;
110 ibsr_p
->ibsr_version
= IF_BOND_STATUS_REQ_VERSION
;
111 ifr
.ifr_data
= (caddr_t
)&ibr
;
113 /* how many of them are there? */
114 if (ioctl(s
, SIOCGIFBOND
, (caddr_t
)&ifr
) < 0) {
117 if (ibsr_p
->ibsr_total
== 0) {
119 printf("\tbond key: 0x%04x interfaces: <none>\n",
123 printf("\tbond interfaces: <none>\n");
128 = (char *)malloc(sizeof(struct if_bond_status
)
129 * ibsr_p
->ibsr_total
);
130 ibsr_p
->ibsr_count
= ibsr_p
->ibsr_total
;
133 if (ioctl(s
, SIOCGIFBOND
, (caddr_t
)&ifr
) < 0) {
136 if (ibsr_p
->ibsr_total
> 0) {
138 printf("\tbond key: 0x%04x interfaces:",
142 printf("\tbond interfaces:");
144 ibs_p
= (struct if_bond_status
*)ibsr_p
->ibsr_buffer
;
145 for (i
= 0; i
< ibsr_p
->ibsr_total
; i
++, ibs_p
++) {
146 printf(" %s", ibs_p
->ibs_if_name
);
148 u_char s
= ibs_p
->ibs_selected_state
;
149 printf(" (%s)", selected_state_string(s
));
154 bond_print_details((struct if_bond_status
*)
159 else if (bond_details
) {
160 printf("\tbond key: 0x%04x interfaces: <none>\n",
164 printf("\tbond interfaces: <none>\n");
168 free(ibsr_p
->ibsr_buffer
);
173 setbonddev(const char *val
, int d
, int s
, const struct afswtch
* afp
)
175 struct if_bond_req ibr
;
177 bzero((char *)&ibr
, sizeof(ibr
));
178 if ((unsigned int)snprintf(ibr
.ibr_ibru
.ibru_if_name
,
179 sizeof(ibr
.ibr_ibru
.ibru_if_name
),
180 "%s", val
) >= IFNAMSIZ
) {
181 errx(1, "interface name too long");
183 ibr
.ibr_op
= IF_BOND_OP_ADD_INTERFACE
;
184 ifr
.ifr_data
= (caddr_t
)&ibr
;
185 if (ioctl(s
, SIOCSIFBOND
, (caddr_t
)&ifr
) == -1)
186 err(1, "SIOCSIFBOND add interface");
192 unsetbonddev(const char *val
, int d
, int s
, const struct afswtch
* afp
)
194 struct if_bond_req ibr
;
196 bzero((char *)&ibr
, sizeof(ibr
));
197 if ((unsigned int)snprintf(ibr
.ibr_ibru
.ibru_if_name
,
198 sizeof(ibr
.ibr_ibru
.ibru_if_name
),
199 "%s", val
) >= IFNAMSIZ
) {
200 errx(1, "interface name too long");
202 ibr
.ibr_op
= IF_BOND_OP_REMOVE_INTERFACE
;
203 ifr
.ifr_data
= (caddr_t
)&ibr
;
204 if (ioctl(s
, SIOCSIFBOND
, (caddr_t
)&ifr
) == -1)
205 err(1, "SIOCSIFBOND remove interface");