summaryrefslogtreecommitdiffhomepage
path: root/interface-ip.c
diff options
context:
space:
mode:
authorBaptiste Jonglez <git@bitsofnetworks.org>2015-09-14 12:25:33 +0200
committerFelix Fietkau <nbd@openwrt.org>2015-09-26 13:50:48 +0200
commita0f133ed22dee4eccc05961f646e14ecc0514060 (patch)
tree0a1dd925456d609167e3e6ff6db2b1fd72e5174a /interface-ip.c
parent014698606902e495c7b169bf30688a685cd72d64 (diff)
interface-ip: Fix broadcast address when using /31 or /32 IPv4 addressing
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>
Diffstat (limited to 'interface-ip.c')
-rw-r--r--interface-ip.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/interface-ip.c b/interface-ip.c
index 4a2ee35..54f56d6 100644
--- a/interface-ip.c
+++ b/interface-ip.c
@@ -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);
+ }
}
}