Skip to content

Commit d1fb3dd

Browse files
authored
[BFD]Retry create BFD with different source UDP port on failure (#2225)
* [BFD]Retry create BFD with different source UDP port on failure. The create_bfd_session API can fail when a source port already used by a different application is passed to SAI create. To avoid failure, a retry logic is added to try with a different port number three times before failing
1 parent 53620f3 commit d1fb3dd

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

orchagent/bfdorch.cpp

+40
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ using namespace swss;
1717
#define BFD_SESSION_MILLISECOND_TO_MICROSECOND 1000
1818
#define BFD_SRCPORTINIT 49152
1919
#define BFD_SRCPORTMAX 65536
20+
#define NUM_BFD_SRCPORT_RETRIES 3
2021

2122
extern sai_bfd_api_t* sai_bfd_api;
2223
extern sai_object_id_t gSwitchId;
@@ -416,6 +417,12 @@ bool BfdOrch::create_bfd_session(const string& key, const vector<FieldValueTuple
416417

417418
sai_object_id_t bfd_session_id = SAI_NULL_OBJECT_ID;
418419
sai_status_t status = sai_bfd_api->create_bfd_session(&bfd_session_id, gSwitchId, (uint32_t)attrs.size(), attrs.data());
420+
421+
if (status != SAI_STATUS_SUCCESS)
422+
{
423+
status = retry_create_bfd_session(bfd_session_id, attrs);
424+
}
425+
419426
if (status != SAI_STATUS_SUCCESS)
420427
{
421428
SWSS_LOG_ERROR("Failed to create bfd session %s, rv:%d", key.c_str(), status);
@@ -439,6 +446,38 @@ bool BfdOrch::create_bfd_session(const string& key, const vector<FieldValueTuple
439446
return true;
440447
}
441448

449+
void BfdOrch::update_port_number(vector<sai_attribute_t> &attrs)
450+
{
451+
for (uint32_t attr_idx = 0; attr_idx < (uint32_t)attrs.size(); attr_idx++)
452+
{
453+
if (attrs[attr_idx].id == SAI_BFD_SESSION_ATTR_UDP_SRC_PORT)
454+
{
455+
auto old_num = attrs[attr_idx].value.u32;
456+
attrs[attr_idx].value.u32 = bfd_src_port();
457+
SWSS_LOG_WARN("BFD create using port number %d failed. Retrying with port number %d",
458+
old_num, attrs[attr_idx].value.u32);
459+
return;
460+
}
461+
}
462+
}
463+
464+
sai_status_t BfdOrch::retry_create_bfd_session(sai_object_id_t &bfd_session_id, vector<sai_attribute_t> attrs)
465+
{
466+
sai_status_t status = SAI_STATUS_FAILURE;
467+
468+
for (int retry = 0; retry < NUM_BFD_SRCPORT_RETRIES; retry++)
469+
{
470+
update_port_number(attrs);
471+
status = sai_bfd_api->create_bfd_session(&bfd_session_id, gSwitchId,
472+
(uint32_t)attrs.size(), attrs.data());
473+
if (status == SAI_STATUS_SUCCESS)
474+
{
475+
return status;
476+
}
477+
}
478+
return status;
479+
}
480+
442481
bool BfdOrch::remove_bfd_session(const string& key)
443482
{
444483
if (bfd_session_map.find(key) == bfd_session_map.end())
@@ -487,3 +526,4 @@ uint32_t BfdOrch::bfd_src_port(void)
487526

488527
return (port++);
489528
}
529+

orchagent/bfdorch.h

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ class BfdOrch: public Orch, public Subject
2727
uint32_t bfd_src_port(void);
2828

2929
bool register_bfd_state_change_notification(void);
30+
void update_port_number(std::vector<sai_attribute_t> &attrs);
31+
sai_status_t retry_create_bfd_session(sai_object_id_t &bfd_session_id, vector<sai_attribute_t> attrs);
3032

3133
std::map<std::string, sai_object_id_t> bfd_session_map;
3234
std::map<sai_object_id_t, BfdUpdate> bfd_session_lookup;

0 commit comments

Comments
 (0)