Skip to content

Commit

Permalink
Add L2 bcast addr to Iface
Browse files Browse the repository at this point in the history
  • Loading branch information
TimoRoth committed Jun 30, 2024
1 parent 67842fc commit 4cd8b78
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/lib/dhcp/dhcp4.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ enum HType {
/// arp-parameters/arp-parameters.xhtml suggest that
/// Ethernet (1) should be used in DOCSIS environment.
HTYPE_IEEE802 = 6, ///< IEEE 802.2 Token Ring
HTYPE_FDDI = 8 ///< FDDI
/// TODO Add infiniband here
HTYPE_FDDI = 8, ///< FDDI
HTYPE_INFINIBAND = 32 ///< InfiniBand
};

/* DHCP Option codes: */
Expand Down
33 changes: 31 additions & 2 deletions src/lib/dhcp/iface_mgr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ IfaceMgr::instancePtr() {
}

Iface::Iface(const std::string& name, unsigned int ifindex)
: name_(name), ifindex_(ifindex), mac_len_(0), hardware_type_(0),
: name_(name), ifindex_(ifindex), mac_len_(0), bcast_mac_len_(0), hardware_type_(0),
flag_loopback_(false), flag_up_(false), flag_running_(false),
flag_multicast_(false), flag_broadcast_(false), flags_(0),
inactive4_(false), inactive6_(false) {
Expand Down Expand Up @@ -142,6 +142,21 @@ Iface::getPlainMac() const {
return (tmp.str());
}

std::string
Iface::getPlainBcastMac() const {
ostringstream tmp;
tmp.fill('0');
tmp << hex;
for (int i = 0; i < bcast_mac_len_; i++) {
tmp.width(2);
tmp << static_cast<int>(bcast_mac_[i]);
if (i < bcast_mac_len_-1) {
tmp << ":";
}
}
return (tmp.str());
}

void Iface::setMac(const uint8_t* mac, size_t len) {
if (len > MAX_MAC_LEN) {
isc_throw(OutOfRange, "Interface " << getFullName()
Expand All @@ -155,6 +170,19 @@ void Iface::setMac(const uint8_t* mac, size_t len) {
}
}

void Iface::setBcastMac(const uint8_t* mac, size_t len) {
if (len > MAX_MAC_LEN) {
isc_throw(OutOfRange, "Interface " << getFullName()
<< " was detected to have link address of length "
<< len << ", but maximum supported length is "
<< MAX_MAC_LEN);
}
bcast_mac_len_ = len;
if (len > 0) {
memcpy(bcast_mac_, mac, len);
}
}

bool Iface::delAddress(const isc::asiolink::IOAddress& addr) {
for (AddressCollection::iterator a = addrs_.begin(); a != addrs_.end(); ++a) {
if (a->get() == addr) {
Expand Down Expand Up @@ -791,7 +819,8 @@ IfaceMgr::printIfaces(std::ostream& out /*= std::cout*/) {

out << "Detected interface " << iface->getFullName()
<< ", hwtype=" << iface->getHWType()
<< ", mac=" << iface->getPlainMac();
<< ", mac=" << iface->getPlainMac()
<< ", bcast=" << iface->getPlainBcastMac();
out << ", flags=" << hex << iface->flags_ << dec << "("
<< (iface->flag_loopback_?"LOOPBACK ":"")
<< (iface->flag_up_?"UP ":"")
Expand Down
28 changes: 28 additions & 0 deletions src/lib/dhcp/iface_mgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,28 @@ class Iface : public boost::noncopyable {
/// that returned it.
const uint8_t* getMac() const { return mac_; }

/// @brief Returns broadcast MAC address a plain text.
///
/// @return MAC address as a plain text (string)
std::string getPlainBcastMac() const;

/// @brief Sets broadcast MAC address of the interface.
///
/// @param mac pointer to bcast MAC address buffer
/// @param macLen length of bcast mac address
void setBcastMac(const uint8_t* bcastMac, size_t bcastMacLen);

/// @brief Returns broadcast MAC length.
///
/// @return length of bcast MAC address
size_t getBcastMacLen() const { return bcast_mac_len_; }

/// @brief Returns pointer to broadcast MAC address.
///
/// Note: Returned pointer is only valid as long as the interface object
/// that returned it.
const uint8_t* getBcastMac() const { return bcast_mac_; }

/// @brief Sets flag_*_ fields based on bitmask value returned by OS
///
/// @note Implementation of this method is OS-dependent as bits have
Expand Down Expand Up @@ -430,6 +452,12 @@ class Iface : public boost::noncopyable {
/// Length of link-layer address (usually 6).
size_t mac_len_;

/// Link-layer braodcast address.
uint8_t bcast_mac_[MAX_MAC_LEN];

/// Length of link-layer broadcast address (usually 6).
size_t bcast_mac_len_;

/// Hardware type.
uint16_t hardware_type_;

Expand Down
28 changes: 28 additions & 0 deletions src/lib/dhcp/iface_mgr_bsd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;

namespace {

static const uint8_t default_ib_bcast_addr[20] = {
0x00, 0xff, 0xff, 0xff,
0xff, 0x12, 0x40, 0x1b,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff
};

static const uint8_t default_ether_bcast_addr[6] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

}

namespace isc {
namespace dhcp {

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

iface_iter->second->setHWType(ldata->sdl_type);
iface_iter->second->setMac(ptr, ldata->sdl_alen);

//TODO: I don't have BSD, this needs tested
if (ifptr->ifa_flags & IFF_BROADCAST) {
ldata = reinterpret_cast<struct sockaddr_dl *>(ifptr->ifa_broadaddr);
ptr = reinterpret_cast<uint8_t *>(LLADDR(ldata));

iface_iter->second->setBcastMac(ptr, ldata->sdl_alen);
} else if (interface_info->ifi_type == HTYPE_INFINIBAND) {
iface_iter->second->setBcastMac(default_ib_bcast_addr, sizeof(default_ib_bcast_addr));
} else if (interface_info->ifi_type == HTYPE_ETHER) {
iface_iter->second->setBcastMac(default_ether_bcast_addr, sizeof(default_ether_bcast_addr));
}
} else if (ifptr->ifa_addr->sa_family == AF_INET6) {
// IPv6 Addr
struct sockaddr_in6 * adata =
Expand Down
22 changes: 22 additions & 0 deletions src/lib/dhcp/iface_mgr_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,18 @@ void Netlink::release_list(NetlinkMessages& messages) {
messages.clear();
}

static const uint8_t default_ib_bcast_addr[20] = {
0x00, 0xff, 0xff, 0xff,
0xff, 0x12, 0x40, 0x1b,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff
};

static const uint8_t default_ether_bcast_addr[6] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

} // end of anonymous namespace

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

// Does interface have an L2 broadcast address?
if ((interface_info->ifi_flags & IFF_BROADCAST) && attribs_table[IFLA_BROADCAST]) {
iface->setBcastMac(static_cast<const uint8_t*>(RTA_DATA(attribs_table[IFLA_BROADCAST])),
RTA_PAYLOAD(attribs_table[IFLA_BROADCAST]));
} else if (interface_info->ifi_type == HTYPE_INFINIBAND) {
iface->setBcastMac(default_ib_bcast_addr, sizeof(default_ib_bcast_addr));
} else if (interface_info->ifi_type == HTYPE_ETHER) {
iface->setBcastMac(default_ether_bcast_addr, sizeof(default_ether_bcast_addr));
}

nl.ipaddrs_get(*iface, addr_info);

// addInterface can now throw so protect against memory leaks.
Expand Down
28 changes: 28 additions & 0 deletions src/lib/dhcp/iface_mgr_sun.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;

namespace {

static const uint8_t default_ib_bcast_addr[20] = {
0x00, 0xff, 0xff, 0xff,
0xff, 0x12, 0x40, 0x1b,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff
};

static const uint8_t default_ether_bcast_addr[6] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff
};

}

namespace isc {
namespace dhcp {

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

iface_iter->second->setHWType(ldata->sdl_type);
iface_iter->second->setMac(ptr, ldata->sdl_alen);

//TODO: I don't have SUN, this needs tested
if (ifptr->ifa_flags & IFF_BROADCAST) {
ldata = reinterpret_cast<struct sockaddr_dl *>(ifptr->ifa_broadaddr);
ptr = reinterpret_cast<uint8_t *>(LLADDR(ldata));

iface_iter->second->setBcastMac(ptr, ldata->sdl_alen);
} else if (ldata->sdl_type == HTYPE_INFINIBAND) {
iface_iter->second->setBcastMac(default_ib_bcast_addr, sizeof(default_ib_bcast_addr));
} else if (ldata->sdl_type == HTYPE_ETHER) {
iface_iter->second->setBcastMac(default_ether_bcast_addr, sizeof(default_ether_bcast_addr));
}
} else if (ifptr->ifa_addr->sa_family == AF_INET6) {
// IPv6 Addr
struct sockaddr_in6 * adata =
Expand Down

0 comments on commit 4cd8b78

Please sign in to comment.