blob: 2ac364ff5f43e0f063c36e3e055456c6675afa66 [file] [log] [blame]
Chirantan Ekbotead25b652017-12-11 18:37:09 -08001// Copyright 2017 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Garrick Evans3388a032020-03-24 11:25:55 +09005#ifndef PATCHPANEL_MAC_ADDRESS_GENERATOR_H_
6#define PATCHPANEL_MAC_ADDRESS_GENERATOR_H_
Chirantan Ekbotead25b652017-12-11 18:37:09 -08007
8#include <stdint.h>
9
10#include <array>
11#include <functional>
12#include <unordered_set>
13
14#include <base/macros.h>
Garrick Evans4b66f632019-01-24 15:09:16 +090015#include <brillo/brillo_export.h>
Chirantan Ekbotead25b652017-12-11 18:37:09 -080016
Garrick Evans3388a032020-03-24 11:25:55 +090017namespace patchpanel {
Chirantan Ekbotead25b652017-12-11 18:37:09 -080018
19using MacAddress = std::array<uint8_t, 6>;
20
21// Generates locally managed EUI-48 MAC addresses and ensures no collisions
22// with any previously generated addresses by this instance.
Garrick Evans4b66f632019-01-24 15:09:16 +090023class BRILLO_EXPORT MacAddressGenerator {
Chirantan Ekbotead25b652017-12-11 18:37:09 -080024 public:
25 MacAddressGenerator() = default;
Qijiang Fan6bc59e12020-11-11 02:51:06 +090026 MacAddressGenerator(const MacAddressGenerator&) = delete;
27 MacAddressGenerator& operator=(const MacAddressGenerator&) = delete;
28
Chirantan Ekbotead25b652017-12-11 18:37:09 -080029 ~MacAddressGenerator() = default;
30
31 // Generates a new EUI-48 MAC address and ensures that there are no
32 // collisions with any addresses previously generated by this instance of
33 // the generator.
34 MacAddress Generate();
35
Garrick Evans2013a792020-04-02 11:27:57 +090036 // Returns a stable MAC address whose first 5 octets are fixed and using |id|
37 // as the sixth. The base address is itself random and was not generated from
38 // any particular device, physical or virtual. Additionally, the |id| should
39 // associated with any specific device either, and should be set indepedently.
40 MacAddress GetStable(uint8_t id) const;
41
Chirantan Ekbotead25b652017-12-11 18:37:09 -080042 private:
43 // The standard library sadly does not provide a hash function for std::array.
44 // So implement one here for MacAddress based off boost::hash_combine.
45 struct MacAddressHasher {
46 size_t operator()(const MacAddress& addr) const noexcept {
47 std::hash<uint8_t> hasher;
48
49 size_t hash = 0;
50 for (uint8_t octet : addr) {
51 hash ^= hasher(octet) + 0x9e3779b9 + (hash << 6) + (hash >> 2);
52 }
53
54 return hash;
55 }
56 };
57
58 // Set of all addresses generated by this instance. This doesn't _need_ to be
59 // an unordered_set but making it one improves the performance of the
60 // "Duplicates" unit test by ~33% (~150 seconds -> ~100 seconds) and it
61 // doesn't have a huge impact in production use so that's why we use it here.
62 std::unordered_set<MacAddress, MacAddressHasher> addrs_;
Chirantan Ekbotead25b652017-12-11 18:37:09 -080063};
64
Garrick Evans3388a032020-03-24 11:25:55 +090065} // namespace patchpanel
Chirantan Ekbotead25b652017-12-11 18:37:09 -080066
Garrick Evans3388a032020-03-24 11:25:55 +090067#endif // PATCHPANEL_MAC_ADDRESS_GENERATOR_H_