]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
interfaces: abstract a bit MAC address mangling for bonding devices
authorVincent Bernat <bernat@luffy.cx>
Sun, 11 Aug 2013 20:07:57 +0000 (22:07 +0200)
committerVincent Bernat <bernat@luffy.cx>
Sun, 11 Aug 2013 20:07:57 +0000 (22:07 +0200)
A variable in `struct lldpd_hardware` control the mangling. On the
other end, `hardware->h_ops->send()` should not be called directly
anymore. Instead, `interfaces_helper_send()` should be used instead.

src/daemon/cdp.c
src/daemon/edp.c
src/daemon/interfaces-linux.c
src/daemon/interfaces.c
src/daemon/lldp.c
src/daemon/lldpd.h
src/daemon/sonmp.c
src/lldpd-structs.h

index 7dcdb12053bbfc4120ec8c6b18d52912c5478530..bf5921d90c0715979012a47cbe374591c81b70db 100644 (file)
@@ -205,7 +205,7 @@ cdp_send(struct lldpd *global,
        POKE_RESTORE(pos_checksum);
        if (!(POKE_UINT16(ntohs(checksum)))) goto toobig;
 
-       if (hardware->h_ops->send(global, hardware,
+       if (interfaces_send_helper(global, hardware,
                (char *)packet, end - packet) == -1) {
                log_warn("cdp", "unable to send packet on real device for %s",
                           hardware->h_ifname);
index 801093762a40858b84208f4ec2890e0823bcba4d..4a9cfbdc6662e089bf55369f9288b08affe315a0 100644 (file)
@@ -200,7 +200,7 @@ edp_send(struct lldpd *global,
                checksum = frame_checksum(pos_edp, v, 0);
                if (!(POKE_UINT16(ntohs(checksum)))) goto toobig;
 
-               if (hardware->h_ops->send(global, hardware,
+               if (interfaces_send_helper(global, hardware,
                        (char *)packet, end - packet) == -1) {
                        log_warn("edp", "unable to send packet on real device for %s",
                            hardware->h_ifname);
index 804d5eed19f67a6fa99f034684e718894434565f..63b96a660ab09b4ac176debc723db23386b6dfb9 100644 (file)
@@ -465,23 +465,6 @@ iface_bond_init(struct lldpd *cfg, struct lldpd_hardware *hardware)
        return 0;
 }
 
-static int
-iface_bond_send(struct lldpd *cfg, struct lldpd_hardware *hardware,
-    char *buffer, size_t size)
-{
-       log_debug("interfaces", "send PDU to bonded device %s",
-           hardware->h_ifname);
-       if (size < 2 * ETHER_ADDR_LEN) {
-               log_warnx("interfaces",
-                   "packet to send on %s is too small!",
-                   hardware->h_ifname);
-               return 0;
-       }
-       interfaces_helper_mangle_mac(cfg, buffer + ETHER_ADDR_LEN);
-       return write(hardware->h_sendfd,
-           buffer, size);
-}
-
 static int
 iface_bond_recv(struct lldpd *cfg, struct lldpd_hardware *hardware,
     int fd, char *buffer, size_t size)
@@ -531,7 +514,7 @@ iface_bond_close(struct lldpd *cfg, struct lldpd_hardware *hardware)
 }
 
 struct lldpd_ops bond_ops = {
-       .send = iface_bond_send,
+       .send = iflinux_eth_send,
        .recv = iface_bond_recv,
        .cleanup = iface_bond_close,
 };
@@ -575,6 +558,7 @@ iflinux_handle_bond(struct lldpd *cfg, struct interfaces_device_list *interfaces
                                continue;
                        }
                        hardware->h_ops = &bond_ops;
+                       hardware->h_mangle = 1;
                        TAILQ_INSERT_TAIL(&cfg->g_hardware, hardware, h_entries);
                } else {
                        if (hardware->h_flags) continue; /* Already seen this time */
index f1c5fa4316dd9832f6002bf7956cb211211b89e6..6fc8fbbcab020788cf57b24a2a63765ae255f2da 100644 (file)
@@ -558,33 +558,45 @@ interfaces_helper_physical(struct lldpd *cfg,
 }
 
 /**
- * Mangle the MAC address to avoid duplicates.
+ * Send the packet using the hardware function. Optionnaly mangle the MAC address.
  *
  * With bonds, we have duplicate MAC address on different physical
- * interfaces. We need to alter the source MAC address when we send on
- * an inactive slave. We try to set "local" bit to 1 first. If it is
- * already set to 1, use an unused MAC address instead.
+ * interfaces. We need to alter the source MAC address when we send on an
+ * inactive slave. The `h_mangle` flah is used to know if we need to do
+ * something like that.
  */
-void
-interfaces_helper_mangle_mac(struct lldpd *cfg, char *src_mac)
+int
+interfaces_send_helper(struct lldpd *cfg,
+    struct lldpd_hardware *hardware,
+    char *buffer, size_t size)
 {
+       if (size < 2 * ETHER_ADDR_LEN) {
+               log_warnx("interfaces",
+                   "packet to send on %s is too small!",
+                   hardware->h_ifname);
+               return 0;
+       }
+       if (hardware->h_mangle) {
 #define MAC_UL_ADMINISTERED_BIT_MASK 0x02
-       char arbitrary[] = { 0x00, 0x60, 0x08, 0x69, 0x97, 0xef};
-
-       switch (cfg->g_config.c_bond_slave_src_mac_type) {
-       case LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED:
-               if (*src_mac & MAC_UL_ADMINISTERED_BIT_MASK) {
-                       /* If locally administered bit already set,
-                        * use zero mac
-                        */
+               char *src_mac = buffer + ETHER_ADDR_LEN;
+               char arbitrary[] = { 0x00, 0x60, 0x08, 0x69, 0x97, 0xef};
+
+               switch (cfg->g_config.c_bond_slave_src_mac_type) {
+               case LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED:
+                       if (*src_mac & MAC_UL_ADMINISTERED_BIT_MASK) {
+                               /* If locally administered bit already set,
+                                * use zero mac
+                                */
+                               memset(src_mac, 0, ETHER_ADDR_LEN);
+                               break;
+                       }
+               case LLDP_BOND_SLAVE_SRC_MAC_TYPE_FIXED:
+                       memcpy(src_mac, arbitrary, ETHER_ADDR_LEN);
+                       break;
+               case LLDP_BOND_SLAVE_SRC_MAC_TYPE_ZERO:
                        memset(src_mac, 0, ETHER_ADDR_LEN);
-                       return;
+                       break;
                }
-       case LLDP_BOND_SLAVE_SRC_MAC_TYPE_FIXED:
-               memcpy(src_mac, arbitrary, ETHER_ADDR_LEN);
-               return;
-       case LLDP_BOND_SLAVE_SRC_MAC_TYPE_ZERO:
-               memset(src_mac, 0, ETHER_ADDR_LEN);
-               return;
        }
+       return hardware->h_ops->send(cfg, hardware, buffer, size);
 }
index 7d99b27cfabce7167d9802300083f7a8ee25faf1..3d60563be1b5312ca40c5a932468d10df0ed569e 100644 (file)
@@ -424,7 +424,7 @@ lldp_send(struct lldpd *global,
              POKE_END_LLDP_TLV))
                goto toobig;
 
-       if (hardware->h_ops->send(global, hardware,
+       if (interfaces_send_helper(global, hardware,
                (char *)packet, pos - packet) == -1) {
                log_warn("lldp", "unable to send packet on real device for %s",
                    hardware->h_ifname);
index da8aea8ac2d4d09162d91088625f3d6f9c0e2d1d..659e3e60a30619430b56305e2fea902ee370d5a4 100644 (file)
@@ -364,7 +364,8 @@ void interfaces_helper_mgmt(struct lldpd *,
 void interfaces_helper_vlan(struct lldpd *,
     struct interfaces_device_list *);
 #endif
-void interfaces_helper_mangle_mac(struct lldpd *, char *);
+int interfaces_send_helper(struct lldpd *,
+    struct lldpd_hardware *, char *, size_t);
 
 void interfaces_setup_multicast(struct lldpd *, const char *, int);
 int interfaces_routing_enabled(struct lldpd *);
index 444b4ef2362975419381fbb616c62b2f05d46dbf..75638d1c3efd9f8a84e9a09ee23556bf7a77d86c 100644 (file)
@@ -249,7 +249,7 @@ sonmp_send(struct lldpd *global,
                  POKE_SAVE(end)))
                goto toobig;
                                
-       if (hardware->h_ops->send(global, hardware,
+       if (interfaces_send_helper(global, hardware,
                (char *)packet, end - packet) == -1) {
                log_warn("sonmp", "unable to send packet on real device for %s",
                           hardware->h_ifname);
@@ -263,7 +263,7 @@ sonmp_send(struct lldpd *global,
        PEEK_DISCARD(ETHER_ADDR_LEN - 1); /* Modify the last byte of the MAC address */
        (void)POKE_UINT8(1);
 
-       if (hardware->h_ops->send(global, hardware,
+       if (interfaces_send_helper(global, hardware,
                (char *)packet, end - packet) == -1) {
                log_warn("sonmp", "unable to send second SONMP packet on real device for %s",
                           hardware->h_ifname);
index 396c2e1655133d1b3ac720101731f64e0320e98a..848fd667fad56e866c2597f60d1efcbce79deaaf 100644 (file)
@@ -371,6 +371,7 @@ struct lldpd_hardware {
        struct lldpd            *h_cfg;     /* Pointer to main configuration */
        void                    *h_recv;    /* FD for reception */
        int                      h_sendfd;  /* FD for sending, only used by h_ops */
+       int                      h_mangle;  /* 1 if we have to mangle the MAC address */
        struct lldpd_ops        *h_ops;     /* Hardware-dependent functions */
        void                    *h_data;    /* Hardware-dependent data */
        void                    *h_timer;   /* Timer for this port */