2 * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 * - add and remove interfaces from a bond interface
30 * Modification History:
32 * July 14, 2004 Dieter Siegmund (dieter@apple.com)
36 #include <sys/param.h>
37 #include <sys/ioctl.h>
38 #include <sys/socket.h>
43 #include <net/ethernet.h>
45 #include <net/if_var.h>
46 #include <net/if_bond_var.h>
48 #include <net/route.h>
59 extern int bond_details
;
61 #define EA_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x"
62 #define EA_CH(e, i) ((u_char)((u_char *)(e))[(i)])
63 #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)
65 static __inline__
const char *
66 selected_state_string(u_char s
)
68 static const char * names
[] = { "unselected", "selected", "standby" };
70 if (s
<= IF_BOND_STATUS_SELECTED_STATE_STANDBY
) {
77 bond_print_details(struct if_bond_status
* ibs_p
, int count
)
81 struct if_bond_status
* scan_p
= ibs_p
;
83 for (i
= 0; i
< count
; i
++, scan_p
++) {
84 struct if_bond_partner_state
* ps
;
85 ps
= &scan_p
->ibs_partner_state
;
86 printf("\tbond interface: %s priority: 0x%04x "
87 "state: 0x%02x partner system: 0x%04x,"
89 "key: 0x%04x port: 0x%04x priority: 0x%04x "
91 scan_p
->ibs_if_name
, scan_p
->ibs_port_priority
,
92 scan_p
->ibs_state
, ps
->ibps_system_priority
,
93 EA_LIST(&ps
->ibps_system
), ps
->ibps_key
,
94 ps
->ibps_port
, ps
->ibps_port_priority
,
101 bond_status(int s
, struct rt_addrinfo
* info __unused
)
104 struct if_bond_req ibr
;
105 struct if_bond_status
* ibs_p
;
106 struct if_bond_status_req
* ibsr_p
;
108 bzero((char *)&ibr
, sizeof(ibr
));
109 ibr
.ibr_op
= IF_BOND_OP_GET_STATUS
;
110 ibsr_p
= &ibr
.ibr_ibru
.ibru_status
;
111 ibsr_p
->ibsr_version
= IF_BOND_STATUS_REQ_VERSION
;
112 ifr
.ifr_data
= (caddr_t
)&ibr
;
114 /* how many of them are there? */
115 if (ioctl(s
, SIOCGIFBOND
, (caddr_t
)&ifr
) < 0) {
118 if (ibsr_p
->ibsr_total
== 0) {
120 printf("\tbond key: 0x%04x interfaces: <none>\n",
124 printf("\tbond interfaces: <none>\n");
129 = (char *)malloc(sizeof(struct if_bond_status
)
130 * ibsr_p
->ibsr_total
);
131 ibsr_p
->ibsr_count
= ibsr_p
->ibsr_total
;
134 if (ioctl(s
, SIOCGIFBOND
, (caddr_t
)&ifr
) < 0) {
137 if (ibsr_p
->ibsr_total
> 0) {
139 printf("\tbond key: 0x%04x interfaces:",
143 printf("\tbond interfaces:");
145 ibs_p
= (struct if_bond_status
*)ibsr_p
->ibsr_buffer
;
146 for (i
= 0; i
< ibsr_p
->ibsr_total
; i
++, ibs_p
++) {
147 printf(" %s", ibs_p
->ibs_if_name
);
149 u_char s
= ibs_p
->ibs_selected_state
;
150 printf(" (%s)", selected_state_string(s
));
155 bond_print_details((struct if_bond_status
*)
160 else if (bond_details
) {
161 printf("\tbond key: 0x%04x interfaces: <none>\n",
165 printf("\tbond interfaces: <none>\n");
169 free(ibsr_p
->ibsr_buffer
);
174 setbonddev(const char *val
, int d
, int s
, const struct afswtch
* afp
)
176 struct if_bond_req ibr
;
178 bzero((char *)&ibr
, sizeof(ibr
));
179 if ((unsigned int)snprintf(ibr
.ibr_ibru
.ibru_if_name
,
180 sizeof(ibr
.ibr_ibru
.ibru_if_name
),
181 "%s", val
) >= IFNAMSIZ
) {
182 errx(1, "interface name too long");
184 ibr
.ibr_op
= IF_BOND_OP_ADD_INTERFACE
;
185 ifr
.ifr_data
= (caddr_t
)&ibr
;
186 if (ioctl(s
, SIOCSIFBOND
, (caddr_t
)&ifr
) == -1)
187 err(1, "SIOCSIFBOND add interface");
193 unsetbonddev(const char *val
, int d
, int s
, const struct afswtch
* afp
)
195 struct if_bond_req ibr
;
197 bzero((char *)&ibr
, sizeof(ibr
));
198 if ((unsigned int)snprintf(ibr
.ibr_ibru
.ibru_if_name
,
199 sizeof(ibr
.ibr_ibru
.ibru_if_name
),
200 "%s", val
) >= IFNAMSIZ
) {
201 errx(1, "interface name too long");
203 ibr
.ibr_op
= IF_BOND_OP_REMOVE_INTERFACE
;
204 ifr
.ifr_data
= (caddr_t
)&ibr
;
205 if (ioctl(s
, SIOCSIFBOND
, (caddr_t
)&ifr
) == -1)
206 err(1, "SIOCSIFBOND remove interface");