22#include " neighorch.h"
33#include " crmorch.h"
44#include " routeorch.h"
5+ #include " srv6orch.h"
56#include " bulker.h"
67#include " logger.h"
78#include " swssnet.h"
@@ -12,6 +13,7 @@ extern IntfsOrch *gIntfsOrch;
1213extern NeighOrch *gNeighOrch ;
1314extern RouteOrch *gRouteOrch ;
1415extern NhgOrch *gNhgOrch ;
16+ extern Srv6Orch *gSrv6Orch ;
1517
1618extern size_t gMaxBulkSize ;
1719
@@ -61,6 +63,9 @@ void NhgOrch::doTask(Consumer& consumer)
6163 string mpls_nhs;
6264 string nhgs;
6365 bool is_recursive = false ;
66+ string srv6_source;
67+ bool overlay_nh = false ;
68+ bool srv6_nh = false ;
6469
6570 /* Get group's next hop IPs and aliases */
6671 for (auto i : kfvFieldsValues (t))
@@ -77,6 +82,12 @@ void NhgOrch::doTask(Consumer& consumer)
7782 if (fvField (i) == " mpls_nh" )
7883 mpls_nhs = fvValue (i);
7984
85+ if (fvField (i) == " seg_src" )
86+ {
87+ srv6_source = fvValue (i);
88+ srv6_nh = true ;
89+ }
90+
8091 if (fvField (i) == " nexthop_group" )
8192 {
8293 nhgs = fvValue (i);
@@ -96,9 +107,11 @@ void NhgOrch::doTask(Consumer& consumer)
96107 vector<string> alsv = tokenize (aliases, ' ,' );
97108 vector<string> mpls_nhv = tokenize (mpls_nhs, ' ,' );
98109 vector<string> nhgv = tokenize (nhgs, NHG_DELIMITER);
110+ vector<string> srv6_srcv = tokenize (srv6_source, ' ,' );
99111
100112 /* Create the next hop group key. */
101113 string nhg_str;
114+ NextHopGroupKey nhg_key;
102115
103116 /* Keeps track of any non-existing member of a recursive nexthop group */
104117 bool non_existent_member = false ;
@@ -154,28 +167,77 @@ void NhgOrch::doTask(Consumer& consumer)
154167 /* Form nexthopgroup key with the nexthopgroup keys of available members */
155168 nhgv = tokenize (nhgs, NHG_DELIMITER);
156169
170+ bool nhg_mismatch = false ;
157171 for (uint32_t i = 0 ; i < nhgv.size (); i++)
158172 {
159- if (i) nhg_str += NHG_DELIMITER;
173+ auto k = m_syncdNextHopGroups.at (nhgv[i]).nhg ->getKey ();
174+ if (i)
175+ {
176+ if (k.is_srv6_nexthop () != srv6_nh || k.is_overlay_nexthop () != overlay_nh)
177+ {
178+ SWSS_LOG_ERROR (" Inconsistent nexthop group type between %s and %s" ,
179+ m_syncdNextHopGroups.at (nhgv[0 ]).nhg ->getKey ().to_string ().c_str (),
180+ k.to_string ().c_str ());
181+ nhg_mismatch = true ;
182+ break ;
183+ }
184+ nhg_str += NHG_DELIMITER;
185+ }
186+ else
187+ {
188+ srv6_nh = k.is_srv6_nexthop ();
189+ overlay_nh = k.is_overlay_nexthop ();
190+ }
160191
161192 nhg_str += m_syncdNextHopGroups.at (nhgv[i]).nhg ->getKey ().to_string ();
162193 }
194+
195+ if (nhg_mismatch)
196+ {
197+ it = consumer.m_toSync .erase (it);
198+ continue ;
199+ }
200+
201+ if (srv6_nh)
202+ nhg_key = NextHopGroupKey (nhg_str, overlay_nh, srv6_nh);
203+ else
204+ nhg_key = NextHopGroupKey (nhg_str, weights);
163205 }
164206 else
165207 {
166- for ( uint32_t i = 0 ; i < ipv. size (); i++ )
208+ if (srv6_nh )
167209 {
168- if (i) nhg_str += NHG_DELIMITER;
169- if (!mpls_nhv.empty () && mpls_nhv[i] != " na" )
210+ if (ipv.size () != srv6_srcv.size ())
211+ {
212+ SWSS_LOG_ERROR (" inconsistent number of endpoints and srv6_srcs." );
213+ it = consumer.m_toSync .erase (it);
214+ continue ;
215+ }
216+ for (uint32_t i = 0 ; i < ipv.size (); i++)
170217 {
171- nhg_str += mpls_nhv[i] + LABELSTACK_DELIMITER;
218+ if (i) nhg_str += NHG_DELIMITER;
219+ nhg_str += ipv[i] + NH_DELIMITER; // ip address
220+ nhg_str += NH_DELIMITER; // srv6 segment
221+ nhg_str += srv6_srcv[i] + NH_DELIMITER; // srv6 source
222+ nhg_str += NH_DELIMITER; // srv6 vpn sid
223+ }
224+ nhg_key = NextHopGroupKey (nhg_str, overlay_nh, srv6_nh);
225+ }
226+ else
227+ {
228+ for (uint32_t i = 0 ; i < ipv.size (); i++)
229+ {
230+ if (i) nhg_str += NHG_DELIMITER;
231+ if (!mpls_nhv.empty () && mpls_nhv[i] != " na" )
232+ {
233+ nhg_str += mpls_nhv[i] + LABELSTACK_DELIMITER;
234+ }
235+ nhg_str += ipv[i] + NH_DELIMITER + alsv[i];
172236 }
173- nhg_str += ipv[i] + NH_DELIMITER + alsv[i] ;
237+ nhg_key = NextHopGroupKey (nhg_str, weights) ;
174238 }
175239 }
176240
177- NextHopGroupKey nhg_key = NextHopGroupKey (nhg_str, weights);
178-
179241 /* If the group does not exist, create one. */
180242 if (nhg_it == m_syncdNextHopGroups.end ())
181243 {
@@ -192,6 +254,13 @@ void NhgOrch::doTask(Consumer& consumer)
192254 {
193255 SWSS_LOG_DEBUG (" Next hop group count reached its limit." );
194256
257+ // don't create temp nhg for srv6
258+ if (nhg_key.is_srv6_nexthop ())
259+ {
260+ ++it;
261+ continue ;
262+ }
263+
195264 try
196265 {
197266 auto nhg = std::make_unique<NextHopGroup>(createTempNhg (nhg_key));
@@ -476,6 +545,14 @@ sai_object_id_t NextHopGroupMember::getNhId() const
476545 else if (gNeighOrch ->hasNextHop (m_key))
477546 {
478547 nh_id = gNeighOrch ->getNextHopId (m_key);
548+ if (m_key.isSrv6NextHop ())
549+ {
550+ SWSS_LOG_INFO (" Single NH: create srv6 nexthop %s" , m_key.to_string (false , true ).c_str ());
551+ if (!gSrv6Orch ->createSrv6NexthopWithoutVpn (m_key, nh_id))
552+ {
553+ SWSS_LOG_ERROR (" Failed to create SRv6 nexthop %s" , m_key.to_string (false , true ).c_str ());
554+ }
555+ }
479556 }
480557 /*
481558 * If the next hop is labeled and the IP next hop exists, create the
@@ -494,7 +571,20 @@ sai_object_id_t NextHopGroupMember::getNhId() const
494571 }
495572 else
496573 {
497- gNeighOrch ->resolveNeighbor (m_key);
574+ if (m_key.isSrv6NextHop ())
575+ {
576+ SWSS_LOG_INFO (" Single NH: create srv6 nexthop %s" , m_key.to_string (false , true ).c_str ());
577+ if (!gSrv6Orch ->createSrv6NexthopWithoutVpn (m_key, nh_id))
578+ {
579+ SWSS_LOG_ERROR (" Failed to create SRv6 nexthop %s" , m_key.to_string (false , true ).c_str ());
580+ }
581+ }
582+ else
583+ {
584+ SWSS_LOG_INFO (" Failed to get next hop %s, resolving neighbor" ,
585+ m_key.to_string ().c_str ());
586+ gNeighOrch ->resolveNeighbor (m_key);
587+ }
498588 }
499589
500590 return nh_id;
@@ -570,14 +660,22 @@ NextHopGroupMember::~NextHopGroupMember()
570660{
571661 SWSS_LOG_ENTER ();
572662
663+ if (m_key.isSrv6NextHop () && gNeighOrch ->hasNextHop (m_key) &&
664+ !gNeighOrch ->getNextHopRefCount (m_key))
665+ {
666+ if (!gSrv6Orch ->removeSrv6NexthopWithoutVpn (m_key))
667+ {
668+ SWSS_LOG_ERROR (" SRv6 Nexthop %s delete failed" , m_key.to_string (false , true ).c_str ());
669+ }
670+ }
573671 /*
574672 * If the labeled next hop is unreferenced, remove it from NeighOrch as
575673 * NhgOrch and RouteOrch are the ones controlling it's lifetime. They both
576674 * watch over these labeled next hops, so it doesn't matter who created
577675 * them as they're both doing the same checks before removing a labeled
578676 * next hop.
579677 */
580- if (isLabeled () &&
678+ else if (isLabeled () &&
581679 gNeighOrch ->hasNextHop (m_key) &&
582680 (gNeighOrch ->getNextHopRefCount (m_key) == 0 ))
583681 {
@@ -824,6 +922,7 @@ bool NextHopGroup::syncMembers(const std::set<NextHopKey>& nh_keys)
824922 */
825923 std::map<NextHopKey, sai_object_id_t > syncingMembers;
826924
925+ bool success = true ;
827926 for (const auto & nh_key : nh_keys)
828927 {
829928 NextHopGroupMember& nhgm = m_members.at (nh_key);
@@ -841,7 +940,8 @@ bool NextHopGroup::syncMembers(const std::set<NextHopKey>& nh_keys)
841940 {
842941 SWSS_LOG_WARN (" Failed to get next hop %s in group %s" ,
843942 nhgm.to_string ().c_str (), to_string ().c_str ());
844- return false ;
943+ success = false ;
944+ continue ;
845945 }
846946
847947 /* If the neighbor's interface is down, skip from being syncd. */
@@ -868,7 +968,6 @@ bool NextHopGroup::syncMembers(const std::set<NextHopKey>& nh_keys)
868968 * Go through the synced members and increment the Crm ref count for the
869969 * successful ones.
870970 */
871- bool success = true ;
872971 for (const auto & mbr : syncingMembers)
873972 {
874973 /* Check that the returned member ID is valid. */
@@ -941,7 +1040,7 @@ bool NextHopGroup::update(const NextHopGroupKey& nhg_key)
9411040 /* If the member is updated, update it's weight. */
9421041 else
9431042 {
944- if (!mbr_it.second .updateWeight (new_nh_key_it->weight ))
1043+ if (new_nh_key_it-> weight && mbr_it. second . getWeight () != new_nh_key_it-> weight && !mbr_it.second .updateWeight (new_nh_key_it->weight ))
9451044 {
9461045 SWSS_LOG_WARN (" Failed to update member %s weight" , nh_key.to_string ().c_str ());
9471046 return false ;
0 commit comments