netifd-proto.sh: execute proto_add_host_dependency() actions in subshell to retain...
[project/netifd.git] / interface-ip.c
index e09a74f..d8d8606 100644 (file)
@@ -141,14 +141,19 @@ interface_ip_add_target_route(union if_addr *addr, bool v6)
 {
        struct interface *iface;
        struct device_route *route, *r_next = NULL;
+       bool defaultroute_target = false;
+       int addrsize = v6 ? sizeof(addr->in6) : sizeof(addr->in);
 
        route = calloc(1, sizeof(*route));
        if (!route)
-               return false;
+               return NULL;
 
        route->flags = v6 ? DEVADDR_INET6 : DEVADDR_INET4;
        route->mask = v6 ? 128 : 32;
-       memcpy(&route->addr, addr, v6 ? sizeof(addr->in6) : sizeof(addr->in));
+       if (memcmp(&route->addr, addr, addrsize) == 0)
+               defaultroute_target = true;
+       else
+               memcpy(&route->addr, addr, addrsize);
 
        vlist_for_each_element(&interfaces, iface, node) {
                /* look for locally addressable target first */
@@ -160,8 +165,10 @@ interface_ip_add_target_route(union if_addr *addr, bool v6)
                interface_ip_find_route_target(iface, addr, v6, &r_next);
        }
 
-       if (!r_next)
+       if (!r_next) {
+               free(route);
                return NULL;
+       }
 
        iface = r_next->iface;
        memcpy(&route->nexthop, &r_next->nexthop, sizeof(route->nexthop));
@@ -170,7 +177,10 @@ interface_ip_add_target_route(union if_addr *addr, bool v6)
 
 done:
        route->iface = iface;
-       vlist_add(&iface->host_routes, &route->node, &route->flags);
+       if (defaultroute_target)
+               free(route);
+       else
+               vlist_add(&iface->host_routes, &route->node, &route->flags);
        return iface;
 }
 
@@ -301,7 +311,7 @@ interface_update_proto_addr(struct vlist_tree *tree,
                        uint32_t *a = (uint32_t *) &a_new->addr;
 
                        mask >>= a_new->mask;
-                       a_new->broadcast = *a | mask;
+                       a_new->broadcast = *a | htonl(mask);
                }
        }