}
void
-bond_status(int s, struct rt_addrinfo * info __unused)
+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;
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 key: 0x%04x interfaces: <none>\n",
- ibsr_p->ibsr_key);
+ printf("\tbond mode: %s\n"
+ "\tbond key: 0x%04x interfaces: <none>",
+ mode_str, ibsr_p->ibsr_key);
}
else {
printf("\tbond interfaces: <none>\n");
}
if (ibsr_p->ibsr_total > 0) {
if (bond_details) {
- printf("\tbond key: 0x%04x interfaces:",
- ibsr_p->ibsr_key);
+ printf("\tbond mode: %s\n"
+ "\tbond key: 0x%04x interfaces:",
+ mode_str, ibsr_p->ibsr_key);
}
else {
printf("\tbond interfaces:");
}
}
else if (bond_details) {
- printf("\tbond key: 0x%04x interfaces: <none>\n",
- ibsr_p->ibsr_key);
+ printf("\tbond mode: %s\n"
+ "\tbond key: 0x%04x interfaces: <none>\n",
+ mode_str, ibsr_p->ibsr_key);
}
else {
printf("\tbond interfaces: <none>\n");
return;
}
-void
-setbonddev(const char *val, int d, int s, const struct afswtch * afp)
+static
+DECL_CMD_FUNC(setbonddev, val, d)
{
struct if_bond_req ibr;
return;
}
-void
-unsetbonddev(const char *val, int d, int s, const struct afswtch * afp)
+static
+DECL_CMD_FUNC(unsetbonddev, val, d)
{
struct if_bond_req ibr;
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
+}
+