summaryrefslogtreecommitdiff
path: root/filter/data.c
diff options
context:
space:
mode:
authorMaria Matejka <mq@ucw.cz>2022-04-10 18:55:15 +0200
committerMaria Matejka <mq@ucw.cz>2022-05-04 15:37:41 +0200
commitf2f3163f6c3fba7f9ef03640d7b2f6323873d2cc (patch)
treed0f3129250e783d347c63f649b02880abf569c1d /filter/data.c
parentde86040b2cf4ec9bfbb64f0e208a19d4d7e51adc (diff)
Filters always allocate from tmp_linpool
Diffstat (limited to 'filter/data.c')
-rw-r--r--filter/data.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/filter/data.c b/filter/data.c
index 381448fa..425dfdd3 100644
--- a/filter/data.c
+++ b/filter/data.c
@@ -602,3 +602,75 @@ val_dump(const struct f_val *v) {
return val_dump_buffer;
}
+
+struct f_val *
+lp_val_copy(struct linpool *lp, const struct f_val *v)
+{
+ switch (v->type)
+ {
+ case T_VOID:
+ case T_BOOL:
+ case T_INT:
+ case T_IP:
+ case T_PAIR:
+ case T_QUAD:
+ case T_EC:
+ case T_LC:
+ case T_RD:
+ case T_ENUM:
+ case T_PATH_MASK_ITEM:
+ /* These aren't embedded but there is no need to copy them */
+ case T_SET:
+ case T_PREFIX_SET:
+ case T_PATH_MASK:
+ case T_IFACE:
+ {
+ struct f_val *out = lp_alloc(lp, sizeof(*out));
+ *out = *v;
+ return out;
+ }
+
+ case T_NET:
+ {
+ struct {
+ struct f_val val;
+ net_addr net[0];
+ } *out = lp_alloc(lp, sizeof(*out) + v->val.net->length);
+ out->val = *v;
+ out->val.val.net = out->net;
+ net_copy(out->net, v->val.net);
+ return &out->val;
+ }
+
+ case T_STRING:
+ {
+ uint len = strlen(v->val.s);
+ struct {
+ struct f_val val;
+ char buf[0];
+ } *out = lp_alloc(lp, sizeof(*out) + len + 1);
+ out->val = *v;
+ out->val.val.s = out->buf;
+ memcpy(out->buf, v->val.s, len+1);
+ return &out->val;
+ }
+
+ case T_PATH:
+ case T_CLIST:
+ case T_ECLIST:
+ case T_LCLIST:
+ {
+ struct {
+ struct f_val val;
+ struct adata ad;
+ } *out = lp_alloc(lp, sizeof(*out) + v->val.ad->length);
+ out->val = *v;
+ out->val.val.ad = &out->ad;
+ memcpy(&out->ad, v->val.ad, v->val.ad->length);
+ return &out->val;
+ }
+
+ default:
+ bug("Unknown type in value copy: %d", v->type);
+ }
+}