interface-ip: Fix broadcast address when using /31 or /32 IPv4 addressing
authorBaptiste Jonglez <git@bitsofnetworks.org>
Mon, 14 Sep 2015 10:25:33 +0000 (12:25 +0200)
committerFelix Fietkau <nbd@openwrt.org>
Sat, 26 Sep 2015 11:50:48 +0000 (13:50 +0200)
A /31-addressed interface requires a broadcast address of 255.255.255.255,
because there is no room for a proper broadcast address.  Without this,
any packet destinated to the other end of the link is sent as broadcast,
which is incorrect.

For consistency with the Linux kernel, /32-addressed interfaces are
treated in the same way.

Signed-off-by: Baptiste Jonglez <git@bitsofnetworks.org>
interface-ip.c

index 4a2ee354f46978be77b81f7c398a0431b1c3ec28..54f56d69b291d2eb207dd596cd19039c300a7286 100644 (file)
@@ -473,11 +473,17 @@ interface_update_proto_addr(struct vlist_tree *tree,
                if ((a_new->flags & DEVADDR_FAMILY) == DEVADDR_INET4 &&
                    !a_new->broadcast) {
 
-                       uint32_t mask = ~0;
-                       uint32_t *a = (uint32_t *) &a_new->addr;
-
-                       mask >>= a_new->mask;
-                       a_new->broadcast = *a | htonl(mask);
+                       /* /31 and /32 addressing need 255.255.255.255
+                        * as broadcast address. */
+                       if (a_new->mask >= 31) {
+                               a_new->broadcast = (uint32_t) ~0;
+                       } else {
+                               uint32_t mask = ~0;
+                               uint32_t *a = (uint32_t *) &a_new->addr;
+
+                               mask >>= a_new->mask;
+                               a_new->broadcast = *a | htonl(mask);
+                       }
                }
        }