[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