From ac1180752c0cc47491b7999a1f81a783a80af30a Mon Sep 17 00:00:00 2001 From: Hari Date: Mon, 18 Apr 2016 11:28:52 +0530 Subject: [PATCH] Check for packet being IPv6 while sending it to DHCPv6 module. When an IPv4 packet has UDP port as DHCPv6 client or server ports, dont consider it as DHCPv6 packet. Add test case for the same. Change-Id: I2010b6a04caf4c23116d8ab262d84f246efc0ba0 closes-bug: #1570705 --- src/vnsw/agent/pkt/pkt_handler.cc | 8 +-- src/vnsw/agent/services/test/dhcp_test.cc | 62 +++++++++++++++++++++-- 2 files changed, 61 insertions(+), 9 deletions(-) diff --git a/src/vnsw/agent/pkt/pkt_handler.cc b/src/vnsw/agent/pkt/pkt_handler.cc index 678d581276e..e96f2e39d48 100644 --- a/src/vnsw/agent/pkt/pkt_handler.cc +++ b/src/vnsw/agent/pkt/pkt_handler.cc @@ -144,12 +144,12 @@ PktHandler::PktModuleName PktHandler::ParsePacket(const AgentHdr &hdr, // Look for DHCP and DNS packets if corresponding service is enabled // Service processing over-rides ACL/Flow if (intf->dhcp_enabled() && (pkt_type == PktType::UDP)) { - if (pkt_info->dport == DHCP_SERVER_PORT || - pkt_info->sport == DHCP_CLIENT_PORT) { + if (pkt_info->ip && (pkt_info->dport == DHCP_SERVER_PORT || + pkt_info->sport == DHCP_CLIENT_PORT)) { return DHCP; } - if (pkt_info->dport == DHCPV6_SERVER_PORT || - pkt_info->sport == DHCPV6_CLIENT_PORT) { + if (pkt_info->ip6 && (pkt_info->dport == DHCPV6_SERVER_PORT || + pkt_info->sport == DHCPV6_CLIENT_PORT)) { return DHCPV6; } } diff --git a/src/vnsw/agent/services/test/dhcp_test.cc b/src/vnsw/agent/services/test/dhcp_test.cc index 09ec6c91801..297262ee5c2 100644 --- a/src/vnsw/agent/services/test/dhcp_test.cc +++ b/src/vnsw/agent/services/test/dhcp_test.cc @@ -226,7 +226,8 @@ class DhcpTest : public ::testing::Test { void SendDhcp(short ifindex, uint16_t flags, uint8_t msg_type, uint8_t *options, int num_options, bool error = false, bool response = false, uint32_t yiaddr = 0, - uint32_t vmifindex = 0) { + uint32_t vmifindex = 0, + uint16_t server_port = DHCP_SERVER_PORT) { int len = 512; uint8_t *buf = new uint8_t[len]; memset(buf, 0, len); @@ -265,11 +266,11 @@ class DhcpTest : public ::testing::Test { udphdr *udp = (udphdr *) (ip + 1); if (response) { - udp->uh_sport = htons(DHCP_SERVER_PORT); - udp->uh_dport = htons(DHCP_SERVER_PORT); + udp->uh_sport = htons(server_port); + udp->uh_dport = htons(server_port + 1); } else { - udp->uh_sport = htons(DHCP_CLIENT_PORT); - udp->uh_dport = htons(DHCP_SERVER_PORT); + udp->uh_sport = htons(server_port + 1); + udp->uh_dport = htons(server_port); } udp->uh_sum = 0; @@ -2435,6 +2436,57 @@ TEST_F(DhcpTest, GatewayDhcpLeaseTimeout) { remove("./dhcp.00000000-0000-0000-0000-000000000001.leases"); } +// Send DHCP request to v6 port +TEST_F(DhcpTest, DhcpReqv6PortTest) { + struct PortInfo input[] = { + {"vnet1", 1, "1.1.1.1", "00:00:00:01:01:01", 1, 1}, + }; + uint8_t options[] = { + DHCP_OPTION_MSG_TYPE, + DHCP_OPTION_HOST_NAME, + DHCP_OPTION_DOMAIN_NAME, + DHCP_OPTION_END + }; + DhcpProto::DhcpStats stats; + + ClearPktTrace(); + IpamInfo ipam_info[] = { + {"1.1.1.0", 24, "1.1.1.200", true}, + }; + char vdns_attr[] = "\n test.contrail.juniper.net\n true\n fixed\n 120\n \n"; + char ipam_attr[] = "\n virtual-dns-server\n vdns1\n \n"; + + CreateVmportEnv(input, 1, 0); + client->WaitForIdle(); + client->Reset(); + AddVDNS("vdns1", vdns_attr); + client->WaitForIdle(); + AddIPAM("vn1", ipam_info, 1, ipam_attr, "vdns1"); + client->WaitForIdle(); + + SendDhcp(GetItfId(0), 0x8000, DHCP_DISCOVER, options, 4, + false, false, 0, 0, DHCPV6_SERVER_PORT); + SendDhcp(GetItfId(0), 0x8000, DHCP_REQUEST, options, 4, + false, false, 0, 0, DHCPV6_SERVER_PORT); + client->WaitForIdle(); + EXPECT_EQ(0U, stats.discover); + EXPECT_EQ(0U, stats.request); + EXPECT_EQ(0U, stats.offers); + EXPECT_EQ(0U, stats.acks); + + client->Reset(); + DelIPAM("vn1", "vdns1"); + client->WaitForIdle(); + DelVDNS("vdns1"); + client->WaitForIdle(); + + client->Reset(); + DeleteVmportEnv(input, 1, 1, 0); + client->WaitForIdle(); + + Agent::GetInstance()->GetDhcpProto()->ClearStats(); +} + void RouterIdDepInit(Agent *agent) { }