[ovs-dev] [PATCH ovn 4/4] bfp: support demand mode on rx side
Lorenzo Bianconi
lorenzo.bianconi at redhat.com
Wed Nov 25 09:59:41 UTC 2020
Introduce rx demand mode support according to RFC5880 [0].
Demand mode on tx side is not supported yet
https://tools.ietf.org/html/rfc5880
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
---
controller/pinctrl.c | 104 +++++++++++++++++++++++++++----------------
1 file changed, 66 insertions(+), 38 deletions(-)
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index c46a19ca2..89b632058 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -331,7 +331,7 @@ static void bfd_monitor_send_msg(struct rconn *swconn, long long int *bfd_time)
OVS_REQUIRES(pinctrl_mutex);
static void
pinctrl_handle_bfd_msg(struct rconn *swconn, const struct flow *ip_flow,
- struct dp_packet *pkt_in, const struct match *md)
+ struct dp_packet *pkt_in)
OVS_REQUIRES(pinctrl_mutex);
static void bfd_monitor_run(const struct sbrec_bfd_table *bfd_table,
struct ovsdb_idl_index *sbrec_port_binding_by_name,
@@ -2981,7 +2981,7 @@ process_packet_in(struct rconn *swconn, const struct ofp_header *msg)
case ACTION_OPCODE_BFD_MSG:
ovs_mutex_lock(&pinctrl_mutex);
- pinctrl_handle_bfd_msg(swconn, &headers, &packet, &pin.flow_metadata);
+ pinctrl_handle_bfd_msg(swconn, &headers, &packet);
ovs_mutex_unlock(&pinctrl_mutex);
break;
@@ -6401,6 +6401,8 @@ struct bfd_entry {
uint32_t local_min_rx;
uint32_t remote_min_rx;
+ bool remote_demand_mode;
+
uint8_t local_mult;
int64_t port_key;
@@ -6482,7 +6484,8 @@ bfd_monitor_wait(long long int timeout)
}
static void
-bfd_monitor_put_bfd_msg(struct bfd_entry *entry, struct dp_packet *packet)
+bfd_monitor_put_bfd_msg(struct bfd_entry *entry, struct dp_packet *packet,
+ bool final)
{
struct udp_header *udp;
struct bfd_msg *msg;
@@ -6513,13 +6516,54 @@ bfd_monitor_put_bfd_msg(struct bfd_entry *entry, struct dp_packet *packet)
msg->vers_diag = (BFD_VERSION << 5);
msg->mult = entry->local_mult;
msg->length = BFD_PACKET_LEN;
- msg->flags = entry->state << 6;
+ msg->flags = final ? BFD_FLAG_FINAL : 0;
+ msg->flags |= entry->state << 6;
msg->my_disc = entry->local_disc;
msg->your_disc = entry->remote_disc;
msg->min_tx = htonl(entry->local_min_tx * 1000);
msg->min_rx = htonl(entry->local_min_rx * 1000);
}
+static void
+pinctrl_send_bfd_tx_msg(struct rconn *swconn, struct bfd_entry *entry,
+ bool final)
+{
+ uint64_t packet_stub[256 / 8];
+ struct dp_packet packet;
+ dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
+ bfd_monitor_put_bfd_msg(entry, &packet, final);
+
+ uint64_t ofpacts_stub[4096 / 8];
+ struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
+
+ /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
+ uint32_t dp_key = entry->metadata;
+ uint32_t port_key = entry->port_key;
+ put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, &ofpacts);
+ put_load(port_key, MFF_LOG_INPORT, 0, 32, &ofpacts);
+ put_load(1, MFF_LOG_FLAGS, MLF_LOCAL_ONLY_BIT, 1, &ofpacts);
+ struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
+ resubmit->in_port = OFPP_CONTROLLER;
+ resubmit->table_id = OFTABLE_LOG_INGRESS_PIPELINE;
+
+ struct ofputil_packet_out po = {
+ .packet = dp_packet_data(&packet),
+ .packet_len = dp_packet_size(&packet),
+ .buffer_id = UINT32_MAX,
+ .ofpacts = ofpacts.data,
+ .ofpacts_len = ofpacts.size,
+ };
+
+ match_set_in_port(&po.flow_metadata, OFPP_CONTROLLER);
+ enum ofp_version version = rconn_get_version(swconn);
+ enum ofputil_protocol proto =
+ ofputil_protocol_from_ofp_version(version);
+ queue_msg(swconn, ofputil_encode_packet_out(&po, proto));
+ dp_packet_uninit(&packet);
+ ofpbuf_uninit(&ofpacts);
+}
+
+
static bool
bpf_monitor_need_update(void)
{
@@ -6570,40 +6614,11 @@ bfd_monitor_send_msg(struct rconn *swconn, long long int *bfd_time)
goto next;
}
- uint64_t packet_stub[256 / 8];
- struct dp_packet packet;
- dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
- bfd_monitor_put_bfd_msg(entry, &packet);
-
- uint64_t ofpacts_stub[4096 / 8];
- struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
-
- /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
- uint32_t dp_key = entry->metadata;
- uint32_t port_key = entry->port_key;
- put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, &ofpacts);
- put_load(port_key, MFF_LOG_INPORT, 0, 32, &ofpacts);
- put_load(1, MFF_LOG_FLAGS, MLF_LOCAL_ONLY_BIT, 1, &ofpacts);
- struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
- resubmit->in_port = OFPP_CONTROLLER;
- resubmit->table_id = OFTABLE_LOG_INGRESS_PIPELINE;
-
- struct ofputil_packet_out po = {
- .packet = dp_packet_data(&packet),
- .packet_len = dp_packet_size(&packet),
- .buffer_id = UINT32_MAX,
- .ofpacts = ofpacts.data,
- .ofpacts_len = ofpacts.size,
- };
-
- match_set_in_port(&po.flow_metadata, OFPP_CONTROLLER);
- enum ofp_version version = rconn_get_version(swconn);
- enum ofputil_protocol proto =
- ofputil_protocol_from_ofp_version(version);
- queue_msg(swconn, ofputil_encode_packet_out(&po, proto));
- dp_packet_uninit(&packet);
- ofpbuf_uninit(&ofpacts);
+ if (entry->remote_demand_mode) {
+ goto next;
+ }
+ pinctrl_send_bfd_tx_msg(swconn, entry, false);
unsigned long tx_timeout = MAX(entry->local_min_tx,
entry->remote_min_rx);
tx_timeout -= random_range((tx_timeout * 25) / 100);
@@ -6660,6 +6675,10 @@ pinctrl_check_bfd_msg(const struct flow *ip_flow, struct dp_packet *pkt_in)
return false;
}
+ if ((flags & BFD_FLAG_FINAL) && (flags & BFD_FLAG_POLL)) {
+ return false;
+ }
+
enum bfd_state peer_state = msg->flags >> 6;
if (peer_state >= BFD_STATE_INIT && !msg->your_disc) {
return false;
@@ -6670,7 +6689,7 @@ pinctrl_check_bfd_msg(const struct flow *ip_flow, struct dp_packet *pkt_in)
static void
pinctrl_handle_bfd_msg(struct rconn *swconn, const struct flow *ip_flow,
- struct dp_packet *pkt_in, const struct match *md)
+ struct dp_packet *pkt_in)
OVS_REQUIRES(pinctrl_mutex)
{
if (!pinctrl_check_bfd_msg(ip_flow, pkt_in)) {
@@ -6740,6 +6759,15 @@ pinctrl_handle_bfd_msg(struct rconn *swconn, const struct flow *ip_flow,
break;
}
+ if (entry->state == BFD_STATE_UP &&
+ (msg->flags & BFD_FLAG_DEMAND)) {
+ entry->remote_demand_mode = true;
+ }
+
+ if (msg->flags & BFD_FLAG_POLL) {
+ pinctrl_send_bfd_tx_msg(swconn, entry, true);
+ }
+
out:
/* let's try to bacth db updates */
if (change_state) {
--
2.28.0
More information about the dev
mailing list