Commit 3f3d1c27 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[2893] Use BPF packet filter for BSDs.

parent 65465cde
......@@ -64,7 +64,7 @@ public:
}
/// Does nothing.
virtual SocketInfo openSocket(const Iface&,
virtual SocketInfo openSocket(Iface&,
const isc::asiolink::IOAddress& addr,
const uint16_t port, const bool, const bool) {
return (SocketInfo(addr, port, 0));
......
......@@ -428,18 +428,6 @@ bool
IfaceMgr::openSockets4(const uint16_t port, const bool use_bcast,
IfaceMgrErrorMsgCallback error_handler) {
int count = 0;
// This option is used to bind sockets to particular interfaces.
// This is currently the only way to discover on which interface
// the broadcast packet has been received. If this option is
// not supported then only one interface should be confugured
// to listen for broadcast traffic.
#ifdef SO_BINDTODEVICE
const bool bind_to_device = true;
#else
const bool bind_to_device = false;
#endif
int bcast_num = 0;
for (IfaceCollection::iterator iface = ifaces_.begin();
......@@ -467,17 +455,26 @@ IfaceMgr::openSockets4(const uint16_t port, const bool use_bcast,
// options on the socket so as it can receive and send broadcast
// messages.
if (iface->flag_broadcast_ && use_bcast) {
// If our OS supports binding socket to a device we can listen
// for broadcast messages on multiple interfaces. Otherwise we
// bind to INADDR_ANY address but we can do it only once. Thus,
// if one socket has been bound we can't do it any further.
if (!bind_to_device && bcast_num > 0) {
// The DHCP server must have means to determine which interface
// the broadcast packets are coming from. This is achieved by
// binding a socket to the device (interface) and specialized
// packet filters (e.g. BPF and LPF) implement this mechanism.
// If the PktFilterInet (generic one) is used, the socket is
// bound to INADDR_ANY which effectively binds the socket to
// all addresses on all interfaces. So, only one of those can
// be opened. Currently, the direct response support is
// provided by the PktFilterLPF and PktFilterBPF, so by checking
// the support for direct response we actually determine that
// one of those objects is in use. For all other objects we
// assume that binding to the device is not supported and we
// cease opening sockets and display the appropriate message.
if (!isDirectResponseSupported() && bcast_num > 0) {
IFACEMGR_ERROR(SocketConfigError, error_handler,
"SO_BINDTODEVICE socket option is"
" not supported on this OS;"
" therefore, DHCP server can only"
" listen broadcast traffic on a"
" single interface");
"Binding socket to an interface is not"
" supported on this OS; therefore only"
" one socket listening to broadcast traffic"
" can be opened. Sockets will not be opened"
" on remaining interfaces");
continue;
} else {
......@@ -496,9 +493,7 @@ IfaceMgr::openSockets4(const uint16_t port, const bool use_bcast,
// Binding socket to an interface is not supported so we
// can't open any more broadcast sockets. Increase the
// number of open broadcast sockets.
if (!bind_to_device) {
++bcast_num;
}
++bcast_num;
}
} else {
......
......@@ -18,7 +18,7 @@
#include <dhcp/iface_mgr.h>
#include <dhcp/iface_mgr_error_handler.h>
#include <dhcp/pkt_filter_inet.h>
#include <dhcp/pkt_filter_bpf.h>
#include <exceptions/exceptions.h>
#include <sys/types.h>
......@@ -145,9 +145,7 @@ bool IfaceMgr::os_receive4(struct msghdr& /*m*/, Pkt4Ptr& /*pkt*/) {
void
IfaceMgr::setMatchingPacketFilter(const bool /* direct_response_desired */) {
// @todo Currently we ignore the preference to use direct traffic
// because it hasn't been implemented for BSD systems.
setPacketFilter(PktFilterPtr(new PktFilterInet()));
setPacketFilter(PktFilterPtr(new PktFilterBPF()));
}
bool
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment