]> git.saurik.com Git - apple/network_cmds.git/blobdiff - ifconfig.tproj/ifbond.c
network_cmds-543.tar.gz
[apple/network_cmds.git] / ifconfig.tproj / ifbond.c
index 6a3fc5b68f632962070214a271ecc32c3ebaa129..b8bcdfe03c79e6b1ccfdac5d640854e23b18f3e0 100644 (file)
@@ -97,12 +97,14 @@ bond_print_details(struct if_bond_status * ibs_p, int count)
 }
 
 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;
@@ -114,10 +116,23 @@ bond_status(int s, struct rt_addrinfo * info __unused)
        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");
@@ -135,8 +150,9 @@ bond_status(int s, struct rt_addrinfo * info __unused)
        }
        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:");
@@ -157,8 +173,9 @@ bond_status(int s, struct rt_addrinfo * info __unused)
                }
        }
        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");
@@ -169,8 +186,8 @@ bond_status(int s, struct rt_addrinfo * info __unused)
        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;
 
@@ -188,8 +205,8 @@ setbonddev(const char *val, int d, int s, const struct afswtch * afp)
        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;
 
@@ -207,3 +224,61 @@ unsetbonddev(const char *val, int d, int s, const struct afswtch * afp)
        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
+}
+