9c6c51
From 46d50fe9ca30e8377995fea2b7d59239b46a0cfa Mon Sep 17 00:00:00 2001
9c6c51
Message-Id: <46d50fe9ca30e8377995fea2b7d59239b46a0cfa@dist-git>
9c6c51
From: Laine Stump <laine@laine.org>
9c6c51
Date: Mon, 14 Jan 2019 11:35:04 -0500
9c6c51
Subject: [PATCH] util: use nlmsg_find_attr() instead of an open-coded loop
9c6c51
9c6c51
This is about the same number of code lines, but is simpler, and more
9c6c51
consistent with what will be added to check another attribute in a
9c6c51
coming patch.
9c6c51
9c6c51
As a side effect, it
9c6c51
9c6c51
Resolves: https://bugzilla.redhat.com/1583131
9c6c51
9c6c51
Signed-off-by: Laine Stump <laine@laine.org>
9c6c51
Reviewed-by: Erik Skultety <eskultet@redhat.com>
9c6c51
(cherry picked from commit 7282f455aaaa8bf2f73236aa9ec6b65b33c0fcdb)
9c6c51
9c6c51
Conflicts: src/util/virnetdevip.c -  more blowback from the addition of VIR_AUTOPTR
9c6c51
                             upstream.
9c6c51
Signed-off-by: Laine Stump <laine@laine.org>
9c6c51
Reviewed-by: Jiri Denemark <jdenemar@redhat.com>
9c6c51
---
9c6c51
 src/util/virnetdevip.c | 52 ++++++++++++++++++------------------------
9c6c51
 1 file changed, 22 insertions(+), 30 deletions(-)
9c6c51
9c6c51
diff --git a/src/util/virnetdevip.c b/src/util/virnetdevip.c
9c6c51
index 937ebcdbdb..d56f4f05f3 100644
9c6c51
--- a/src/util/virnetdevip.c
9c6c51
+++ b/src/util/virnetdevip.c
9c6c51
@@ -564,50 +564,42 @@ virNetDevIPCheckIPv6ForwardingCallback(struct nlmsghdr *resp,
9c6c51
 {
9c6c51
     struct rtmsg *rtmsg = NLMSG_DATA(resp);
9c6c51
     int accept_ra = -1;
9c6c51
-    struct rtattr *rta;
9c6c51
+    struct rtattr *rta_attr;
9c6c51
     char *ifname = NULL;
9c6c51
+    int ifindex = -1;
9c6c51
     struct virNetDevIPCheckIPv6ForwardingData *data = opaque;
9c6c51
     int ret = 0;
9c6c51
-    int len = RTM_PAYLOAD(resp);
9c6c51
-    int oif = -1;
9c6c51
 
9c6c51
     /* Ignore messages other than route ones */
9c6c51
     if (resp->nlmsg_type != RTM_NEWROUTE)
9c6c51
         return ret;
9c6c51
 
9c6c51
-    /* Extract a device ID attribute */
9c6c51
-    VIR_WARNINGS_NO_CAST_ALIGN
9c6c51
-    for (rta = RTM_RTA(rtmsg); RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) {
9c6c51
-        VIR_WARNINGS_RESET
9c6c51
-        if (rta->rta_type == RTA_OIF) {
9c6c51
-            oif = *(int *)RTA_DATA(rta);
9c6c51
-
9c6c51
-            /* Should never happen: netlink message would be broken */
9c6c51
-            if (ifname) {
9c6c51
-                char *ifname2 = virNetDevGetName(oif);
9c6c51
-                VIR_WARN("Single route has unexpected 2nd interface "
9c6c51
-                         "- '%s' and '%s'", ifname, ifname2);
9c6c51
-                VIR_FREE(ifname2);
9c6c51
-                break;
9c6c51
-            }
9c6c51
-
9c6c51
-            if (!(ifname = virNetDevGetName(oif)))
9c6c51
-                goto error;
9c6c51
-        }
9c6c51
-    }
9c6c51
-
9c6c51
     /* No need to do anything else for non RA routes */
9c6c51
     if (rtmsg->rtm_protocol != RTPROT_RA)
9c6c51
         goto cleanup;
9c6c51
 
9c6c51
-    data->hasRARoutes = true;
9c6c51
+    rta_attr = (struct rtattr *)nlmsg_find_attr(resp, sizeof(struct rtmsg), RTA_OIF);
9c6c51
+    if (rta_attr) {
9c6c51
+        /* This is a single path route, with interface used to reach
9c6c51
+         * nexthop in the RTA_OIF attribute.
9c6c51
+         */
9c6c51
+        ifindex = *(int *)RTA_DATA(rta_attr);
9c6c51
+        ifname = virNetDevGetName(ifindex);
9c6c51
 
9c6c51
-    /* Check the accept_ra value for the interface */
9c6c51
-    accept_ra = virNetDevIPGetAcceptRA(ifname);
9c6c51
-    VIR_DEBUG("Checking route for device %s, accept_ra: %d", ifname, accept_ra);
9c6c51
+        if (!ifname)
9c6c51
+            goto error;
9c6c51
 
9c6c51
-    if (accept_ra != 2 && virNetDevIPCheckIPv6ForwardingAddIF(data, &ifname) < 0)
9c6c51
-        goto error;
9c6c51
+        accept_ra = virNetDevIPGetAcceptRA(ifname);
9c6c51
+
9c6c51
+        VIR_DEBUG("Checking route for device %s (%d), accept_ra: %d",
9c6c51
+                  ifname, ifindex, accept_ra);
9c6c51
+
9c6c51
+        if (accept_ra != 2 && virNetDevIPCheckIPv6ForwardingAddIF(data, &ifname) < 0)
9c6c51
+            goto error;
9c6c51
+
9c6c51
+        data->hasRARoutes = true;
9c6c51
+        goto cleanup;
9c6c51
+    }
9c6c51
 
9c6c51
  cleanup:
9c6c51
     VIR_FREE(ifname);
9c6c51
-- 
9c6c51
2.20.1
9c6c51