1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
5 #include <libubox/avl-cmp.h>
15 static const struct blobmsg_policy service_policy
[__SERVICE_ATTR_MAX
] = {
16 [SERVICE_ATTR_TYPE
] = { "type", BLOBMSG_TYPE_STRING
},
17 [SERVICE_ATTR_CONFIG
] = { "config", BLOBMSG_TYPE_TABLE
},
18 [SERVICE_ATTR_MEMBERS
] = { "members", BLOBMSG_TYPE_ARRAY
},
21 void network_services_free(struct network
*net
)
23 vlist_flush_all(&net
->services
);
27 __service_parse_members(struct network
*net
, struct network_service
*s
,
30 struct network_group
*group
;
31 struct network_host
*host
;
34 host
= avl_find_element(&net
->hosts
, name
, host
, node
);
40 s
->members
[s
->n_members
++] = host
;
46 group
= avl_find_element(&net
->groups
, name
, group
, node
);
51 memcpy(&s
->members
[s
->n_members
], group
->members
,
52 group
->n_members
* sizeof(group
->members
[0]));
53 s
->n_members
+= group
->n_members
;
56 return group
->n_members
;
60 service_parse_members(struct network
*net
, struct network_service
*s
,
61 struct blob_attr
*data
)
63 struct blob_attr
*cur
;
67 blobmsg_for_each_attr(cur
, data
, rem
)
68 n
+= __service_parse_members(net
, s
, blobmsg_get_string(cur
));
74 service_add(struct network
*net
, struct blob_attr
*data
)
76 struct network_service
*s
;
77 struct blob_attr
*tb
[__SERVICE_ATTR_MAX
];
78 struct blob_attr
*cur
, *config
;
79 const char *name
= blobmsg_name(data
);
80 const char *type
= NULL
;
81 char *name_buf
, *type_buf
;
85 blobmsg_parse(service_policy
, __SERVICE_ATTR_MAX
, tb
,
86 blobmsg_data(data
), blobmsg_len(data
));
88 if ((cur
= tb
[SERVICE_ATTR_TYPE
]) != NULL
)
89 type
= blobmsg_get_string(cur
);
91 if (blobmsg_check_array(tb
[SERVICE_ATTR_MEMBERS
], BLOBMSG_TYPE_STRING
) < 0)
94 config
= tb
[SERVICE_ATTR_CONFIG
];
96 n_members
= service_parse_members(net
, NULL
, tb
[SERVICE_ATTR_MEMBERS
]);
97 s
= calloc_a(sizeof(*s
) + n_members
* sizeof(s
->members
[0]),
98 &name_buf
, strlen(name
) + 1,
99 &type_buf
, type
? strlen(type
) + 1 : 0,
100 &config_buf
, config
? blob_pad_len(config
) : 0);
102 strcpy(name_buf
, name
);
104 s
->type
= strcpy(type_buf
, type
);
106 s
->config
= memcpy(config_buf
, config
, blob_pad_len(config
));
108 service_parse_members(net
, s
, tb
[SERVICE_ATTR_MEMBERS
]);
109 vlist_add(&net
->services
, &s
->node
, name_buf
);
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
);
122 service_update(struct vlist_tree
*tree
, struct vlist_node
*node_new
,
123 struct vlist_node
*node_old
)
125 struct network_service
*s_old
;
127 s_old
= container_of_safe(node_old
, struct network_service
, node
);
132 void network_services_init(struct network
*net
)
134 vlist_init(&net
->services
, avl_strcmp
, service_update
);