[netcf-devel] [PATCH] Add required vlan properties to live xml - THIS PATCH IS DEPRECATED!

Laine Stump laine at laine.org
Mon Nov 2 04:39:36 UTC 2009


Please don't apply this patch! I have seriously reorganized, along with 
adding reporting of bridge and bond interface details, and will be 
posting a new patch soon.

On 10/29/2009 02:26 AM, Laine Stump wrote:
> Grab the vlan id and master interface name during the libnl "link"
> cache traversal callback, and add it to the xml for vlans.
>
> This is necessary for the xml to pass libvirt's parsing.
> ---
>   src/dutil.c |  127 +++++++++++++++++++++++++++++++++++++++++++++-------------
>   1 files changed, 98 insertions(+), 29 deletions(-)
>
> diff --git a/src/dutil.c b/src/dutil.c
> index d4eea90..93bb597 100644
> --- a/src/dutil.c
> +++ b/src/dutil.c
> @@ -50,6 +50,9 @@
>   #include<netlink/cache.h>
>   #include<netlink/route/addr.h>
>   #include<netlink/route/link.h>
> +/* For some reason, the headers for libnl vlan functions aren't installed */
> +extern int rtnl_link_vlan_get_id(struct rtnl_link *link);
> +
>
>   #include<libxml/parser.h>
>   #include<libxml/relaxng.h>
> @@ -611,6 +614,7 @@ struct nl_callback_data {
>       xmlNodePtr protov4;
>       xmlNodePtr protov6;
>       xmlNodePtr mac;
> +    xmlNodePtr vlan;
>       struct netcf_if *nif;
>   };
>
> @@ -709,58 +713,123 @@ error:
>       return;
>   }
>
> -static void add_mac_cb(struct nl_object *obj, void *arg) {
> +static void add_link_info_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];
> +    char *link_type;
>       xmlNodePtr cur;
>       xmlAttrPtr prop = NULL;
>
> -    if (cb_data->mac != NULL)
> -        return;
> +    /* look for mac address */
> +    if ((cb_data->mac == NULL)
> +&&  ((addr = rtnl_link_get_addr(iflink)) != NULL)
> +&&  !nl_addr_iszero(addr)) {
>
> -    addr = rtnl_link_get_addr(iflink);
> -    if ((addr == NULL) || nl_addr_iszero(addr))
> -        return;
> +        char mac_str[64];
>
> -    nl_addr2str(addr, mac_str, sizeof(mac_str));
> +        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;
> +            }
> +        }
>
> -    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);
>       }
>
> -    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);
> +    /* If this is a vlan link, get the master interface and vlan id.
> +     */
> +    if ((cb_data->vlan == NULL)
> +&&  ((link_type = rtnl_link_get_info_type(iflink)) != NULL)
> +&&  STREQ(link_type, "vlan")) {
> +
> +        struct rtnl_link *master_link;
> +        char *master_name = NULL;
> +        int vlan_id = rtnl_link_vlan_get_id(iflink);
> +        int l_link = rtnl_link_get_link(iflink);
> +
> +        if ((l_link != RTNL_LINK_NOT_FOUND)
> +&&  ((master_link = rtnl_link_get(nl_object_get_cache(obj),
> +                                             l_link)) != NULL)
> +&&  ((master_name = rtnl_link_get_name(master_link)) != NULL)) {
> +
> +            char vlan_id_str[16];
> +            xmlNodePtr master;
> +
> +            for (cur = cb_data->root->children; cur != NULL; cur = cur->next) {
> +                if ((cur->type == XML_ELEMENT_NODE)&&
> +                    xmlStrEqual(cur->name, BAD_CAST "vlan")) {
> +                    cb_data->vlan = cur;
> +                    break;
> +                }
> +            }
>
> -        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;
> +            if (cb_data->vlan == NULL) {
> +                /* No vlan node exists in the document, create a new one.
> +                 */
> +                cb_data->vlan = xmlNewDocNode(cb_data->doc, NULL,
> +                                              BAD_CAST "vlan", NULL);
> +                ERR_NOMEM(cb_data->vlan == NULL, ncf);
> +
> +                cur = xmlAddChild(cb_data->root, cb_data->vlan);
> +                if (cur == NULL) {
> +                    xmlFreeNode(cb_data->vlan);
> +                    cb_data->vlan = NULL;
> +                    report_error(ncf, NETCF_ENOMEM, NULL);
> +                    goto error;
> +                }
> +            }
> +
> +            snprintf(vlan_id_str, sizeof(vlan_id_str), "%d", vlan_id);
> +            prop = xmlSetProp(cb_data->vlan, BAD_CAST "tag",
> +                              BAD_CAST vlan_id_str);
> +            ERR_NOMEM(prop == NULL, ncf);
> +
> +            master = xmlNewDocNode(cb_data->doc, NULL,
> +                                   BAD_CAST "interface", NULL);
> +            ERR_NOMEM(master == NULL, ncf);
> +            cur = xmlAddChild(cb_data->vlan, master);
> +            if (cur == NULL) {
> +                xmlFreeNode(master);
> +                report_error(ncf, NETCF_ENOMEM, NULL);
> +                goto error;
> +            }
> +            prop = xmlSetProp(master, BAD_CAST "name", BAD_CAST master_name);
> +            ERR_NOMEM(prop == NULL, ncf);
>           }
>       }
>
> -    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, NULL, nif };
> +    struct nl_callback_data cb_data
> +        = { doc, NULL, NULL, NULL, NULL, NULL, nif };
>       struct rtnl_addr *filter_addr = NULL;
>       struct rtnl_link *filter_link = NULL;
>       int ifindex, code;
> @@ -795,7 +864,7 @@ void add_state_to_xml_doc(struct netcf_if *nif, xmlDocPtr doc) {
>
>       rtnl_link_set_ifindex(filter_link, ifindex);
>       nl_cache_foreach_filter(nif->ncf->driver->link_cache,
> -                            OBJ_CAST(filter_link), add_mac_cb,
> +                            OBJ_CAST(filter_link), add_link_info_cb,
>                               &cb_data);
>
>       /* Build an rtnl_addr with the interface name set. This is used by
>    



More information about the netcf-devel mailing list