Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 81 additions & 13 deletions cfgmgr/stpmgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ void StpMgr::doStpGlobalTask(Consumer &consumer)
STP_BRIDGE_CONFIG_MSG msg;
memset(&msg, 0, sizeof(STP_BRIDGE_CONFIG_MSG));

enum L2_PROTO_MODE old_l2ProtoEnabled = l2ProtoEnabled;

KeyOpFieldsValuesTuple t = it->second;

string key = kfvKey(t);
Expand Down Expand Up @@ -143,11 +145,75 @@ void StpMgr::doStpGlobalTask(Consumer &consumer)
}

memcpy(msg.base_mac_addr, macAddress.getMac(), 6);

/* Send once when PVST/MSTP is enabled first time */
if ((l2ProtoEnabled == L2_MSTP) && (old_l2ProtoEnabled == L2_NONE))
{
SWSS_LOG_INFO("Populating VLANs for STP mode change: %d -> %d", old_l2ProtoEnabled, l2ProtoEnabled);

// Get all existing VLANs from state table instead of iterating 1-4095
vector<string> vlanKeys;
m_stateVlanTable.getKeys(vlanKeys);

SWSS_LOG_INFO("Found %zu configured VLANs to populate", vlanKeys.size());

for (const auto& vlanKey : vlanKeys)
{
STP_MST_VLAN_PORT_MAP *vlan_msg = NULL;
vector<PORT_ATTR> port_list;
uint16_t portCnt = 0;
int len;

// Extract VLAN ID from key (e.g., "Vlan100" -> 100)
string vlanIdStr = vlanKey.substr(4);
int vlan_id = stoi(vlanIdStr);

// Skip reserved VLANs (e.g., VLAN 4095)
if (vlan_id == 4095)
continue;

// Get all port members for this VLAN
portCnt = (uint16_t)getAllVlanMem(vlanKey, port_list);
if (!portCnt)
continue;

SWSS_LOG_DEBUG("VLAN %d has %d ports", vlan_id, portCnt);
len = (int)(sizeof(STP_MST_VLAN_PORT_MAP) + (portCnt * sizeof(PORT_LIST)));

vlan_msg = (STP_MST_VLAN_PORT_MAP *)calloc(1, len);
if (!vlan_msg)
{
SWSS_LOG_ERROR("calloc failed for vlan %d", vlan_id);
// Continue processing other VLANs instead of returning
continue;
}

// Populate port list
PORT_LIST *attr = vlan_msg->port_list;
for (size_t i = 0; i < port_list.size(); i++)
{
snprintf(attr[i].intf_name, IFNAMSIZ, "%s", port_list[i].intf_name);
attr[i].tagging_mode = port_list[i].mode;
SWSS_LOG_DEBUG(" Port[%zu]: %s Mode %d", i, port_list[i].intf_name, port_list[i].mode);
}

// Fill in VLAN message
vlan_msg->port_count = portCnt;
vlan_msg->vlan_id = (uint16_t)vlan_id;
vlan_msg->stp_mode = l2ProtoEnabled;
vlan_msg->add = true;

// Send message to STP daemon
sendMsgStpd(STP_MST_VLAN_PORT_LIST_CONFIG, len, (void *)vlan_msg, (L2_PROTO_MODE)vlan_msg->stp_mode);

free(vlan_msg);
}
}
}
else if (op == DEL_COMMAND)
{
msg.opcode = STP_DEL_COMMAND;

msg.stp_mode = l2ProtoEnabled;
// Free Up all instances
FREE_ALL_INST_ID();

Expand All @@ -165,10 +231,11 @@ void StpMgr::doStpGlobalTask(Consumer &consumer)
SWSS_LOG_ERROR("ebtables del failed for PVST %d", ret_pvst);
}
l2ProtoEnabled = L2_NONE;

}

// Send the message to the daemon
sendMsgStpd(STP_BRIDGE_CONFIG, sizeof(msg), (void *)&msg);
sendMsgStpd(STP_BRIDGE_CONFIG, sizeof(msg), (void *)&msg, (L2_PROTO_MODE)msg.stp_mode);

