From f53196b90c15eb5135aa09ad4c9d78f9117c8b21 Mon Sep 17 00:00:00 2001 From: Carmine Scarpitta Date: Wed, 29 May 2024 11:52:52 -0500 Subject: [PATCH] [fpmsyncd]: Add test cases to verify SRv6 functionality Signed-off-by: Carmine Scarpitta --- .../fpmsyncd/receive_srv6_localsids_ut.cpp | 1070 ++++++++++++++++- .../fpmsyncd/receive_srv6_steer_routes_ut.cpp | 416 ++++++- .../fpmsyncd/ut_helpers_fpmsyncd.cpp | 341 ++++-- .../mock_tests/fpmsyncd/ut_helpers_fpmsyncd.h | 11 +- 4 files changed, 1670 insertions(+), 168 deletions(-) diff --git a/tests/mock_tests/fpmsyncd/receive_srv6_localsids_ut.cpp b/tests/mock_tests/fpmsyncd/receive_srv6_localsids_ut.cpp index 89fdb58930..6e115b05eb 100644 --- a/tests/mock_tests/fpmsyncd/receive_srv6_localsids_ut.cpp +++ b/tests/mock_tests/fpmsyncd/receive_srv6_localsids_ut.cpp @@ -55,23 +55,22 @@ namespace ut_fpmsyncd namespace ut_fpmsyncd { - /* Test Receiving a route containing an SRv6 Local SID nexthop bound to the End.DT4 behavior */ - TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEndDT4) + /* Test Receiving an SRv6 Local SID nexthop bound to the End behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEnd) { ASSERT_NE(m_routeSync, nullptr); /* Create a Netlink object containing an SRv6 Local SID */ IpAddress _localsid = IpAddress("fc00:0:1:1::"); - uint8_t _block_len = 32; - uint8_t _node_len = 16; - uint8_t _func_len = 16; - uint8_t _arg_len = 0; - uint32_t _action = SRV6_LOCALSID_ACTION_END_DT4; - char *_vrf = "Vrf10"; + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_END; - struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action); if (!nl_obj) - printf("Error\n\n"); + throw std::runtime_error("SRv6 Local SID creation failed"); /* Send the Netlink object to the FpmLink */ m_fpmLink->processRawMsg(&nl_obj->n); @@ -79,33 +78,43 @@ namespace ut_fpmsyncd /* Check that fpmsyncd created the correct entries in APP_DB */ std::string action; ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), true); - ASSERT_EQ(action, "end.dt4"); + ASSERT_EQ(action, "end"); - std::string vrf; - ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "vrf", vrf), true); - ASSERT_EQ(vrf, "Vrf10"); + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); /* Destroy the Netlink object and free the memory */ free_nlobj(nl_obj); } - /* Test Receiving a route containing an SRv6 Local SID nexthop bound to the End.DT6 behavior */ - TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEndDT6) + /* Test Receiving an SRv6 Local SID nexthop bound to the End.X behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEndX) { ASSERT_NE(m_routeSync, nullptr); /* Create a Netlink object containing an SRv6 Local SID */ IpAddress _localsid = IpAddress("fc00:0:1:1::"); - uint8_t _block_len = 32; - uint8_t _node_len = 16; - uint8_t _func_len = 16; - uint8_t _arg_len = 0; - uint32_t _action = SRV6_LOCALSID_ACTION_END_DT6; - char *_vrf = "Vrf10"; + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_END_X; + IpAddress _adj = IpAddress("2001:db8:1::1"); - struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); if (!nl_obj) - printf("Error\n\n"); + throw std::runtime_error("SRv6 Local SID creation failed"); /* Send the Netlink object to the FpmLink */ m_fpmLink->processRawMsg(&nl_obj->n); @@ -113,33 +122,49 @@ namespace ut_fpmsyncd /* Check that fpmsyncd created the correct entries in APP_DB */ std::string action; ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), true); - ASSERT_EQ(action, "end.dt6"); + ASSERT_EQ(action, "end.x"); - std::string vrf; - ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "vrf", vrf), true); - ASSERT_EQ(vrf, "Vrf10"); + std::string adj; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "adj", adj), true); + ASSERT_EQ(adj, "2001:db8:1::1"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "adj", adj), false); /* Destroy the Netlink object and free the memory */ free_nlobj(nl_obj); } - /* Test Receiving a route containing an SRv6 Local SID nexthop bound to the End.DT46 behavior */ - TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEndDT46) + /* Test Receiving an SRv6 Local SID nexthop bound to the End.T behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEndT) { ASSERT_NE(m_routeSync, nullptr); /* Create a Netlink object containing an SRv6 Local SID */ IpAddress _localsid = IpAddress("fc00:0:1:1::"); - uint8_t _block_len = 32; - uint8_t _node_len = 16; - uint8_t _func_len = 16; - uint8_t _arg_len = 0; - uint32_t _action = SRV6_LOCALSID_ACTION_END_DT46; + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_END_T; char *_vrf = "Vrf10"; struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); if (!nl_obj) - printf("Error\n\n"); + throw std::runtime_error("SRv6 Local SID creation failed"); /* Send the Netlink object to the FpmLink */ m_fpmLink->processRawMsg(&nl_obj->n); @@ -147,7 +172,7 @@ namespace ut_fpmsyncd /* Check that fpmsyncd created the correct entries in APP_DB */ std::string action; ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), true); - ASSERT_EQ(action, "end.dt46"); + ASSERT_EQ(action, "end.t"); std::string vrf; ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "vrf", vrf), true); @@ -155,25 +180,140 @@ namespace ut_fpmsyncd /* Destroy the Netlink object and free the memory */ free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "vrf", vrf), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); } - /* Test Receiving a route containing an SRv6 Local SID nexthop bound to the uDT4 behavior */ - TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDUDT4) + /* Test Receiving an SRv6 Local SID nexthop bound to the End.DX6 behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEndDX6) { ASSERT_NE(m_routeSync, nullptr); /* Create a Netlink object containing an SRv6 Local SID */ IpAddress _localsid = IpAddress("fc00:0:1:1::"); - uint8_t _block_len = 32; - uint8_t _node_len = 16; - uint8_t _func_len = 16; - uint8_t _arg_len = 0; - uint32_t _action = SRV6_LOCALSID_ACTION_UDT4; + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_END_DX6; + IpAddress _adj = IpAddress("2001:db8:1::1"); + + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + std::string action; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), true); + ASSERT_EQ(action, "end.dx6"); + + std::string adj; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "adj", adj), true); + ASSERT_EQ(adj, "2001:db8:1::1"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "adj", adj), false); + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 Local SID nexthop bound to the End.DX4 behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEndDX4) + { + ASSERT_NE(m_routeSync, nullptr); + + /* Create a Netlink object containing an SRv6 Local SID */ + IpAddress _localsid = IpAddress("fc00:0:1:1::"); + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_END_DX4; + IpAddress _adj = IpAddress("10.0.0.1"); + + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + std::string action; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), true); + ASSERT_EQ(action, "end.dx4"); + + std::string adj; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "adj", adj), true); + ASSERT_EQ(adj, "10.0.0.1"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "adj", adj), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 Local SID nexthop bound to the End.DT4 behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEndDT4) + { + ASSERT_NE(m_routeSync, nullptr); + + /* Create a Netlink object containing an SRv6 Local SID */ + IpAddress _localsid = IpAddress("fc00:0:1:1::"); + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_END_DT4; char *_vrf = "Vrf10"; struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); if (!nl_obj) - printf("Error\n\n"); + throw std::runtime_error("SRv6 Local SID creation failed"); /* Send the Netlink object to the FpmLink */ m_fpmLink->processRawMsg(&nl_obj->n); @@ -181,7 +321,7 @@ namespace ut_fpmsyncd /* Check that fpmsyncd created the correct entries in APP_DB */ std::string action; ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), true); - ASSERT_EQ(action, "udt4"); + ASSERT_EQ(action, "end.dt4"); std::string vrf; ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "vrf", vrf), true); @@ -189,25 +329,41 @@ namespace ut_fpmsyncd /* Destroy the Netlink object and free the memory */ free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "vrf", vrf), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); } - /* Test Receiving a route containing an SRv6 Local SID nexthop bound to the uDT6 behavior */ - TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDUDT6) + /* Test Receiving an SRv6 Local SID nexthop bound to the End.DT6 behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEndDT6) { ASSERT_NE(m_routeSync, nullptr); /* Create a Netlink object containing an SRv6 Local SID */ IpAddress _localsid = IpAddress("fc00:0:1:1::"); - uint8_t _block_len = 32; - uint8_t _node_len = 16; - uint8_t _func_len = 16; - uint8_t _arg_len = 0; - uint32_t _action = SRV6_LOCALSID_ACTION_UDT6; + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_END_DT6; char *_vrf = "Vrf10"; struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); if (!nl_obj) - printf("Error\n\n"); + throw std::runtime_error("SRv6 Local SID creation failed"); /* Send the Netlink object to the FpmLink */ m_fpmLink->processRawMsg(&nl_obj->n); @@ -215,7 +371,7 @@ namespace ut_fpmsyncd /* Check that fpmsyncd created the correct entries in APP_DB */ std::string action; ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), true); - ASSERT_EQ(action, "udt6"); + ASSERT_EQ(action, "end.dt6"); std::string vrf; ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "vrf", vrf), true); @@ -223,25 +379,41 @@ namespace ut_fpmsyncd /* Destroy the Netlink object and free the memory */ free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "vrf", vrf), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); } - /* Test Receiving a route containing an SRv6 Local SID nexthop bound to the uDT46 behavior */ - TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDUDT46) + /* Test Receiving an SRv6 Local SID nexthop bound to the End.DT46 behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDEndDT46) { ASSERT_NE(m_routeSync, nullptr); /* Create a Netlink object containing an SRv6 Local SID */ IpAddress _localsid = IpAddress("fc00:0:1:1::"); - uint8_t _block_len = 32; - uint8_t _node_len = 16; - uint8_t _func_len = 16; - uint8_t _arg_len = 0; - uint32_t _action = SRV6_LOCALSID_ACTION_UDT46; + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_END_DT46; char *_vrf = "Vrf10"; struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); if (!nl_obj) - printf("Error\n\n"); + throw std::runtime_error("SRv6 Local SID creation failed"); /* Send the Netlink object to the FpmLink */ m_fpmLink->processRawMsg(&nl_obj->n); @@ -249,7 +421,7 @@ namespace ut_fpmsyncd /* Check that fpmsyncd created the correct entries in APP_DB */ std::string action; ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), true); - ASSERT_EQ(action, "udt46"); + ASSERT_EQ(action, "end.dt46"); std::string vrf; ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "vrf", vrf), true); @@ -257,5 +429,775 @@ namespace ut_fpmsyncd /* Destroy the Netlink object and free the memory */ free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "vrf", vrf), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 Local SID nexthop bound to the uN behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDUN) + { + ASSERT_NE(m_routeSync, nullptr); + + /* Create a Netlink object containing an SRv6 Local SID */ + IpAddress _localsid = IpAddress("fc00:0:1::"); + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_UN; + + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + std::string action; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1::", "action", action), true); + ASSERT_EQ(action, "un"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 Local SID nexthop bound to the uA behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDUA) + { + ASSERT_NE(m_routeSync, nullptr); + + /* Create a Netlink object containing an SRv6 Local SID */ + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_UA; + IpAddress _adj = IpAddress("2001:db8:1::1"); + + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + std::string action; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), true); + ASSERT_EQ(action, "ua"); + + std::string adj; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "adj", adj), true); + ASSERT_EQ(adj, "2001:db8:1::1"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "adj", adj), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 Local SID nexthop bound to the uDX6 behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDUDX6) + { + ASSERT_NE(m_routeSync, nullptr); + + /* Create a Netlink object containing an SRv6 Local SID */ + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_UDX6; + IpAddress _adj = IpAddress("2001:db8:1::1"); + + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + std::string action; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), true); + ASSERT_EQ(action, "udx6"); + + std::string adj; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "adj", adj), true); + ASSERT_EQ(adj, "2001:db8:1::1"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "adj", adj), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 Local SID nexthop bound to the uDX4 behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDUDX4) + { + ASSERT_NE(m_routeSync, nullptr); + + /* Create a Netlink object containing an SRv6 Local SID */ + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_UDX4; + IpAddress _adj = IpAddress("10.0.0.1"); + + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + std::string action; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), true); + ASSERT_EQ(action, "udx4"); + + std::string adj; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "adj", adj), true); + ASSERT_EQ(adj, "10.0.0.1"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, NULL, &_adj); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "adj", adj), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 Local SID nexthop bound to the uDT4 behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDUDT4) + { + ASSERT_NE(m_routeSync, nullptr); + + /* Create a Netlink object containing an SRv6 Local SID */ + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_UDT4; + char *_vrf = "Vrf10"; + + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + std::string action; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), true); + ASSERT_EQ(action, "udt4"); + + std::string vrf; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "vrf", vrf), true); + ASSERT_EQ(vrf, "Vrf10"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "vrf", vrf), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 Local SID nexthop bound to the uDT6 behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDUDT6) + { + ASSERT_NE(m_routeSync, nullptr); + + /* Create a Netlink object containing an SRv6 Local SID */ + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_UDT6; + char *_vrf = "Vrf10"; + + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + std::string action; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), true); + ASSERT_EQ(action, "udt6"); + + std::string vrf; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "vrf", vrf), true); + ASSERT_EQ(vrf, "Vrf10"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "vrf", vrf), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 Local SID nexthop bound to the uDT46 behavior */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDUDT46) + { + ASSERT_NE(m_routeSync, nullptr); + + /* Create a Netlink object containing an SRv6 Local SID */ + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + int8_t _block_len = 32; + int8_t _node_len = 16; + int8_t _func_len = 16; + int8_t _arg_len = 0; + uint32_t _action = SRV6_LOCALSID_ACTION_UDT46; + char *_vrf = "Vrf10"; + + struct nlmsg *nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + std::string action; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), true); + ASSERT_EQ(action, "udt46"); + + std::string vrf; + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "vrf", vrf), true); + ASSERT_EQ(vrf, "Vrf10"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action, _vrf); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "vrf", vrf), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 Local SID with default SID structure */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidEndDefaultSidStructure) + { + ASSERT_NE(m_routeSync, nullptr); + + shared_ptr m_app_db; + m_app_db = make_shared("APPL_DB", 0); + Table srv6_my_sid_table(m_app_db.get(), APP_SRV6_MY_SID_TABLE_NAME); + + struct nlmsg *nl_obj; + std::string action; + std::string adj; + std::string vrf; + + /* Create a Netlink object containing an SRv6 Local SID */ + IpAddress _localsid = IpAddress("fc00:0:1:40::"); + + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, -1, -1, -1, -1, SRV6_LOCALSID_ACTION_END); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:40::", "action", action), true); + ASSERT_EQ(action, "end"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, 32, 16, 16, 0, SRV6_LOCALSID_ACTION_END); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd removed the entry from the APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:40::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an invalid SRv6 Local SID */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, RecevingRouteWithSRv6LocalSIDInvalid) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("fc00:0:1:1::"); + int8_t _block_len; + int8_t _node_len; + int8_t _func_len; + int8_t _arg_len; + uint32_t _action = SRV6_LOCALSID_ACTION_UN; + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID with missing block length */ + _block_len = -1; + _node_len = 16; + _func_len = 16; + _arg_len = 0; + + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Ensure that fpmsyncd does not create an entry in APP_DB (because local SID is invalid)*/ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + + /* Create a Netlink object containing an SRv6 Local SID with missing node length */ + _block_len = 32; + _node_len = -1; + _func_len = 16; + _arg_len = 0; + + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Ensure that fpmsyncd does not create an entry in APP_DB (because local SID is invalid)*/ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + + /* Create a Netlink object containing an SRv6 Local SID with missing function length */ + _block_len = 32; + _node_len = 16; + _func_len = -1; + _arg_len = 0; + + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Ensure that fpmsyncd does not create an entry in APP_DB (because local SID is invalid)*/ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + + /* Create a Netlink object containing an SRv6 Local SID with missing argument length */ + _block_len = 32; + _node_len = 16; + _func_len = 16; + _arg_len = -1; + + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, _block_len, _node_len, _func_len, _arg_len, _action); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB (with default argument length)*/ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:1::", "action", action), true); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + } + + /* Test Receiving a route containing an invalid SRv6 Local SID with missing SID value */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidInvalidMissingSidValue) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID with missing SID value */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, NULL, 32, 16, 16, 0, SRV6_LOCALSID_ACTION_END); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an invalid SRv6 Local SID with IPv4 address as the SID value */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidInvalidIpv4SidValue) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("10.0.0.1"); + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID with IPv4 SID value */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, 32, 16, 16, 0, SRV6_LOCALSID_ACTION_END, NULL, NULL, 10, 0, AF_INET); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:10.0.0.1", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an invalid SRv6 Local SID with invalid SID value prefix length */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidInvalidSidPrefixlen) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID with invalid SID value prefix length */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, 32, 16, 16, 0, SRV6_LOCALSID_ACTION_END, NULL, NULL, 10, 200, AF_INET6); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an SRv6 Local SID with invalid action */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidInvalidAction) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID with invalid action */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, 32, 16, 16, 0, 329); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an SRv6 Local SID with unspec action */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidInvalidUnspecAction) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID with unspec action */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, 32, 16, 16, 0, SRV6_LOCALSID_ACTION_UNSPEC); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an SRv6 Local SID bound to End.DT6 behavior with empty VRF */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidInvalidVrf) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID bound to End.DT6 behavior with empty VRF */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, 32, 16, 16, 0, SRV6_LOCALSID_ACTION_END_DT6, NULL); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an invalid SRv6 Local SID bound to End.X behavior with empty adjacency */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidInvalidAdjacency) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID bound to End.X behavior with empty adjacency */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, 32, 16, 16, 0, SRV6_LOCALSID_ACTION_END_X, NULL, NULL); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an SRv6 Local SID with missing block length */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidInvalidMissingBlockLen) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID with missing block length */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, -1, 16, 16, 0, SRV6_LOCALSID_ACTION_END, NULL, NULL, 10, AF_INET6, 200); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an SRv6 Local SID with missing node length */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidInvalidMissingNodeLen) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID with missing node length */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, 32, -1, 16, 0, SRV6_LOCALSID_ACTION_END, NULL, NULL, 10, AF_INET6, 200); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an SRv6 Local SID with missing function length */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidMissingFunctionLen) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID with missing node length */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, 32, 16, -1, 0, SRV6_LOCALSID_ACTION_END, NULL, NULL, 10, AF_INET6, 200); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving a route containing an SRv6 Local SID with missing argument length */ + TEST_F(FpmSyncdSRv6LocalSIDsTest, SRv6LocalSidMissingArgumentLen) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpAddress _localsid = IpAddress("fc00:0:1:e000::"); + std::string action; + + /* Create a Netlink object containing an SRv6 Local SID with missing node length */ + nl_obj = create_srv6_localsid_nlmsg(RTM_NEWSRV6LOCALSID, &_localsid, 32, 16, 16, -1, SRV6_LOCALSID_ACTION_END); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd did not create any entry in APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), true); + ASSERT_EQ(action, "end"); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + /* Delete Local SID */ + nl_obj = create_srv6_localsid_nlmsg(RTM_DELSRV6LOCALSID, &_localsid, 32, 16, 16, 0, SRV6_LOCALSID_ACTION_END); + if (!nl_obj) + throw std::runtime_error("SRv6 Local SID creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd removed the entry from the APP_DB */ + ASSERT_EQ(m_srv6LocalSidTable->hget("32:16:16:0:fc00:0:1:e000::", "action", action), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); } } \ No newline at end of file diff --git a/tests/mock_tests/fpmsyncd/receive_srv6_steer_routes_ut.cpp b/tests/mock_tests/fpmsyncd/receive_srv6_steer_routes_ut.cpp index 92d4e394b7..7c74d63fad 100644 --- a/tests/mock_tests/fpmsyncd/receive_srv6_steer_routes_ut.cpp +++ b/tests/mock_tests/fpmsyncd/receive_srv6_steer_routes_ut.cpp @@ -65,33 +65,109 @@ namespace ut_fpmsyncd { ASSERT_NE(m_routeSync, nullptr); - /* Create a Netlink object containing an SRv6 VPN Route */ + struct nlmsg *nl_obj; + std::string path; + std::string segment; + std::string seg_src; + + /* Create a Netlink object to install the SRv6 VPN Route */ IpPrefix _dst = IpPrefix("192.168.6.0/24"); IpAddress _vpn_sid = IpAddress("fc00:0:2:1::"); IpAddress _encap_src_addr = IpAddress("fc00:0:1:1::1"); - struct nlmsg *nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid); + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid); if (!nl_obj) throw std::runtime_error("SRv6 VPN Route creation failed"); /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); m_fpmLink->processRawMsg(&nl_obj->n); /* Check that fpmsyncd created the correct entries in APP_DB */ - std::string path; ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:192.168.6.0/24", "path", path), true); ASSERT_EQ(path, _vpn_sid.to_string()); - std::string segment; ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.0/24", "segment", segment), true); ASSERT_EQ(segment, "Vrf10:192.168.6.0/24"); - std::string seg_src; ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.0/24", "seg_src", seg_src), true); ASSERT_EQ(seg_src, _encap_src_addr.to_string()); /* Destroy the Netlink object and free the memory */ free_nlobj(nl_obj); + + + /* Create a Netlink object to uninstall the SRv6 VPN Route */ + nl_obj = create_srv6_vpn_route_nlmsg(RTM_DELROUTE, &_dst, &_encap_src_addr, &_vpn_sid); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd removed the entry from APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:192.168.6.0/24", "path", path), false); + ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.0/24", "segment", segment), false); + ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.0/24", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 VPN Route (with an IPv4 prefix with /32 prefix length) */ + TEST_F(FpmSyncdSRv6RoutesTest, RecevingSRv6VpnRoutesWithIPv4PrefixMaxPrefixLength) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + std::string path; + std::string segment; + std::string seg_src; + + + /* Create a Netlink object containing an SRv6 VPN Route */ + IpPrefix _dst = IpPrefix("192.168.6.1/32"); + IpAddress _vpn_sid = IpAddress("fc00:0:2:1::"); + IpAddress _encap_src_addr = IpAddress("fc00:0:1:1::1"); + + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:192.168.6.1", "path", path), true); + ASSERT_EQ(path, _vpn_sid.to_string()); + + ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.1", "segment", segment), true); + ASSERT_EQ(segment, "Vrf10:192.168.6.1"); + + ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.1", "seg_src", seg_src), true); + ASSERT_EQ(seg_src, _encap_src_addr.to_string()); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + + + /* Create a Netlink object to uninstall the SRv6 VPN Route */ + nl_obj = create_srv6_vpn_route_nlmsg(RTM_DELROUTE, &_dst, &_encap_src_addr, &_vpn_sid); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd removed the entry from APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:192.168.6.1/32", "path", path), false); + ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.1/32", "segment", segment), false); + ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.1/32", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); } /* Test Receiving an SRv6 VPN Route (with an IPv6 prefix) */ @@ -99,12 +175,17 @@ namespace ut_fpmsyncd { ASSERT_NE(m_routeSync, nullptr); + struct nlmsg *nl_obj; + std::string path; + std::string segment; + std::string seg_src; + /* Create a Netlink object containing an SRv6 VPN Route */ IpPrefix _dst = IpPrefix("fd00:0:21::/64"); IpAddress _vpn_sid = IpAddress("fc00:0:2:1::"); IpAddress _encap_src_addr = IpAddress("fc00:0:1:1::1"); - struct nlmsg *nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid); + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid); if (!nl_obj) throw std::runtime_error("SRv6 VPN Route creation failed"); @@ -112,19 +193,336 @@ namespace ut_fpmsyncd m_fpmLink->processRawMsg(&nl_obj->n); /* Check that fpmsyncd created the correct entries in APP_DB */ - std::string path; ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:fd00:0:21::/64", "path", path), true); ASSERT_EQ(path, _vpn_sid.to_string()); - std::string segment; ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "segment", segment), true); ASSERT_EQ(segment, "Vrf10:fd00:0:21::/64"); - std::string seg_src; ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "seg_src", seg_src), true); ASSERT_EQ(seg_src, _encap_src_addr.to_string()); /* Destroy the Netlink object and free the memory */ free_nlobj(nl_obj); + + + /* Create a Netlink object to uninstall the SRv6 VPN Route */ + nl_obj = create_srv6_vpn_route_nlmsg(RTM_DELROUTE, &_dst, &_encap_src_addr, &_vpn_sid); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd removed the entry from APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:fd00:0:21::/64", "path", path), false); + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "segment", segment), false); + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an SRv6 VPN Route with missing destination prefix */ + TEST_F(FpmSyncdSRv6RoutesTest, SRv6VpnRoutesInvalidMissingDst) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + std::string path; + std::string segment; + std::string seg_src; + + /* + * Scenario 1: SRv6 VPN Route with missing destination + */ + + /* Create a Netlink object containing an SRv6 VPN Route with missing destination */ + IpAddress _vpn_sid = IpAddress("fc00:0:2:1::"); + IpAddress _encap_src_addr = IpAddress("fc00:0:1:1::1"); + + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, NULL, &_encap_src_addr, &_vpn_sid); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:192.168.6.0/24", "path", path), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.0/24", "segment", segment), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.0/24", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + + /* Test Receiving an invalid SRv6 VPN Route IPv4 with invalid prefix length */ + TEST_F(FpmSyncdSRv6RoutesTest, SRv6VpnRoutesInvalidPrefixlenIpv4) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpPrefix _dst; + IpAddress _vpn_sid; + IpAddress _encap_src_addr; + std::string path; + std::string segment; + std::string seg_src; + + /* Create a Netlink object containing an SRv6 VPN Route IPv4 with invalid prefix length */ + _dst = IpPrefix("192.168.6.0"); + _vpn_sid = IpAddress("fc00:0:2:1::"); + _encap_src_addr = IpAddress("fc00:0:1:1::1"); + + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid, 10, 100); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:192.168.6.0/100", "path", path), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.0/100", "segment", segment), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:192.168.6.0/100", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an invalid SRv6 VPN Route IPv6 with invalid prefix length */ + TEST_F(FpmSyncdSRv6RoutesTest, SRv6VpnRoutesInvalidPrefixlenIpv6) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpPrefix _dst; + IpAddress _vpn_sid; + IpAddress _encap_src_addr; + std::string path; + std::string segment; + std::string seg_src; + + /* Create a Netlink object containing an SRv6 VPN Route IPv6 with invalid prefix length */ + _dst = IpPrefix("fd00:0:21::"); + _vpn_sid = IpAddress("fc00:0:2:1::"); + _encap_src_addr = IpAddress("fc00:0:1:1::1"); + + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid, 10, 200); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:fd00:0:21::/200", "path", path), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/200", "segment", segment), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/200", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an invalid SRv6 VPN Route with invalid address family */ + TEST_F(FpmSyncdSRv6RoutesTest, SRv6VpnRoutesInvalidAddressFamily) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpPrefix _dst; + IpAddress _vpn_sid; + IpAddress _encap_src_addr; + std::string path; + std::string segment; + std::string seg_src; + + + /* + * Scenario 4: SRv6 VPN Route with invalid address family + */ + + /* Create a Netlink object containing an SRv6 VPN Route IPv6 with invalid address family */ + _dst = IpPrefix("fd00:0:21::/64"); + _vpn_sid = IpAddress("fc00:0:2:1::"); + _encap_src_addr = IpAddress("fc00:0:1:1::1"); + + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid, 10, 64, 100); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:fd00:0:21::/64", "path", path), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "segment", segment), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an invalid SRv6 VPN Route with invalid Vrf */ + TEST_F(FpmSyncdSRv6RoutesTest, SRv6VpnRoutesInvalidVrf) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpPrefix _dst; + IpAddress _vpn_sid; + IpAddress _encap_src_addr; + std::string path; + std::string segment; + std::string seg_src; + + /* Create a Netlink object containing an SRv6 VPN Route IPv6 with invalid Vrf */ + _dst = IpPrefix("fd00:0:21::/64"); + _vpn_sid = IpAddress("fc00:0:2:1::"); + _encap_src_addr = IpAddress("fc00:0:1:1::1"); + + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid, 20); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:fd00:0:21::/64", "path", path), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "segment", segment), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an invalid SRv6 VPN Route with invalid Vrf name (not starting with "Vrf" prefix) */ + TEST_F(FpmSyncdSRv6RoutesTest, SRv6VpnRoutesInvalidVrfName) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpPrefix _dst; + IpAddress _vpn_sid; + IpAddress _encap_src_addr; + std::string path; + std::string segment; + std::string seg_src; + + /* Create a Netlink object containing an SRv6 VPN Route IPv6 with invalid Vrf name (not starting with "Vrf" prefix) */ + _dst = IpPrefix("fd00:0:21::/64"); + _vpn_sid = IpAddress("fc00:0:2:1::"); + _encap_src_addr = IpAddress("fc00:0:1:1::1"); + + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid, 30); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("invalidVrf:fd00:0:21::/64", "path", path), false); + + ASSERT_EQ(m_routeTable->hget("invalidVrf:fd00:0:21::/64", "segment", segment), false); + + ASSERT_EQ(m_routeTable->hget("invalidVrf:fd00:0:21::/64", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an invalid SRv6 VPN Route with invalid route type (blackhole) */ + TEST_F(FpmSyncdSRv6RoutesTest, SRv6VpnRoutesInvalidRouteTypeBlackhole) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpPrefix _dst; + IpAddress _vpn_sid; + IpAddress _encap_src_addr; + std::string path; + std::string segment; + std::string seg_src; + + /* Create a Netlink object containing an SRv6 VPN Route IPv6 with invalid route type (blackhole) */ + _dst = IpPrefix("fd00:0:21::/64"); + _vpn_sid = IpAddress("fc00:0:2:1::"); + _encap_src_addr = IpAddress("fc00:0:1:1::1"); + + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid, 30, 64, AF_INET6, RTN_BLACKHOLE); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:fd00:0:21::/64", "path", path), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "segment", segment), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); + } + + /* Test Receiving an invalid SRv6 VPN Route with invalid route type (multicast) */ + TEST_F(FpmSyncdSRv6RoutesTest, SRv6VpnRoutesInvalidRouteTypeMulticast) + { + ASSERT_NE(m_routeSync, nullptr); + + struct nlmsg *nl_obj; + IpPrefix _dst; + IpAddress _vpn_sid; + IpAddress _encap_src_addr; + std::string path; + std::string segment; + std::string seg_src; + + /* Create a Netlink object containing an SRv6 VPN Route IPv6 with invalid route type (multicast) */ + _dst = IpPrefix("fd00:0:21::/64"); + _vpn_sid = IpAddress("fc00:0:2:1::"); + _encap_src_addr = IpAddress("fc00:0:1:1::1"); + + nl_obj = create_srv6_vpn_route_nlmsg(RTM_NEWROUTE, &_dst, &_encap_src_addr, &_vpn_sid, 30, 64, AF_INET6, RTN_MULTICAST); + if (!nl_obj) + throw std::runtime_error("SRv6 VPN Route creation failed"); + + /* Send the Netlink object to the FpmLink */ + ASSERT_EQ(m_fpmLink->isRawProcessing(&nl_obj->n), true); + m_fpmLink->processRawMsg(&nl_obj->n); + + /* Check that fpmsyncd created the correct entries in APP_DB */ + ASSERT_EQ(m_srv6SidListTable->hget("Vrf10:fd00:0:21::/64", "path", path), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "segment", segment), false); + + ASSERT_EQ(m_routeTable->hget("Vrf10:fd00:0:21::/64", "seg_src", seg_src), false); + + /* Destroy the Netlink object and free the memory */ + free_nlobj(nl_obj); } } \ No newline at end of file diff --git a/tests/mock_tests/fpmsyncd/ut_helpers_fpmsyncd.cpp b/tests/mock_tests/fpmsyncd/ut_helpers_fpmsyncd.cpp index f89caa6b15..ee11b43b0d 100644 --- a/tests/mock_tests/fpmsyncd/ut_helpers_fpmsyncd.cpp +++ b/tests/mock_tests/fpmsyncd/ut_helpers_fpmsyncd.cpp @@ -20,6 +20,9 @@ char *__wrap_rtnl_link_i2name(struct nl_cache *cache, int ifindex, char *dst, si case 10: strncpy(dst, "Vrf10", 6); return dst; + case 30: + strncpy(dst, "invalidVrf", 11); + return dst; default: return NULL; } @@ -100,7 +103,10 @@ namespace ut_fpmsyncd IpPrefix *dst, IpAddress *encap_src_addr, IpAddress *vpn_sid, - uint16_t table_id) + uint16_t table_id, + uint8_t prefixlen, + uint8_t address_family, + uint8_t rtm_type) { struct rtattr *nest; @@ -113,34 +119,45 @@ namespace ut_fpmsyncd nl_obj->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST; if (cmd == RTM_NEWROUTE && - dst->isV4()) + dst && dst->isV4()) nl_obj->n.nlmsg_flags |= NLM_F_REPLACE; nl_obj->n.nlmsg_type = cmd; nl_obj->n.nlmsg_pid = 100; - nl_obj->r.rtm_family = dst->getIp().getIp().family; - nl_obj->r.rtm_dst_len = (unsigned char)(dst->getMaskLength()); + if (address_family > 0) + nl_obj->r.rtm_family = address_family; + else + nl_obj->r.rtm_family = dst ? dst->getIp().getIp().family : AF_INET6; + if (prefixlen > 0) + nl_obj->r.rtm_dst_len = prefixlen; + else + nl_obj->r.rtm_dst_len = dst ? (unsigned char)(dst->getMaskLength()): IPV6_MAX_BITLEN; nl_obj->r.rtm_scope = RT_SCOPE_UNIVERSE; nl_obj->r.rtm_protocol = 11; // ZEBRA protocol - if (cmd != RTM_DELROUTE) + if (rtm_type > 0) + nl_obj->r.rtm_type = rtm_type; + else nl_obj->r.rtm_type = RTN_UNICAST; /* Add the destination address */ - if (dst->isV4()) - { - if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), - RTA_DST, dst->getIp().getV4Addr())) - return NULL; - } - else + if (dst) { - if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), - RTA_DST, dst->getIp().getV6Addr(), IPV6_MAX_BYTE)) - return NULL; + if (dst->isV4()) + { + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + RTA_DST, dst->getIp().getV4Addr())) + return NULL; + } + else + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + RTA_DST, dst->getIp().getV6Addr(), IPV6_MAX_BYTE)) + return NULL; + } } /* Add the table ID */ @@ -153,13 +170,6 @@ namespace ut_fpmsyncd return NULL; } - /* If the Netlink message is a Delete Route message, we have done */ - if (cmd == RTM_DELROUTE) - { - NLMSG_ALIGN(nl_obj->n.nlmsg_len); - return nl_obj; - } - /* Add encapsulation type NH_ENCAP_SRV6_ROUTE (SRv6 Route) */ if (!nl_attr_put16(&nl_obj->n, sizeof(*nl_obj), RTA_ENCAP_TYPE, NH_ENCAP_SRV6_ROUTE)) @@ -190,13 +200,17 @@ namespace ut_fpmsyncd struct nlmsg *create_srv6_localsid_nlmsg( uint16_t cmd, IpAddress *localsid, - uint8_t block_len, - uint8_t node_len, - uint8_t func_len, - uint8_t arg_len, + int8_t block_len, + int8_t node_len, + int8_t func_len, + int8_t arg_len, uint32_t action, char *vrf, - uint16_t table_id) + IpAddress *adj, + uint16_t table_id, + uint8_t prefixlen, + uint8_t address_family + ) { struct rtattr *nest; @@ -214,8 +228,14 @@ namespace ut_fpmsyncd nl_obj->n.nlmsg_pid = 100; - nl_obj->r.rtm_family = AF_INET6; - nl_obj->r.rtm_dst_len = IPV6_MAX_BITLEN; + if (address_family > 0) + nl_obj->r.rtm_family = address_family; + else + nl_obj->r.rtm_family = localsid ? localsid->getIp().family : AF_INET6; + if (prefixlen > 0) + nl_obj->r.rtm_dst_len = prefixlen; + else + nl_obj->r.rtm_dst_len = IPV6_MAX_BITLEN; nl_obj->r.rtm_scope = RT_SCOPE_UNIVERSE; nl_obj->r.rtm_protocol = 11; // Protocol ZEBRA @@ -224,15 +244,20 @@ namespace ut_fpmsyncd nl_obj->r.rtm_type = RTN_UNICAST; /* Add local SID address */ - if (localsid->isV4()) - { - throw std::runtime_error("SRv6 local SID cannot be an IPv4 address"); - } - else + if (localsid) { - if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), - RTA_DST, localsid->getV6Addr(), 16)) - return NULL; + if (localsid->isV4()) + { + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + RTA_DST, localsid->getV4Addr())) + return NULL; + } + else + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + RTA_DST, localsid->getV6Addr(), 16)) + return NULL; + } } /* Add table ID */ @@ -246,39 +271,49 @@ namespace ut_fpmsyncd } /* Add SID format information */ - nest = - nl_attr_nest(&nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_FORMAT); - - /* Add block bits length */ - if (!nl_attr_put8( - &nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_FORMAT_BLOCK_LEN, - block_len)) - return NULL; + if (block_len > 0 || + node_len > 0 || + func_len > 0 || + arg_len > 0) + { + nest = + nl_attr_nest(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_FORMAT); + + /* Add block bits length */ + if (block_len >= 0) + if (!nl_attr_put8( + &nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_FORMAT_BLOCK_LEN, + block_len)) + return NULL; - /* Add node bits length */ - if (!nl_attr_put8( - &nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_FORMAT_NODE_LEN, - node_len)) - return NULL; + /* Add node bits length */ + if (node_len >= 0) + if (!nl_attr_put8( + &nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_FORMAT_NODE_LEN, + node_len)) + return NULL; - /* Add function bits length */ - if (!nl_attr_put8( - &nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_FORMAT_FUNC_LEN, - func_len)) - return NULL; + /* Add function bits length */ + if (func_len >= 0) + if (!nl_attr_put8( + &nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_FORMAT_FUNC_LEN, + func_len)) + return NULL; - /* Add argument bits length */ - if (!nl_attr_put8( - &nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_FORMAT_ARG_LEN, - arg_len)) - return NULL; + /* Add argument bits length */ + if (arg_len >= 0) + if (!nl_attr_put8( + &nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_FORMAT_ARG_LEN, + arg_len)) + return NULL; - nl_attr_nest_end(&nl_obj->n, nest); + nl_attr_nest_end(&nl_obj->n, nest); + } /* If the Netlink message is a Delete Route message, we have done */ if (cmd == RTM_DELROUTE) @@ -290,68 +325,192 @@ namespace ut_fpmsyncd /* Add local SID behavior (action and parameters) */ switch (action) { + case SRV6_LOCALSID_ACTION_END: + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_ACTION, + SRV6_LOCALSID_ACTION_END)) + return NULL; + break; + case SRV6_LOCALSID_ACTION_END_X: + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_ACTION, + SRV6_LOCALSID_ACTION_END_X)) + return NULL; + if (adj) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_NH6, + adj->getV6Addr(), 16)) + return NULL; + } + break; + case SRV6_LOCALSID_ACTION_END_T: + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_ACTION, + SRV6_LOCALSID_ACTION_END_T)) + return NULL; + if (vrf) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_VRFNAME, + vrf, (uint32_t)strlen(vrf))) + return NULL; + } + break; + case SRV6_LOCALSID_ACTION_END_DX4: + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_ACTION, + SRV6_LOCALSID_ACTION_END_DX4)) + return NULL; + if (adj) + { + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_NH4, + adj->getV4Addr())) + return NULL; + } + break; + case SRV6_LOCALSID_ACTION_END_DX6: + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_ACTION, + SRV6_LOCALSID_ACTION_END_DX6)) + return NULL; + if (adj) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_NH6, + adj->getV6Addr(), 16)) + return NULL; + } + break; case SRV6_LOCALSID_ACTION_END_DT4: if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), SRV6_LOCALSID_ACTION, SRV6_LOCALSID_ACTION_END_DT4)) return NULL; - if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_VRFNAME, - vrf, (uint32_t)strlen(vrf))) - return NULL; + if (vrf) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_VRFNAME, + vrf, (uint32_t)strlen(vrf))) + return NULL; + } break; case SRV6_LOCALSID_ACTION_END_DT6: if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), SRV6_LOCALSID_ACTION, SRV6_LOCALSID_ACTION_END_DT6)) return NULL; - if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_VRFNAME, - vrf, (uint32_t)strlen(vrf))) - return NULL; + if (vrf) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_VRFNAME, + vrf, (uint32_t)strlen(vrf))) + return NULL; + } break; case SRV6_LOCALSID_ACTION_END_DT46: if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), SRV6_LOCALSID_ACTION, SRV6_LOCALSID_ACTION_END_DT46)) return NULL; - if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_VRFNAME, - vrf, (uint32_t)strlen(vrf))) - return NULL; + if (vrf) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_VRFNAME, + vrf, (uint32_t)strlen(vrf))) + return NULL; + } break; + case SRV6_LOCALSID_ACTION_UN: + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_ACTION, + SRV6_LOCALSID_ACTION_UN)) + return NULL; + break; + case SRV6_LOCALSID_ACTION_UA: + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_ACTION, + SRV6_LOCALSID_ACTION_UA)) + return NULL; + if (adj) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_NH6, + adj->getV6Addr(), 16)) + return NULL; + } + break; + case SRV6_LOCALSID_ACTION_UDX4: + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_ACTION, + SRV6_LOCALSID_ACTION_UDX4)) + return NULL; + if (adj) + { + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_NH4, + adj->getV4Addr())) + return NULL; + } + break; + case SRV6_LOCALSID_ACTION_UDX6: + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_ACTION, + SRV6_LOCALSID_ACTION_UDX6)) + return NULL; + if (adj) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_NH6, + adj->getV6Addr(), 16)) + return NULL; + } + break; case SRV6_LOCALSID_ACTION_UDT4: if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), SRV6_LOCALSID_ACTION, SRV6_LOCALSID_ACTION_UDT4)) return NULL; - if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_VRFNAME, - vrf, (uint32_t)strlen(vrf))) - return NULL; + if (vrf) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_VRFNAME, + vrf, (uint32_t)strlen(vrf))) + return NULL; + } break; case SRV6_LOCALSID_ACTION_UDT6: if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), SRV6_LOCALSID_ACTION, SRV6_LOCALSID_ACTION_UDT6)) return NULL; - if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_VRFNAME, - vrf, (uint32_t)strlen(vrf))) - return NULL; + if (vrf) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_VRFNAME, + vrf, (uint32_t)strlen(vrf))) + return NULL; + } break; case SRV6_LOCALSID_ACTION_UDT46: if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), SRV6_LOCALSID_ACTION, SRV6_LOCALSID_ACTION_UDT46)) return NULL; - if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), - SRV6_LOCALSID_VRFNAME, - vrf, (uint32_t)strlen(vrf))) - return NULL; + if (vrf) + { + if (!nl_attr_put(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_VRFNAME, + vrf, (uint32_t)strlen(vrf))) + return NULL; + } break; default: - throw std::runtime_error("Unsupported localsid action\n"); + if (!nl_attr_put32(&nl_obj->n, sizeof(*nl_obj), + SRV6_LOCALSID_ACTION, + action)) + return NULL; } return nl_obj; diff --git a/tests/mock_tests/fpmsyncd/ut_helpers_fpmsyncd.h b/tests/mock_tests/fpmsyncd/ut_helpers_fpmsyncd.h index bdd4c599b1..ca512d43b9 100644 --- a/tests/mock_tests/fpmsyncd/ut_helpers_fpmsyncd.h +++ b/tests/mock_tests/fpmsyncd/ut_helpers_fpmsyncd.h @@ -96,11 +96,14 @@ namespace ut_fpmsyncd int nl_attr_nest_end(struct nlmsghdr *n, struct rtattr *nest); /* Build a Netlink object containing an SRv6 VPN Route */ struct nlmsg *create_srv6_vpn_route_nlmsg(uint16_t cmd, IpPrefix *dst, IpAddress *encap_src_addr, - IpAddress *vpn_sid, uint16_t table_id = 10); + IpAddress *vpn_sid, uint16_t table_id = 10, uint8_t prefixlen = 0, + uint8_t address_family = 0, uint8_t rtm_type = 0); /* Build a Netlink object containing an SRv6 Local SID */ - struct nlmsg *create_srv6_localsid_nlmsg(uint16_t cmd, IpAddress *localsid, uint8_t block_len, - uint8_t node_len, uint8_t func_len, uint8_t arg_len, - uint32_t action, char *vrf, uint16_t table_id = 10); + struct nlmsg *create_srv6_localsid_nlmsg(uint16_t cmd, IpAddress *localsid, int8_t block_len, + int8_t node_len, int8_t func_len, int8_t arg_len, + uint32_t action, char *vrf = NULL, IpAddress *nh = NULL, + uint16_t table_id = 10, uint8_t prefixlen = 0, + uint8_t address_family = 0); /* Free the memory allocated for a Netlink object */ inline void free_nlobj(struct nlmsg *msg) {