summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Modify-Get-Lan-Configuration-IP-Address-Source-to-us.patch
blob: 7e3f92dbc735b064eff420dd6a481f0bbab96525 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
From 8e9fba263179ccc87be7212c7dbd87cd7a37ac30 Mon Sep 17 00:00:00 2001
From: Johnathan Mantey <johnathanx.mantey@intel.com>
Date: Thu, 14 Nov 2019 11:24:19 -0800
Subject: [PATCH] Modify Get Lan Configuration IP Address Source to use correct
 DBus DHCPEnabled type

The Get/Set Lan Configuration "IP Address Source" subcommand got
broken by phosphor-dbus-interfaces commit 12162be

12162be changed the DBus DHCPEnabled type from boolean to enum
type. The Get LAN Configuration IP address Source IPMI command did not
get changed to an enum type prior to 12162be being merged. This commit
retroactively updates the boolean type to enum type.

Tested:

ipmitool raw 0xc 2 3 4 0 0  # returns correct state
ipmitool raw 0xc 1 3 4 1    # changes DCHP to Static
ipmitool raw 0xc 1 3 4 2    # returns Static to DHCP

Assigned a static address via Redfish and tested using:
ipmitool raw 0xc 2 3 4 0 0  # returns correct state

Returned the NIC to use DHCP via Redfish and tested using:
ipmitool raw 0xc 2 3 4 0 0  # returns correct state

Change-Id: Ia66f7fcf3d5ad0a383b06658b18e8ce2b282e052
Signed-off-by: Johnathan Mantey <johnathanx.mantey@intel.com>
---
 transporthandler.cpp | 97 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 79 insertions(+), 18 deletions(-)

diff --git a/transporthandler.cpp b/transporthandler.cpp
index 16ce2b2..ccc2a97 100644
--- a/transporthandler.cpp
+++ b/transporthandler.cpp
@@ -109,6 +109,18 @@ constexpr auto INTF_NEIGHBOR_CREATE_STATIC =
 constexpr auto INTF_VLAN = "xyz.openbmc_project.Network.VLAN";
 constexpr auto INTF_VLAN_CREATE = "xyz.openbmc_project.Network.VLAN.Create";
 
+static constexpr auto dhcpv4v6 =
+    "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.both";
+static constexpr auto dhcpv6 =
+    "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v6";
+static constexpr auto dhcpv4 =
+    "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.v4";
+static constexpr auto dhcpoff =
+    "xyz.openbmc_project.Network.EthernetInterface.DHCPConf.none";
+
+static std::array<const char*, 4> dhcpEnumerations = {dhcpv4v6, dhcpv4, dhcpv6,
+                                                      dhcpoff};
+
 /** @brief Generic paramters for different address families */
 template <int family>
 struct AddrFamily
@@ -456,25 +468,63 @@ auto channelCall(uint8_t channel, Args&&... args)
  *
  *  @param[in] bus    - The bus object used for lookups
  *  @param[in] params - The parameters for the channel
- *  @return True if DHCP is enabled, false otherwise
+ *  @return string containing an enumerated value
+ *          constexpr's dhcpv4v6, dhcpv4, dhcpv6, and dhcpoff
  */
