@@ -513,6 +513,7 @@ void RouteOrch::doTask(Consumer& consumer)
513513 string remote_macs;
514514 bool & excp_intfs_flag = ctx.excp_intfs_flag ;
515515 bool overlay_nh = false ;
516+ bool blackhole = false ;
516517
517518 for (auto i : kfvFieldsValues (t))
518519 {
@@ -529,6 +530,9 @@ void RouteOrch::doTask(Consumer& consumer)
529530
530531 if (fvField (i) == " router_mac" )
531532 remote_macs = fvValue (i);
533+
534+ if (fvField (i) == " blackhole" )
535+ blackhole = fvValue (i) == " true" ;
532536 }
533537
534538 vector<string>& ipv = ctx.ipv ;
@@ -544,7 +548,7 @@ void RouteOrch::doTask(Consumer& consumer)
544548
545549 /* Resize the ip vector to match ifname vector
546550 * as tokenize(",", ',') will miss the last empty segment. */
547- if (alsv.size () == 0 )
551+ if (alsv.size () == 0 && !blackhole )
548552 {
549553 SWSS_LOG_WARN (" Skip the route %s, for it has an empty ifname field." , key.c_str ());
550554 it = consumer.m_toSync .erase (it);
@@ -597,7 +601,11 @@ void RouteOrch::doTask(Consumer& consumer)
597601 string nhg_str = " " ;
598602 NextHopGroupKey& nhg = ctx.nhg ;
599603
600- if (overlay_nh == false )
604+ if (blackhole)
605+ {
606+ nhg = NextHopGroupKey ();
607+ }
608+ else if (overlay_nh == false )
601609 {
602610 if (alsv[0 ] == " tun0" && !(IpAddress (ipv[0 ]).isZero ()))
603611 {
@@ -630,10 +638,8 @@ void RouteOrch::doTask(Consumer& consumer)
630638
631639 if (ipv.size () == 1 && IpAddress (ipv[0 ]).isZero ())
632640 {
633- /* blackhole to be done */
634641 if (alsv[0 ] == " unknown" )
635642 {
636- /* add addBlackholeRoute or addRoute support empty nhg */
637643 it = consumer.m_toSync .erase (it);
638644 }
639645 /* skip direct routes to tun0 */
@@ -1349,6 +1355,7 @@ bool RouteOrch::addRoute(RouteBulkContext& ctx, const NextHopGroupKey &nextHops)
13491355 bool status = false ;
13501356 bool curNhgIsFineGrained = false ;
13511357 bool prevNhgWasFineGrained = false ;
1358+ bool blackhole = false ;
13521359
13531360 if (m_syncdRoutes.find (vrf_id) == m_syncdRoutes.end ())
13541361 {
@@ -1377,6 +1384,11 @@ bool RouteOrch::addRoute(RouteBulkContext& ctx, const NextHopGroupKey &nextHops)
13771384 return false ;
13781385 }
13791386 }
1387+ else if (nextHops.getSize () == 0 )
1388+ {
1389+ /* The route is pointing to a blackhole */
1390+ blackhole = true ;
1391+ }
13801392 else if (nextHops.getSize () == 1 )
13811393 {
13821394 /* The route is pointing to a next hop */
@@ -1544,8 +1556,16 @@ bool RouteOrch::addRoute(RouteBulkContext& ctx, const NextHopGroupKey &nextHops)
15441556 */
15451557 if (it_route == m_syncdRoutes.at (vrf_id).end ())
15461558 {
1547- route_attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID;
1548- route_attr.value .oid = next_hop_id;
1559+ if (blackhole)
1560+ {
1561+ route_attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION;
1562+ route_attr.value .s32 = SAI_PACKET_ACTION_DROP;
1563+ }
1564+ else
1565+ {
1566+ route_attr.id = SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID;
1567+ route_attr.value .oid = next_hop_id;
1568+ }
15491569
15501570 /* Default SAI_ROUTE_ATTR_PACKET_ACTION is SAI_PACKET_ACTION_FORWARD */
15511571 object_statuses.emplace_back ();
@@ -1559,8 +1579,8 @@ bool RouteOrch::addRoute(RouteBulkContext& ctx, const NextHopGroupKey &nextHops)
15591579 }
15601580 else
15611581 {
1562- /* Set the packet action to forward when there was no next hop (dropped) */
1563- if (it_route->second .getSize () == 0 )
1582+ /* Set the packet action to forward when there was no next hop (dropped) and not pointing to blackhole */
1583+ if (it_route->second .getSize () == 0 && !blackhole )
15641584 {
15651585 route_attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION;
15661586 route_attr.value .s32 = SAI_PACKET_ACTION_FORWARD;
@@ -1584,6 +1604,15 @@ bool RouteOrch::addRoute(RouteBulkContext& ctx, const NextHopGroupKey &nextHops)
15841604 object_statuses.emplace_back ();
15851605 gRouteBulker .set_entry_attribute (&object_statuses.back (), &route_entry, &route_attr);
15861606 }
1607+
1608+ if (blackhole)
1609+ {
1610+ route_attr.id = SAI_ROUTE_ENTRY_ATTR_PACKET_ACTION;
1611+ route_attr.value .s32 = SAI_PACKET_ACTION_DROP;
1612+
1613+ object_statuses.emplace_back ();
1614+ gRouteBulker .set_entry_attribute (&object_statuses.back (), &route_entry, &route_attr);
1615+ }
15871616 }
15881617 return false ;
15891618}
@@ -1595,6 +1624,7 @@ bool RouteOrch::addRoutePost(const RouteBulkContext& ctx, const NextHopGroupKey
15951624 const sai_object_id_t & vrf_id = ctx.vrf_id ;
15961625 const IpPrefix& ipPrefix = ctx.ip_prefix ;
15971626 bool isFineGrained = false ;
1627+ bool blackhole = false ;
15981628
15991629 const auto & object_statuses = ctx.object_statuses ;
16001630
@@ -1612,6 +1642,11 @@ bool RouteOrch::addRoutePost(const RouteBulkContext& ctx, const NextHopGroupKey
16121642 /* Route is pointing to Fine Grained ECMP nexthop group */
16131643 isFineGrained = true ;
16141644 }
1645+ else if (nextHops.getSize () == 0 )
1646+ {
1647+ /* The route is pointing to a blackhole */
1648+ blackhole = true ;
1649+ }
16151650 else if (nextHops.getSize () == 1 )
16161651 {
16171652 /* The route is pointing to a next hop */
@@ -1739,8 +1774,8 @@ bool RouteOrch::addRoutePost(const RouteBulkContext& ctx, const NextHopGroupKey
17391774 {
17401775 sai_status_t status;
17411776
1742- /* Set the packet action to forward when there was no next hop (dropped) */
1743- if (it_route->second .getSize () == 0 )
1777+ /* Set the packet action to forward when there was no next hop (dropped) and not pointing to blackhole */
1778+ if (it_route->second .getSize () == 0 && !blackhole )
17441779 {
17451780 status = *it_status++;
17461781 if (status != SAI_STATUS_SUCCESS)
@@ -1790,6 +1825,22 @@ bool RouteOrch::addRoutePost(const RouteBulkContext& ctx, const NextHopGroupKey
17901825 }
17911826 }
17921827
1828+ if (blackhole)
1829+ {
1830+ /* Set the packet action to drop for blackhole routes */
1831+ status = *it_status++;
1832+ if (status != SAI_STATUS_SUCCESS)
1833+ {
1834+ SWSS_LOG_ERROR (" Failed to set blackhole route %s with packet action drop, %d" ,
1835+ ipPrefix.to_string ().c_str (), status);
1836+ task_process_status handle_status = handleSaiSetStatus (SAI_API_ROUTE, status);
1837+ if (handle_status != task_success)
1838+ {
1839+ return parseHandleSaiStatusFailure (handle_status);
1840+ }
1841+ }
1842+ }
1843+
17931844 SWSS_LOG_INFO (" Post set route %s with next hop(s) %s" ,
17941845 ipPrefix.to_string ().c_str (), nextHops.to_string ().c_str ());
17951846 }
0 commit comments