Skip to content

Commit 012e59e

Browse files
committed
[sonic-dhcp4relay]: Defect fixes
Below sonic-mgmt issues are fixed: 1. Random source port 2. Padding issues 3. DHCP Server fixes Signed-off-by: Shivashankar CR <[email protected]>
1 parent 39e28c4 commit 012e59e

File tree

6 files changed

+34
-22
lines changed

6 files changed

+34
-22
lines changed

dhcp4relay/patch/0001-dhcpv4-relay-accept-random-src-port.patch

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
diff --git a/PcapPlusPlus-24.09/Packet++/header/DhcpLayer.h b/PcapPlusPlus-24.09/Packet++/header/DhcpLayer.h
1+
diff --git a/Packet++/header/DhcpLayer.h b/Packet++/header/DhcpLayer.h
22
index 435becb..282d739 100644
3-
--- a/PcapPlusPlus-24.09/Packet++/header/DhcpLayer.h
4-
+++ b/PcapPlusPlus-24.09/Packet++/header/DhcpLayer.h
3+
--- a/Packet++/header/DhcpLayer.h
4+
+++ b/Packet++/header/DhcpLayer.h
55
@@ -881,8 +881,8 @@ namespace pcpp
66

77
bool DhcpLayer::isDhcpPorts(uint16_t portSrc, uint16_t portDst)

