|
|
5f9769 |
From a3a3062985cadc2f2193b10ccb3404d587028c61 Mon Sep 17 00:00:00 2001
|
|
|
5f9769 |
Message-Id: <a3a3062985cadc2f2193b10ccb3404d587028c61.1610458802.git.lorenzo.bianconi@redhat.com>
|
|
|
5f9769 |
In-Reply-To: <f21c1b7a467a691847b5552d4570af706fcc5bb0.1610458802.git.lorenzo.bianconi@redhat.com>
|
|
|
5f9769 |
References: <f21c1b7a467a691847b5552d4570af706fcc5bb0.1610458802.git.lorenzo.bianconi@redhat.com>
|
|
|
5f9769 |
From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
|
|
|
5f9769 |
Date: Fri, 8 Jan 2021 17:36:23 +0100
|
|
|
5f9769 |
Subject: [PATCH 15/16] bfd: support demand mode on rx side.
|
|
|
5f9769 |
|
|
|
5f9769 |
Introduce rx demand mode support according to RFC5880 [0].
|
|
|
5f9769 |
Demand mode on tx side is not supported yet.
|
|
|
5f9769 |
|
|
|
5f9769 |
https://tools.ietf.org/html/rfc5880
|
|
|
5f9769 |
Acked-by: Mark Michelson <mmichels@redhat.com>
|
|
|
5f9769 |
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
|
|
|
5f9769 |
Signed-off-by: Numan Siddique <numans@ovn.org>
|
|
|
5f9769 |
---
|
|
|
5f9769 |
controller/pinctrl.c | 105 ++++++++++++++++++++++++++++---------------
|
|
|
5f9769 |
1 file changed, 68 insertions(+), 37 deletions(-)
|
|
|
5f9769 |
|
|
|
5f9769 |
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
|
|
|
5f9769 |
index 6e363a0f9..5820ab659 100644
|
|
|
5f9769 |
--- a/controller/pinctrl.c
|
|
|
5f9769 |
+++ b/controller/pinctrl.c
|
|
|
5f9769 |
@@ -330,7 +330,8 @@ static void bfd_monitor_destroy(void);
|
|
|
5f9769 |
static void bfd_monitor_send_msg(struct rconn *swconn, long long int *bfd_time)
|
|
|
5f9769 |
OVS_REQUIRES(pinctrl_mutex);
|
|
|
5f9769 |
static void
|
|
|
5f9769 |
-pinctrl_handle_bfd_msg(const struct flow *ip_flow, struct dp_packet *pkt_in)
|
|
|
5f9769 |
+pinctrl_handle_bfd_msg(struct rconn *swconn, const struct flow *ip_flow,
|
|
|
5f9769 |
+ struct dp_packet *pkt_in)
|
|
|
5f9769 |
OVS_REQUIRES(pinctrl_mutex);
|
|
|
5f9769 |
static void bfd_monitor_run(struct ovsdb_idl_txn *ovnsb_idl_txn,
|
|
|
5f9769 |
const struct sbrec_bfd_table *bfd_table,
|
|
|
5f9769 |
@@ -2981,7 +2982,7 @@ process_packet_in(struct rconn *swconn, const struct ofp_header *msg)
|
|
|
5f9769 |
|
|
|
5f9769 |
case ACTION_OPCODE_BFD_MSG:
|
|
|
5f9769 |
ovs_mutex_lock(&pinctrl_mutex);
|
|
|
5f9769 |
- pinctrl_handle_bfd_msg(&headers, &packet);
|
|
|
5f9769 |
+ pinctrl_handle_bfd_msg(swconn, &headers, &packet);
|
|
|
5f9769 |
ovs_mutex_unlock(&pinctrl_mutex);
|
|
|
5f9769 |
break;
|
|
|
5f9769 |
|
|
|
5f9769 |
@@ -6411,6 +6412,8 @@ struct bfd_entry {
|
|
|
5f9769 |
uint32_t local_min_rx;
|
|
|
5f9769 |
uint32_t remote_min_rx;
|
|
|
5f9769 |
|
|
|
5f9769 |
+ bool remote_demand_mode;
|
|
|
5f9769 |
+
|
|
|
5f9769 |
uint8_t local_mult;
|
|
|
5f9769 |
|
|
|
5f9769 |
int64_t port_key;
|
|
|
5f9769 |
@@ -6495,7 +6498,8 @@ bfd_monitor_wait(long long int timeout)
|
|
|
5f9769 |
}
|
|
|
5f9769 |
|
|
|
5f9769 |
static void
|
|
|
5f9769 |
-bfd_monitor_put_bfd_msg(struct bfd_entry *entry, struct dp_packet *packet)
|
|
|
5f9769 |
+bfd_monitor_put_bfd_msg(struct bfd_entry *entry, struct dp_packet *packet,
|
|
|
5f9769 |
+ bool final)
|
|
|
5f9769 |
{
|
|
|
5f9769 |
struct udp_header *udp;
|
|
|
5f9769 |
struct bfd_msg *msg;
|
|
|
5f9769 |
@@ -6527,7 +6531,8 @@ bfd_monitor_put_bfd_msg(struct bfd_entry *entry, struct dp_packet *packet)
|
|
|
5f9769 |
msg->vers_diag = (BFD_VERSION << 5);
|
|
|
5f9769 |
msg->mult = entry->local_mult;
|
|
|
5f9769 |
msg->length = BFD_PACKET_LEN;
|
|
|
5f9769 |
- msg->flags = entry->state << 6;
|
|
|
5f9769 |
+ msg->flags = final ? BFD_FLAG_FINAL : 0;
|
|
|
5f9769 |
+ msg->flags |= entry->state << 6;
|
|
|
5f9769 |
msg->my_disc = entry->local_disc;
|
|
|
5f9769 |
msg->your_disc = entry->remote_disc;
|
|
|
5f9769 |
/* min_tx and min_rx are in us - RFC 5880 page 9 */
|
|
|
5f9769 |
@@ -6535,6 +6540,46 @@ bfd_monitor_put_bfd_msg(struct bfd_entry *entry, struct dp_packet *packet)
|
|
|
5f9769 |
msg->min_rx = htonl(entry->local_min_rx * 1000);
|
|
|
5f9769 |
}
|
|
|
5f9769 |
|
|
|
5f9769 |
+static void
|
|
|
5f9769 |
+pinctrl_send_bfd_tx_msg(struct rconn *swconn, struct bfd_entry *entry,
|
|
|
5f9769 |
+ bool final)
|
|
|
5f9769 |
+{
|
|
|
5f9769 |
+ uint64_t packet_stub[256 / 8];
|
|
|
5f9769 |
+ struct dp_packet packet;
|
|
|
5f9769 |
+ dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
|
|
|
5f9769 |
+ bfd_monitor_put_bfd_msg(entry, &packet, final);
|
|
|
5f9769 |
+
|
|
|
5f9769 |
+ uint64_t ofpacts_stub[4096 / 8];
|
|
|
5f9769 |
+ struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
|
|
|
5f9769 |
+
|
|
|
5f9769 |
+ /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
|
|
|
5f9769 |
+ uint32_t dp_key = entry->metadata;
|
|
|
5f9769 |
+ uint32_t port_key = entry->port_key;
|
|
|
5f9769 |
+ put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, &ofpacts);
|
|
|
5f9769 |
+ put_load(port_key, MFF_LOG_INPORT, 0, 32, &ofpacts);
|
|
|
5f9769 |
+ put_load(1, MFF_LOG_FLAGS, MLF_LOCAL_ONLY_BIT, 1, &ofpacts);
|
|
|
5f9769 |
+ struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
|
|
|
5f9769 |
+ resubmit->in_port = OFPP_CONTROLLER;
|
|
|
5f9769 |
+ resubmit->table_id = OFTABLE_LOG_INGRESS_PIPELINE;
|
|
|
5f9769 |
+
|
|
|
5f9769 |
+ struct ofputil_packet_out po = {
|
|
|
5f9769 |
+ .packet = dp_packet_data(&packet),
|
|
|
5f9769 |
+ .packet_len = dp_packet_size(&packet),
|
|
|
5f9769 |
+ .buffer_id = UINT32_MAX,
|
|
|
5f9769 |
+ .ofpacts = ofpacts.data,
|
|
|
5f9769 |
+ .ofpacts_len = ofpacts.size,
|
|
|
5f9769 |
+ };
|
|
|
5f9769 |
+
|
|
|
5f9769 |
+ match_set_in_port(&po.flow_metadata, OFPP_CONTROLLER);
|
|
|
5f9769 |
+ enum ofp_version version = rconn_get_version(swconn);
|
|
|
5f9769 |
+ enum ofputil_protocol proto =
|
|
|
5f9769 |
+ ofputil_protocol_from_ofp_version(version);
|
|
|
5f9769 |
+ queue_msg(swconn, ofputil_encode_packet_out(&po, proto));
|
|
|
5f9769 |
+ dp_packet_uninit(&packet);
|
|
|
5f9769 |
+ ofpbuf_uninit(&ofpacts);
|
|
|
5f9769 |
+}
|
|
|
5f9769 |
+
|
|
|
5f9769 |
+
|
|
|
5f9769 |
static bool
|
|
|
5f9769 |
bfd_monitor_need_update(void)
|
|
|
5f9769 |
{
|
|
|
5f9769 |
@@ -6607,39 +6652,11 @@ bfd_monitor_send_msg(struct rconn *swconn, long long int *bfd_time)
|
|
|
5f9769 |
continue;
|
|
|
5f9769 |
}
|
|
|
5f9769 |
|
|
|
5f9769 |
- uint64_t packet_stub[256 / 8];
|
|
|
5f9769 |
- struct dp_packet packet;
|
|
|
5f9769 |
- dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
|
|
|
5f9769 |
- bfd_monitor_put_bfd_msg(entry, &packet);
|
|
|
5f9769 |
-
|
|
|
5f9769 |
- uint64_t ofpacts_stub[4096 / 8];
|
|
|
5f9769 |
- struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
|
|
|
5f9769 |
-
|
|
|
5f9769 |
- /* Set MFF_LOG_DATAPATH and MFF_LOG_INPORT. */
|
|
|
5f9769 |
- uint32_t dp_key = entry->metadata;
|
|
|
5f9769 |
- uint32_t port_key = entry->port_key;
|
|
|
5f9769 |
- put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, &ofpacts);
|
|
|
5f9769 |
- put_load(port_key, MFF_LOG_INPORT, 0, 32, &ofpacts);
|
|
|
5f9769 |
- put_load(1, MFF_LOG_FLAGS, MLF_LOCAL_ONLY_BIT, 1, &ofpacts);
|
|
|
5f9769 |
- struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
|
|
|
5f9769 |
- resubmit->in_port = OFPP_CONTROLLER;
|
|
|
5f9769 |
- resubmit->table_id = OFTABLE_LOG_INGRESS_PIPELINE;
|
|
|
5f9769 |
-
|
|
|
5f9769 |
- struct ofputil_packet_out po = {
|
|
|
5f9769 |
- .packet = dp_packet_data(&packet),
|
|
|
5f9769 |
- .packet_len = dp_packet_size(&packet),
|
|
|
5f9769 |
- .buffer_id = UINT32_MAX,
|
|
|
5f9769 |
- .ofpacts = ofpacts.data,
|
|
|
5f9769 |
- .ofpacts_len = ofpacts.size,
|
|
|
5f9769 |
- };
|
|
|
5f9769 |
+ if (entry->remote_demand_mode) {
|
|
|
5f9769 |
+ continue;
|
|
|
5f9769 |
+ }
|
|
|
5f9769 |
|
|
|
5f9769 |
- match_set_in_port(&po.flow_metadata, OFPP_CONTROLLER);
|
|
|
5f9769 |
- enum ofp_version version = rconn_get_version(swconn);
|
|
|
5f9769 |
- enum ofputil_protocol proto =
|
|
|
5f9769 |
- ofputil_protocol_from_ofp_version(version);
|
|
|
5f9769 |
- queue_msg(swconn, ofputil_encode_packet_out(&po, proto));
|
|
|
5f9769 |
- dp_packet_uninit(&packet);
|
|
|
5f9769 |
- ofpbuf_uninit(&ofpacts);
|
|
|
5f9769 |
+ pinctrl_send_bfd_tx_msg(swconn, entry, false);
|
|
|
5f9769 |
|
|
|
5f9769 |
tx_timeout = MAX(entry->local_min_tx, entry->remote_min_rx);
|
|
|
5f9769 |
tx_timeout -= random_range((tx_timeout * 25) / 100);
|
|
|
5f9769 |
@@ -6696,6 +6713,10 @@ pinctrl_check_bfd_msg(const struct flow *ip_flow, struct dp_packet *pkt_in)
|
|
|
5f9769 |
return false;
|
|
|
5f9769 |
}
|
|
|
5f9769 |
|
|
|
5f9769 |
+ if ((flags & BFD_FLAG_FINAL) && (flags & BFD_FLAG_POLL)) {
|
|
|
5f9769 |
+ return false;
|
|
|
5f9769 |
+ }
|
|
|
5f9769 |
+
|
|
|
5f9769 |
enum bfd_state peer_state = msg->flags >> 6;
|
|
|
5f9769 |
if (peer_state >= BFD_STATE_INIT && !msg->your_disc) {
|
|
|
5f9769 |
return false;
|
|
|
5f9769 |
@@ -6705,7 +6726,8 @@ pinctrl_check_bfd_msg(const struct flow *ip_flow, struct dp_packet *pkt_in)
|
|
|
5f9769 |
}
|
|
|
5f9769 |
|
|
|
5f9769 |
static void
|
|
|
5f9769 |
-pinctrl_handle_bfd_msg(const struct flow *ip_flow, struct dp_packet *pkt_in)
|
|
|
5f9769 |
+pinctrl_handle_bfd_msg(struct rconn *swconn, const struct flow *ip_flow,
|
|
|
5f9769 |
+ struct dp_packet *pkt_in)
|
|
|
5f9769 |
OVS_REQUIRES(pinctrl_mutex)
|
|
|
5f9769 |
{
|
|
|
5f9769 |
if (!pinctrl_check_bfd_msg(ip_flow, pkt_in)) {
|
|
|
5f9769 |
@@ -6775,6 +6797,15 @@ pinctrl_handle_bfd_msg(const struct flow *ip_flow, struct dp_packet *pkt_in)
|
|
|
5f9769 |
break;
|
|
|
5f9769 |
}
|
|
|
5f9769 |
|
|
|
5f9769 |
+ if (entry->state == BFD_STATE_UP &&
|
|
|
5f9769 |
+ (msg->flags & BFD_FLAG_DEMAND)) {
|
|
|
5f9769 |
+ entry->remote_demand_mode = true;
|
|
|
5f9769 |
+ }
|
|
|
5f9769 |
+
|
|
|
5f9769 |
+ if (msg->flags & BFD_FLAG_POLL) {
|
|
|
5f9769 |
+ pinctrl_send_bfd_tx_msg(swconn, entry, true);
|
|
|
5f9769 |
+ }
|
|
|
5f9769 |
+
|
|
|
5f9769 |
out:
|
|
|
5f9769 |
/* let's try to bacth db updates */
|
|
|
5f9769 |
if (change_state) {
|
|
|
5f9769 |
--
|
|
|
5f9769 |
2.29.2
|
|
|
5f9769 |
|