[netcf-devel] [PATCH] Report actual mac address in ncf_if_xml_state.

Laine Stump laine at laine.org
Fri Oct 23 17:32:31 UTC 2009


Iterate the NETLINK link cache to find the entry for each interface,
extract the mac address, and add it to the XML.
---
 src/dutil.c |   67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 66 insertions(+), 1 deletions(-)

diff --git a/src/dutil.c b/src/dutil.c
index 1fc6097..a010d27 100644
--- a/src/dutil.c
+++ b/src/dutil.c
@@ -610,6 +610,7 @@ struct nl_callback_data {
     xmlNodePtr root;
     xmlNodePtr protov4;
     xmlNodePtr protov6;
+    xmlNodePtr mac;
     struct netcf_if *nif;
 };
 
@@ -708,10 +709,60 @@ error:
     return;
 }
 
+static void _add_mac_cb(struct nl_object *obj, void *arg) {
+    struct nl_callback_data *cb_data = arg;
+    struct rtnl_link *iflink = (struct rtnl_link *)obj;
+    struct netcf *ncf = cb_data->nif->ncf;
+
+    struct nl_addr *addr;
+    char mac_str[64];
+    xmlNodePtr cur;
+    xmlAttrPtr prop = NULL;
+
+    if (cb_data->mac != NULL)
+        return;
+
+    addr = rtnl_link_get_addr(iflink);
+    if ((addr == NULL) || nl_addr_iszero(addr))
+        return;
+
+    nl_addr2str(addr, mac_str, sizeof(mac_str));
+
+    for (cur = cb_data->root->children; cur != NULL; cur = cur->next) {
+        if ((cur->type == XML_ELEMENT_NODE) &&
+            xmlStrEqual(cur->name, BAD_CAST "mac")) {
+            cb_data->mac = cur;
+            break;
+        }
+    }
+
+    if (cb_data->mac == NULL) {
+        /* No mac node exists in the document, create a new one.
+         */
+        cb_data->mac = xmlNewDocNode(cb_data->doc, NULL, BAD_CAST "mac", NULL);
+        ERR_NOMEM(cb_data->mac == NULL, ncf);
+
+        cur = xmlAddChild(cb_data->root, cb_data->mac);
+        if (cur == NULL) {
+            xmlFreeNode(cb_data->mac);
+            cb_data->mac = NULL;
+            report_error(ncf, NETCF_ENOMEM, NULL);
+            goto error;
+        }
+    }
+
+    prop = xmlSetProp(cb_data->mac, BAD_CAST "address", BAD_CAST mac_str);
+    ERR_NOMEM(prop == NULL, ncf);
+
+error:
+    return;
+}
+
 void add_state_to_xml_doc(struct netcf_if *nif, xmlDocPtr doc) {
 
-    struct nl_callback_data cb_data = { doc, NULL, NULL, NULL, nif };
+    struct nl_callback_data cb_data = { doc, NULL, NULL, NULL, NULL, nif };
     struct rtnl_addr *filter_addr = NULL;
+    struct rtnl_link *filter_link = NULL;
     int ifindex, code;
 
     cb_data.root = xmlDocGetRootElement(doc);
@@ -735,6 +786,18 @@ void add_state_to_xml_doc(struct netcf_if *nif, xmlDocPtr doc) {
     ERR_THROW((ifindex == RTNL_LINK_NOT_FOUND), nif->ncf, ENETLINK,
               "Could find ifindex for interface `%s`", nif->name);
 
+    /* Build an rtnl_link with the interface index set, and use it to
+     * find the entry for this interface and extract the mac
+     * address.
+     */
+    filter_link = rtnl_link_alloc();
+    ERR_NOMEM((filter_link == NULL), nif->ncf);
+
+    rtnl_link_set_ifindex(filter_link, ifindex);
+    nl_cache_foreach_filter(nif->ncf->driver->link_cache,
+                            OBJ_CAST(filter_link), _add_mac_cb,
+                            &cb_data);
+
     /* Build an rtnl_addr with the interface name set. This is used by
      * the iterator to filter the contents of the address cache.
      */
@@ -749,6 +812,8 @@ void add_state_to_xml_doc(struct netcf_if *nif, xmlDocPtr doc) {
 error:
     if (filter_addr)
         rtnl_addr_put(filter_addr);
+    if (filter_link)
+        rtnl_link_put(filter_link);
     return;
 }
 
-- 
1.6.5.15.gc274d



More information about the netcf-devel mailing list