summaryrefslogtreecommitdiffhomepage
path: root/proto-shell.c
diff options
context:
space:
mode:
authorSteven Barth <steven@midlink.org>2013-05-13 10:55:01 +0200
committerSteven Barth <steven@midlink.org>2013-05-13 10:55:01 +0200
commit570302d28d18d47f095f864be161045e169b5941 (patch)
tree186fc425d49a6fcc25075d4d517df43f466248ab /proto-shell.c
parent3b8673edadc8ce6d1d90c12e6b8e57eeb291c521 (diff)
Add support for IPv6 and interface target-routes & dependencies
Signed-off-by: Steven Barth <steven@midlink.org>
Diffstat (limited to 'proto-shell.c')
-rw-r--r--proto-shell.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/proto-shell.c b/proto-shell.c
index 02f1836..8bbc36e 100644
--- a/proto-shell.c
+++ b/proto-shell.c
@@ -58,6 +58,8 @@ struct proto_shell_dependency {
union if_addr host;
bool v6;
+
+ char interface[];
};
struct proto_shell_state {
@@ -105,12 +107,15 @@ proto_shell_if_down_cb(struct interface_user *dep, struct interface *iface,
static void
proto_shell_update_host_dep(struct proto_shell_dependency *dep)
{
- struct interface *iface;
+ struct interface *iface = NULL;
if (dep->dep.iface)
goto out;
- iface = interface_ip_add_target_route(&dep->host, dep->v6);
+ if (dep->interface[0])
+ iface = vlist_find(&interfaces, dep->interface, iface, node);
+
+ iface = interface_ip_add_target_route(&dep->host, dep->v6, iface);
if (!iface)
goto out;
@@ -616,17 +621,28 @@ proto_shell_add_host_dependency(struct proto_shell_state *state, struct blob_att
{
struct proto_shell_dependency *dep;
struct blob_attr *host = tb[NOTIFY_HOST];
+ struct blob_attr *ifname = tb[NOTIFY_IFNAME];
+ size_t ifnamelen = (ifname) ? blobmsg_data_len(ifname) : 1;
if (!host)
return UBUS_STATUS_INVALID_ARGUMENT;
- dep = calloc(1, sizeof(*dep));
- if (!inet_pton(AF_INET, blobmsg_data(host), &dep->host)) {
- free(dep);
- return UBUS_STATUS_INVALID_ARGUMENT;
+ dep = calloc(1, sizeof(*dep) + ifnamelen);
+ if (inet_pton(AF_INET, blobmsg_data(host), &dep->host) < 1) {
+ if (inet_pton(AF_INET6, blobmsg_data(host), &dep->host) < 1) {
+ free(dep);
+ return UBUS_STATUS_INVALID_ARGUMENT;
+ } else {
+ dep->v6 = true;
+ }
}
dep->proto = state;
+ if (ifname)
+ memcpy(dep->interface, blobmsg_data(ifname), ifnamelen);
+ else
+ dep->interface[0] = 0;
+
dep->dep.cb = proto_shell_if_up_cb;
interface_add_user(&dep->dep, NULL);
list_add(&dep->list, &state->deps);