]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/libsystemd-network/sd-ipv4ll.c
network: return 1 on start and 0 if ipv4ll is already started
[thirdparty/systemd.git] / src / libsystemd-network / sd-ipv4ll.c
index 5603a533a5e679dc7fd20a3949e66cb98f18f9f1..4f4d9ebe87719add28630b590dcc4057f4d61349 100644 (file)
@@ -1,29 +1,14 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
-  This file is part of systemd.
-
-  Copyright (C) 2014 Axis Communications AB. All rights reserved.
-  Copyright (C) 2015 Tom Gundersen
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+  Copyright © 2014 Axis Communications AB. All rights reserved.
 ***/
 
 #include <arpa/inet.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 
+#include "sd-id128.h"
 #include "sd-ipv4acd.h"
 #include "sd-ipv4ll.h"
 
@@ -64,37 +49,20 @@ struct sd_ipv4ll {
         void* userdata;
 };
 
-#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, __FILE__, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__)
+#define log_ipv4ll_errno(ll, error, fmt, ...) log_internal(LOG_DEBUG, error, PROJECT_FILE, __LINE__, __func__, "IPV4LL: " fmt, ##__VA_ARGS__)
 #define log_ipv4ll(ll, fmt, ...) log_ipv4ll_errno(ll, 0, fmt, ##__VA_ARGS__)
 
 static void ipv4ll_on_acd(sd_ipv4acd *ll, int event, void *userdata);
 
-sd_ipv4ll *sd_ipv4ll_ref(sd_ipv4ll *ll) {
-        if (!ll)
-                return NULL;
-
-        assert(ll->n_ref >= 1);
-        ll->n_ref++;
-
-        return ll;
-}
-
-sd_ipv4ll *sd_ipv4ll_unref(sd_ipv4ll *ll) {
-        if (!ll)
-                return NULL;
-
-        assert(ll->n_ref >= 1);
-        ll->n_ref--;
-
-        if (ll->n_ref > 0)
-                return NULL;
+static sd_ipv4ll *ipv4ll_free(sd_ipv4ll *ll) {
+        assert(ll);
 
         sd_ipv4acd_unref(ll->acd);
-        free(ll);
-
-        return NULL;
+        return mfree(ll);
 }
 
+DEFINE_TRIVIAL_REF_UNREF_FUNC(sd_ipv4ll, sd_ipv4ll, ipv4ll_free);
+
 int sd_ipv4ll_new(sd_ipv4ll **ret) {
         _cleanup_(sd_ipv4ll_unrefp) sd_ipv4ll *ll = NULL;
         int r;
@@ -115,8 +83,7 @@ int sd_ipv4ll_new(sd_ipv4ll **ret) {
         if (r < 0)
                 return r;
 
-        *ret = ll;
-        ll = NULL;
+        *ret = TAKE_PTR(ll);
 
         return 0;
 }
@@ -252,20 +219,19 @@ static int ipv4ll_pick_address(sd_ipv4ll *ll) {
 
 #define MAC_HASH_KEY SD_ID128_MAKE(df,04,22,98,3f,ad,14,52,f9,87,2e,d1,9c,70,e2,f2)
 
-int sd_ipv4ll_start(sd_ipv4ll *ll) {
+static int ipv4ll_start_internal(sd_ipv4ll *ll, bool reset_generation) {
         int r;
         bool picked_address = false;
 
         assert_return(ll, -EINVAL);
         assert_return(!ether_addr_is_null(&ll->mac), -EINVAL);
-        assert_return(sd_ipv4ll_is_running(ll) == 0, -EBUSY);
 
         /* If no random seed is set, generate some from the MAC address */
         if (!ll->seed_set)
                 ll->seed.value = htole64(siphash24(ll->mac.ether_addr_octet, ETH_ALEN, MAC_HASH_KEY.bytes));
 
-        /* Restart the generation counter. */
-        ll->seed.generation = 0;
+        if (reset_generation)
+                ll->seed.generation = 0;
 
         if (ll->address == 0) {
                 r = ipv4ll_pick_address(ll);
@@ -275,7 +241,7 @@ int sd_ipv4ll_start(sd_ipv4ll *ll) {
                 picked_address = true;
         }
 
-        r = sd_ipv4acd_start(ll->acd);
+        r = sd_ipv4acd_start(ll->acd, reset_generation);
         if (r < 0) {
 
                 /* We couldn't start? If so, let's forget the picked address again, the user might make a change and
@@ -286,7 +252,22 @@ int sd_ipv4ll_start(sd_ipv4ll *ll) {
                 return r;
         }
 
-        return 0;
+        return 1;
+}
+
+int sd_ipv4ll_start(sd_ipv4ll *ll) {
+        assert_return(ll, -EINVAL);
+
+        if (sd_ipv4ll_is_running(ll))
+                return 0;
+
+        return ipv4ll_start_internal(ll, true);
+}
+
+int sd_ipv4ll_restart(sd_ipv4ll *ll) {
+        ll->address = 0;
+
+        return ipv4ll_start_internal(ll, false);
 }
 
 static void ipv4ll_client_notify(sd_ipv4ll *ll, int event) {
@@ -324,11 +305,7 @@ void ipv4ll_on_acd(sd_ipv4acd *acd, int event, void *userdata) {
 
                         ll->claimed_address = 0;
                 } else {
-                        r = ipv4ll_pick_address(ll);
-                        if (r < 0)
-                                goto error;
-
-                        r = sd_ipv4acd_start(ll->acd);
+                        r = sd_ipv4ll_restart(ll);
                         if (r < 0)
                                 goto error;
                 }