1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
5 #include <libubox/avl-cmp.h>
14 static const struct blobmsg_policy service_policy
[__SERVICE_ATTR_MAX
] = {
15 [SERVICE_ATTR_TYPE
] = { "type", BLOBMSG_TYPE_STRING
},
16 [SERVICE_ATTR_MEMBERS
] = { "members", BLOBMSG_TYPE_ARRAY
},
19 void network_services_init(struct network
*net
)
21 avl_init(&net
->services
, avl_strcmp
, false, NULL
);
24 void network_services_free(struct network
*net
)
26 struct network_service
*s
, *tmp
;
28 avl_remove_all_elements(&net
->services
, s
, node
, tmp
)
33 __service_parse_members(struct network
*net
, struct network_service
*s
,
36 struct network_group
*group
;
37 struct network_host
*host
;
40 host
= avl_find_element(&net
->hosts
, name
, host
, node
);
46 s
->members
[s
->n_members
++] = host
;
52 group
= avl_find_element(&net
->groups
, name
, group
, node
);
57 memcpy(&s
->members
[s
->n_members
], group
->members
,
58 group
->n_members
* sizeof(group
->members
[0]));
59 s
->n_members
+= group
->n_members
;
62 return group
->n_members
;
66 service_parse_members(struct network
*net
, struct network_service
*s
,
67 struct blob_attr
*data
)
69 struct blob_attr
*cur
;
73 blobmsg_for_each_attr(cur
, data
, rem
)
74 n
+= __service_parse_members(net
, s
, blobmsg_get_string(cur
));
80 service_add(struct network
*net
, struct blob_attr
*data
)
82 struct network_service
*s
;
83 struct blob_attr
*tb
[__SERVICE_ATTR_MAX
];
84 struct blob_attr
*cur
;
85 const char *name
= blobmsg_name(data
);
86 const char *type
= NULL
;
87 char *name_buf
, *type_buf
;
90 blobmsg_parse(service_policy
, __SERVICE_ATTR_MAX
, tb
,
91 blobmsg_data(data
), blobmsg_len(data
));
93 if ((cur
= tb
[SERVICE_ATTR_TYPE
]) != NULL
)
94 type
= blobmsg_get_string(cur
);
96 if (blobmsg_check_array(tb
[SERVICE_ATTR_MEMBERS
], BLOBMSG_TYPE_STRING
) < 0)
99 n_members
= service_parse_members(net
, NULL
, tb
[SERVICE_ATTR_MEMBERS
]);
100 s
= calloc_a(sizeof(*s
) + n_members
* sizeof(s
->members
[0]),
101 &name_buf
, strlen(name
) + 1,
102 &type_buf
, type
? strlen(type
) + 1 : 0);
104 s
->node
.key
= strcpy(name_buf
, name
);
106 s
->type
= strcpy(type_buf
, type
);
108 service_parse_members(net
, s
, tb
[SERVICE_ATTR_MEMBERS
]);
109 avl_insert(&net
->services
, &s
->node
);
112 void network_services_add(struct network
*net
, struct blob_attr
*data
)
114 struct blob_attr
*cur
;
117 blobmsg_for_each_attr(cur
, data
, rem
)
118 service_add(net
, cur
);