@@ -21,6 +21,7 @@ struct tcf_ct_params {
struct {
u32 pkts;
+ u32 timeout;
} offload_policy;
struct nf_nat_range2 range;
@@ -22,6 +22,7 @@ enum {
TCA_CT_NAT_PORT_MIN, /* be16 */
TCA_CT_NAT_PORT_MAX, /* be16 */
TCA_CT_OFFLOAD_POLICY_PKTS, /* u32 */
+ TCA_CT_OFFLOAD_POLICY_TIMEOUT, /* u32 */
TCA_CT_PAD,
__TCA_CT_MAX
};
@@ -49,6 +49,7 @@ struct tcf_ct_flow_table {
struct {
u32 pkts;
+ u32 timeout;
} offload_policy;
bool dying;
@@ -284,6 +285,12 @@ static int tcf_ct_flow_table_policy_set(struct net *net,
NL_SET_ERR_MSG_MOD(extack, "Policy pkts must match previous action ct instance");
return -EOPNOTSUPP;
}
+
+ if (params->offload_policy.timeout !=
+ ct_ft->offload_policy.timeout) {
+ NL_SET_ERR_MSG_MOD(extack, "Policy timeout must match previous action ct instance");
+ return -EOPNOTSUPP;
+ }
return 0;
}
@@ -292,6 +299,8 @@ static int tcf_ct_flow_table_policy_set(struct net *net,
if (!nf_ct_acct_enabled(net))
nf_ct_set_acct(net, true);
}
+
+ ct_ft->offload_policy.timeout = params->offload_policy.timeout;
return 0;
}
@@ -344,6 +353,7 @@ static int tcf_ct_flow_table_get(struct tcf_ct_params *params,
ct_ft->nf_ft.type = &flowtable_ct;
ct_ft->nf_ft.flags |= NF_FLOWTABLE_HW_OFFLOAD;
+ ct_ft->nf_ft.flow_timeout = params->offload_policy.timeout;
err = nf_flow_table_init(&ct_ft->nf_ft);
if (err)
goto err_init;
@@ -1089,6 +1099,7 @@ static int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
[TCA_CT_NAT_PORT_MIN] = { .type = NLA_U16 },
[TCA_CT_NAT_PORT_MAX] = { .type = NLA_U16 },
[TCA_CT_OFFLOAD_POLICY_PKTS] = { .type = NLA_U32 },
+ [TCA_CT_OFFLOAD_POLICY_TIMEOUT] = { .type = NLA_U32 },
};
static int tcf_ct_fill_params_nat(struct tcf_ct_params *p,
@@ -1238,6 +1249,10 @@ static int tcf_ct_fill_params(struct net *net,
p->offload_policy.pkts =
nla_get_u32(tb[TCA_CT_OFFLOAD_POLICY_PKTS]);
+ if (tb[TCA_CT_OFFLOAD_POLICY_TIMEOUT])
+ p->offload_policy.timeout =
+ nla_get_u32(tb[TCA_CT_OFFLOAD_POLICY_TIMEOUT]);
+
if (p->zone == NF_CT_DEFAULT_ZONE_ID)
return 0;
@@ -1484,6 +1499,10 @@ static inline int tcf_ct_dump(struct sk_buff *skb, struct tc_action *a,
p->offload_policy.pkts))
goto nla_put_failure;
+ if (nla_put_u32(skb, TCA_CT_OFFLOAD_POLICY_TIMEOUT,
+ p->offload_policy.timeout))
+ goto nla_put_failure;
+
skip_dump:
if (nla_put(skb, TCA_CT_PARMS, sizeof(opt), &opt))
goto nla_put_failure;