1 /*
2  * Copyright 2021 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include "platforms/nemora/portable/net_types.h"
20 
21 #include <net_iface.h>
22 
23 #include <sdbusplus/bus.hpp>
24 
25 #include <experimental/optional>
26 #include <list>
27 #include <map>
28 #include <optional>
29 #include <string>
30 #include <vector>
31 
32 // The API for configuring and querying network.
33 
34 namespace net
35 {
36 
37 using DBusObjectPath = std::string;
38 using DBusService = std::string;
39 using DBusInterface = std::string;
40 using ObjectTree =
41     std::map<DBusObjectPath, std::map<DBusService, std::vector<DBusInterface>>>;
42 
43 class ConfigBase
44 {
45   public:
46     virtual ~ConfigBase() = default;
47 
48     virtual int get_mac_addr(mac_addr_t* mac) = 0;
49 
50     virtual int set_mac_addr(const mac_addr_t& mac) = 0;
51 
52     // Called each time is_nic_hostless state is sampled.
53     virtual int set_nic_hostless(bool is_nic_hostless) = 0;
54 };
55 
56 // Calls Socket Ioctl to obtain information about NIC (previously
57 // phosphor-networkd)
58 class PhosphorConfig : public ConfigBase
59 {
60   public:
61     explicit PhosphorConfig(const std::string& iface_name);
62 
63     // Reads the MAC address from socket interface or internal
64     // cache, and store in the mac pointer.
65     // Returns -1 if failed, 0 if succeeded.
66     int get_mac_addr(mac_addr_t* mac) override;
67 
68     // Sets the MAC address over socket, and update internal
69     // cache.
70     // Returns -1 if failed, 0 if succeeded.
71     int set_mac_addr(const mac_addr_t& mac) override;
72     virtual int set_nic_hostless(bool is_nic_hostless) override;
73 
74   private:
75     sdbusplus::message_t new_networkd_call(sdbusplus::bus_t* dbus,
76                                            bool get = false) const;
77 
78     const std::string iface_name_;
79     const std::string iface_path_;
80 
81     // Stores the currently configured nic state, if previously set
82     std::optional<bool> was_nic_hostless_;
83 
84     // Function helper allows get_mac_addr and set_mac_addr to do
85     // ioctl calls to get and set different states of NIC.
86     void call_nic(auto fd, struct ifreq& ifr, int op);
87 
88     // The MAC address obtained from NIC.
89     // ncsid will commit this MAC address over DBus to phosphor-networkd
90     // and expect it to be persisted. If actual host MAC address changes or
91     // BMC MAC address is overwritten, a daemon reboot is needed to reset
92     // the MAC.
93     //   Initialized to nullopt which evaluates to false. Once a value is
94     // set, bool() evaluates to true.
95     std::experimental::optional<mac_addr_t> shared_host_mac_;
96 
97     // List of outstanding pids for config jobs
98     std::list<pid_t> running_pids_;
99 
100     // Holds a reference to the bus for issuing commands to update network
101     // config
102     sdbusplus::bus_t bus;
103 };
104 
105 } // namespace net
106