From bb94f8e92ad226e78b1f339db26bf58a0debdb44 Mon Sep 17 00:00:00 2001 From: Prince Sunny Date: Wed, 21 Oct 2020 20:58:27 -0700 Subject: [PATCH] Use vlan-mac for Vlan interfaces if specified in VLAN table (#1472) --- cfgmgr/vlanmgr.cpp | 24 ++++++++++++++++++++++++ cfgmgr/vlanmgr.h | 1 + orchagent/intfsorch.cpp | 32 +++++++++++++++++++++++++++++++- orchagent/intfsorch.h | 1 + orchagent/port.h | 1 + orchagent/portsorch.cpp | 14 ++++++++++++++ 6 files changed, 72 insertions(+), 1 deletion(-) diff --git a/cfgmgr/vlanmgr.cpp b/cfgmgr/vlanmgr.cpp index ef8bc4845647..4570374cb459 100644 --- a/cfgmgr/vlanmgr.cpp +++ b/cfgmgr/vlanmgr.cpp @@ -167,6 +167,21 @@ bool VlanMgr::setHostVlanMtu(int vlan_id, uint32_t mtu) return false; } +bool VlanMgr::setHostVlanMac(int vlan_id, const string &mac) +{ + SWSS_LOG_ENTER(); + + // The command should be generated as: + // /sbin/ip link set Vlan{{vlan_id}} address {{mac}} + ostringstream cmds; + cmds << IP_CMD " link set " VLAN_PREFIX + std::to_string(vlan_id) + " address " << shellquote(mac); + + std::string res; + EXEC_WITH_ERROR_THROW(cmds.str(), res); + + return true; +} + bool VlanMgr::addHostVlanMember(int vlan_id, const string &port_alias, const string& tagging_mode) { SWSS_LOG_ENTER(); @@ -268,6 +283,7 @@ void VlanMgr::doVlanTask(Consumer &consumer) { string admin_status; string mtu = DEFAULT_MTU_STR; + string mac = gMacAddress.to_string(); vector fvVector; string members; @@ -317,6 +333,11 @@ void VlanMgr::doVlanTask(Consumer &consumer) else if (fvField(i) == "members@") { members = fvValue(i); } + else if (fvField(i) == "mac") + { + mac = fvValue(i); + setHostVlanMac(vlan_id, mac); + } } /* fvVector should not be empty */ if (fvVector.empty()) @@ -328,6 +349,9 @@ void VlanMgr::doVlanTask(Consumer &consumer) FieldValueTuple m("mtu", mtu); fvVector.push_back(m); + FieldValueTuple mc("mac", mac); + fvVector.push_back(mc); + m_appVlanTableProducer.set(key, fvVector); m_vlans.insert(key); diff --git a/cfgmgr/vlanmgr.h b/cfgmgr/vlanmgr.h index 469f16ccafa5..7c2f0c68b144 100644 --- a/cfgmgr/vlanmgr.h +++ b/cfgmgr/vlanmgr.h @@ -33,6 +33,7 @@ class VlanMgr : public Orch bool removeHostVlan(int vlan_id); bool setHostVlanAdminState(int vlan_id, const std::string &admin_status); bool setHostVlanMtu(int vlan_id, uint32_t mtu); + bool setHostVlanMac(int vlan_id, const std::string &mac); bool addHostVlanMember(int vlan_id, const std::string &port_alias, const std::string& tagging_mode); bool removeHostVlanMember(int vlan_id, const std::string &port_alias); bool isMemberStateOk(const std::string &alias); diff --git a/orchagent/intfsorch.cpp b/orchagent/intfsorch.cpp index 7f25d47c38ad..39a0c72d5178 100644 --- a/orchagent/intfsorch.cpp +++ b/orchagent/intfsorch.cpp @@ -186,6 +186,28 @@ bool IntfsOrch::setRouterIntfsMtu(const Port &port) return true; } +bool IntfsOrch::setRouterIntfsMac(const Port &port) +{ + SWSS_LOG_ENTER(); + + sai_attribute_t attr; + + attr.id = SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS; + memcpy(attr.value.mac, port.m_mac.getMac(), sizeof(sai_mac_t)); + + sai_status_t status = sai_router_intfs_api-> + set_router_interface_attribute(port.m_rif_id, &attr); + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("Failed to set router interface %s MAC to %s, rv:%d", + port.m_alias.c_str(), port.m_mac.to_string().c_str(), status); + return false; + } + SWSS_LOG_NOTICE("Set router interface %s MAC to %s", + port.m_alias.c_str(), port.m_mac.to_string().c_str()); + return true; +} + bool IntfsOrch::setRouterIntfsNatZoneId(Port &port) { SWSS_LOG_ENTER(); @@ -887,7 +909,15 @@ bool IntfsOrch::addRouterIntfs(sai_object_id_t vrf_id, Port &port) attrs.push_back(attr); attr.id = SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS; - memcpy(attr.value.mac, gMacAddress.getMac(), sizeof(sai_mac_t)); + if (port.m_mac) + { + memcpy(attr.value.mac, port.m_mac.getMac(), sizeof(sai_mac_t)); + } + else + { + memcpy(attr.value.mac, gMacAddress.getMac(), sizeof(sai_mac_t)); + + } attrs.push_back(attr); attr.id = SAI_ROUTER_INTERFACE_ATTR_TYPE; diff --git a/orchagent/intfsorch.h b/orchagent/intfsorch.h index 9db1a3b228f5..c5b54cc5547e 100644 --- a/orchagent/intfsorch.h +++ b/orchagent/intfsorch.h @@ -42,6 +42,7 @@ class IntfsOrch : public Orch void decreaseRouterIntfsRefCount(const string&); bool setRouterIntfsMtu(const Port &port); + bool setRouterIntfsMac(const Port &port); bool setRouterIntfsNatZoneId(Port &port); bool setRouterIntfsAdminStatus(const Port &port); diff --git a/orchagent/port.h b/orchagent/port.h index 74f805ddec75..d3ba42c4a0f2 100644 --- a/orchagent/port.h +++ b/orchagent/port.h @@ -81,6 +81,7 @@ class Port sai_object_id_t m_port_id = 0; sai_port_fec_mode_t m_fec_mode = SAI_PORT_FEC_MODE_NONE; VlanInfo m_vlan_info; + MacAddress m_mac; sai_object_id_t m_bridge_port_id = 0; // TODO: port could have multiple bridge port IDs sai_vlan_id_t m_port_vlan_id = DEFAULT_PORT_VLAN_ID; // Port VLAN ID sai_object_id_t m_rif_id = 0; diff --git a/orchagent/portsorch.cpp b/orchagent/portsorch.cpp index e75f8ec584bc..7f06c73bf974 100755 --- a/orchagent/portsorch.cpp +++ b/orchagent/portsorch.cpp @@ -2578,12 +2578,17 @@ void PortsOrch::doVlanTask(Consumer &consumer) { // Retrieve attributes uint32_t mtu = 0; + MacAddress mac; for (auto i : kfvFieldsValues(t)) { if (fvField(i) == "mtu") { mtu = (uint32_t)stoul(fvValue(i)); } + if (fvField(i) == "mac") + { + mac = MacAddress(fvValue(i)); + } } /* @@ -2617,6 +2622,15 @@ void PortsOrch::doVlanTask(Consumer &consumer) gIntfsOrch->setRouterIntfsMtu(vl); } } + if (mac) + { + vl.m_mac = mac; + m_portList[vlan_alias] = vl; + if (vl.m_rif_id) + { + gIntfsOrch->setRouterIntfsMac(vl); + } + } } it = consumer.m_toSync.erase(it);