1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
9 static struct ubus_auto_conn conn
;
10 static struct blob_buf b
;
13 ubus_network_add(struct ubus_context
*ctx
, struct ubus_object
*obj
,
14 struct ubus_request_data
*req
, const char *method
,
15 struct blob_attr
*msg
)
17 struct blob_attr
*name
;
19 blobmsg_parse(&network_policy
[NETWORK_ATTR_NAME
], 1, &name
,
20 blobmsg_data(msg
), blobmsg_len(msg
));
23 return UBUS_STATUS_INVALID_ARGUMENT
;
25 if (unetd_network_add(blobmsg_get_string(name
), msg
))
26 return UBUS_STATUS_INVALID_ARGUMENT
;
33 ubus_network_del(struct ubus_context
*ctx
, struct ubus_object
*obj
,
34 struct ubus_request_data
*req
, const char *method
,
35 struct blob_attr
*msg
)
37 struct blob_attr
*name
;
39 blobmsg_parse(&network_policy
[NETWORK_ATTR_NAME
], 1, &name
,
40 blobmsg_data(msg
), blobmsg_len(msg
));
43 return UBUS_STATUS_INVALID_ARGUMENT
;
45 if (unetd_network_remove(blobmsg_get_string(name
)))
46 return UBUS_STATUS_NOT_FOUND
;
57 static const struct blobmsg_policy service_policy
[__SERVICE_ATTR_MAX
] = {
58 [SERVICE_ATTR_NETWORK
] = { "network", BLOBMSG_TYPE_STRING
},
59 [SERVICE_ATTR_NAME
] = { "name", BLOBMSG_TYPE_STRING
},
64 ubus_service_get_network_members(struct blob_buf
*b
, struct network
*n
,
67 struct network_service
*s
;
70 s
= vlist_find(&n
->services
, name
, s
, node
);
74 for (i
= 0; i
< s
->n_members
; i
++) {
75 struct network_host
*host
= s
->members
[i
];
78 name
= blobmsg_alloc_string_buffer(b
, NULL
, INET6_ADDRSTRLEN
);
79 inet_ntop(AF_INET6
, &host
->peer
.local_addr
.in6
, name
, INET6_ADDRSTRLEN
);
80 blobmsg_add_string_buffer(b
);
86 ubus_service_get(struct ubus_context
*ctx
, struct ubus_object
*obj
,
87 struct ubus_request_data
*req
, const char *method
,
88 struct blob_attr
*msg
)
90 struct blob_attr
*tb
[__SERVICE_ATTR_MAX
];
91 struct blob_attr
*cur
;
92 struct network
*n
= NULL
;
96 blobmsg_parse(service_policy
, __SERVICE_ATTR_MAX
, tb
,
97 blobmsg_data(msg
), blobmsg_len(msg
));
99 if ((cur
= tb
[SERVICE_ATTR_NAME
]) != NULL
)
100 name
= blobmsg_get_string(cur
);
102 return UBUS_STATUS_INVALID_ARGUMENT
;
104 if ((cur
= tb
[SERVICE_ATTR_NETWORK
]) != NULL
) {
105 n
= avl_find_element(&networks
, blobmsg_get_string(cur
), n
, node
);
107 return UBUS_STATUS_INVALID_ARGUMENT
;
110 blob_buf_init(&b
, 0);
112 c
= blobmsg_open_array(&b
, "hosts");
114 ubus_service_get_network_members(&b
, n
, name
);
116 avl_for_each_element(&networks
, n
, node
)
117 ubus_service_get_network_members(&b
, n
, name
);
119 blobmsg_close_array(&b
, c
);
120 ubus_send_reply(ctx
, req
, b
.head
);
125 static const struct ubus_method unetd_methods
[] = {
126 UBUS_METHOD("network_add", ubus_network_add
, network_policy
),
127 UBUS_METHOD_MASK("network_del", ubus_network_del
, network_policy
,
128 (1 << NETWORK_ATTR_NAME
)),
129 UBUS_METHOD("service_get", ubus_service_get
, service_policy
),
132 static struct ubus_object_type unetd_object_type
=
133 UBUS_OBJECT_TYPE("unetd", unetd_methods
);
135 static struct ubus_object unetd_object
= {
137 .type
= &unetd_object_type
,
138 .methods
= unetd_methods
,
139 .n_methods
= ARRAY_SIZE(unetd_methods
),
143 ubus_connect_handler(struct ubus_context
*ctx
)
147 ret
= ubus_add_object(ctx
, &unetd_object
);
149 fprintf(stderr
, "Failed to add object: %s\n", ubus_strerror(ret
));
152 void unetd_ubus_netifd_update(struct blob_attr
*data
)
156 if (ubus_lookup_id(&conn
.ctx
, "network.interface", &id
))
159 ubus_invoke(&conn
.ctx
, id
, "notify_proto", data
, NULL
, NULL
, 5000);
162 void unetd_ubus_netifd_add_route(struct network
*net
, union network_endpoint
*ep
)
168 if (!net
->config
.interface
)
171 if (ubus_lookup_id(&conn
.ctx
, "network", &id
))
174 blob_buf_init(&b
, 0);
176 if (ep
->in
.sin_family
== AF_INET6
)
177 addr
= &ep
->in6
.sin6_addr
;
179 addr
= &ep
->in
.sin_addr
;
181 blobmsg_add_u8(&b
, "v6", ep
->in
.sin_family
== AF_INET6
);
182 buf
= blobmsg_alloc_string_buffer(&b
, "target", INET6_ADDRSTRLEN
);
183 inet_ntop(ep
->in
.sin_family
, addr
, buf
, INET6_ADDRSTRLEN
);
184 blobmsg_add_string_buffer(&b
);
185 blobmsg_add_string(&b
, "interface", net
->config
.interface
);
186 blobmsg_add_u8(&b
, "exclude", true);
188 ubus_invoke(&conn
.ctx
, id
, "add_host_route", b
.head
, NULL
, NULL
, -1);
191 void unetd_ubus_init(void)
193 conn
.cb
= ubus_connect_handler
;
194 ubus_auto_connect(&conn
);