17
17
18
18
using namespace isc ::asiolink;
19
19
using namespace isc ::util;
20
+ using namespace isc ::dhcp;
21
+
22
+ namespace {
23
+
24
+ static HWAddr zero_ib_hwaddr (&std::vector<uint8_t >(HWAddr::INFINIBAND_HWADDR_LEN)[0],
25
+ HWAddr::INFINIBAND_HWADDR_LEN, HTYPE_INFINIBAND);
26
+
27
+ }
20
28
21
29
namespace isc {
22
30
namespace dhcp {
@@ -204,8 +212,15 @@ writeIPoIBHeader(const Iface& iface, const Pkt4Ptr& pkt, OutputBuffer& out_buf)
204
212
<< remote_addr->hwaddr_ .size () << " when constructing"
205
213
<< " an ethernet frame header; expected size is"
206
214
<< " " << HWAddr::INFINIBAND_HWADDR_LEN);
207
- } else if (!pkt->isRelayed () &&
208
- (pkt->getFlags () & Pkt4::FLAG_BROADCAST_MASK)) {
215
+ } else if ((!pkt->isRelayed () &&
216
+ (pkt->getFlags () & Pkt4::FLAG_BROADCAST_MASK)) ||
217
+ *remote_addr == zero_ib_hwaddr) {
218
+ // We also broadcast if the received hwaddr is full zero.
219
+ // This happens on some IB drivers which don't provide the remote
220
+ // hwaddr to userspace.
221
+ // Generally, according to the RFC, all IPoIB clients MUST request
222
+ // broadcast anyway, but better to be safe and handle non-compliant
223
+ // clients.
209
224
if (iface.getBcastMacLen () != HWAddr::INFINIBAND_HWADDR_LEN) {
210
225
isc_throw (BadValue, " invalid size of the bcast HW address "
211
226
<< iface.getBcastMacLen () << " when constructing"
@@ -223,8 +238,7 @@ writeIPoIBHeader(const Iface& iface, const Pkt4Ptr& pkt, OutputBuffer& out_buf)
223
238
// packet through a logical interface (e.g. lo). In such cases, we
224
239
// don't want to fail but rather provide a default HW address, which
225
240
// consists of zeros.
226
- out_buf.writeData (&std::vector<uint8_t >(HWAddr::INFINIBAND_HWADDR_LEN)[0 ],
227
- HWAddr::INFINIBAND_HWADDR_LEN);
241
+ out_buf.writeData (&zero_ib_hwaddr.hwaddr_ [0 ], HWAddr::INFINIBAND_HWADDR_LEN);
228
242
}
229
243
230
244
// Type IP.
0 commit comments