// Move to the next item
it = consumer.m_toSync.erase(it);
Expand Down Expand Up @@ -329,7 +396,7 @@ void StpMgr::doStpVlanTask(Consumer &consumer)
deallocL2Instance(vlan_id);
}

sendMsgStpd(STP_VLAN_CONFIG, len, (void *)msg);
sendMsgStpd(STP_VLAN_CONFIG, len, (void *)msg, l2ProtoEnabled);
if (msg)
free(msg);

Expand Down Expand Up @@ -399,7 +466,7 @@ void StpMgr::doStpMstGlobalTask(Consumer &consumer)
msg.opcode = STP_DEL_COMMAND;
}

sendMsgStpd(STP_MST_GLOBAL_CONFIG, sizeof(msg), (void *)&msg);
sendMsgStpd(STP_MST_GLOBAL_CONFIG, sizeof(msg), (void *)&msg, l2ProtoEnabled);

it = consumer.m_toSync.erase(it);
}
Expand Down Expand Up @@ -438,7 +505,7 @@ void StpMgr::processStpVlanPortAttr(const string op, uint32_t vlan_id, const str
msg.opcode = STP_DEL_COMMAND;
}

sendMsgStpd(STP_VLAN_PORT_CONFIG, sizeof(msg), (void *)&msg);
sendMsgStpd(STP_VLAN_PORT_CONFIG, sizeof(msg), (void *)&msg, l2ProtoEnabled);
}

void StpMgr::doStpVlanPortTask(Consumer &consumer)
Expand Down Expand Up @@ -621,7 +688,7 @@ void StpMgr::processStpPortAttr(const string op,
}

// Send the fully prepared message to the STP daemon.
sendMsgStpd(STP_PORT_CONFIG, len, reinterpret_cast<void *>(msg));
sendMsgStpd(STP_PORT_CONFIG, len, reinterpret_cast<void *>(msg), l2ProtoEnabled);

// Clean up.
free(msg);
Expand Down Expand Up @@ -750,7 +817,7 @@ void StpMgr::doVlanMemUpdateTask(Consumer &consumer)

strncpy(msg.intf_name, intfName.c_str(), IFNAMSIZ-1);

sendMsgStpd(STP_VLAN_MEM_CONFIG, sizeof(msg), (void *)&msg);
sendMsgStpd(STP_VLAN_MEM_CONFIG, sizeof(msg), (void *)&msg, l2ProtoEnabled);
}

it = consumer.m_toSync.erase(it);
Expand Down Expand Up @@ -1105,7 +1172,7 @@ void StpMgr::doStpMstInstTask(Consumer &consumer)
updateVlanInstanceMap(instance_id, vlan_ids, false);
}

sendMsgStpd(STP_MST_INST_CONFIG, len, (void *)msg);
sendMsgStpd(STP_MST_INST_CONFIG, len, (void *)msg, l2ProtoEnabled);
if (msg)
free(msg);

Expand Down Expand Up @@ -1149,7 +1216,7 @@ void StpMgr::processStpMstInstPortAttr(const string op, uint16_t mst_id, const s
}

// Send the message to the daemon
sendMsgStpd(STP_MST_INST_PORT_CONFIG, sizeof(msg), (void *)&msg);
sendMsgStpd(STP_MST_INST_PORT_CONFIG, sizeof(msg), (void *)&msg, l2ProtoEnabled);
}


Expand Down Expand Up @@ -1215,7 +1282,7 @@ void StpMgr::doStpMstInstPortTask(Consumer &consumer)
}

