@@ -262,9 +262,11 @@ VNetVrfObject::~VNetVrfObject()
262262 */
263263std::bitset<VNET_BITMAP_SIZE> VNetBitmapObject::vnetBitmap_;
264264std::bitset<VNET_TUNNEL_SIZE> VNetBitmapObject::tunnelOffsets_;
265+ std::bitset<VNET_TUNNEL_SIZE> VNetBitmapObject::tunnelIdOffsets_;
265266map<string, uint32_t > VNetBitmapObject::vnetIds_;
266267map<uint32_t , VnetBridgeInfo> VNetBitmapObject::bridgeInfoMap_;
267268map<tuple<MacAddress, sai_object_id_t >, VnetNeighInfo> VNetBitmapObject::neighInfoMap_;
269+ map<tuple<IpAddress, sai_object_id_t >, uint16_t > VNetBitmapObject::endpointMap_;
268270
269271VNetBitmapObject::VNetBitmapObject (const std::string& vnet, const VNetInfo& vnetInfo,
270272 vector<sai_attribute_t >& attrs) : VNetObject(vnetInfo)
@@ -349,6 +351,29 @@ void VNetBitmapObject::recycleTunnelRouteTableOffset(uint32_t offset)
349351 tunnelOffsets_[offset] = false ;
350352}
351353
354+ uint16_t VNetBitmapObject::getFreeTunnelId ()
355+ {
356+ SWSS_LOG_ENTER ();
357+
358+ for (uint16_t i = 1 ; i < tunnelIdOffsets_.size (); i++)
359+ {
360+ if (tunnelIdOffsets_[i] == false )
361+ {
362+ tunnelIdOffsets_[i] = true ;
363+ return i;
364+ }
365+ }
366+
367+ return 0 ;
368+ }
369+
370+ void VNetBitmapObject::recycleTunnelId (uint16_t offset)
371+ {
372+ SWSS_LOG_ENTER ();
373+
374+ tunnelIdOffsets_[offset] = false ;
375+ }
376+
352377VnetBridgeInfo VNetBitmapObject::getBridgeInfoByVni (uint32_t vni, string tunnelName)
353378{
354379 SWSS_LOG_ENTER ();
@@ -828,6 +853,8 @@ bool VNetBitmapObject::addTunnelRoute(IpPrefix& ipPrefix, tunnelEndpoint& endp)
828853 uint32_t peerBitmap = vnet_id_;
829854 MacAddress mac = endp.mac ? endp.mac : gVxlanMacAddress ;
830855 TunnelRouteInfo tunnelRouteInfo;
856+ sai_ip_address_t underlayAddr;
857+ copy (underlayAddr, endp.ip );
831858
832859 VNetOrch* vnet_orch = gDirectory .get <VNetOrch*>();
833860 for (auto peer : peer_list)
@@ -847,8 +874,6 @@ bool VNetBitmapObject::addTunnelRoute(IpPrefix& ipPrefix, tunnelEndpoint& endp)
847874
848875 /* FDB entry to the tunnel */
849876 vector<sai_attribute_t > fdb_attrs;
850- sai_ip_address_t underlayAddr;
851- copy (underlayAddr, endp.ip );
852877 neighInfo.fdb_entry .switch_id = gSwitchId ;
853878 mac.getMac (neighInfo.fdb_entry .mac_address );
854879 neighInfo.fdb_entry .bv_id = bInfo.bridge_id ;
@@ -858,11 +883,11 @@ bool VNetBitmapObject::addTunnelRoute(IpPrefix& ipPrefix, tunnelEndpoint& endp)
858883 fdb_attrs.push_back (attr);
859884
860885 attr.id = SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID;
861- attr.value .oid = bInfo.bridge_port_tunnel_id ;
886+ attr.value .oid = bInfo.bridge_port_rif_id ;
862887 fdb_attrs.push_back (attr);
863888
864- attr.id = SAI_FDB_ENTRY_ATTR_ENDPOINT_IP ;
865- attr.value .ipaddr = underlayAddr ;
889+ attr.id = SAI_FDB_ENTRY_ATTR_PACKET_ACTION ;
890+ attr.value .s32 = SAI_PACKET_ACTION_FORWARD ;
866891 fdb_attrs.push_back (attr);
867892
868893 status = sai_fdb_api->create_fdb_entry (
@@ -930,6 +955,52 @@ bool VNetBitmapObject::addTunnelRoute(IpPrefix& ipPrefix, tunnelEndpoint& endp)
930955 throw std::runtime_error (" VNet route creation failed" );
931956 }
932957
958+ /* Tunnel endpoint */
959+ VxlanTunnelOrch* vxlan_orch = gDirectory .get <VxlanTunnelOrch*>();
960+ auto *tunnel = vxlan_orch->getVxlanTunnel (getTunnelName ());
961+ auto endpoint = make_tuple (endp.ip , tunnel->getTunnelId ());
962+ uint16_t tunnelIndex = 0 ;
963+ if (endpointMap_.find (endpoint) == endpointMap_.end ())
964+ {
965+ tunnelIndex = getFreeTunnelId ();
966+ vector<sai_attribute_t > vxlan_attrs;
967+
968+ sai_object_id_t tunnelL3VxlanEntryId;
969+ attr.id = SAI_TABLE_META_TUNNEL_ENTRY_ATTR_ACTION;
970+ attr.value .s32 = SAI_TABLE_META_TUNNEL_ENTRY_ACTION_TUNNEL_ENCAP;
971+ vxlan_attrs.push_back (attr);
972+
973+ attr.id = SAI_TABLE_META_TUNNEL_ENTRY_ATTR_METADATA_KEY;
974+ attr.value .u16 = tunnelIndex;
975+ vxlan_attrs.push_back (attr);
976+
977+ attr.id = SAI_TABLE_META_TUNNEL_ENTRY_ATTR_UNDERLAY_DIP;
978+ attr.value .ipaddr = underlayAddr;
979+ vxlan_attrs.push_back (attr);
980+
981+ attr.id = SAI_TABLE_META_TUNNEL_ENTRY_ATTR_TUNNEL_ID;
982+ attr.value .oid = tunnel->getTunnelId ();
983+ vxlan_attrs.push_back (attr);
984+
985+ status = sai_bmtor_api->create_table_meta_tunnel_entry (
986+ &tunnelL3VxlanEntryId,
987+ gSwitchId ,
988+ (uint32_t )vxlan_attrs.size (),
989+ vxlan_attrs.data ());
990+
991+ if (status != SAI_STATUS_SUCCESS)
992+ {
993+ SWSS_LOG_ERROR (" Failed to create L3 VXLAN entry, SAI rc: %d" , status);
994+ throw std::runtime_error (" VNet route creation failed" );
995+ }
996+
997+ endpointMap_.emplace (endpoint, tunnelIndex);
998+ }
999+ else
1000+ {
1001+ tunnelIndex = endpointMap_.at (endpoint);
1002+ }
1003+
9331004 /* Tunnel route */
9341005 vector<sai_attribute_t > tr_attrs;
9351006 sai_ip_prefix_t pfx;
@@ -960,6 +1031,10 @@ bool VNetBitmapObject::addTunnelRoute(IpPrefix& ipPrefix, tunnelEndpoint& endp)
9601031 attr.value .oid = tunnelRouteInfo.nexthopId ;
9611032 tr_attrs.push_back (attr);
9621033
1034+ attr.id = SAI_TABLE_BITMAP_ROUTER_ENTRY_ATTR_TUNNEL_INDEX;
1035+ attr.value .u16 = tunnelIndex;
1036+ tr_attrs.push_back (attr);
1037+
9631038 status = sai_bmtor_api->create_table_bitmap_router_entry (
9641039 &tunnelRouteInfo.tunnelRouteTableEntryId ,
9651040 gSwitchId ,
@@ -1105,6 +1180,11 @@ bool VNetBitmapObject::addRoute(IpPrefix& ipPrefix, nextHop& nh)
11051180 attr.id = SAI_TABLE_BITMAP_ROUTER_ENTRY_ATTR_NEXT_HOP;
11061181 attr.value .oid = nh_id;
11071182 attrs.push_back (attr);
1183+
1184+ attr.id = SAI_TABLE_BITMAP_ROUTER_ENTRY_ATTR_TUNNEL_INDEX;
1185+ attr.value .u16 = 0 ;
1186+ attrs.push_back (attr);
1187+
11081188 }
11091189 else
11101190 {
0 commit comments