From ac3036d7dd9fe12d03d91d9442bb18d30b8b7203 Mon Sep 17 00:00:00 2001 From: Manish Date: Thu, 14 Apr 2016 10:39:09 +0530 Subject: [PATCH] Non VMI IP was not working in bgp as service. Problem: Bgp as service selects control-node to connect by identying if destination IP is gateway or DNS. To identify gateway/dns it was trying to locate subnet using source sent in packet. Source in this case was non-Vm IP which will fail and hence session will not get established. Solution: Instead of using source IP, use VM interface primary ip address. Change-Id: Iabaf6f1e7323f75ef8da6b64664f520aeb578494 Closes-bug: #1569702 --- src/vnsw/agent/oper/bgp_as_service.cc | 10 +- src/vnsw/agent/pkt/test/SConscript | 2 + src/vnsw/agent/pkt/test/test_bgp_service.cc | 152 ++++++++++++++++++++ 3 files changed, 160 insertions(+), 4 deletions(-) create mode 100644 src/vnsw/agent/pkt/test/test_bgp_service.cc diff --git a/src/vnsw/agent/oper/bgp_as_service.cc b/src/vnsw/agent/oper/bgp_as_service.cc index d54a0226684..44f02c14a9c 100644 --- a/src/vnsw/agent/oper/bgp_as_service.cc +++ b/src/vnsw/agent/oper/bgp_as_service.cc @@ -247,8 +247,9 @@ bool BgpAsAService::IsBgpService(const VmInterface *vm_intf, const VnEntry *vn = vm_intf->vn(); if (vn == NULL) return false; - if ((vn->GetGatewayFromIpam(source_ip) == dest_ip) || - (vn->GetDnsFromIpam(source_ip) == dest_ip)) { + const IpAddress &vm_ip = vm_intf->primary_ip_addr(); + if ((vn->GetGatewayFromIpam(vm_ip) == dest_ip) || + (vn->GetDnsFromIpam(vm_ip) == dest_ip)) { ret = true; } return ret; @@ -262,8 +263,9 @@ bool BgpAsAService::GetBgpRouterServiceDestination(const VmInterface *vm_intf, const VnEntry *vn = vm_intf->vn(); if (vn == NULL) return false; - const IpAddress &gw = vn->GetGatewayFromIpam(source_ip); - const IpAddress &dns = vn->GetDnsFromIpam(source_ip); + const IpAddress &vm_ip = vm_intf->primary_ip_addr(); + const IpAddress &gw = vn->GetGatewayFromIpam(vm_ip); + const IpAddress &dns = vn->GetDnsFromIpam(vm_ip); boost::system::error_code ec; BgpAsAServiceEntryMapConstIterator map_it = diff --git a/src/vnsw/agent/pkt/test/SConscript b/src/vnsw/agent/pkt/test/SConscript index 2ac982dcd20..893ca5ebe73 100644 --- a/src/vnsw/agent/pkt/test/SConscript +++ b/src/vnsw/agent/pkt/test/SConscript @@ -51,6 +51,8 @@ test_fip_src_ecmp = AgentEnv.MakeTestCmd(env, 'test_fip_src_ecmp', pkt_test_suite) test_ecmp_local = AgentEnv.MakeTestCmd(env, 'test_ecmp_local', pkt_test_suite) +test_bgp_service = AgentEnv.MakeTestCmd(env, 'test_bgp_service', + pkt_test_suite) test_xml_packet_ut = AgentEnv.MakeTestCmdSrc(env, 'test_xml_packet_ut', [ diff --git a/src/vnsw/agent/pkt/test/test_bgp_service.cc b/src/vnsw/agent/pkt/test/test_bgp_service.cc new file mode 100644 index 00000000000..a35a579e058 --- /dev/null +++ b/src/vnsw/agent/pkt/test/test_bgp_service.cc @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. + */ + +#include "base/os.h" +#include "test/test_cmn_util.h" +#include "test_pkt_util.h" +#include "pkt/flow_proto.h" +#include "pkt/flow_mgmt.h" +#include +#include + +VmInterface *vnet[16]; +InetInterface *vhost; +char vhost_addr[32]; +char vnet_addr[16][32]; + +PhysicalInterface *eth; +int hash_id; + +void RouterIdDepInit(Agent *agent) { +} + +struct PortInfo input[] = { + {"vnet1", 1, "1.1.1.10", "00:00:01:01:01:01", 1, 1}, +}; + +IpamInfo ipam_info[] = { + {"1.1.1.0", 24, "1.1.1.1", true}, +}; + +class BgpServiceTest : public ::testing::Test { +public: + void AddAap(std::string intf_name, int intf_id, Ip4Address ip, + const std::string &mac) { + std::ostringstream buf; + buf << ""; + buf << ""; + buf << ""; + buf << "" << ip.to_string() <<""; + buf << ""<< 32 << ""; + buf << ""; + buf << "" << mac << ""; + buf << "" << "act-stby" << ""; + buf << ""; + buf << ""; + char cbuf[10000]; + strcpy(cbuf, buf.str().c_str()); + AddNode("virtual-machine-interface", intf_name.c_str(), + intf_id, cbuf); + client->WaitForIdle(); + } + + virtual void SetUp() { + agent_ = Agent::GetInstance(); + flow_proto_ = agent_->pkt()->get_flow_proto(); + client->WaitForIdle(); + EXPECT_EQ(0U, flow_proto_->FlowCount()); + CreateVmportEnv(input, 1); + AddIPAM("vn1", ipam_info, 1); + client->WaitForIdle(); + SendBgpServiceConfig("1.1.1.10", 50000, 1, "vnet1", + "vrf1", "bgpaas-client", + false); + client->WaitForIdle(); + } + + virtual void TearDown() { + client->EnqueueFlowFlush(); + client->WaitForIdle(); + EXPECT_EQ(0U, flow_proto_->FlowCount()); + client->WaitForIdle(); + SendBgpServiceConfig("1.1.1.10", 50000, 1, "vnet1", + "vrf1", "bgpaas-server", + true); + DelIPAM("vn1"); + DeleteVmportEnv(input, 1, true); + client->WaitForIdle(); + } + + Agent *agent_; + FlowProto *flow_proto_; + BgpPeer *peer; +}; + +TEST_F(BgpServiceTest, Test_1) { + peer = CreateBgpPeer("127.0.0.1", "remote"); + client->WaitForIdle(); + + TxTcpPacket(VmInterfaceGet(1)->id(), "1.1.1.10", "1.1.1.1", 10000, 179, + false); + client->WaitForIdle(); + FlowEntry *fe = FlowGet(VmInterfaceGet(1)->flow_key_nh()->id(), + "1.1.1.10", "1.1.1.1", 6, 10000, 179); + EXPECT_TRUE(fe != NULL); + EXPECT_TRUE(fe->reverse_flow_entry() != NULL); + EXPECT_TRUE(fe->is_flags_set(FlowEntry::BgpRouterService)); + + DeleteBgpPeer(peer); + client->WaitForIdle(); +} + +TEST_F(BgpServiceTest, Test_2) { + peer = CreateBgpPeer("127.0.0.1", "remote"); + client->WaitForIdle(); + + TxTcpPacket(VmInterfaceGet(1)->id(), "1.1.1.10", "1.1.1.1", 10000, 179, + false); + client->WaitForIdle(); + FlowEntry *fe = FlowGet(VmInterfaceGet(1)->flow_key_nh()->id(), + "1.1.1.10", "1.1.1.1", 6, 10000, 179); + EXPECT_TRUE(fe != NULL); + EXPECT_TRUE(fe->reverse_flow_entry() != NULL); + EXPECT_TRUE(fe->is_flags_set(FlowEntry::BgpRouterService)); + + //Explicitly call deleteall on bgp service tree. + //agent_->pkt()->flow_mgmt_manager()->ControllerNotify(0); + //agent_->pkt()->flow_mgmt_manager()->ControllerNotify(1); + client->WaitForIdle(); + + DeleteBgpPeer(peer); + client->WaitForIdle(); +} + +TEST_F(BgpServiceTest, Test_3) { + AddAap("vnet1", 1, Ip4Address::from_string("10.10.10.10"), "00:00:01:01:01:01"); + peer = CreateBgpPeer("127.0.0.1", "remote"); + client->WaitForIdle(); + + TxTcpPacket(VmInterfaceGet(1)->id(), "10.10.10.10", "1.1.1.1", 10000, 179, + false); + client->WaitForIdle(); + FlowEntry *fe = FlowGet(VmInterfaceGet(1)->flow_key_nh()->id(), + "10.10.10.10", "1.1.1.1", 6, 10000, 179); + EXPECT_TRUE(fe != NULL); + EXPECT_TRUE(fe->reverse_flow_entry() != NULL); + EXPECT_TRUE(fe->is_flags_set(FlowEntry::BgpRouterService)); + + DeleteBgpPeer(peer); + client->WaitForIdle(); +} + +int main(int argc, char *argv[]) { + int ret = 0; + GETUSERARGS(); + client = TestInit(init_file, ksync_init, true, true, true, 100*1000); + ret = RUN_ALL_TESTS(); + usleep(100000); + TestShutdown(); + delete client; + return ret; +}