This connects the offload provider infrastructure with the various places in conntrack where connection status changes take place.
Batches are only used in one place at the moment - during the expiration list traversal in ct_sweep. Future batch uses may be when processing the packet batch in the main conntrack_execute loop, but that isn't part of this series. Assisted-by: Claude Sonnet 4.6 <[email protected]> Signed-off-by: Aaron Conole <[email protected]> --- lib/conntrack.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 90 insertions(+), 3 deletions(-) diff --git a/lib/conntrack.c b/lib/conntrack.c index d183d4920b..fbc7e43dc6 100644 --- a/lib/conntrack.c +++ b/lib/conntrack.c @@ -27,6 +27,7 @@ #include "conntrack-tcp.h" #include "conntrack-tp.h" #include "coverage.h" +#include "ct-offload.h" #include "crc32c.h" #include "csum.h" #include "ct-dpif.h" @@ -533,6 +534,18 @@ conn_clean(struct conntrack *ct, struct conn *conn) atomic_count_dec(&zl->czl.count); } + struct ct_offload_ctx offload_ctx = { + .conn = conn, + .netdev_in = NULL, + .input_port_id = ODPP_NONE, + .key = &conn->key_node[CT_DIR_FWD].key, + }; + ovs_mutex_lock(&offload_ctx.conn->lock); + if (ct_offload_conn_is_offloaded(offload_ctx.conn)) { + ct_offload_conn_del(&offload_ctx); + } + ovs_mutex_unlock(&offload_ctx.conn->lock); + ovsrcu_postpone(delete_conn, conn); atomic_count_dec(&ct->n_conn); } @@ -1382,6 +1395,38 @@ process_one(struct conntrack *ct, struct dp_packet *pkt, helper, alg_exp, ct_alg_ctl, tp_id); } ovs_mutex_unlock(&ct->ct_lock); + + if (conn) { + struct ct_offload_ctx offload_ctx = { + .conn = conn, + .netdev_in = NULL, + .input_port_id = pkt->md.orig_in_port, + .key = &conn->key_node[CT_DIR_FWD].key, + }; + ovs_mutex_lock(&offload_ctx.conn->lock); + ct_offload_conn_add(&offload_ctx); + ovs_mutex_unlock(&offload_ctx.conn->lock); + } + } + + if (!create_new_conn && conn && ctx->reply && + (pkt->md.ct_state & CS_ESTABLISHED)) { + /* Notify offload providers that the connection is established. + * We use the reply bit to detect that the connection has + * transitioned and give us the input port, which should be the + * reverse direction port. */ + struct ct_offload_ctx offload_ctx = { + .conn = conn, + .netdev_in = NULL, + .input_port_id = pkt->md.orig_in_port, + .key = &conn->key_node[CT_DIR_FWD].key, + }; + ovs_mutex_lock(&offload_ctx.conn->lock); + if (ct_offload_conn_is_offloaded(offload_ctx.conn) && + !ct_offload_conn_is_established(offload_ctx.conn)) { + ct_offload_conn_established(&offload_ctx); + } + ovs_mutex_unlock(&offload_ctx.conn->lock); } write_ct_md(pkt, zone, conn, &ctx->key, alg_exp); @@ -1527,19 +1572,61 @@ ct_sweep(struct conntrack *ct, struct rculist *list, long long now, size_t *cleaned_count) OVS_NO_THREAD_SAFETY_ANALYSIS { + struct ct_offload_op_batch batch; + struct ct_offload_op *op; struct conn *conn; size_t cleaned = 0; size_t count = 0; + ct_offload_op_batch_init(&batch); + RCULIST_FOR_EACH (conn, node, list) { if (conn_expired(conn, now)) { - conn_clean(ct, conn); - cleaned++; + if (!ct_offload_conn_is_offloaded(conn)) { + conn_clean(ct, conn); + cleaned++; + } else { + struct ct_offload_ctx offload_ctx = { + .conn = conn, + .netdev_in = NULL, + .input_port_id = ODPP_NONE, + .key = &conn->key_node[CT_DIR_FWD].key, + }; + ct_offload_op_batch_add(&batch, CT_OFFLOAD_OP_UPD, + &offload_ctx); + } } - count++; } + /* Submit the batch to ask providers whether each offloaded connection + * is still active in hardware. The batch holds raw conn pointers; + * connections remain in the RCU-protected list for the duration of + * this sweep, so they are guaranteed live here. */ + ct_offload_op_batch_submit(&batch); + + CT_OFFLOAD_BATCH_OP_FOR_EACH (idx, op, &batch) { + struct conn *c = op->ctx.conn; + + if (op->error) { + /* Provider reports the connection is no longer active. */ + conn_clean(ct, c); + cleaned++; + } else { + /* Extend expiration by one sweep interval so the connection + * survives until the next pass. */ + long long new_exp = now + conntrack_get_sweep_interval(ct); + long long cur; + + atomic_read_relaxed(&c->expiration, &cur); + if (new_exp > cur) { + atomic_store_relaxed(&c->expiration, new_exp); + } + } + } + + ct_offload_op_batch_destroy(&batch); + if (cleaned_count) { *cleaned_count = cleaned; } -- 2.51.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
