1717
1818using namespace isc ::asiolink;
1919using 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+ }
2028
2129namespace isc {
2230namespace dhcp {
@@ -204,8 +212,15 @@ writeIPoIBHeader(const Iface& iface, const Pkt4Ptr& pkt, OutputBuffer& out_buf)
204212 << remote_addr->hwaddr_ .size () << " when constructing"
205213 << " an ethernet frame header; expected size is"
206214 << " " << 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.
209224 if (iface.getBcastMacLen () != HWAddr::INFINIBAND_HWADDR_LEN) {
210225 isc_throw (BadValue, " invalid size of the bcast HW address "
211226 << iface.getBcastMacLen () << " when constructing"
@@ -223,8 +238,7 @@ writeIPoIBHeader(const Iface& iface, const Pkt4Ptr& pkt, OutputBuffer& out_buf)
223238 // packet through a logical interface (e.g. lo). In such cases, we
224239 // don't want to fail but rather provide a default HW address, which
225240 // 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);
228242 }
229243
230244 // Type IP.
0 commit comments