Skip to content

Commit cb89a04

Browse files
committed
Add L2 bcast addr to Iface
1 parent 42bd2b5 commit cb89a04

File tree

6 files changed

+139
-4
lines changed

6 files changed

+139
-4
lines changed

src/lib/dhcp/dhcp4.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ enum HType {
6060
/// arp-parameters/arp-parameters.xhtml suggest that
6161
/// Ethernet (1) should be used in DOCSIS environment.
6262
HTYPE_IEEE802 = 6, ///< IEEE 802.2 Token Ring
63-
HTYPE_FDDI = 8 ///< FDDI
64-
/// TODO Add infiniband here
63+
HTYPE_FDDI = 8, ///< FDDI
64+
HTYPE_INFINIBAND = 32 ///< InfiniBand
6565
};
6666

6767
/* DHCP Option codes: */

src/lib/dhcp/iface_mgr.cc

+31-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ IfaceMgr::instancePtr() {
6262
}
6363

6464
Iface::Iface(const std::string& name, unsigned int ifindex)
65-
: name_(name), ifindex_(ifindex), mac_len_(0), hardware_type_(0),
65+
: name_(name), ifindex_(ifindex), mac_len_(0), bcast_mac_len_(0), hardware_type_(0),
6666
flag_loopback_(false), flag_up_(false), flag_running_(false),
6767
flag_multicast_(false), flag_broadcast_(false), flags_(0),
6868
inactive4_(false), inactive6_(false) {
@@ -142,6 +142,21 @@ Iface::getPlainMac() const {
142142
return (tmp.str());
143143
}
144144

145+
std::string
146+
Iface::getPlainBcastMac() const {
147+
ostringstream tmp;
148+
tmp.fill('0');
149+
tmp << hex;
150+
for (int i = 0; i < bcast_mac_len_; i++) {
151+
tmp.width(2);
152+
tmp << static_cast<int>(bcast_mac_[i]);
153+
if (i < bcast_mac_len_-1) {
154+
tmp << ":";
155+
}
156+
}
157+
return (tmp.str());
158+
}
159+
145160
void Iface::setMac(const uint8_t* mac, size_t len) {
146161
if (len > MAX_MAC_LEN) {
147162
isc_throw(OutOfRange, "Interface " << getFullName()
@@ -155,6 +170,19 @@ void Iface::setMac(const uint8_t* mac, size_t len) {
155170
}
156171
}
157172

173+
void Iface::setBcastMac(const uint8_t* mac, size_t len) {
174+
if (len > MAX_MAC_LEN) {
175+
isc_throw(OutOfRange, "Interface " << getFullName()
176+
<< " was detected to have link address of length "
177+
<< len << ", but maximum supported length is "
178+
<< MAX_MAC_LEN);
179+
}
180+
bcast_mac_len_ = len;
181+
if (len > 0) {
182+
memcpy(bcast_mac_, mac, len);
183+
}
184+
}
185+
158186
bool Iface::delAddress(const isc::asiolink::IOAddress& addr) {
159187
for (AddressCollection::iterator a = addrs_.begin(); a != addrs_.end(); ++a) {
160188
if (a->get() == addr) {
@@ -791,7 +819,8 @@ IfaceMgr::printIfaces(std::ostream& out /*= std::cout*/) {
791819

792820
out << "Detected interface " << iface->getFullName()
793821
<< ", hwtype=" << iface->getHWType()
794-
<< ", mac=" << iface->getPlainMac();
822+
<< ", mac=" << iface->getPlainMac()
823+
<< ", bcast=" << iface->getPlainBcastMac();
795824
out << ", flags=" << hex << iface->flags_ << dec << "("
796825
<< (iface->flag_loopback_?"LOOPBACK ":"")
797826
<< (iface->flag_up_?"UP ":"")

src/lib/dhcp/iface_mgr.h

+28
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,28 @@ class Iface : public boost::noncopyable {
204204
/// that returned it.
205205
const uint8_t* getMac() const { return mac_; }
206206

207+
/// @brief Returns broadcast MAC address a plain text.
208+
///
209+
/// @return MAC address as a plain text (string)
210+
std::string getPlainBcastMac() const;
211+
212+
/// @brief Sets broadcast MAC address of the interface.
213+
///
214+
/// @param mac pointer to bcast MAC address buffer
215+
/// @param macLen length of bcast mac address
216+
void setBcastMac(const uint8_t* bcastMac, size_t bcastMacLen);
217+
218+
/// @brief Returns broadcast MAC length.
219+
///
220+
/// @return length of bcast MAC address
221+
size_t getBcastMacLen() const { return bcast_mac_len_; }
222+
223+
/// @brief Returns pointer to broadcast MAC address.
224+
///
225+
/// Note: Returned pointer is only valid as long as the interface object
226+
/// that returned it.
227+
const uint8_t* getBcastMac() const { return bcast_mac_; }
228+
207229
/// @brief Sets flag_*_ fields based on bitmask value returned by OS
208230
///
209231
/// @note Implementation of this method is OS-dependent as bits have
@@ -430,6 +452,12 @@ class Iface : public boost::noncopyable {
430452
/// Length of link-layer address (usually 6).
431453
size_t mac_len_;
432454

455+
/// Link-layer braodcast address.
456+
uint8_t bcast_mac_[MAX_MAC_LEN];
457+
458+
/// Length of link-layer broadcast address (usually 6).
459+
size_t bcast_mac_len_;
460+
433461
/// Hardware type.
434462
uint16_t hardware_type_;
435463

src/lib/dhcp/iface_mgr_bsd.cc

+28
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@ using namespace isc;
2525
using namespace isc::asiolink;
2626
using namespace isc::dhcp;
2727

28+
namespace {
29+
30+
static const uint8_t default_ib_bcast_addr[20] = {
31+
0x00, 0xff, 0xff, 0xff,
32+
0xff, 0x12, 0x40, 0x1b,
33+
0x00, 0x00, 0x00, 0x00,
34+
0x00, 0x00, 0x00, 0x00,
35+
0xff, 0xff, 0xff, 0xff
36+
};
37+
38+
static const uint8_t default_ether_bcast_addr[6] = {
39+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
40+
};
41+
42+
}
43+
2844
namespace isc {
2945
namespace dhcp {
3046

@@ -92,6 +108,18 @@ IfaceMgr::detectIfaces(bool update_only) {
92108

93109
iface_iter->second->setHWType(ldata->sdl_type);
94110
iface_iter->second->setMac(ptr, ldata->sdl_alen);
111+
112+
//TODO: I don't have BSD, this needs tested
113+
if (ifptr->ifa_flags & IFF_BROADCAST) {
114+
ldata = reinterpret_cast<struct sockaddr_dl *>(ifptr->ifa_broadaddr);
115+
ptr = reinterpret_cast<uint8_t *>(LLADDR(ldata));
116+
117+
iface_iter->second->setBcastMac(ptr, ldata->sdl_alen);
118+
} else if (interface_info->ifi_type == HTYPE_INFINIBAND) {
119+
iface_iter->second->setBcastMac(default_ib_bcast_addr, sizeof(default_ib_bcast_addr));
120+
} else if (interface_info->ifi_type == HTYPE_ETHER) {
121+
iface_iter->second->setBcastMac(default_ether_bcast_addr, sizeof(default_ether_bcast_addr));
122+
}
95123
} else if (ifptr->ifa_addr->sa_family == AF_INET6) {
96124
// IPv6 Addr
97125
struct sockaddr_in6 * adata =

src/lib/dhcp/iface_mgr_linux.cc

+22
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,18 @@ void Netlink::release_list(NetlinkMessages& messages) {
403403
messages.clear();
404404
}
405405

406+
static const uint8_t default_ib_bcast_addr[20] = {
407+
0x00, 0xff, 0xff, 0xff,
408+
0xff, 0x12, 0x40, 0x1b,
409+
0x00, 0x00, 0x00, 0x00,
410+
0x00, 0x00, 0x00, 0x00,
411+
0xff, 0xff, 0xff, 0xff
412+
};
413+
414+
static const uint8_t default_ether_bcast_addr[6] = {
415+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
416+
};
417+
406418
} // end of anonymous namespace
407419

408420
namespace isc {
@@ -504,6 +516,16 @@ void IfaceMgr::detectIfaces(bool update_only) {
504516
// try to dereference it in this manner
505517
}
506518

519+
// Does interface have an L2 broadcast address?
520+
if ((interface_info->ifi_flags & IFF_BROADCAST) && attribs_table[IFLA_BROADCAST]) {
521+
iface->setBcastMac(static_cast<const uint8_t*>(RTA_DATA(attribs_table[IFLA_BROADCAST])),
522+
RTA_PAYLOAD(attribs_table[IFLA_BROADCAST]));
523+
} else if (interface_info->ifi_type == HTYPE_INFINIBAND) {
524+
iface->setBcastMac(default_ib_bcast_addr, sizeof(default_ib_bcast_addr));
525+
} else if (interface_info->ifi_type == HTYPE_ETHER) {
526+
iface->setBcastMac(default_ether_bcast_addr, sizeof(default_ether_bcast_addr));
527+
}
528+
507529
nl.ipaddrs_get(*iface, addr_info);
508530

509531
// addInterface can now throw so protect against memory leaks.

src/lib/dhcp/iface_mgr_sun.cc

+28
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,22 @@ using namespace isc;
2424
using namespace isc::asiolink;
2525
using namespace isc::dhcp;
2626

27+
namespace {
28+
29+
static const uint8_t default_ib_bcast_addr[20] = {
30+
0x00, 0xff, 0xff, 0xff,
31+
0xff, 0x12, 0x40, 0x1b,
32+
0x00, 0x00, 0x00, 0x00,
33+
0x00, 0x00, 0x00, 0x00,
34+
0xff, 0xff, 0xff, 0xff
35+
};
36+
37+
static const uint8_t default_ether_bcast_addr[6] = {
38+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
39+
};
40+
41+
}
42+
2743
namespace isc {
2844
namespace dhcp {
2945

@@ -92,6 +108,18 @@ IfaceMgr::detectIfaces(bool update_only) {
92108

93109
iface_iter->second->setHWType(ldata->sdl_type);
94110
iface_iter->second->setMac(ptr, ldata->sdl_alen);
111+
112+
//TODO: I don't have SUN, this needs tested
113+
if (ifptr->ifa_flags & IFF_BROADCAST) {
114+
ldata = reinterpret_cast<struct sockaddr_dl *>(ifptr->ifa_broadaddr);
115+
ptr = reinterpret_cast<uint8_t *>(LLADDR(ldata));
116+
117+
iface_iter->second->setBcastMac(ptr, ldata->sdl_alen);
118+
} else if (ldata->sdl_type == HTYPE_INFINIBAND) {
119+
iface_iter->second->setBcastMac(default_ib_bcast_addr, sizeof(default_ib_bcast_addr));
120+
} else if (ldata->sdl_type == HTYPE_ETHER) {
121+
iface_iter->second->setBcastMac(default_ether_bcast_addr, sizeof(default_ether_bcast_addr));
122+
}
95123
} else if (ifptr->ifa_addr->sa_family == AF_INET6) {
96124
// IPv6 Addr
97125
struct sockaddr_in6 * adata =

0 commit comments

Comments
 (0)