From 5fd83771641d15c418f747bd343ba6738d3875f7 Mon Sep 17 00:00:00 2001 From: Cameron Katri Date: Sun, 9 May 2021 14:20:58 -0400 Subject: Import macOS userland adv_cmds-176 basic_cmds-55 bootstrap_cmds-116.100.1 developer_cmds-66 diskdev_cmds-667.40.1 doc_cmds-53.60.1 file_cmds-321.40.3 mail_cmds-35 misc_cmds-34 network_cmds-606.40.1 patch_cmds-17 remote_cmds-63 shell_cmds-216.60.1 system_cmds-880.60.2 text_cmds-106 --- network_cmds/ifconfig.tproj/ifbond.c | 284 +++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 network_cmds/ifconfig.tproj/ifbond.c (limited to 'network_cmds/ifconfig.tproj/ifbond.c') diff --git a/network_cmds/ifconfig.tproj/ifbond.c b/network_cmds/ifconfig.tproj/ifbond.c new file mode 100644 index 0000000..b8bcdfe --- /dev/null +++ b/network_cmds/ifconfig.tproj/ifbond.c @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * The contents of this file constitute Original Code as defined in and + * are subject to the Apple Public Source License Version 1.1 (the + * "License"). You may not use this file except in compliance with the + * License. Please obtain a copy of the License at + * http://www.apple.com/publicsource and read it before using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License. + * + * @APPLE_LICENSE_HEADER_END@ + */ + +/* + * ifbond.c + * - add and remove interfaces from a bond interface + */ + +/* + * Modification History: + * + * July 14, 2004 Dieter Siegmund (dieter@apple.com) + * - created + */ + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "ifconfig.h" +extern int bond_details; + +#define EA_FORMAT "%02x:%02x:%02x:%02x:%02x:%02x" +#define EA_CH(e, i) ((u_char)((u_char *)(e))[(i)]) +#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) + +static __inline__ const char * +selected_state_string(u_char s) +{ + static const char * names[] = { "unselected", "selected", "standby" }; + + if (s <= IF_BOND_STATUS_SELECTED_STATE_STANDBY) { + return (names[s]); + } + return (""); +} + +static void +bond_print_details(struct if_bond_status * ibs_p, int count) + +{ + int i; + struct if_bond_status * scan_p = ibs_p; + + for (i = 0; i < count; i++, scan_p++) { + struct if_bond_partner_state * ps; + ps = &scan_p->ibs_partner_state; + printf("\tbond interface: %s priority: 0x%04x " + "state: 0x%02x partner system: 0x%04x," + EA_FORMAT " " + "key: 0x%04x port: 0x%04x priority: 0x%04x " + "state: 0x%02x\n", + scan_p->ibs_if_name, scan_p->ibs_port_priority, + scan_p->ibs_state, ps->ibps_system_priority, + EA_LIST(&ps->ibps_system), ps->ibps_key, + ps->ibps_port, ps->ibps_port_priority, + ps->ibps_state); + } + return; +} + +void +bond_status(int s) +{ + int i; + struct if_bond_req ibr; + struct if_bond_status * ibs_p; + struct if_bond_status_req * ibsr_p; + char mode_buf[16]; + const char * mode_str; + + bzero((char *)&ibr, sizeof(ibr)); + ibr.ibr_op = IF_BOND_OP_GET_STATUS; + ibsr_p = &ibr.ibr_ibru.ibru_status; + ibsr_p->ibsr_version = IF_BOND_STATUS_REQ_VERSION; + ifr.ifr_data = (caddr_t)&ibr; + + /* how many of them are there? */ + if (ioctl(s, SIOCGIFBOND, (caddr_t)&ifr) < 0) { + return; + } + switch (ibsr_p->ibsr_mode) { + case IF_BOND_MODE_LACP: + mode_str = "lacp"; + break; + case IF_BOND_MODE_STATIC: + mode_str = "static"; + break; + default: + snprintf(mode_buf, sizeof(mode_buf), "%d", ibsr_p->ibsr_mode); + mode_str = mode_buf; + break; + } + if (ibsr_p->ibsr_total == 0) { + if (bond_details) { + printf("\tbond mode: %s\n" + "\tbond key: 0x%04x interfaces: ", + mode_str, ibsr_p->ibsr_key); + } + else { + printf("\tbond interfaces: \n"); + } + return; + } + ibsr_p->ibsr_buffer + = (char *)malloc(sizeof(struct if_bond_status) + * ibsr_p->ibsr_total); + ibsr_p->ibsr_count = ibsr_p->ibsr_total; + + /* get the list */ + if (ioctl(s, SIOCGIFBOND, (caddr_t)&ifr) < 0) { + goto done; + } + if (ibsr_p->ibsr_total > 0) { + if (bond_details) { + printf("\tbond mode: %s\n" + "\tbond key: 0x%04x interfaces:", + mode_str, ibsr_p->ibsr_key); + } + else { + printf("\tbond interfaces:"); + } + ibs_p = (struct if_bond_status *)ibsr_p->ibsr_buffer; + for (i = 0; i < ibsr_p->ibsr_total; i++, ibs_p++) { + printf(" %s", ibs_p->ibs_if_name); + if (bond_details) { + u_char s = ibs_p->ibs_selected_state; + printf(" (%s)", selected_state_string(s)); + } + } + printf("\n"); + if (bond_details) { + bond_print_details((struct if_bond_status *) + ibsr_p->ibsr_buffer, + ibsr_p->ibsr_total); + } + } + else if (bond_details) { + printf("\tbond mode: %s\n" + "\tbond key: 0x%04x interfaces: \n", + mode_str, ibsr_p->ibsr_key); + } + else { + printf("\tbond interfaces: \n"); + } + + done: + free(ibsr_p->ibsr_buffer); + return; +} + +static +DECL_CMD_FUNC(setbonddev, val, d) +{ + struct if_bond_req ibr; + + bzero((char *)&ibr, sizeof(ibr)); + if ((unsigned int)snprintf(ibr.ibr_ibru.ibru_if_name, + sizeof(ibr.ibr_ibru.ibru_if_name), + "%s", val) >= IFNAMSIZ) { + errx(1, "interface name too long"); + } + ibr.ibr_op = IF_BOND_OP_ADD_INTERFACE; + ifr.ifr_data = (caddr_t)&ibr; + if (ioctl(s, SIOCSIFBOND, (caddr_t)&ifr) == -1) + err(1, "SIOCSIFBOND add interface"); + + return; +} + +static +DECL_CMD_FUNC(unsetbonddev, val, d) +{ + struct if_bond_req ibr; + + bzero((char *)&ibr, sizeof(ibr)); + if ((unsigned int)snprintf(ibr.ibr_ibru.ibru_if_name, + sizeof(ibr.ibr_ibru.ibru_if_name), + "%s", val) >= IFNAMSIZ) { + errx(1, "interface name too long"); + } + ibr.ibr_op = IF_BOND_OP_REMOVE_INTERFACE; + ifr.ifr_data = (caddr_t)&ibr; + if (ioctl(s, SIOCSIFBOND, (caddr_t)&ifr) == -1) + err(1, "SIOCSIFBOND remove interface"); + + return; +} + +static +DECL_CMD_FUNC(setbondmode, val, d) +{ + struct if_bond_req ibr; + int mode; + + if (strcmp(val, "lacp") == 0) { + mode = IF_BOND_MODE_LACP; + } + else if (strcmp(val, "static") == 0) { + mode = IF_BOND_MODE_STATIC; + } + else { + mode = strtoul(val, NULL, 0); + if (errno != 0) { + errx(1, "invalid mode value " + "(must be either \"lacp\" or \"static\")"); + } + } + + bzero((char *)&ibr, sizeof(ibr)); + if ((unsigned int)snprintf(ibr.ibr_ibru.ibru_if_name, + sizeof(ibr.ibr_ibru.ibru_if_name), + "%s", val) >= IFNAMSIZ) { + errx(1, "interface name too long"); + } + ibr.ibr_op = IF_BOND_OP_SET_MODE; + ibr.ibr_ibru.ibru_int_val = mode; + ifr.ifr_data = (caddr_t)&ibr; + if (ioctl(s, SIOCSIFBOND, (caddr_t)&ifr) == -1) + err(1, "SIOCSIFBOND set mode"); + + return; +} + +static struct cmd bond_cmds[] = { + DEF_CLONE_CMD_ARG("bonddev", setbonddev), + DEF_CLONE_CMD_ARG("-bonddev", unsetbonddev), + DEF_CMD_ARG("bondmode", setbondmode), +}; +static struct afswtch af_bond = { + .af_name = "af_bond", + .af_af = AF_UNSPEC, + .af_other_status = bond_status, +}; + +static __constructor void +bond_ctor(void) +{ +#define N(a) (sizeof(a) / sizeof(a[0])) + int i; + + for (i = 0; i < N(bond_cmds); i++) + cmd_register(&bond_cmds[i]); + af_register(&af_bond); +#undef N +} + -- cgit v1.2.3-56-ge451