-bool getDHCPProperty(sdbusplus::bus::bus& bus, const ChannelParams& params)
+std::string getDHCPProperty(sdbusplus::bus::bus& bus,
+                            const ChannelParams& params)
 {
-    return std::get<bool>(getDbusProperty(
+    return std::get<std::string>(getDbusProperty(
         bus, params.service, params.logicalPath, INTF_ETHERNET, "DHCPEnabled"));
 }
 
 /** @brief Sets the system value for DHCP on the given interface
  *
- *  @param[in] bus    - The bus object used for lookups
- *  @param[in] params - The parameters for the channel
- *  @param[in] on     - Whether or not to enable DHCP
+ *  @param[in] bus     - The bus object used for lookups
+ *  @param[in] params  - The parameters for the channel
+ *  @param[in] setting - DHCP state to assign (none, v4, v6, both)
  */
 void setDHCPProperty(sdbusplus::bus::bus& bus, const ChannelParams& params,
-                     bool on)
+                     const std::string& setting)
 {
+    auto it = dhcpEnumerations.begin();
+    while (it != dhcpEnumerations.end())
+    {
+        if (*it == setting)
+        {
+            break;
+        }
+        it++;
+    }
+    if (it == dhcpEnumerations.end())
+    {
+        log<level::ERR>("Invalid DHCP setting.",
+                        entry("Requested DHCP mode=%s", setting.c_str()));
+        elog<InternalFailure>();
+    }
+
+    std::string dhcp = getDHCPProperty(bus, params);
+    std::string nextDhcp{};
+
+    if (((dhcp == dhcpv4) && (setting == dhcpv6)) ||
+        ((dhcp == dhcpv6) && (setting == dhcpv4)))
+    {
+        // DHCP is enabled independently for IPv4 and IPv6. If IPv4
+        // DHCP is enabled, and a request to add IPv6 is received,
+        // change the DHCPEnabled enum to "both" active. The same
+        // logic is applied if IPV6 is already enabled, and an IPv4
+        // enable request is made.
+        nextDhcp = dhcpv4v6;
+    }
+    else
+    {
+        // "both" enabled -> ipv4 only
+        // "both" enabled -> ipv6 only
+        // "ip4v", "ipv6", or "both" enabled -> no DHCP
+        nextDhcp = setting;
+    }
     setDbusProperty(bus, params.service, params.logicalPath, INTF_ETHERNET,
-                    "DHCPEnabled", on);
+                    "DHCPEnabled", nextDhcp);
 }
 
 /** @brief Converts a human readable MAC string into MAC bytes
@@ -1113,7 +1163,7 @@ void deconfigureChannel(sdbusplus::bus::bus& bus, ChannelParams& params)
     }
 
     // Clear out any settings on the lower physical interface
-    setDHCPProperty(bus, params, false);
+    setDHCPProperty(bus, params, dhcpoff);
 }
 
 /** @brief Creates a new VLAN on the specified interface
@@ -1401,7 +1451,8 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter,
         }
         case LanParam::IP:
         {
-            if (channelCall<getDHCPProperty>(channel))
+            std::string dhcpSetting = channelCall<getDHCPProperty>(channel);
+            if ((dhcpSetting == dhcpv4) || (dhcpSetting == dhcpv4v6))
             {
                 return responseCommandNotAvailable();
             }
@@ -1431,7 +1482,11 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter,
             {
                 case IPSrc::DHCP:
                 {
-                    channelCall<setDHCPProperty>(channel, true);
+                    // The IPSrc IPMI command is only for IPv4
+                    // management. Modifying IPv6 state is done using
+                    // a completely different Set LAN Configuration
+                    // subcommand.
+                    channelCall<setDHCPProperty>(channel, dhcpv4);
                     return responseSuccess();
                 }
                 case IPSrc::Unspecified:
@@ -1439,7 +1494,7 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter,
                 case IPSrc::BIOS:
                 case IPSrc::BMC:
                 {
-                    channelCall<setDHCPProperty>(channel, false);
+                    channelCall<setDHCPProperty>(channel, dhcpoff);
                     return responseSuccess();
                 }
             }
@@ -1464,7 +1519,8 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter,
         }
         case LanParam::SubnetMask:
         {
-            if (channelCall<getDHCPProperty>(channel))
+            std::string dhcpSetting = channelCall<getDHCPProperty>(channel);
+            if ((dhcpSetting == dhcpv4) || (dhcpSetting == dhcpv4v6))
             {
                 return responseCommandNotAvailable();
             }
@@ -1481,7 +1537,8 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter,
         }
         case LanParam::Gateway1:
         {
-            if (channelCall<getDHCPProperty>(channel))
+            std::string dhcpSetting = channelCall<getDHCPProperty>(channel);
+            if ((dhcpSetting == dhcpv4) || (dhcpSetting == dhcpv4v6))
             {
                 return responseCommandNotAvailable();
             }
@@ -1606,7 +1663,8 @@ RspType<> setLan(uint4_t channelBits, uint4_t, uint8_t parameter,
                 return responseReqDataLenInvalid();
             }
             std::bitset<8> expected;
-            if (channelCall<getDHCPProperty>(channel))
+            std::string dhcp = channelCall<getDHCPProperty>(channel);
+            if ((dhcp == dhcpv4v6) || (dhcp == dhcpv6))
             {
                 expected[IPv6RouterControlFlag::Dynamic] = 1;
             }
@@ -1756,7 +1814,8 @@ RspType<message::Payload> getLan(uint4_t channelBits, uint3_t, bool revOnly,
         case LanParam::IPSrc:
         {
             auto src = IPSrc::Static;
-            if (channelCall<getDHCPProperty>(channel))
+            std::string dhcp = channelCall<getDHCPProperty>(channel);
+            if ((dhcp == dhcpv4) || (dhcp == dhcpv4v6))
             {
                 src = IPSrc::DHCP;
             }
@@ -1877,7 +1936,8 @@ RspType<message::Payload> getLan(uint4_t channelBits, uint3_t, bool revOnly,
         case LanParam::IPv6RouterControl:
         {
             std::bitset<8> control;
-            if (channelCall<getDHCPProperty>(channel))
+            std::string dhcp = channelCall<getDHCPProperty>(channel);
+            if ((dhcp == dhcpv4v6) || (dhcp == dhcpv6))
             {
                 control[IPv6RouterControlFlag::Dynamic] = 1;
             }
@@ -1891,7 +1951,8 @@ RspType<message::Payload> getLan(uint4_t channelBits, uint3_t, bool revOnly,
         case LanParam::IPv6StaticRouter1IP:
         {
             in6_addr gateway{};
-            if (!channelCall<getDHCPProperty>(channel))
+            std::string dhcp = channelCall<getDHCPProperty>(channel);
+            if ((dhcp == dhcpv4) || (dhcp == dhcpoff))
             {
                 gateway =
                     channelCall<getGatewayProperty<AF_INET6>>(channel).value_or(
-- 
2.24.1