]> git.ipfire.org Git - thirdparty/iw.git/commitdiff
simplify netlink handling
authorJohannes Berg <johannes@sipsolutions.net>
Tue, 16 Sep 2008 16:35:06 +0000 (18:35 +0200)
committerJohannes Berg <johannes@sipsolutions.net>
Tue, 16 Sep 2008 16:35:06 +0000 (18:35 +0200)
info.c
interface.c
iw.c
iw.h
mpath.c
phy.c
reg.c
station.c

diff --git a/info.c b/info.c
index 08025a02deaff022c1bced53020c7eab9c2c3287..0dc05c1c631b69dfcaa66c04c880408d4093bb81 100644 (file)
--- a/info.c
+++ b/info.c
@@ -115,43 +115,13 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
        return NL_SKIP;
 }
 
-
-
-static int ack_wait_handler(struct nl_msg *msg, void *arg)
-{
-       int *finished = arg;
-
-       *finished = 1;
-       return NL_STOP;
-}
-
-static int handle_info(struct nl80211_state *state,
+static int handle_info(struct nl_cb *cb,
                       struct nl_msg *msg,
                       int argc, char **argv)
 {
-       int err = -ENOMEM;
-       struct nl_cb *cb;
-       int finished;
-
-       cb = nl_cb_alloc(NL_CB_CUSTOM);
-       if (!cb)
-               goto out;
-
-       if (nl_send_auto_complete(state->nl_handle, msg) < 0)
-               goto out;
-
        nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_phy_handler, NULL);
-       nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
-
-       nl_recvmsgs(state->nl_handle, cb);
-       err = 0;
-
-       if (!finished)
-               err = nl_wait_for_ack(state->nl_handle);
 
- out:
-       nl_cb_put(cb);
-       return err;
+       return 0;
 }
 TOPLEVEL(info, NULL, NL80211_CMD_GET_WIPHY, 0, CIB_PHY, handle_info);
 TOPLEVEL(list, NULL, NL80211_CMD_GET_WIPHY, NLM_F_DUMP, CIB_NONE, handle_info);
index ad8fc88cf73e8554babb23a40e98bd562b75c93b..1bc0dc410a544fe67f1f3fb16ef52a2ba930d716 100644 (file)
@@ -56,14 +56,14 @@ static int get_if_type(int *argc, char ***argv, enum nl80211_iftype *type)
        return -1;
 }
 
-static int handle_interface_add(struct nl80211_state *state,
+static int handle_interface_add(struct nl_cb *cb,
                                struct nl_msg *msg,
                                int argc, char **argv)
 {
        char *name;
        char *mesh_id = NULL;
        enum nl80211_iftype type;
-       int tpset, err = -ENOBUFS;
+       int tpset;
 
        if (argc < 1)
                return 1;
@@ -98,29 +98,20 @@ static int handle_interface_add(struct nl80211_state *state,
        if (mesh_id)
                NLA_PUT(msg, NL80211_ATTR_MESH_ID, strlen(mesh_id), mesh_id);
 
-       err = nl_send_auto_complete(state->nl_handle, msg);
-       if (err > 0)
-               err = nl_wait_for_ack(state->nl_handle);
-
+       return 0;
  nla_put_failure:
-       return err;
+       return -ENOBUFS;
 }
 COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>]",
        NL80211_CMD_NEW_INTERFACE, 0, CIB_PHY, handle_interface_add);
 COMMAND(interface, add, "<name> type <type> [mesh_id <meshid>]",
        NL80211_CMD_NEW_INTERFACE, 0, CIB_NETDEV, handle_interface_add);
 
-static int handle_interface_del(struct nl80211_state *state,
+static int handle_interface_del(struct nl_cb *cb,
                                struct nl_msg *msg,
                                int argc, char **argv)
 {
-       int err;
-
-       err = nl_send_auto_complete(state->nl_handle, msg);
-       if (err > 0)
-               err = nl_wait_for_ack(state->nl_handle);
-
-       return err;
+       return 0;
 }
 TOPLEVEL(del, NULL, NL80211_CMD_DEL_INTERFACE, 0, CIB_NETDEV, handle_interface_del);
 
@@ -142,41 +133,11 @@ static int print_iface_handler(struct nl_msg *msg, void *arg)
        return NL_SKIP;
 }
 
