arc: Move platform2/arc/network/ to platform2/patchpanel
Next step in the arc-networkd -> patchpanel rename, this patch moves the
location of the code.
BUG=b:151879931
TEST=units,flashed image to atlas
TEST=tasts arc.PlayStore, crostini.LaunchTerminal.download
Change-Id: I1b5cf8d670e1631d46f6449b725395157bf88dde
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/2115863
Tested-by: Garrick Evans <garrick@chromium.org>
Commit-Queue: Garrick Evans <garrick@chromium.org>
Reviewed-by: Hidehiko Abe <hidehiko@chromium.org>
Reviewed-by: Eric Caruso <ejcaruso@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
Reviewed-by: Hugo Benichi <hugobenichi@google.com>
diff --git a/patchpanel/subnet.cc b/patchpanel/subnet.cc
new file mode 100644
index 0000000..8fa6f4b
--- /dev/null
+++ b/patchpanel/subnet.cc
@@ -0,0 +1,144 @@
+// Copyright 2018 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "patchpanel/subnet.h"
+
+#include <arpa/inet.h>
+
+#include <string>
+#include <utility>
+
+#include <base/bind.h>
+#include <base/logging.h>
+
+#include "patchpanel/net_util.h"
+
+namespace {
+// Returns the offset from the base address given in network-byte order for
+// the address given in network-byte order, or 0 if the second address is
+// lower than the base address. Returns the offset in host-byte order.
+uint32_t OffsetFromBaseAddress(uint32_t base_no, uint32_t addr_no) {
+ if (ntohl(addr_no) < ntohl(base_no))
+ return 0;
+ return ntohl(addr_no) - ntohl(base_no);
+}
+// Adds a positive offset given in host order to the address given in
+// network byte order. Returns the address in network-byte order.
+uint32_t AddOffset(uint32_t addr_no, uint32_t offset_ho) {
+ return htonl(ntohl(addr_no) + offset_ho);
+}
+} // namespace
+
+namespace patchpanel {
+
+SubnetAddress::SubnetAddress(uint32_t addr,
+ uint32_t prefix_length,
+ base::Closure release_cb)
+ : addr_(addr),
+ prefix_length_(prefix_length),
+ release_cb_(std::move(release_cb)) {}
+
+SubnetAddress::~SubnetAddress() {
+ release_cb_.Run();
+}
+
+uint32_t SubnetAddress::Address() const {
+ return addr_;
+}
+
+std::string SubnetAddress::ToCidrString() const {
+ return IPv4AddressToCidrString(addr_, prefix_length_);
+}
+
+std::string SubnetAddress::ToIPv4String() const {
+ return IPv4AddressToString(addr_);
+}
+
+uint32_t SubnetAddress::Netmask() const {
+ return Ipv4Netmask(prefix_length_);
+}
+
+Subnet::Subnet(uint32_t base_addr,
+ uint32_t prefix_length,
+ base::Closure release_cb)
+ : base_addr_(base_addr),
+ prefix_length_(prefix_length),
+ release_cb_(std::move(release_cb)),
+ weak_factory_(this) {
+ CHECK_LT(prefix_length, 32);
+
+ addrs_.resize(1ull << (32 - prefix_length), false);
+
+ // Mark the base address and broadcast address as allocated.
+ addrs_.front() = true;
+ addrs_.back() = true;
+}
+
+Subnet::~Subnet() {
+ release_cb_.Run();
+}
+
+std::unique_ptr<SubnetAddress> Subnet::Allocate(uint32_t addr) {
+ return AllocateAtOffset(OffsetFromBaseAddress(base_addr_, addr) - 1);
+}
+
+std::unique_ptr<SubnetAddress> Subnet::AllocateAtOffset(uint32_t offset) {
+ uint32_t addr = AddressAtOffset(offset);
+ if (addr == INADDR_ANY) {
+ return nullptr;
+ }
+
+ if (addrs_[offset + 1]) {
+ // Address is already allocated.
+ return nullptr;
+ }
+
+ addrs_[offset + 1] = true;
+ return std::make_unique<SubnetAddress>(
+ addr, prefix_length_,
+ base::Bind(&Subnet::Free, weak_factory_.GetWeakPtr(), offset + 1));
+}
+
+uint32_t Subnet::AddressAtOffset(uint32_t offset) const {
+ if (offset < 0 || offset >= AvailableCount())
+ return INADDR_ANY;
+
+ // The first usable IP is after the base address.
+ return AddOffset(base_addr_, 1 + offset);
+}
+
+uint32_t Subnet::AvailableCount() const {
+ // The available IP count is all IPs in a subnet, minus the network ID
+ // and the broadcast address.
+ return addrs_.size() - 2;
+}
+
+uint32_t Subnet::BaseAddress() const {
+ return base_addr_;
+}
+
+uint32_t Subnet::Netmask() const {
+ return Ipv4Netmask(prefix_length_);
+}
+
+uint32_t Subnet::Prefix() const {
+ return base_addr_ & Netmask();
+}
+
+uint32_t Subnet::PrefixLength() const {
+ return prefix_length_;
+}
+
+std::string Subnet::ToCidrString() const {
+ return IPv4AddressToCidrString(base_addr_, prefix_length_);
+}
+
+void Subnet::Free(uint32_t offset) {
+ DCHECK_NE(offset, 0);
+ DCHECK_LT(offset, addrs_.size() - 1);
+
+ addrs_[offset] = false;
+}
+
+} // namespace patchpanel