Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linkmgrd subscribing State DB route event #13

Merged
merged 23 commits into from
Jan 19, 2022
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
ecfac00
Declare handlers in mux manager mux port
zjswhhh Dec 14, 2021
21c8202
Define handlers in linkmgrd
zjswhhh Dec 14, 2021
199917d
Fix unstable unit tests (state change handler wasn't invoked) (#8)
zjswhhh Dec 1, 2021
24a11ea
Add pull request template for linkmgrd repo (#9)
zjswhhh Dec 6, 2021
4bd2012
Merge branch 'Azure:master' into subscribeRouteEvent
zjswhhh Dec 15, 2021
9d38f17
Update route table name
zjswhhh Dec 15, 2021
88403cc
Revert "Update route table name"
zjswhhh Dec 15, 2021
2f9fed0
Add unit tests
zjswhhh Dec 16, 2021
12f3b97
Fix syntax issue
zjswhhh Dec 16, 2021
ba54965
Fix syntax issue
zjswhhh Dec 16, 2021
7d4d091
Fix syntax issue
zjswhhh Dec 16, 2021
cc60ba5
Check IPv4 default route state only.
zjswhhh Jan 3, 2022
a0ddcf4
Coding conventions.
zjswhhh Jan 5, 2022
6c29483
Force switch when mux state is not equal to standby
zjswhhh Jan 14, 2022
d34cf11
Merge branch 'Azure:master' into subscribeRouteEvent
zjswhhh Jan 14, 2022
afd2ec8
Improve PR template (#16)
lolyu Dec 13, 2021
a784541
[linkmgrd] update README, set coding style guidance (#15)
yxieca Jan 4, 2022
550aec3
Add missing intermediate states (#16)
lolyu Jan 6, 2022
5438347
Add TLV support to ICMP payload (#11)
lolyu Dec 13, 2021
0dd8eda
Revert "Add TLV support to ICMP payload (#11)"
zjswhhh Jan 18, 2022
650a3b4
update make_adress to handle invalid ip received
zjswhhh Jan 19, 2022
fe583f0
Merge branch 'subscribeRouteEvent' of https://github.com/zjswhhh/soni…
zjswhhh Jan 19, 2022
e14a524
Remove make_address to avoid extra complexity.
zjswhhh Jan 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions src/DbInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,54 @@ void DbInterface::handleMuxStateNotifiction(swss::SubscriberStateTable &statedbP
processMuxStateNotifiction(entries);
}

//
// ---> processDefaultRouteStateNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries)
//
// process default route state notification from orchagent
//
void DbInterface::processDefaultRouteStateNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries)
{
for (auto &entry: entries) {
std::string key = kfvKey(entry);
std::string op = kfvOp(entry);
std::vector<swss::FieldValueTuple> fieldValues = kfvFieldsValues(entry);

std::vector<swss::FieldValueTuple>::const_iterator cit = std::find_if(
fieldValues.cbegin(),
fieldValues.cend(),
[] (const swss::FieldValueTuple &fv) {return fvField(fv) == "state";}
);

if (cit != fieldValues.cend()) {
const std::string field = cit->first;
const std::string value = cit->second;

MUXLOGDEBUG(boost::format("key: %s, operation: %s, field: %s, value: %s") %
key %
op %
field %
value
);

boost::asio::ip::address ipAddress = boost::asio::ip::make_address(key);
mMuxManagerPtr->addOrUpdateDefaultRouteState(ipAddress, value);
}
}
}

//
// ---> handleDefaultRouteStateNotification(swss::SubscriberStateTable &statedbRouteTable);
//
// handle Default Route State notification from orchagent
//
void DbInterface::handleDefaultRouteStateNotification(swss::SubscriberStateTable &statedbRouteTable)
{
std::deque<swss::KeyOpFieldsValuesTuple> entries;

statedbRouteTable.pops(entries);
processDefaultRouteStateNotification(entries);
}

//
// ---> handleSwssNotification();
//
Expand All @@ -752,6 +800,8 @@ void DbInterface::handleSwssNotification()
swss::SubscriberStateTable appDbMuxResponseTable(appDbPtr.get(), APP_MUX_CABLE_RESPONSE_TABLE_NAME);
// for getting state db MUX state when orchagent updates it
swss::SubscriberStateTable stateDbPortTable(stateDbPtr.get(), STATE_MUX_CABLE_TABLE_NAME);
// for getting state db default route state
swss::SubscriberStateTable stateDbRouteTable(stateDbPtr.get(), STATE_ROUTE_TABLE_NAME);

getTorMacAddress(configDbPtr);
getLoopback2InterfaceInfo(configDbPtr);
Expand All @@ -771,6 +821,7 @@ void DbInterface::handleSwssNotification()
swssSelect.addSelectable(&appDbPortTable);
swssSelect.addSelectable(&appDbMuxResponseTable);
swssSelect.addSelectable(&stateDbPortTable);
swssSelect.addSelectable(&stateDbRouteTable);
swssSelect.addSelectable(&netlinkNeighbor);

while (mPollSwssNotifcation) {
Expand All @@ -797,6 +848,8 @@ void DbInterface::handleSwssNotification()
handleMuxResponseNotifiction(appDbMuxResponseTable);
} else if (selectable == static_cast<swss::Selectable *> (&stateDbPortTable)) {
handleMuxStateNotifiction(stateDbPortTable);
} else if (selectable == static_cast<swss::Selectable *> (&stateDbRouteTable)) {
handleDefaultRouteStateNotification(stateDbRouteTable);
} else if (selectable == static_cast<swss::Selectable *> (&netlinkNeighbor)) {
continue;
} else {
Expand Down
22 changes: 22 additions & 0 deletions src/DbInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,28 @@ class DbInterface
*/
void handleSwssNotification();

/**
* @method processDefaultRouteStateNotification
*
* @brief process default route state notification from orchagent
*
* @param entries reference to state db default route state entries
*
* @return none
*/
void processDefaultRouteStateNotification(std::deque<swss::KeyOpFieldsValuesTuple> &entries);

/**
* @method handleDefaultRouteStateNotification
*
* @brief handle Default Route State notification from orchagent
*
* @param statedbRouteTable reference to state db route table
*
* @return none
*/
void handleDefaultRouteStateNotification(swss::SubscriberStateTable &statedbRouteTable);

private:
static std::vector<std::string> mMuxState;
static std::vector<std::string> mMuxLinkmgrState;
Expand Down
28 changes: 28 additions & 0 deletions src/MuxManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,34 @@ void MuxManager::processProbeMuxState(const std::string &portName, const std::st
}
}

//
// ---> addOrUpdateDefaultRouteState(boost::asio::ip::address& address, const std::string &routeState);
//
// update default route state based on state db notification
//
void MuxManager::addOrUpdateDefaultRouteState(boost::asio::ip::address address, const std::string &routeState)
{
MUXLOGINFO(boost::format("%s: default route state: %s") % address % routeState);

if (address.is_v4()) {
mIpv4DefaultRouteState = routeState;
} else {
mIpv6DefaultRouteState = routeState;
}

std::string nextState = "na";
// For now we only need IPv4 default route state, this logic can be updated in the future.
if (mIpv4DefaultRouteState == "ok") {
nextState = "ok";
}

PortMapIterator portMapIterator = mPortMap.begin();
while(portMapIterator != mPortMap.end()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

space after while please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated accordingly.

portMapIterator->second->handleDefaultRouteState(nextState);
portMapIterator ++;
}
}

//
// ---> getMuxPortPtrOrThrow(const std::string &portName);
//
Expand Down
16 changes: 16 additions & 0 deletions src/MuxManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,19 @@ class MuxManager
*/
void processProbeMuxState(const std::string &portName, const std::string &muxState);

/**
* @method addOrUpdateDefaultRouteState
*
* @brief update default route state based on state db notification
*
* @param ipAddress
* @param routeState
*
* @return none
*
*/
void addOrUpdateDefaultRouteState(boost::asio::ip::address address, const std::string &routeState);

private:
/**
*@method getMuxPortPtrOrThrow
Expand Down Expand Up @@ -360,6 +373,9 @@ class MuxManager
std::shared_ptr<mux::DbInterface> mDbInterfacePtr;

PortMap mPortMap;

std::string mIpv4DefaultRouteState = "na";
std::string mIpv6DefaultRouteState = "na";
};

} /* namespace mux */
Expand Down
16 changes: 16 additions & 0 deletions src/MuxPort.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,4 +228,20 @@ void MuxPort::handleMuxConfig(const std::string &config)
)));
}

//
// ---> handleDefaultRouteState(const std::string &routeState);
//
// handles default route state notification
//
void MuxPort::handleDefaultRouteState(const std::string &routeState)
{
MUXLOGDEBUG(boost::format("port: %s, state db default route state: %s") % mMuxPortConfig.getPortName() % routeState);

boost::asio::io_service &ioService = mStrand.context();
ioService.post(mStrand.wrap(boost::bind(
&link_manager::LinkManagerStateMachine::handleDefaultRouteStateNotification,
&mLinkManagerStateMachine,
routeState
)));
}
} /* namespace mux */
11 changes: 11 additions & 0 deletions src/MuxPort.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,17 @@ class MuxPort: public std::enable_shared_from_this<MuxPort>
*/
void handleMuxConfig(const std::string &config);

