From c35dd147919144adb102fe88de22ce4705c487ac Mon Sep 17 00:00:00 2001 From: Hari Date: Mon, 18 Apr 2016 11:26:44 +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 793cfc87dc9..83b74b2add7 100644 --- a/src/vnsw/agent/pkt/pkt_handler.cc +++ b/src/vnsw/agent/pkt/pkt_handler.cc @@ -171,12 +171,12 @@ PktHandler::PktModuleName PktHandler::ParsePacket(const AgentHdr &hdr, // Look for DHCP packets if corresponding service is enabled // Service processing over-rides ACL/Flow and forwarding configuration 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 5c299eceec7..bb97327814c 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) { }