/* The set of characters that may separate one action or one key attribute
* from another. */
static const char *delimiters = ", \t\r\n";
+static const char *delimiters_end = ", \t\r\n)";
struct attr_len_tbl {
int len;
.min_len = sizeof(uint32_t) * 2 },
[OVS_CT_ATTR_LABELS] = { .type = NL_A_UNSPEC, .optional = true,
.min_len = sizeof(struct ovs_key_ct_labels) * 2 },
+ [OVS_CT_ATTR_HELPER] = { .type = NL_A_STRING, .optional = true,
+ .min_len = 1, .max_len = 16 },
};
static void
struct nlattr *a[ARRAY_SIZE(ovs_conntrack_policy)];
const ovs_u128 *label;
const uint32_t *mark;
+ const char *helper;
uint16_t zone;
bool commit;
zone = a[OVS_CT_ATTR_ZONE] ? nl_attr_get_u16(a[OVS_CT_ATTR_ZONE]) : 0;
mark = a[OVS_CT_ATTR_MARK] ? nl_attr_get(a[OVS_CT_ATTR_MARK]) : NULL;
label = a[OVS_CT_ATTR_LABELS] ? nl_attr_get(a[OVS_CT_ATTR_LABELS]): NULL;
+ helper = a[OVS_CT_ATTR_HELPER] ? nl_attr_get(a[OVS_CT_ATTR_HELPER]) : NULL;
ds_put_format(ds, "ct");
- if (commit || zone || mark || label) {
+ if (commit || zone || mark || label || helper) {
ds_put_cstr(ds, "(");
if (commit) {
ds_put_format(ds, "commit,");
ds_put_format(ds, "label=");
format_u128(ds, label, label + 1, true);
}
+ if (helper) {
+ ds_put_format(ds, "helper=%s,", helper);
+ }
ds_chomp(ds, ',');
ds_put_cstr(ds, ")");
}
const char *s = s_;
if (ovs_scan(s, "ct")) {
+ const char *helper = NULL;
+ size_t helper_len = 0;
bool commit = false;
uint16_t zone = 0;
struct {
s += retval;
continue;
}
+ if (ovs_scan(s, "helper=%n", &n)) {
+ s += n;
+ helper_len = strcspn(s, delimiters_end);
+ if (!helper_len || helper_len > 15) {
+ return -EINVAL;
+ }
+ helper = s;
+ s += helper_len;
+ continue;
+ }
return -EINVAL;
}
nl_msg_put_unspec(actions, OVS_CT_ATTR_LABELS, &ct_label,
sizeof ct_label);
}
+ if (helper) {
+ nl_msg_put_string__(actions, OVS_CT_ATTR_HELPER, helper,
+ helper_len);
+ }
nl_msg_end_nested(actions, start);
}