From: Vincent Bernat Date: Tue, 25 Dec 2012 10:40:06 +0000 (+0100) Subject: interfaces: setting up raw interface with BPF filter is OS specific X-Git-Tag: 0.7.0~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=88bc404fec75841f058eacf7402d8f3555cc4409;p=thirdparty%2Flldpd.git interfaces: setting up raw interface with BPF filter is OS specific On Linux, setting up a BPF filter on an interface means using `setsockopt()` on a raw socket. On BSD, we need to open `/dev/bpf` as a raw socket and attach the interface to it. Therefore, physical interface initialization cannot be abstracted. --- diff --git a/src/daemon/interfaces-linux.c b/src/daemon/interfaces-linux.c index 57c86c23..88020365 100644 --- a/src/daemon/interfaces-linux.c +++ b/src/daemon/interfaces-linux.c @@ -35,8 +35,8 @@ #define MAX_BRIDGES 1024 static struct sock_filter lldpd_filter_f[] = { LLDPD_FILTER_F }; -int -interfaces_set_filter(const char *name, int fd) +static int +iflinux_set_filter(const char *name, int fd) { struct sock_fprog prog; log_debug("interfaces", "set BPF filter for %s", name); @@ -53,6 +53,31 @@ interfaces_set_filter(const char *name, int fd) return 0; } +static int +iflinux_eth_init(struct lldpd *cfg, struct lldpd_hardware *hardware) +{ + int fd, status; + + log_debug("interfaces", "initialize ethernet device %s", + hardware->h_ifname); + if ((fd = priv_iface_init(hardware->h_ifindex)) == -1) + return -1; + hardware->h_sendfd = fd; /* Send */ + + /* Set filter */ + if ((status = iflinux_set_filter(hardware->h_ifname, fd)) != 0) { + close(fd); + return status; + } + + interfaces_setup_multicast(cfg, hardware->h_ifname, 0); + + levent_hardware_add_fd(hardware, fd); /* Receive */ + log_debug("interfaces", "interface %s initialized (fd=%d)", hardware->h_ifname, + fd); + return 0; +} + static int old_iflinux_is_bridge(struct lldpd *cfg, struct interfaces_device_list *interfaces, @@ -388,7 +413,7 @@ iface_bond_init(struct lldpd *cfg, struct lldpd_hardware *hardware) if ((fd = priv_iface_init(hardware->h_ifindex)) == -1) return -1; hardware->h_sendfd = fd; - if ((status = interfaces_set_filter(hardware->h_ifname, fd)) != 0) { + if ((status = iflinux_set_filter(hardware->h_ifname, fd)) != 0) { close(fd); return status; } @@ -399,7 +424,7 @@ iface_bond_init(struct lldpd *cfg, struct lldpd_hardware *hardware) close(hardware->h_sendfd); return -1; } - if ((status = interfaces_set_filter(master->name, fd)) != 0) { + if ((status = iflinux_set_filter(master->name, fd)) != 0) { close(hardware->h_sendfd); close(fd); return status; @@ -756,7 +781,8 @@ interfaces_update(struct lldpd *cfg) interfaces_helper_whitelist(cfg, interfaces); iflinux_handle_bond(cfg, interfaces); - interfaces_helper_physical(cfg, interfaces); + interfaces_helper_physical(cfg, interfaces, + iflinux_eth_init); #ifdef ENABLE_DOT1 interfaces_helper_vlan(cfg, interfaces); #endif diff --git a/src/daemon/interfaces.c b/src/daemon/interfaces.c index bf4695d8..14f54763 100644 --- a/src/daemon/interfaces.c +++ b/src/daemon/interfaces.c @@ -102,31 +102,6 @@ interfaces_setup_multicast(struct lldpd *cfg, const char *name, } } -static int -iface_eth_init(struct lldpd *cfg, struct lldpd_hardware *hardware) -{ - int fd, status; - - log_debug("interfaces", "initialize ethernet device %s", - hardware->h_ifname); - if ((fd = priv_iface_init(hardware->h_ifindex)) == -1) - return -1; - hardware->h_sendfd = fd; /* Send */ - - /* Set filter */ - if ((status = interfaces_set_filter(hardware->h_ifname, fd)) != 0) { - close(fd); - return status; - } - - interfaces_setup_multicast(cfg, hardware->h_ifname, 0); - - levent_hardware_add_fd(hardware, fd); /* Receive */ - log_debug("interfaces", "interface %s initialized (fd=%d)", hardware->h_ifname, - fd); - return 0; -} - /** * Free an interface. * @@ -572,7 +547,8 @@ interfaces_helper_port_name_desc(struct lldpd_hardware *hardware, void interfaces_helper_physical(struct lldpd *cfg, - struct interfaces_device_list *interfaces) + struct interfaces_device_list *interfaces, + int(*init)(struct lldpd *, struct lldpd_hardware *)) { struct interfaces_device *iface; struct lldpd_hardware *hardware; @@ -594,7 +570,7 @@ interfaces_helper_physical(struct lldpd *cfg, iface->name); continue; } - if (iface_eth_init(cfg, hardware) != 0) { + if (init(cfg, hardware) != 0) { log_warn("interfaces", "unable to initialize %s", hardware->h_ifname); diff --git a/src/daemon/lldpd.h b/src/daemon/lldpd.h index cd6e6372..400285aa 100644 --- a/src/daemon/lldpd.h +++ b/src/daemon/lldpd.h @@ -257,7 +257,6 @@ void send_fd(int, int); * `interfaces.c` as helper by providing a list of OS-independent interface * devices. */ void interfaces_update(struct lldpd *); -int interfaces_set_filter(const char *name, int fd); /* interfaces.c */ /* An interface cannot be both physical and (bridge or bond or vlan) */ @@ -314,7 +313,8 @@ void interfaces_helper_whitelist(struct lldpd *, void interfaces_helper_chassis(struct lldpd *, struct interfaces_device_list *); void interfaces_helper_physical(struct lldpd *, - struct interfaces_device_list *); + struct interfaces_device_list *, + int(*init)(struct lldpd *, struct lldpd_hardware *)); void interfaces_helper_port_name_desc(struct lldpd_hardware *, struct interfaces_device *); void interfaces_helper_mgmt(struct lldpd *,