in fboss/agent/hw/bcm/BcmWarmBootCache.cpp [448:585]
void BcmWarmBootCache::populate(const folly::dynamic& warmBootState) {
populateFromWarmBootState(warmBootState);
bcm_vlan_data_t* vlanList = nullptr;
int vlanCount = 0;
SCOPE_EXIT {
bcm_vlan_list_destroy(hw_->getUnit(), vlanList, vlanCount);
};
auto rv = bcm_vlan_list(hw_->getUnit(), &vlanList, &vlanCount);
bcmCheckError(rv, "Unable to get vlan information");
for (auto i = 0; i < vlanCount; ++i) {
bcm_vlan_data_t& vlanData = vlanList[i];
int portCount = 0;
BCM_PBMP_COUNT(vlanData.port_bitmap, portCount);
XLOG(DBG1) << "Got vlan : " << vlanData.vlan_tag << " with : " << portCount
<< " ports";
// TODO: Investigate why port_bitmap contains
// the untagged ports rather than ut_port_bitmap
vlan2VlanInfo_.insert(make_pair(
BcmSwitch::getVlanId(vlanData.vlan_tag),
VlanInfo(
VlanID(vlanData.vlan_tag),
vlanData.port_bitmap,
vlanData.port_bitmap)));
bcm_l3_intf_t l3Intf;
bcm_l3_intf_t_init(&l3Intf);
// there can be more than one interfaces per vlan, such as one l3 intf
// and other MPLS tunnels. There is no clear way to identify which is
// which. so keeping track of l3 interfaces in warmboot state file
// look for l3 intf ID in warmboot state file and try to extract it.
l3Intf.l3a_vid = vlanData.vlan_tag;
bool intfFound = false;
auto iter = vlan2BcmIfIdInWarmBootFile_.find(VlanID(vlanData.vlan_tag));
if (iter != vlan2BcmIfIdInWarmBootFile_.end()) {
l3Intf.l3a_intf_id = iter->second;
l3Intf.l3a_flags = BCM_L3_WITH_ID;
rv = bcm_l3_intf_get(hw_->getUnit(), &l3Intf);
} else {
// this can happen for vlan id 1, a special vlan which is returned by
// bcm_vlan_list, this vlan has all ports which has no vlan associated
// it also has port 0 if all front panel ports are associated with some
// vlan. this vlan won't be in vlan2BcmIfIdInWarmBootFile_
rv = bcm_l3_intf_find_vlan(hw_->getUnit(), &l3Intf);
}
if (rv != BCM_E_NOT_FOUND) {
bcmCheckError(rv, "failed to find interface for ", vlanData.vlan_tag);
intfFound = true;
vlanAndMac2Intf_[make_pair(
BcmSwitch::getVlanId(l3Intf.l3a_vid),
macFromBcm(l3Intf.l3a_mac_addr))] = l3Intf;
XLOG(DBG1) << "Found l3 interface for vlan : " << vlanData.vlan_tag;
}
if (intfFound) {
bcm_l2_station_t l2Station;
bcm_l2_station_t_init(&l2Station);
auto stationId =
hw_->getPlatform()->getAsic()->getStationID(l3Intf.l3a_vid);
rv = bcm_l2_station_get(hw_->getUnit(), stationId, &l2Station);
if (!BCM_FAILURE(rv)) {
XLOG(DBG1) << " Found l2 station with id : " << l3Intf.l3a_vid;
vlan2Station_[VlanID(vlanData.vlan_tag)] = l2Station;
} else {
XLOG(DBG1) << "Could not get l2 station for vlan : "
<< vlanData.vlan_tag;
}
}
}
bcm_l3_info_t l3Info;
bcm_l3_info_t_init(&l3Info);
bcm_l3_info(hw_->getUnit(), &l3Info);
if (hw_->getPlatform()->getAsic()->isSupported(HwAsic::Feature::HOSTTABLE)) {
// Traverse V4 hosts
rv = bcm_l3_host_traverse(
hw_->getUnit(),
0,
0,
l3Info.l3info_max_host,
hostTraversalCallback,
this);
bcmCheckError(rv, "Failed to traverse v4 hosts");
// Traverse V6 hosts
rv = bcm_l3_host_traverse(
hw_->getUnit(),
BCM_L3_IP6,
0,
// Diag shell uses this for getting # of v6 host entries
l3Info.l3info_max_host / 2,
hostTraversalCallback,
this);
bcmCheckError(rv, "Failed to traverse v6 hosts");
}
// Traverse V4 routes
rv = bcm_l3_route_traverse(
hw_->getUnit(),
0,
0,
l3Info.l3info_max_route,
routeTraversalCallback,
this);
bcmCheckError(rv, "Failed to traverse v4 routes");
// Traverse V6 routes
rv = bcm_l3_route_traverse(
hw_->getUnit(),
BCM_L3_IP6,
0,
// Diag shell uses this for getting # of v6 route entries
l3Info.l3info_max_route / 2,
routeTraversalCallback,
this);
bcmCheckError(rv, "Failed to traverse v6 routes");
// Get egress entries.
rv = bcm_l3_egress_traverse(hw_->getUnit(), egressTraversalCallback, this);
bcmCheckError(rv, "Failed to traverse egress");
// Traverse ecmp egress entries
if (hw_->getPlatform()->getAsic()->isSupported(HwAsic::Feature::HSDK)) {
rv = bcm_l3_ecmp_traverse(
hw_->getUnit(),
ecmpEgressTraversalCallback<bcm_l3_ecmp_member_t>,
this);
} else {
rv = bcm_l3_egress_ecmp_traverse(
hw_->getUnit(), ecmpEgressTraversalCallback<bcm_if_t>, this);
}
bcmCheckError(rv, "Failed to traverse ecmp egress");
// populate acls, acl stats
populateAcls(
hw_->getPlatform()->getAsic()->getDefaultACLGroupID(),
this->aclEntry2AclStat_,
this->priority2BcmAclEntryHandle_);
populateRtag7State();
populateMirrors();
populateMirroredPorts();
populateQosMaps();
populateLabelSwitchActions();
populateSwitchSettings();
populateRxReasonToQueue();
}