dhcp4relay/src/dhcp4_sender.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@
1616
* @param len length of message
1717
* @param src_ip source IP address as string (optional)
1818
* @param use_src_ip if true, use src_ip as source address
19+
* @param pad if true, do padding
1920
*
2021
* @return boolean True if packet successfully sent
2122
*/
2223
#ifndef UNIT_TEST
23-
bool send_udp(int sock, uint8_t *buffer, struct sockaddr_in target, uint32_t len, in_addr src_ip, bool use_src_ip) {
24+
bool send_udp(int sock, uint8_t *buffer, struct sockaddr_in target, uint32_t len, in_addr src_ip, bool use_src_ip, bool pad) {
2425
/* Pad additional bytes if length is lesser than 300
2526
* to make DHCP packet length to minimum of 300 bytes */
26-
if (len < BOOTP_MIN_LEN) {
27+
if (pad && len < BOOTP_MIN_LEN) {
2728
auto pad_len = BOOTP_MIN_LEN - len;
2829
memset(buffer+len, 0, pad_len);
2930
len = BOOTP_MIN_LEN;

dhcp4relay/src/dhcp4_sender.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
* @param len length of message
1717
* @param src_ip source IP address as string (optional)
1818
* @param use_src_ip if true, use src_ip as source address
19+
* @param pad if true, do padding
1920
*
2021
* @return boolean True if packet successfully sent
2122
*/
22-
bool send_udp(int sock, uint8_t *buffer, struct sockaddr_in target, uint32_t len, in_addr src_ip, bool use_src_ip);
23+
bool send_udp(int sock, uint8_t *buffer, struct sockaddr_in target, uint32_t len, in_addr src_ip, bool use_src_ip, bool pad);

dhcp4relay/src/dhcp4relay.cpp

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ void from_client(pcpp::DhcpLayer *dhcp_pkt, relay_config &config) {
577577
}
578578

579579
for (auto server : config.servers_sock) {
580-
if (send_udp(sock, (uint8_t *)dhcp_pkt->getDhcpHeader(), server, dhcp_pkt->getHeaderLen(), src_ip, use_intf_ip_as_src_ip)) {
580+
if (send_udp(sock, (uint8_t *)dhcp_pkt->getDhcpHeader(), server, dhcp_pkt->getHeaderLen(), src_ip, use_intf_ip_as_src_ip, true)) {
581581
syslog(LOG_INFO, "[DHCPV4_RELAY] DHCP packet is sent to configured server: %s, interface: %s",
582582
config.servers[index].c_str(), config.vlan.c_str());
583583
dhcp_cntr_table.increment_counter(config.vlan, "TX", (int)dhcp_pkt->getMessageType());
@@ -635,6 +635,7 @@ void to_client(pcpp::DhcpLayer *dhcp_pkt, std::unordered_map<std::string, relay_
635635
struct sockaddr_in target_addr = {0};
636636
uint32_t giaddr = dhcp_pkt->getDhcpHeader()->gatewayIpAddress;
637637
uint32_t broadcast_addr = DHCP_BROADCAST_IPADDR;
638+
bool pad = false;
638639
std::unordered_map<std::string, relay_config>::iterator config_itr = vlans->end();
639640

640641
if (getifaddrs(&ifa) == -1) {
@@ -731,8 +732,13 @@ void to_client(pcpp::DhcpLayer *dhcp_pkt, std::unordered_map<std::string, relay_
731732
in_addr ip_zero = {0};
732733
/* TODO: Send unicast message to client if BOOTP flag from client is set to unicast */
733734

734-
dhcp_pkt->removeOption(pcpp::DHCPOPT_DHCP_AGENT_OPTIONS);
735-
if (send_udp(config.client_sock, (uint8_t *)dhcp_pkt->getDhcpHeader(), target_addr, dhcp_pkt->getHeaderLen(), ip_zero, false)) {
735+
/* Perform padding only when DHCP relay (Option 82) information has been stripped from the packet */
736+
if(dhcp_pkt->removeOption(pcpp::DHCPOPT_DHCP_AGENT_OPTIONS)) {
737+
syslog(LOG_NOTICE, "Packet is stripped");
738+
pad = true;
739+
}
740+
741+
if (send_udp(config.client_sock, (uint8_t *)dhcp_pkt->getDhcpHeader(), target_addr, dhcp_pkt->getHeaderLen(), ip_zero, false, pad)) {
736742
syslog(LOG_INFO, "[DHCPV4_RELAY] dhcp relay message is broadcast to client %s from server %s",
737743
config.vlan.c_str(), src_ip.c_str());
738744
dhcp_cntr_table.increment_counter(config.vlan, "TX", (int)dhcp_pkt->getMessageType());
@@ -896,8 +902,8 @@ void pkt_in_callback(evutil_socket_t fd, short event, void *arg) {
896902
std::string intf(interface_name);
897903
auto itr = std::find(interface_list.begin(), interface_list.end(), intf);
898904
/* To avoid duplicate packets, we are only processing packets from
899-
interface in PORT_TABLE and packets from VXLAN interface */
900-
if ((itr == interface_list.end()) && (intf.rfind("VXLAN", 0) != 0)) {
905+
interface in PORT_TABLE and packets from VXLAN interface and docker0 interfaces */
906+
if ((itr == interface_list.end()) && (intf.rfind("VXLAN", 0) != 0) && (intf.rfind("docker0", 0) != 0)) {
901907
continue;
902908
}
903909

dhcp4relay/src/dhcp4relay_mgr.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,12 +59,12 @@ void DHCPMgr::handle_swss_notification() {
5959
swss::SubscriberStateTable config_db_portchannel_table(config_db_ptr.get(), "PORTCHANNEL_INTERFACE");
6060
swss::SubscriberStateTable config_db_device_metadata_table(config_db_ptr.get(), "DEVICE_METADATA");
6161
swss::SubscriberStateTable config_db_vlan_member_table(config_db_ptr.get(), "VLAN_MEMBER");
62-
swss::SubscriberStateTable config_db_vlan_interface_table(config_db_ptr.get(), "VLAN_INTERFACE");
6362
swss::SubscriberStateTable config_db_feature_table(config_db_ptr.get(), "FEATURE");
6463
swss::SubscriberStateTable config_db_vlan_table(config_db_ptr.get(), "VLAN");
6564
config_db_dhcp_server_ipv4_ptr = std::make_shared<swss::SubscriberStateTable>(config_db_ptr.get(), "DHCP_SERVER_IPV4");
6665
state_db_dhcp_server_ipv4_ip_ptr = std::make_shared<swss::SubscriberStateTable>(state_db_ptr.get(), "DHCP_SERVER_IPV4_SERVER_IP");
6766
swss::SubscriberStateTable config_db_port_table(config_db_ptr.get(), "PORT");
67+
swss::SubscriberStateTable state_db_interface_table(state_db_ptr.get(), "INTERFACE_TABLE");
6868

6969
std::deque<swss::KeyOpFieldsValuesTuple> entries;
7070
swss::Select swss_select;
@@ -74,12 +74,12 @@ void DHCPMgr::handle_swss_notification() {
7474
swss_select.addSelectable(&config_db_portchannel_table);
7575
swss_select.addSelectable(&config_db_device_metadata_table);
7676
swss_select.addSelectable(&config_db_vlan_member_table);
77-
swss_select.addSelectable(&config_db_vlan_interface_table);
7877
swss_select.addSelectable(&config_db_feature_table);
7978
swss_select.addSelectable(&config_db_vlan_table);
8079
swss_select.addSelectable(config_db_dhcp_server_ipv4_ptr.get());
8180
swss_select.addSelectable(state_db_dhcp_server_ipv4_ip_ptr.get());
8281
swss_select.addSelectable(&config_db_port_table);
82+
swss_select.addSelectable(&state_db_interface_table);
8383

8484
while (!stop_thread) {
8585
swss::Selectable *selectable;
@@ -125,8 +125,8 @@ void DHCPMgr::handle_swss_notification() {
125125
} else if (selectable == static_cast<swss::Selectable *>(&config_db_vlan_member_table)) {
126126
config_db_vlan_member_table.pops(entries);
127127
process_vlan_member_notification(entries);
128-
} else if (selectable == static_cast<swss::Selectable *>(&config_db_vlan_interface_table)) {
129-
config_db_vlan_interface_table.pops(entries);
128+
} else if (selectable == static_cast<swss::Selectable *>(&state_db_interface_table)) {
129+
state_db_interface_table.pops(entries);
130130
process_vlan_interface_notification(entries);
131131
} else if (selectable == static_cast<swss::Selectable *>(&config_db_feature_table)) {
132132
config_db_feature_table.pops(entries);
@@ -599,7 +599,11 @@ void DHCPMgr::process_vlan_member_notification(std::deque<swss::KeyOpFieldsValue
599599

600600
void DHCPMgr::process_vlan_interface_notification(std::deque<swss::KeyOpFieldsValuesTuple> &entries) {
601601
for (auto &entry : entries) {
602-
std::string key = kfvKey(entry);
602+
std::string key = kfvKey(entry);
603+
// Only process VLAN interfaces (keys starting with "Vlan" and Vlan with IP suffix)
604+
if (key.rfind("Vlan", 0) != 0) {
605+
continue;
606+
}
603607

604608
std::string vlan;
605609
std::string vrf;
@@ -608,7 +612,7 @@ void DHCPMgr::process_vlan_interface_notification(std::deque<swss::KeyOpFieldsVa
608612
vlan = key;
609613
vrf = "default";
610614
for (auto &fv : kfvFieldsValues(entry)) {
611-
if (fvField(fv) == "vrf_name") {
615+
if (fvField(fv) == "vrf") {
612616
vrf = fvValue(fv);
613617
break;
614618
}

dhcp4relay/test/mock_relay.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ using namespace swss;
2424
MOCK_GLOBAL_FUNC1(getifaddrs, int(struct ifaddrs **));
2525
MOCK_GLOBAL_FUNC1(freeifaddrs, void(struct ifaddrs *));
2626
MOCK_GLOBAL_FUNC3(write, ssize_t(int, const void*, size_t));
27-
MOCK_GLOBAL_FUNC6(send_udp, bool(int, uint8_t *, struct sockaddr_in, uint32_t, in_addr, bool));
27+
MOCK_GLOBAL_FUNC7(send_udp, bool(int, uint8_t *, struct sockaddr_in, uint32_t, in_addr, bool, bool));
2828

2929
void encode_relay_option(pcpp::DhcpLayer *dhcp_pkt, relay_config *config);
3030
void to_client(pcpp::DhcpLayer* dhcp_pkt, std::unordered_map<std::string, relay_config > *vlans,
@@ -851,8 +851,8 @@ TEST(DHCPRelayTest, to_client) {
851851
struct ifaddrs *mock_ifaddrs = CreateMockIfaddrs("192.168.1.1", "255.255.255.0", "Vlan100", "192.168.1.2", "Ethernet4");
852852
EXPECT_GLOBAL_CALL(getifaddrs, getifaddrs(_)).WillOnce(DoAll(testing::SetArgPointee<0>(mock_ifaddrs), Return(0)));
853853
EXPECT_GLOBAL_CALL(freeifaddrs, freeifaddrs(_)).Times(1);
854-
EXPECT_GLOBAL_CALL(send_udp, send_udp(_, _, _, _, _, _)).WillOnce([]
855-
(int sock, uint8_t* hdr, struct sockaddr_in target, uint32_t len, in_addr src_ip, bool use_src_ip) {
854+
EXPECT_GLOBAL_CALL(send_udp, send_udp(_, _, _, _, _, _, _)).WillOnce([]
855+
(int sock, uint8_t* hdr, struct sockaddr_in target, uint32_t len, in_addr src_ip, bool use_src_ip, bool pad) {
856856
pcpp::dhcp_header* dhcp_hdr = (pcpp::dhcp_header*)hdr;
857857
EXPECT_EQ((dhcp_hdr->opCode), 1);
858858
EXPECT_EQ((dhcp_hdr->hops), 1);
@@ -891,8 +891,8 @@ TEST(DHCPRelayTest, from_client) {
891891
m_config.host_mac_addr = "12:32:54:24:95:36";
892892
encode_relay_option(&dhcpLayer, &config);
893893

894-
EXPECT_GLOBAL_CALL(send_udp, send_udp(_, _, _, _, _, _)).WillOnce([]
895-
(int sock, uint8_t* hdr, struct sockaddr_in target, uint32_t len, in_addr src_ip, bool use_src_ip) {
894+
EXPECT_GLOBAL_CALL(send_udp, send_udp(_, _, _, _, _, _, _)).WillOnce([]
895+
(int sock, uint8_t* hdr, struct sockaddr_in target, uint32_t len, in_addr src_ip, bool use_src_ip, bool pad) {
896896
pcpp::dhcp_header* dhcp_hdr = (pcpp::dhcp_header*)hdr;
897897
EXPECT_EQ((dhcp_hdr->opCode), 0);
898898
EXPECT_EQ((dhcp_hdr->hops), 1);

0 commit comments

Comments
 (0)