From f9e1205086d4a0ecd2dc8759b8342597c0cf4ac4 Mon Sep 17 00:00:00 2001 From: Naveen N Date: Sat, 3 Mar 2018 13:21:16 +0530 Subject: [PATCH] * Handle DHCP ip update on vhost interface After changes to treat vhost as a VMI, DHCP IP update of vhost was not handled. If IP was not set in configuration file, if address updates comes primary ip address and subnet prefix length Test case for same. Change-Id: Ib4a6153536f25ae9ff1b8d681fd9270881fd1ff5 Closes-bug: #1751124 --- src/vnsw/agent/init/agent_param.h | 3 + src/vnsw/agent/init/contrail_init_common.cc | 8 +- src/vnsw/agent/oper/vm_interface_request.cc | 6 +- src/vnsw/agent/test/vnswa_no_ip_cfg.ini | 145 ++++++++++++++++++ .../agent/vrouter/ksync/test/test_vnswif.cc | 17 +- .../vrouter/ksync/vnswif_listener_base.cc | 2 +- 6 files changed, 165 insertions(+), 16 deletions(-) create mode 100644 src/vnsw/agent/test/vnswa_no_ip_cfg.ini diff --git a/src/vnsw/agent/init/agent_param.h b/src/vnsw/agent/init/agent_param.h index 589e70aaa1a..f2ba7f61cbe 100644 --- a/src/vnsw/agent/init/agent_param.h +++ b/src/vnsw/agent/init/agent_param.h @@ -179,6 +179,9 @@ class AgentParam { const std::string &vhost_name() const { return vhost_.name_; } const Ip4Address &vhost_addr() const { return vhost_.addr_; } + void set_vhost_addr(const Ip4Address &ip) { + vhost_.addr_ = ip; + } const Ip4Address &vhost_prefix() const { return vhost_.prefix_; } const int vhost_plen() const { return vhost_.plen_; } const Ip4Address &vhost_gw() const { return vhost_.gw_; } diff --git a/src/vnsw/agent/init/contrail_init_common.cc b/src/vnsw/agent/init/contrail_init_common.cc index a41d3af6746..f2a02821c79 100644 --- a/src/vnsw/agent/init/contrail_init_common.cc +++ b/src/vnsw/agent/init/contrail_init_common.cc @@ -196,6 +196,10 @@ void ContrailInitCommon::CreateInterfaces() { PhysicalInterfaceKey physical_key(agent()->fabric_interface_name()); assert(table->FindActiveEntry(&physical_key)); + agent()->set_router_id(agent_param()->vhost_addr()); + agent()->set_vhost_prefix_len(agent_param()->vhost_plen()); + agent()->set_vhost_default_gateway(agent_param()->vhost_gw()); + //Add the interface table->CreateVhost(); //Trigger explicit change to sync the configuration @@ -240,10 +244,6 @@ void ContrailInitCommon::CreateInterfaces() { vmware_intf->mac(), ""); } - agent()->set_router_id(agent_param()->vhost_addr()); - agent()->set_vhost_prefix_len(agent_param()->vhost_plen()); - agent()->set_vhost_default_gateway(agent_param()->vhost_gw()); - if (agent()->pkt()) { agent()->pkt()->CreateInterfaces(); } diff --git a/src/vnsw/agent/oper/vm_interface_request.cc b/src/vnsw/agent/oper/vm_interface_request.cc index abda030c766..c5121f641df 100644 --- a/src/vnsw/agent/oper/vm_interface_request.cc +++ b/src/vnsw/agent/oper/vm_interface_request.cc @@ -180,7 +180,7 @@ void VmInterfaceConfigData::CopyVhostData(const Agent *agent) { vmi_type_ = VmInterface::VHOST; vrf_name_ = agent->fabric_policy_vrf_name(); - if (agent->params()->vhost_addr() != Ip4Address(0)) { + if (agent->router_id() != Ip4Address(0)) { addr_ = agent->router_id(); instance_ipv4_list_.list_.insert( VmInterface::InstanceIp(agent->router_id(), 32, false, true, @@ -201,8 +201,8 @@ void VmInterfaceConfigData::CopyVhostData(const Agent *agent) { if (agent->params()->subnet_hosts_resolvable() == true) { //Add resolve route - subnet_ = agent->params()->vhost_addr(); - subnet_plen_ = agent->params()->vhost_plen(); + subnet_ = agent->router_id(); + subnet_plen_ = agent->vhost_prefix_len(); } physical_interface_ = agent->fabric_interface_name(); diff --git a/src/vnsw/agent/test/vnswa_no_ip_cfg.ini b/src/vnsw/agent/test/vnswa_no_ip_cfg.ini new file mode 100644 index 00000000000..7916839c76e --- /dev/null +++ b/src/vnsw/agent/test/vnswa_no_ip_cfg.ini @@ -0,0 +1,145 @@ +# +# Copyright (c) 2014 Juniper Networks, Inc. All rights reserved. +# +# Vnswad configuration options +# + +[CONTROL-NODE] +# IP address to be used to connect to control-node. If IP is not configured +# for server1, value provided by discovery service will be used. +servers=127.0.0.1:5269 + +[DEFAULT] +# IP address and port to be used to connect to collector. If these are not +# configured, value provided by discovery service will be used. Multiple +# IP:port strings separated by space can be provided +collectors=127.0.0.1:8086 + +# Agent mode : can be vrouter / tsn / tor +# agent_mode= + +# Aging time for flow-records in seconds +flow_cache_timeout=10 + +# Hostname of compute-node. If this is not configured value from `hostname` +# will be taken +# hostname= + +# Http server port for inspecting vnswad state (useful for debugging) +# http_server_port=8085 + +# Category for logging. Default value is '*' +# log_category= + +# Local log file name +log_file=vrouter.log + +# Log severity levels. Possible values are SYS_EMERG, SYS_ALERT, SYS_CRIT, +# SYS_ERR, SYS_WARN, SYS_NOTICE, SYS_INFO and SYS_DEBUG. Default is SYS_DEBUG +# log_level=SYS_DEBUG + +# Enable/Disable local file logging. Possible values are 0 (disable) and 1 (enable) +# log_local=0 + +# Encapsulation type for tunnel. Possible values are MPLSoGRE, MPLSoUDP, VXLAN +# tunnel_type= + +# DHCP relay mode (true or false) to determine if a DHCP request in fabric +# interface with an unconfigured IP should be relayed or not +# dhcp_relay_mode= + +#Mode in which vrouter is running, possible values include dpdk, nic or empty +#platform + +# Agent base directory +agent_base_directory=. + +[DNS] +# IP address and port to be used to connect to dns-node. Maximum of 2 IP +# addresses (separated by a space) can be provided. If no IP is configured then +# the value provided by discovery service will be used. +servers=127.0.0.1:53 + +[HYPERVISOR] +# Hypervisor type. Possible values are kvm, xen and vmware +# type=kvm + +# Link-local IP address and prefix in ip/prefix_len format (for xen) +# xen_ll_ip= + +# Link-local interface name when hypervisor type is Xen +# xen_ll_interface= + +# Physical interface name when hypervisor type is vmware +# vmware_physical_interface= + +[FLOWS] +# Maximum flows allowed per VM (given as % of maximum system flows) +max_vm_flows=100 +# Maximum number of link-local flows allowed across all VMs +max_system_linklocal_flows=3 +# Maximum number of link-local flows allowed per VM +max_vm_linklocal_flows=2 + +[METADATA] +# Shared secret for metadata proxy service +metadata_proxy_secret=contrail + +[NETWORKS] +# control-channel IP address used by WEB-UI to connect to vnswad to fetch +# required information +# control_network_ip= + +[VIRTUAL-HOST-INTERFACE] +# name of virtual host interface +name=vhost0 + +# Gateway IP address for virtual host +gateway=10.1.1.254 + +# Physical interface name to which virtual host interface maps to +physical_interface=vnet0 + +[GATEWAY-0] +# Name of the routing_instance for which the gateway is being configured +# routing_instance=default-domain:admin:public:public + +# Gateway interface name +# interface=vgw + +# Virtual network ip blocks for which gateway service is required. +# ip_blocks=1.1.1.1/24 + +[GATEWAY-1] +# Name of the routing_instance for which the gateway is being configured +# routing_instance=default-domain:admin:public1:public1 + +# Gateway interface name +# interface=vgw1 + +# Virtual network ip blocks for which gateway service is required. +# ip_blocks=2.2.1.0/24, 2.2.2.0/24 + +# Routes to be exported in routing_instance +# routes= 10.10.10.1/24, 11.11.11.1/24 + +[RESTART] +# Enable/Disable backup of config and resource files +#backup_enable=true +# +# Directory containing backup of config and resource files +backup_dir=/tmp/backup +# Number of backup files +# backup_file_count=3 +# +# Agent avoids generating backup file if change is detected within time +# configured below (in milli-sec) +# backup_idle_timeout=10000 +# +# Restore config/resource definitions from file +# restore_enable=true +# +# Audit time for config/resource read from file +# restore_audit_timeout=15000 + + diff --git a/src/vnsw/agent/vrouter/ksync/test/test_vnswif.cc b/src/vnsw/agent/vrouter/ksync/test/test_vnswif.cc index 9726cdc8216..c4d7b50029a 100644 --- a/src/vnsw/agent/vrouter/ksync/test/test_vnswif.cc +++ b/src/vnsw/agent/vrouter/ksync/test/test_vnswif.cc @@ -201,9 +201,9 @@ TEST_F(TestVnswIf, vhost_addr_1) { if (entry == NULL) return; - const InetInterface *vhost = - static_cast(agent_->vhost_interface()); - string vhost_ip = vhost->ip_addr().to_string(); + const VmInterface *vhost = + static_cast(agent_->vhost_interface()); + string vhost_ip = "1.1.1.1"; // vnswif module does not know IP address yet EXPECT_EQ(entry->addr_.to_ulong(), 0); @@ -214,7 +214,7 @@ TEST_F(TestVnswIf, vhost_addr_1) { EXPECT_STREQ(entry->addr_.to_string().c_str(), "1.1.1.1"); // Message not sent to kernel since vhost already has IP - EXPECT_EQ(vnswif_->vhost_update_count(), 0); + EXPECT_EQ(vnswif_->vhost_update_count(), 1); InterfaceAddressEvent(true, agent_->vhost_interface_name(), "2.2.2.2"); @@ -222,10 +222,10 @@ TEST_F(TestVnswIf, vhost_addr_1) { EXPECT_STREQ(entry->addr_.to_string().c_str(), "2.2.2.2"); // Message not sent to kernel since vhost already has IP - EXPECT_EQ(vnswif_->vhost_update_count(), 0); + EXPECT_EQ(vnswif_->vhost_update_count(), 1); // Ensure there is no change vhost-ip - EXPECT_STREQ(vhost->ip_addr().to_string().c_str(), vhost_ip.c_str()); + EXPECT_STREQ(vhost->primary_ip_addr().to_string().c_str(), vhost_ip.c_str()); InterfaceAddressEvent(false, agent_->vhost_interface_name(), "1.1.1.1"); @@ -233,10 +233,10 @@ TEST_F(TestVnswIf, vhost_addr_1) { EXPECT_STREQ(entry->addr_.to_string().c_str(), "0.0.0.0"); // Message not sent to kernel since vhost already has IP - EXPECT_EQ(vnswif_->vhost_update_count(), 0); + EXPECT_EQ(vnswif_->vhost_update_count(), 1); // Ensure there is no change vhost-ip - EXPECT_STREQ(vhost->ip_addr().to_string().c_str(), vhost_ip.c_str()); + EXPECT_STREQ(vhost->primary_ip_addr().to_string().c_str(), vhost_ip.c_str()); InterfaceEvent(false, agent_->vhost_interface_name(), 0); ResetSeen(agent_->vhost_interface_name()); @@ -401,6 +401,7 @@ class SetupTask : public Task { int main(int argc, char *argv[]) { GETUSERARGS(); + strcpy(init_file, "controller/src/vnsw/agent/test/vnswa_no_ip_cfg.ini"); client = TestInit(init_file, ksync_init); Agent::GetInstance()->ksync()->VnswInterfaceListenerInit(); Agent::GetInstance()->set_router_id(Ip4Address::from_string("10.1.1.1")); diff --git a/src/vnsw/agent/vrouter/ksync/vnswif_listener_base.cc b/src/vnsw/agent/vrouter/ksync/vnswif_listener_base.cc index 0c3dba17a34..87f1c8f5f31 100644 --- a/src/vnsw/agent/vrouter/ksync/vnswif_listener_base.cc +++ b/src/vnsw/agent/vrouter/ksync/vnswif_listener_base.cc @@ -370,7 +370,7 @@ void VnswInterfaceListenerBase::HandleAddressEvent(const Event *event) { // Check if vhost already has address. We cant handle IP address change yet const VmInterface *vhost = static_cast(agent_->vhost_interface()); - if (vhost->receive_route_list().list_.size() != 0) { + if (vhost->primary_ip_addr() != Ip4Address(0)) { return; }