dhcp-done: Add daemon
Used to communicate with cloud utilities monitoring the netboot status
of the machine. Started once the netboot has completed in order to
provide status.
Change-Id: I6eb8b5a0048e3a9d5d4f56adae42ef5aff2c2bab
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/.gitignore b/.gitignore
index d73d627..fbedebd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
build*/
subprojects/*
!subprojects/acpi-power-state-daemon/
+!subprojects/dhcp-done/
!subprojects/libcr51sign/
!subprojects/metrics-ipmi-blobs/
!subprojects/ncsid/
diff --git a/dhcp-done b/dhcp-done
new file mode 120000
index 0000000..02030d3
--- /dev/null
+++ b/dhcp-done
@@ -0,0 +1 @@
+subprojects/dhcp-done
\ No newline at end of file
diff --git a/subprojects/dhcp-done/dhcp-done.cpp b/subprojects/dhcp-done/dhcp-done.cpp
new file mode 100644
index 0000000..dae06db
--- /dev/null
+++ b/subprojects/dhcp-done/dhcp-done.cpp
@@ -0,0 +1,59 @@
+// Copyright 2022 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <fmt/format.h>
+
+#include <sdeventplus/event.hpp>
+#include <sdeventplus/source/io.hpp>
+#include <stdplus/fd/create.hpp>
+#include <stdplus/fd/ops.hpp>
+
+// A privileged port that is reserved for querying BMC DHCP completion.
+// This is well known by the clients querying the status.
+constexpr uint16_t kListenPort = 23;
+
+stdplus::ManagedFd createListener()
+{
+ using namespace stdplus::fd;
+ auto sock =
+ socket(SocketDomain::INet6, SocketType::Stream, SocketProto::TCP);
+ setFileFlags(sock, getFileFlags(sock).set(stdplus::fd::FileFlag::NonBlock));
+ sockaddr_in6 addr = {};
+ addr.sin6_family = AF_INET6;
+ addr.sin6_port = htons(kListenPort);
+ bind(sock, addr);
+ listen(sock, 10);
+ return sock;
+}
+
+int main()
+{
+ try
+ {
+ auto listener = createListener();
+ auto event = sdeventplus::Event::get_default();
+ sdeventplus::source::IO do_accept(
+ event, listener.get(), EPOLLIN | EPOLLET,
+ [&](sdeventplus::source::IO&, int, uint32_t) {
+ while (stdplus::fd::accept(listener))
+ ;
+ });
+ return event.loop();
+ }
+ catch (const std::exception& e)
+ {
+ fmt::print(stderr, "Failed: {}\n", e.what());
+ return 1;
+ }
+}
diff --git a/subprojects/dhcp-done/dhcp-done.service.in b/subprojects/dhcp-done/dhcp-done.service.in
new file mode 100644
index 0000000..9fa5e24
--- /dev/null
+++ b/subprojects/dhcp-done/dhcp-done.service.in
@@ -0,0 +1,6 @@
+[Unit]
+Description=gBMC DHCP Complete
+
+[Service]
+Restart=on-failure
+ExecStart=@@BIN@ dhcp-done
diff --git a/subprojects/dhcp-done/meson.build b/subprojects/dhcp-done/meson.build
new file mode 100644
index 0000000..a72690b
--- /dev/null
+++ b/subprojects/dhcp-done/meson.build
@@ -0,0 +1,50 @@
+# Copyright 2022 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+project(
+ 'dhcp-done',
+ 'cpp',
+ version: '0.1',
+ meson_version: '>=0.57.0',
+ default_options: [
+ 'warning_level=3',
+ 'werror=true',
+ 'cpp_std=c++20',
+ ],
+)
+
+deps = [
+ dependency('sdeventplus'),
+ dependency('stdplus'),
+]
+
+libexecdir = get_option('prefix') / get_option('libexecdir')
+
+executable(
+ 'dhcp-done',
+ 'dhcp-done.cpp',
+ implicit_include_directories: false,
+ dependencies: deps,
+ install: true,
+ install_dir: libexecdir)
+
+systemd = dependency('systemd')
+systemunitdir = systemd.get_pkgconfig_variable('systemdsystemunitdir')
+
+configure_file(
+ configuration: {'BIN': libexecdir / 'dhcp-done'},
+ input: 'dhcp-done.service.in',
+ output: 'dhcp-done.service',
+ install_mode: 'rw-r--r--',
+ install_dir: systemunitdir)
diff --git a/subprojects/dhcp-done/subprojects b/subprojects/dhcp-done/subprojects
new file mode 120000
index 0000000..a96aa0e
--- /dev/null
+++ b/subprojects/dhcp-done/subprojects
@@ -0,0 +1 @@
+..
\ No newline at end of file
diff --git a/subprojects/sdeventplus.wrap b/subprojects/sdeventplus.wrap
new file mode 100644
index 0000000..a506404
--- /dev/null
+++ b/subprojects/sdeventplus.wrap
@@ -0,0 +1,6 @@
+[wrap-git]
+url = https://github.com/openbmc/sdeventplus
+revision = HEAD
+
+[provide]
+sdeventplus = sdeventplus_dep
diff --git a/subprojects/stdplus.wrap b/subprojects/stdplus.wrap
index 00dae65..765ba71 100644
--- a/subprojects/stdplus.wrap
+++ b/subprojects/stdplus.wrap
@@ -1,3 +1,6 @@
[wrap-git]
url = https://github.com/openbmc/stdplus
revision = HEAD
+
+[provide]
+stdplus = stdplus_dep