-static int ack_wait_handler(struct nl_msg *msg, void *arg)
-{
-       int *finished = arg;
-
-       *finished = 1;
-       return NL_STOP;
-}
-
-static int handle_interface_info(struct nl80211_state *state,
+static int handle_interface_info(struct nl_cb *cb,
                                 struct nl_msg *msg,
                                 int argc, char **argv)
 {
-       int err = -ENOBUFS;
-       struct nl_cb *cb = NULL;
-       int finished = 0;
-
-       cb = nl_cb_alloc(NL_CB_CUSTOM);
-       if (!cb)
-               goto out;
-
-       err = nl_send_auto_complete(state->nl_handle, msg);
-       if (err)
-               goto out;
-
        nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_iface_handler, NULL);
-       nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_wait_handler, &finished);
-
-       nl_recvmsgs(state->nl_handle, cb);
-       err = 0;
-
-       if (!finished)
-               err = nl_wait_for_ack(state->nl_handle);
-
- out:
-       nl_cb_put(cb);
-       return err;
+       return 0;
 }
 TOPLEVEL(info, NULL, NL80211_CMD_GET_INTERFACE, 0, CIB_NETDEV, handle_interface_info);
diff --git a/iw.c b/iw.c
index c3b9297d42e435b4df9b8ffe958fca4eaf4b819e..5feb406ff2061e9923ef869e963c78a307841c6d 100644 (file)
--- a/iw.c
+++ b/iw.c
@@ -112,13 +112,30 @@ static int phy_lookup(char *name)
        return atoi(buf);
 }
 