/**
* @method handleDefaultRouteState(const std::string &routeState)
*
* @brief handles default route state notification
*
* @param routeState
*
* @return none
*/
void handleDefaultRouteState(const std::string &routeState);

protected:
friend class test::MuxManagerTest;
friend class test::FakeMuxPort;
Expand Down
23 changes: 23 additions & 0 deletions src/link_manager/LinkManagerStateMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,29 @@ void LinkManagerStateMachine::handleSwitchActiveRequestEvent()
}
}

//
// ---> handleDefaultRouteStateNotification(const std::string &routeState);
//
// handle default route state notification from routeorch
//
void LinkManagerStateMachine::handleDefaultRouteStateNotification(const std::string &routeState)
{
MUXLOGWARNING(boost::format("%s: state db default route state: %s") % mMuxPortConfig.getPortName() % routeState);

if(mComponentInitState.test(MuxStateComponent)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add space after if

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated accordingly.

if (ms(mCompositeState) == mux_state::MuxState::Label::Active &&
routeState == "na") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest putting '{' on a new line, especially when if condition expands multiple lines. new line helps to identify the beginning of the if body.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated accordingly.

CompositeState nextState = mCompositeState;
enterLinkProberState(nextState, link_prober::LinkProberState::Wait);
switchMuxState(nextState, mux_state::MuxState::Label::Standby);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does it behave if both ToRs have default route as "na" ?

Copy link
Contributor Author

@zjswhhh zjswhhh Jan 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both ToRs will switch to standby, the one switches first will be "active" at the end.

Do we expect both ToRs to be "standby" in this scenario? This is not supported currently by linkmgrd as I know, we might need find other workaround if so.

LOGWARNING_MUX_STATE_TRANSITION(mMuxPortConfig.getPortName(), mCompositeState, nextState);
mCompositeState = nextState;
} else {
enterMuxWaitState(mCompositeState);
}
}
}

