]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
interfaces: setting up raw interface with BPF filter is OS specific
authorVincent Bernat <bernat@luffy.cx>
Tue, 25 Dec 2012 10:40:06 +0000 (11:40 +0100)
committerVincent Bernat <bernat@luffy.cx>
Tue, 25 Dec 2012 10:40:06 +0000 (11:40 +0100)
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.

src/daemon/interfaces-linux.c
src/daemon/interfaces.c
src/daemon/lldpd.h

index 57c86c23ebcfdcb1aef229b6569299b0b0a5ef0f..88020365fe81d184579337bc58f1f6dde3392290 100644 (file)
@@ -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
index bf4695d8218bafb3070fe68e260e3711546792d6..14f54763f849f5c695e5a753449c04b7d6d3d6de 100644 (file)
@@ -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);
index cd6e63721d321a7650d9e7e80c9b061e6157af8a..400285aa8071389d91e8abd5363a0327701c4831 100644 (file)
@@ -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 *,