+static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
+                        void *arg)
+{
+       int *ret = arg;
+       *ret = err->error;
+       return NL_STOP;
+}
+
+static int wait_handler(struct nl_msg *msg, void *arg)
+{
+       int *ret = arg;
+       *ret = 0;
+       return NL_STOP;
+}
+
 static int handle_cmd(struct nl80211_state *state,
                      enum command_identify_by idby,
                      int argc, char **argv)
 {
        struct cmd *cmd;
+       struct nl_cb *cb = NULL;
        struct nl_msg *msg;
        int devidx = 0;
+       int err;
        const char *command, *section;
 
        if (argc <= 1 && idby != CIB_NONE)
@@ -171,8 +188,15 @@ static int handle_cmd(struct nl80211_state *state,
 
        msg = nlmsg_alloc();
        if (!msg) {
-               fprintf(stderr, "out of memory\n");
-               return -ENOMEM;
+               fprintf(stderr, "failed to allocate netlink message\n");
+               return 2;
+       }
+
+       cb = nl_cb_alloc(NL_CB_CUSTOM);
+       if (!cb) {
+               fprintf(stderr, "failed to allocate netlink callbacks\n");
+               err = 2;
+               goto out_free_msg;
        }
 
        genlmsg_put(msg, 0, 0, genl_family_get_id(state->nl80211), 0,
@@ -189,10 +213,30 @@ static int handle_cmd(struct nl80211_state *state,
                break;
        }
 
-       return cmd->handler(state, msg, argc, argv);
+       err = cmd->handler(cb, msg, argc, argv);
+       if (err)
+               goto out;
+
+       err = nl_send_auto_complete(state->nl_handle, msg);
+       if (err < 0)
+               goto out;
+
+       nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
+       nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, wait_handler, &err);
+
+       err = 1;
+       nl_recvmsgs(state->nl_handle, cb);
+
+       if (err == 1)
+               err = nl_wait_for_ack(state->nl_handle);
+ out:
+       nl_cb_put(cb);
+ out_free_msg:
+       nlmsg_free(msg);
+       return err;
  nla_put_failure:
        fprintf(stderr, "building message failed\n");
-       return -ENOMEM;
+       return 2;
 }
 
 int main(int argc, char **argv)
diff --git a/iw.h b/iw.h
index a7b47a2bc1ab00f1a125e77156f980f1f8d09d08..c9d905215dade5d8f2bb967a8041f1c9c11dc168 100644 (file)
--- a/iw.h
+++ b/iw.h
@@ -32,7 +32,7 @@ struct cmd {
         * zero on success, 1 if the arguments were wrong
         * and the usage message should and 2 otherwise.
         */
-       int (*handler)(struct nl80211_state *state,
+       int (*handler)(struct nl_cb *cb,
                       struct nl_msg *msg,
                       int argc, char **argv);
 };
@@ -51,8 +51,6 @@ extern struct cmd __stop___cmd;
 int mac_addr_a2n(unsigned char *mac_addr, char *arg);
 int mac_addr_n2a(char *mac_addr, unsigned char *arg);
 
-int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
-
 const char *iftype_name(enum nl80211_iftype iftype);
 
 #endif /* __IW_H */
diff --git a/mpath.c b/mpath.c
index 2e32976671382dbedd45f67e66cf00462eab2de7..0d01cd79d8d0ae06b649eb3640f29f9403173ae5 100644 (file)
--- a/mpath.c
+++ b/mpath.c
@@ -28,14 +28,6 @@ enum plink_actions {
 };
 
 
-static int wait_handler(struct nl_msg *msg, void *arg)
-{
-       int *finished = arg;
-
-       *finished = 1;
-       return NL_STOP;
-}
-
 static int print_mpath_handler(struct nl_msg *msg, void *arg)
 {
        struct nlattr *tb[NL80211_ATTR_MAX + 1];
@@ -102,13 +94,10 @@ static int print_mpath_handler(struct nl_msg *msg, void *arg)
        return NL_SKIP;
 }
 
-static int handle_mpath_get(struct nl80211_state *state,
+static int handle_mpath_get(struct nl_cb *cb,
                            struct nl_msg *msg,
                            int argc, char **argv)
 {
-       struct nl_cb *cb = NULL;
-       int err = -ENOMEM;
-       int finished = 0;
        unsigned char dst[ETH_ALEN];
 
        if (argc < 1)
@@ -126,40 +115,21 @@ static int handle_mpath_get(struct nl80211_state *state,
 
        NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
 
-       cb = nl_cb_alloc(NL_CB_CUSTOM);
-       if (!cb)
-               goto out;
-
-       if (nl_send_auto_complete(state->nl_handle, msg) < 0)
-               goto out;
-
        nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL);
-       nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
-       nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);
-
-       nl_recvmsgs(state->nl_handle, cb);
-       err = 0;
-
-       if (!finished)
-               err = nl_wait_for_ack(state->nl_handle);
 
- out:
-       nl_cb_put(cb);
+       return 0;
  nla_put_failure:
-       return err;
+       return -ENOBUFS;
 }
 COMMAND(mpath, get, "<MAC address>",
        NL80211_CMD_GET_MPATH, 0, CIB_NETDEV, handle_mpath_get);
 COMMAND(mpath, del, "<MAC address>",
        NL80211_CMD_DEL_MPATH, 0, CIB_NETDEV, handle_mpath_get);
 
-static int handle_mpath_set(struct nl80211_state *state,
+static int handle_mpath_set(struct nl_cb *cb,
                            struct nl_msg *msg,
                            int argc, char **argv)
 {
-       struct nl_cb *cb = NULL;
-       int err = -ENOMEM;
-       int finished = 0;
        unsigned char dst[ETH_ALEN];
        unsigned char next_hop[ETH_ALEN];
 
@@ -188,67 +158,25 @@ static int handle_mpath_set(struct nl80211_state *state,
        if (argc)
                return 1;
 
-       msg = nlmsg_alloc();
-       if (!msg)
-               goto out;
-
        NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, dst);
        NLA_PUT(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop);
 
-       cb = nl_cb_alloc(NL_CB_CUSTOM);
-       if (!cb)
-               goto out;
-
-       if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0)
-               goto out;
-
        nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL);
-       nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
-       nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);
-
-       nl_recvmsgs(state->nl_handle, cb);
-       err = 0;
-
-       if (!finished)
-               err = nl_wait_for_ack(state->nl_handle);
-
- out:
-       nl_cb_put(cb);
+       return 0;
  nla_put_failure:
-       return err;
+       return -ENOBUFS;
 }
 COMMAND(mpath, new, "<destination MAC address> next_hop <next hop MAC address>",
        NL80211_CMD_NEW_MPATH, 0, CIB_NETDEV, handle_mpath_set);
 COMMAND(mpath, set, "<destination MAC address> next_hop <next hop MAC address>",
        NL80211_CMD_SET_MPATH, 0, CIB_NETDEV, handle_mpath_set);
 