//
// ---> updateMuxLinkmgrState();
//
Expand Down
11 changes: 11 additions & 0 deletions src/link_manager/LinkManagerStateMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,17 @@ class LinkManagerStateMachine: public common::StateMachine,
*/
void handleSwitchActiveRequestEvent();

/**
* @method handleDefaultRouteStateNotification(const std::string &routeState)
*
* @brief handle default route state notification from routeorch
*
* @param routeState
*
* @return none
*/
void handleDefaultRouteStateNotification(const std::string &routeState);

private:
/**
*@method updateMuxLinkmgrState
Expand Down
40 changes: 40 additions & 0 deletions test/LinkManagerStateMachineTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,12 @@ void LinkManagerStateMachineTest::setMuxStandby()
VALIDATE_STATE(Standby, Standby, Up);
}

void LinkManagerStateMachineTest::postDefaultRouteEvent(std::string routeState, uint32_t count)
{
mFakeMuxPort.handleDefaultRouteState(routeState);
runIoService(count);
}

TEST_F(LinkManagerStateMachineTest, MuxActiveSwitchOver)
{
setMuxActive();
Expand Down Expand Up @@ -1002,4 +1008,38 @@ TEST_F(LinkManagerStateMachineTest, MuxStandby2Unknown2Error)
VALIDATE_STATE(Standby, Error, Down);
}

TEST_F(LinkManagerStateMachineTest, MuxActivDefaultRouteStateNA)
{
setMuxActive();

EXPECT_EQ(mDbInterfacePtr->mSetMuxStateInvokeCount, 0);
postDefaultRouteEvent("na", 3);

VALIDATE_STATE(Wait, Wait, Up);
EXPECT_EQ(mDbInterfacePtr->mSetMuxStateInvokeCount, 1);

postLinkProberEvent(link_prober::LinkProberState::Standby, 3);
VALIDATE_STATE(Standby, Wait, Up);

handleMuxState("standby", 3);
VALIDATE_STATE(Standby, Standby, Up);
}

TEST_F(LinkManagerStateMachineTest, MuxStandbyDefaultRouteStateOK)
{
setMuxStandby();

EXPECT_EQ(mDbInterfacePtr->mProbeMuxStateInvokeCount, 0);
postDefaultRouteEvent("ok", 2);

VALIDATE_STATE(Standby, Wait, Up);
EXPECT_EQ(mDbInterfacePtr->mProbeMuxStateInvokeCount, 1);

postLinkProberEvent(link_prober::LinkProberState::Standby, 3);
VALIDATE_STATE(Standby, Wait, Up);

handleMuxState("standby", 3);
VALIDATE_STATE(Standby, Standby, Up);
}

} /* namespace test */
1 change: 1 addition & 0 deletions test/LinkManagerStateMachineTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class LinkManagerStateMachineTest: public ::testing::Test
void activateStateMachine();
void setMuxActive();
void setMuxStandby();
void postDefaultRouteEvent(std::string routeState, uint32_t count = 0);

public:
boost::asio::io_service mIoService;
Expand Down