summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interface-ip.c12
-rw-r--r--interface-ip.h3
-rw-r--r--proto-shell.c2
-rw-r--r--ubus.c9
4 files changed, 21 insertions, 5 deletions
diff --git a/interface-ip.c b/interface-ip.c
index 54d5fe0..585cb6f 100644
--- a/interface-ip.c
+++ b/interface-ip.c
@@ -257,12 +257,19 @@ interface_ip_find_route_target(struct interface *iface, union if_addr *a,
}
struct interface *
-interface_ip_add_target_route(union if_addr *addr, bool v6, struct interface *iface)
+interface_ip_add_target_route(union if_addr *addr, bool v6, struct interface *iface,
+ bool exclude)
{
struct device_route *route, *r_next = NULL;
bool defaultroute_target = false;
union if_addr addr_zero;
int addrsize = v6 ? sizeof(addr->in6) : sizeof(addr->in);
+ struct interface *exclude_iface = NULL;
+
+ if (exclude) {
+ exclude_iface = iface;
+ iface = NULL;
+ }
memset(&addr_zero, 0, sizeof(addr_zero));
if (memcmp(&addr_zero, addr, addrsize) == 0)
@@ -278,6 +285,9 @@ interface_ip_add_target_route(union if_addr *addr, bool v6, struct interface *if
interface_ip_find_route_target(iface, addr, v6, &r_next);
} else {
vlist_for_each_element(&interfaces, iface, node) {
+ if (iface == exclude_iface)
+ continue;
+
/* look for locally addressable target first */
if (interface_ip_find_addr_target(iface, addr, v6))
return iface;
diff --git a/interface-ip.h b/interface-ip.h
index b17ad94..8843349 100644
--- a/interface-ip.h
+++ b/interface-ip.h
@@ -184,7 +184,8 @@ void interface_ip_flush(struct interface_ip_settings *ip);
void interface_ip_set_enabled(struct interface_ip_settings *ip, bool enabled);
void interface_ip_update_metric(struct interface_ip_settings *ip, int metric);
-struct interface *interface_ip_add_target_route(union if_addr *addr, bool v6, struct interface *iface);
+struct interface *interface_ip_add_target_route(union if_addr *addr, bool v6, struct interface *iface,
+ bool exclude);
struct device_prefix* interface_ip_add_device_prefix(struct interface *iface,
struct in6_addr *addr, uint8_t length, time_t valid_until, time_t preferred_until,
diff --git a/proto-shell.c b/proto-shell.c
index e20d539..9cdbc7f 100644
--- a/proto-shell.c
+++ b/proto-shell.c
@@ -129,7 +129,7 @@ proto_shell_update_host_dep(struct proto_shell_dependency *dep)
}
if (!dep->any)
- iface = interface_ip_add_target_route(&dep->host, dep->v6, iface);
+ iface = interface_ip_add_target_route(&dep->host, dep->v6, iface, false);
if (!iface)
goto out;
diff --git a/ubus.c b/ubus.c
index a386179..2876e7d 100644
--- a/ubus.c
+++ b/ubus.c
@@ -54,6 +54,7 @@ enum {
HR_TARGET,
HR_V6,
HR_INTERFACE,
+ HR_EXCLUDE,
__HR_MAX
};
@@ -61,6 +62,7 @@ static const struct blobmsg_policy route_policy[__HR_MAX] = {
[HR_TARGET] = { .name = "target", .type = BLOBMSG_TYPE_STRING },
[HR_V6] = { .name = "v6", .type = BLOBMSG_TYPE_BOOL },
[HR_INTERFACE] = { .name = "interface", .type = BLOBMSG_TYPE_STRING },
+ [HR_EXCLUDE] = { .name = "exclude", .type = BLOBMSG_TYPE_BOOL },
};
static int
@@ -72,6 +74,7 @@ netifd_add_host_route(struct ubus_context *ctx, struct ubus_object *obj,
struct interface *iface = NULL;
union if_addr a;
bool v6 = false;
+ bool exclude = false;
blobmsg_parse(route_policy, __HR_MAX, tb, blob_data(msg), blob_len(msg));
if (!tb[HR_TARGET])
@@ -80,6 +83,9 @@ netifd_add_host_route(struct ubus_context *ctx, struct ubus_object *obj,
if (tb[HR_V6])
v6 = blobmsg_get_bool(tb[HR_V6]);
+ if (tb[HR_EXCLUDE])
+ exclude = blobmsg_get_bool(tb[HR_EXCLUDE]);
+
if (tb[HR_INTERFACE])
iface = vlist_find(&interfaces, blobmsg_data(tb[HR_INTERFACE]), iface, node);
@@ -87,8 +93,7 @@ netifd_add_host_route(struct ubus_context *ctx, struct ubus_object *obj,
if (!inet_pton(v6 ? AF_INET6 : AF_INET, blobmsg_data(tb[HR_TARGET]), &a))
return UBUS_STATUS_INVALID_ARGUMENT;
-
- iface = interface_ip_add_target_route(&a, v6, iface);
+ iface = interface_ip_add_target_route(&a, v6, iface, exclude);
if (!iface)
return UBUS_STATUS_NOT_FOUND;