in vslib/SwitchStateBaseFdb.cpp [92:269]
void SwitchStateBase::findBridgeVlanForPortVlan(
_In_ sai_object_id_t port_id,
_In_ sai_vlan_id_t vlan_id,
_Inout_ sai_object_id_t &bv_id,
_Inout_ sai_object_id_t &bridge_port_id)
{
SWSS_LOG_ENTER();
bv_id = SAI_NULL_OBJECT_ID;
bridge_port_id = SAI_NULL_OBJECT_ID;
sai_object_id_t bridge_id;
/*
* The bridge port lookup process is two steps:
*
* - use (vlan_id, physical port_id) to match any .1D bridge port created.
* If there is match, then quit, found=true
*
* - use (physical port_id) to match any .1Q bridge created. if there is a
* match, the quite, found=true.
*
* If found==true, generate fdb learn event on the .1D or .1Q bridge port.
* If not found, then do not generate fdb event. It means the packet is not
* received on the bridge port.
*
* XXX this is not whats happening here, we are just looking for any
* bridge id (as in our case this is shortcut, we will remove all bridge ports
* when we will use router interface based port/lag and no bridge
* will be found.
*/
auto &objectHash = m_objectHash.at(SAI_OBJECT_TYPE_BRIDGE_PORT);
// iterate via all bridge ports to find match on port id
sai_object_id_t lag_id = SAI_NULL_OBJECT_ID;
if (getLagFromPort(port_id,lag_id))
{
SWSS_LOG_INFO("got lag %s for port %s",
sai_serialize_object_id(lag_id).c_str(),
sai_serialize_object_id(port_id).c_str());
}
bool bv_id_set = false;
for (auto it = objectHash.begin(); it != objectHash.end(); ++it)
{
sai_object_id_t bpid;
sai_deserialize_object_id(it->first, bpid);
sai_attribute_t attrs[2];
attrs[0].id = SAI_BRIDGE_PORT_ATTR_PORT_ID;
attrs[1].id = SAI_BRIDGE_PORT_ATTR_TYPE;
sai_status_t status = get(SAI_OBJECT_TYPE_BRIDGE_PORT, bpid, (uint32_t)(sizeof(attrs)/sizeof(attrs[0])), attrs);
if (status != SAI_STATUS_SUCCESS)
{
SWSS_LOG_WARN("failed to get attr PORT_ID and TYPE for bridge port %s",
sai_serialize_object_id(bpid).c_str());
continue;
}
if (lag_id != SAI_NULL_OBJECT_ID)
{
// if port is member of lag, we should check if port_id is that LAG
if (port_id == attrs[0].value.oid)
{
// there should be no case that the same port is lag member and has bridge port object on it
SWSS_LOG_ERROR("port %s is member of lag %s, and also has bridge port created: %s",
sai_serialize_object_id(port_id).c_str(),
sai_serialize_object_id(lag_id).c_str(),
sai_serialize_object_id(attrs[0].value.oid).c_str());
continue;
}
if (lag_id != attrs[0].value.oid)
{
// this is not expected port
continue;
}
}
else if (port_id != attrs[0].value.oid)
{
// this is not expected port
continue;
}
bridge_port_id = bpid;
// get the 1D bridge id if the bridge port type is subport
auto bp_type = attrs[1].value.s32;
SWSS_LOG_DEBUG("found bridge port %s of type %d",
sai_serialize_object_id(bridge_port_id).c_str(),
bp_type);
if (bp_type == SAI_BRIDGE_PORT_TYPE_SUB_PORT)
{
sai_attribute_t attr;
attr.id = SAI_BRIDGE_PORT_ATTR_BRIDGE_ID;
status = get(SAI_OBJECT_TYPE_BRIDGE_PORT, bridge_port_id, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
break;
}
bridge_id = attr.value.oid;
SWSS_LOG_DEBUG("found bridge %s for port %s",
sai_serialize_object_id(bridge_id).c_str(),
sai_serialize_object_id(port_id).c_str());
attr.id = SAI_BRIDGE_ATTR_TYPE;
status = get(SAI_OBJECT_TYPE_BRIDGE, bridge_id, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
break;
}
SWSS_LOG_DEBUG("bridge %s type is %d",
sai_serialize_object_id(bridge_id).c_str(),
attr.value.s32);
bv_id = bridge_id;
bv_id_set = true;
}
else
{
auto &objectHash2 = m_objectHash.at(SAI_OBJECT_TYPE_VLAN);
// iterate via all vlans to find match on vlan id
for (auto it2 = objectHash2.begin(); it2 != objectHash2.end(); ++it2)
{
sai_object_id_t vlan_oid;
sai_deserialize_object_id(it2->first, vlan_oid);
sai_attribute_t attr;
attr.id = SAI_VLAN_ATTR_VLAN_ID;
status = get(SAI_OBJECT_TYPE_VLAN, vlan_oid, 1, &attr);
if (status != SAI_STATUS_SUCCESS)
{
continue;
}
if (vlan_id == attr.value.u16)
{
bv_id = vlan_oid;
bv_id_set = true;
break;
}
}
}
break;
}
if (!bv_id_set)
{
// if port is lag member, then we didn't found bridge_port for that lag (expected for rif lag)
SWSS_LOG_WARN("failed to find bv_id for vlan %d and port_id %s",
vlan_id,
sai_serialize_object_id(port_id).c_str());
}
}