Skip to content

Commit dad55b8

Browse files
committed
[sonic-dhcp4relay] Smart switch support
Signed-off-by: Shivashankar CR <[email protected]>
1 parent 012e59e commit dad55b8

File tree

3 files changed

+60
-4
lines changed

3 files changed

+60
-4
lines changed

dhcp4relay/src/dhcp4relay.cpp

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <pcapplusplus/UdpLayer.h>
1212
#include <signal.h>
1313
#include <unistd.h>
14+
#include <fstream>
1415

1516
#include "configdb.h"
1617
#include "dhcp4_sender.h"
@@ -430,9 +431,22 @@ uint8_t encode_tlv(uint8_t *buf, uint8_t t, uint8_t l, uint8_t *v) {
430431
return (l + DHCP_SUB_OPT_TLV_HEADER_LEN);
431432
}
432433

434+
std::string get_mac_address(const std::string &ifname) {
435+
std::string path = "/sys/class/net/" + ifname + "/address";
436+
std::ifstream file(path);
437+
if (!file.is_open()) {
438+
syslog(LOG_ERR, "Fetching mac address for interface %s", ifname.c_str());
439+
return "";
440+
}
441+
std::string mac;
442+
std::getline(file, mac);
443+
return mac;
444+
}
445+
433446
void encode_relay_option(pcpp::DhcpLayer *dhcp_pkt, relay_config *config) {
434447
uint8_t buf[256] = {0};
435448
uint8_t buf_offset = 0;
449+
std::string bm_mac;
436450

437451
auto vrf = vlan_vrf_map[config->vlan.c_str()];
438452

@@ -454,11 +468,22 @@ void encode_relay_option(pcpp::DhcpLayer *dhcp_pkt, relay_config *config) {
454468
(uint8_t *)circuit_id.c_str());
455469
buf_offset += offset;
456470

471+
if (!m_config.midplane_bridge.empty()) {
472+
bm_mac = get_mac_address(m_config.midplane_bridge);
473+
}
474+
457475
/* Encode remote ID sub-option */
458476
/* | 2 | 6 | my_mac| */
459-
offset = encode_tlv((buf + buf_offset), OPTION82_SUBOPT_REMOTE_ID,
460-
MAC_ADDR_STR_LEN, (uint8_t *)(m_config.host_mac_addr.c_str()));
461-
buf_offset += offset;
477+
/* if its SmartSwitch we need to fetch mac of bridge-midplane */
478+
if ((m_config.is_SmartSwitch) && (!bm_mac.empty())) {
479+
offset = encode_tlv((buf + buf_offset), OPTION82_SUBOPT_REMOTE_ID,
480+
MAC_ADDR_STR_LEN, (uint8_t *)(bm_mac.c_str()));
481+
buf_offset += offset;
482+
} else {
483+
offset = encode_tlv((buf + buf_offset), OPTION82_SUBOPT_REMOTE_ID,
484+
MAC_ADDR_STR_LEN, (uint8_t *)(m_config.host_mac_addr.c_str()));
485+
buf_offset += offset;
486+
}
462487

463488
/* TODO: this sub-option should be set if source interface selection is enabled */
464489
/* | 5 | 4 | ipv4 | */
@@ -914,6 +939,9 @@ void pkt_in_callback(evutil_socket_t fd, short event, void *arg) {
914939
if (vlan == vlan_map.end()) {
915940
if (intf.find(CLIENT_IF_PREFIX) != std::string::npos) {
916941
syslog(LOG_WARNING, "[DHCPV4_RELAY] Invalid input interface %s\n", interface_name);
942+
} else if ((m_config.is_SmartSwitch) && (intf.rfind("dpu", 0) == 0) && !m_config.midplane_bridge.empty()) {
943+
// if its SmartSwitch, we need to check for bridge_midplane interface
944+
vlan_str = m_config.midplane_bridge;
917945
}
918946
} else {
919947
vlan_str = vlan->second;

dhcp4relay/src/dhcp4relay.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,8 @@ struct metadata_config {
162162
std::string hostname = "sonic";
163163
uint32_t deployment_id;
164164
bool is_dualTor;
165+
bool is_SmartSwitch;
166+
std::string midplane_bridge;
165167
};
166168

167169
/**

dhcp4relay/src/dhcp4relay_mgr.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ void DHCPMgr::handle_swss_notification() {
6464
config_db_dhcp_server_ipv4_ptr = std::make_shared<swss::SubscriberStateTable>(config_db_ptr.get(), "DHCP_SERVER_IPV4");
6565
state_db_dhcp_server_ipv4_ip_ptr = std::make_shared<swss::SubscriberStateTable>(state_db_ptr.get(), "DHCP_SERVER_IPV4_SERVER_IP");
6666
swss::SubscriberStateTable config_db_port_table(config_db_ptr.get(), "PORT");
67+
swss::SubscriberStateTable config_db_dpu_table(config_db_ptr.get(), "DPUS");
6768
swss::SubscriberStateTable state_db_interface_table(state_db_ptr.get(), "INTERFACE_TABLE");
6869

6970
std::deque<swss::KeyOpFieldsValuesTuple> entries;
@@ -79,6 +80,7 @@ void DHCPMgr::handle_swss_notification() {
7980
swss_select.addSelectable(config_db_dhcp_server_ipv4_ptr.get());
8081
swss_select.addSelectable(state_db_dhcp_server_ipv4_ip_ptr.get());
8182
swss_select.addSelectable(&config_db_port_table);
83+
swss_select.addSelectable(&config_db_dpu_table);
8284
swss_select.addSelectable(&state_db_interface_table);
8385

8486
while (!stop_thread) {
@@ -137,6 +139,9 @@ void DHCPMgr::handle_swss_notification() {
137139
} else if (selectable == static_cast<swss::Selectable *>(&config_db_port_table)) {
138140
config_db_port_table.pops(entries);
139141
process_port_notification(entries);
142+
} else if (selectable == static_cast<swss::Selectable *>(&config_db_dpu_table)) {
143+
config_db_dpu_table.pops(entries);
144+
process_port_notification(entries);
140145
}
141146
}
142147
}
@@ -157,6 +162,8 @@ void DHCPMgr::process_device_metadata_notification(std::deque<swss::KeyOpFieldsV
157162
std::string key = kfvKey(entry);
158163
std::vector<swss::FieldValueTuple> field_values = kfvFieldsValues(entry);
159164
std::string operation = kfvOp(entry);
165+
std::shared_ptr<swss::DBConnector> config_db = std::make_shared<swss::DBConnector>("CONFIG_DB", 0);
166+
swss::Table midplane_tbl(config_db.get(), "MID_PLANE_BRIDGE");
160167

161168
if (key != "localhost") {
162169
continue;
@@ -191,6 +198,20 @@ void DHCPMgr::process_device_metadata_notification(std::deque<swss::KeyOpFieldsV
191198
send_dualTor_event = true;
192199
}
193200

201+
// Handle is_SmartSwitch logic
202+
if (subtype_found && subtype_value == "SmartSwitch") {
203+
m_config.is_SmartSwitch = true;
204+
std::string bridge_name;
205+
bool ok = midplane_tbl.hget("GLOBAL", "bridge", bridge_name);
206+
if (ok) {
207+
m_config.midplane_bridge = bridge_name;
208+
} else {
209+
syslog(LOG_ERR, "Failed to read midplane bridge name\n");
210+
}
211+
} else if (m_config.is_SmartSwitch) {
212+
m_config.is_SmartSwitch = false;
213+
}
214+
194215
if (send_dualTor_event) {
195216
relay_config *relay_msg = nullptr;
196217
try {
@@ -724,8 +745,10 @@ void DHCPMgr::process_dhcp_server_ipv4_notification(std::deque<swss::KeyOpFields
724745
}
725746

726747
/*Validation to check vlan is present in VLAN table or not */
748+
/*If its a smartswitch, we are checking midplane_bridge details */
727749
std::string value;
728-
if (!vlan_tbl.hget(vlan, "vlanid", value)) {
750+
if ((!vlan_tbl.hget(vlan, "vlanid", value))
751+
&& (!m_config.is_SmartSwitch || (!m_config.midplane_bridge.empty() && m_config.midplane_bridge != vlan))) {
729752
delete relay_msg;
730753
continue;
731754
}
@@ -812,6 +835,9 @@ void DHCPMgr::process_port_notification(std::deque<swss::KeyOpFieldsValuesTuple>
812835
if (fvField(fv) == "alias") {
813836
port_msg->alias = fvValue(fv);
814837
break;
838+
} else if (fvField(fv) == "midplane_interface") {
839+
port_msg->alias = fvValue(fv);
840+
break;
815841
}
816842
}
817843
} else {

0 commit comments

Comments
 (0)