-static int handle_mpath_dump(struct nl80211_state *state,
+static int handle_mpath_dump(struct nl_cb *cb,
                             struct nl_msg *msg,
                             int argc, char **argv)
 {
-       struct nl_cb *cb = NULL;
-       int err = -ENOMEM;
-       int finished = 0;
-
-       cb = nl_cb_alloc(NL_CB_CUSTOM);
-       if (!cb)
-               goto out;
-
-       if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0)
-               goto out;
-
        nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_mpath_handler, NULL);
-       nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, wait_handler, &finished);
-
-       nl_recvmsgs(state->nl_handle, cb);
-       err = finished;
-
-       if (!finished)
-               err = nl_wait_for_ack(state->nl_handle);
-
- out:
-       nl_cb_put(cb);
-       return err;
+       return 0;
 }
 COMMAND(mpath, dump, NULL,
        NL80211_CMD_GET_MPATH, NLM_F_DUMP, CIB_NETDEV, handle_mpath_dump);
diff --git a/phy.c b/phy.c
index 43fa1d58c50037d368c8e37f3d8233c1d7b74b7c..03287b0a2f06e3bbfa1671d36ac01c738b8d3115 100644 (file)
--- a/phy.c
+++ b/phy.c
 
 #include "iw.h"
 
-static int handle_name(struct nl80211_state *state,
+static int handle_name(struct nl_cb *cb,
                       struct nl_msg *msg,
                       int argc, char **argv)
 {
-       int err = -ENOMEM;
-       struct nl_cb *cb;
-
        if (argc != 1)
                return 1;
 
        NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, *argv);
 
-       cb = nl_cb_alloc(NL_CB_CUSTOM);
-       if (!cb)
-               goto out;
-
-       if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0)
-               goto out;
-
-       err = nl_wait_for_ack(state->nl_handle);
-
- out:
-       nl_cb_put(cb);
+       return 0;
  nla_put_failure:
-       return err;
+       return -ENOBUFS;
 }
 COMMAND(set, name, "<new name>", NL80211_CMD_SET_WIPHY, 0, CIB_PHY, handle_name);
diff --git a/reg.c b/reg.c
index 31d9cca152391f1e6a57f5da582c616e5cb6243c..69281a0a83fe59c772437a84a085574a3014f8d0 100644 (file)
--- a/reg.c
+++ b/reg.c
@@ -33,12 +33,10 @@ static int is_world_regdom(char *alpha2)
        return 0;
 }
 