// Send Message to STPd
int StpMgr::sendMsgStpd(STP_MSG_TYPE msgType, uint32_t msgLen, void *data)
int StpMgr::sendMsgStpd(STP_MSG_TYPE msgType, uint32_t msgLen, void *data, L2_PROTO_MODE protocol)
{
STP_IPC_MSG *tx_msg;
size_t len = 0;
Expand All @@ -1228,12 +1295,13 @@ int StpMgr::sendMsgStpd(STP_MSG_TYPE msgType, uint32_t msgLen, void *data)
tx_msg = (STP_IPC_MSG *)calloc(1, len);
if (tx_msg == NULL)
{
SWSS_LOG_ERROR("tx_msg mem alloc error\n");
SWSS_LOG_ERROR("tx_msg mem alloc error\n");
return -1;
}

tx_msg->msg_type = msgType;
tx_msg->msg_len = msgLen;
tx_msg->proto_mode = protocol;
memcpy(tx_msg->data, data, msgLen);

bzero(&addr, sizeof(addr));
Expand All @@ -1243,11 +1311,11 @@ int StpMgr::sendMsgStpd(STP_MSG_TYPE msgType, uint32_t msgLen, void *data)
rc = (int)sendto(stpd_fd, (void*)tx_msg, len, 0, (struct sockaddr *)&addr, sizeof(addr));
if (rc == -1)
{
SWSS_LOG_ERROR("tx_msg send error\n");
SWSS_LOG_ERROR("tx_msg send error\n");
}
else
{
SWSS_LOG_INFO("tx_msg sent %d", rc);
SWSS_LOG_INFO("tx_msg sent %d, proto_mode %d", rc, protocol);
}

free(tx_msg);
Expand Down
18 changes: 17 additions & 1 deletion cfgmgr/stpmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#define INVALID_MODE -1

#define MAX_VLANS 4096
#define MIN_VLAN_ID 1
#define MAX_VLAN_ID 4095

// Maximum number of instances supported
#define L2_INSTANCE_MAX MAX_VLANS
Expand Down Expand Up @@ -73,6 +75,7 @@ typedef enum STP_MSG_TYPE {
STP_STPCTL_MSG,
STP_MST_GLOBAL_CONFIG,
STP_MST_INST_CONFIG,
STP_MST_VLAN_PORT_LIST_CONFIG,
STP_MST_INST_PORT_CONFIG,
STP_MAX_MSG
} STP_MSG_TYPE;
Expand Down Expand Up @@ -225,6 +228,19 @@ typedef struct STP_MST_INST_PORT_CONFIG_MSG {
int priority; // Port priority
} __attribute__((packed)) STP_MST_INST_PORT_CONFIG_MSG;

typedef struct PORT_LIST {
char intf_name[IFNAMSIZ];
int8_t tagging_mode;
} PORT_LIST;

typedef struct STP_MST_VLAN_PORT_MAP {
uint16_t vlan_id;
uint16_t port_count;
int8_t stp_mode;
uint8_t add;
PORT_LIST port_list[0];
} __attribute__((aligned(4))) STP_MST_VLAN_PORT_MAP;

namespace swss {

class StpMgr : public Orch
Expand All @@ -235,7 +251,7 @@ class StpMgr : public Orch

using Orch::doTask;
void ipcInitStpd();
int sendMsgStpd(STP_MSG_TYPE msgType, uint32_t msgLen, void *data);
int sendMsgStpd(STP_MSG_TYPE msgType, uint32_t msgLen, void *data, L2_PROTO_MODE protocol);
MacAddress macAddress;
bool isPortInitDone(DBConnector *app_db);
uint16_t getStpMaxInstances(void);
Expand Down
2 changes: 1 addition & 1 deletion cfgmgr/stpmgrd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ int main(int argc, char **argv)
STP_INIT_READY_MSG msg;
memset(&msg, 0, sizeof(STP_INIT_READY_MSG));
msg.max_stp_instances = stpmgr.getStpMaxInstances();
stpmgr.sendMsgStpd(STP_INIT_READY, sizeof(msg), (void *)&msg);
stpmgr.sendMsgStpd(STP_INIT_READY, sizeof(msg), (void *)&msg, L2_NONE);

// Get Base MAC
Table table(&conf_db, "DEVICE_METADATA");
Expand Down
Loading