-static int handle_reg_set(struct nl80211_state *state,
+static int handle_reg_set(struct nl_cb *cb,
                          struct nl_msg *msg,
                          int argc, char **argv)
 {
-       struct nl_cb *cb = NULL;
-       int err = -ENOMEM;
        char alpha2[3];
 
        if (argc < 1)
@@ -63,21 +61,9 @@ static int handle_reg_set(struct nl80211_state *state,
 
        NLA_PUT_STRING(msg, NL80211_ATTR_REG_ALPHA2, alpha2);
 
-       cb = nl_cb_alloc(NL_CB_CUSTOM);
-       if (!cb)
-               goto out;
-
-       err = nl_send_auto_complete(state->nl_handle, msg);
-
-       if (err < 0)
-               goto out;
-
-       err = nl_wait_for_ack(state->nl_handle);
-
- out:
-       nl_cb_put(cb);
+       return 0;
  nla_put_failure:
-       return err;
+       return -ENOBUFS;
 }
 COMMAND(reg, set, "<ISO/IEC 3166-1 alpha2>",
        NL80211_CMD_REQ_SET_REG, 0, CIB_NONE, handle_reg_set);
index 0996d0accaae01a30b701da473d3030fe7c996a5..c3fcb78872aed90f6ec47c085955f29c40c9c583 100644 (file)
--- a/station.c
+++ b/station.c
@@ -28,14 +28,6 @@ enum plink_actions {
 };
 
 
-static int wait_handler(struct nl_msg *msg, void *arg)
-{
-       int *finished = arg;
-
-       *finished = 1;
-       return NL_STOP;
-}
-
 static int print_sta_handler(struct nl_msg *msg, void *arg)
 {
        struct nlattr *tb[NL80211_ATTR_MAX + 1];
@@ -124,13 +116,10 @@ static int print_sta_handler(struct nl_msg *msg, void *arg)
        return NL_SKIP;
 }
 
-static int handle_station_get(struct nl80211_state *state,
+static int handle_station_get(struct nl_cb *cb,
                              struct nl_msg *msg,
                              int argc, char **argv)
 {
-       struct nl_cb *cb = NULL;
-       int err = -ENOMEM;
-       int finished = 0;
        unsigned char mac_addr[ETH_ALEN];
 
        if (argc < 1)
@@ -149,40 +138,21 @@ static int handle_station_get(struct nl80211_state *state,
 
        NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
 
-       cb = nl_cb_alloc(NL_CB_CUSTOM);
-       if (!cb)
-               goto out;
-
-       if (nl_send_auto_complete(state->nl_handle, msg) < 0)
-               goto out;
-
        nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL);
-       nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
-       nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);
 
-       nl_recvmsgs(state->nl_handle, cb);
-       err = 0;
-
-       if (!finished)
-               err = nl_wait_for_ack(state->nl_handle);
-
- out:
-       nl_cb_put(cb);
+       return 0;
  nla_put_failure:
-       return err;
+       return -ENOBUFS;
 }
 COMMAND(station, get, "<MAC address>",
        NL80211_CMD_GET_STATION, 0, CIB_NETDEV, handle_station_get);
 COMMAND(station, del, "<MAC address>",
        NL80211_CMD_DEL_STATION, 0, CIB_NETDEV, handle_station_get);
 
-static int handle_station_set(struct nl80211_state *state,
+static int handle_station_set(struct nl_cb *cb,
                              struct nl_msg *msg,
                              int argc, char **argv)
 {
-       struct nl_cb *cb = NULL;
-       int err = -ENOMEM;
-       int finished = 0;
        unsigned char plink_action;
        unsigned char mac_addr[ETH_ALEN];
 
@@ -218,62 +188,19 @@ static int handle_station_set(struct nl80211_state *state,
        NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr);
        NLA_PUT_U8(msg, NL80211_ATTR_STA_PLINK_ACTION, plink_action);
 
-       cb = nl_cb_alloc(NL_CB_CUSTOM);
-       if (!cb)
-               goto out;
-
-       if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0)
-               goto out;
-
-       nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL);
-       nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, wait_handler, &finished);
-       nl_cb_err(cb, NL_CB_CUSTOM, error_handler, NULL);
-
-       nl_recvmsgs(state->nl_handle, cb);
-       err = 0;
-
-       if (!finished)
-               err = nl_wait_for_ack(state->nl_handle);
-
- out:
-       nl_cb_put(cb);
+       return 0;
  nla_put_failure:
-       return err;
+       return -ENOBUFS;
 }
 COMMAND(station, set, "<MAC address> plink_action <open|block>",
        NL80211_CMD_SET_STATION, 0, CIB_NETDEV, handle_station_set);
 
-static int handle_station_dump(struct nl80211_state *state,
+static int handle_station_dump(struct nl_cb *cb,
                               struct nl_msg *msg,
                               int argc, char **argv)
 {
-       struct nl_cb *cb = NULL;
-       int err = -ENOMEM;
-       int finished = 0;
-
-       if (argc)
-               return 1;
-
-       cb = nl_cb_alloc(NL_CB_CUSTOM);
-       if (!cb)
-               goto out;
-
-       if ((err = nl_send_auto_complete(state->nl_handle, msg)) < 0)
-               goto out;
-
        nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_sta_handler, NULL);
-       nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &finished);
-       nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, wait_handler, &finished);
-
-       nl_recvmsgs(state->nl_handle, cb);
-       err = finished;
-
-       if (!finished)
-               err = nl_wait_for_ack(state->nl_handle);
-
- out:
-       nl_cb_put(cb);
-       return err;
+       return 0;
 }
 COMMAND(station, dump, NULL,
        NL80211_CMD_SET_STATION, NLM_F_DUMP, CIB_NETDEV, handle_station_dump);