Skip to content

Commit

Permalink
* Handle DHCP ip update on vhost interface
Browse files Browse the repository at this point in the history
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
  • Loading branch information
naveen-n committed Mar 3, 2018
1 parent 28042d8 commit f9e1205
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 16 deletions.
3 changes: 3 additions & 0 deletions src/vnsw/agent/init/agent_param.h
Expand Up @@ -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_; }
Expand Down
8 changes: 4 additions & 4 deletions src/vnsw/agent/init/contrail_init_common.cc
Expand Up @@ -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
Expand Down Expand Up @@ -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();
}
Expand Down
6 changes: 3 additions & 3 deletions src/vnsw/agent/oper/vm_interface_request.cc
Expand Up @@ -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,
Expand All @@ -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();
Expand Down
145 changes: 145 additions & 0 deletions 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


17 changes: 9 additions & 8 deletions src/vnsw/agent/vrouter/ksync/test/test_vnswif.cc
Expand Up @@ -201,9 +201,9 @@ TEST_F(TestVnswIf, vhost_addr_1) {
if (entry == NULL)
return;

const InetInterface *vhost =
static_cast<const InetInterface *>(agent_->vhost_interface());
string vhost_ip = vhost->ip_addr().to_string();
const VmInterface *vhost =
static_cast<const VmInterface *>(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);
Expand All @@ -214,29 +214,29 @@ 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");

// Validate address in local entry
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");

// Validate address in local entry
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());
Expand Down Expand Up @@ -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"));
Expand Down
2 changes: 1 addition & 1 deletion src/vnsw/agent/vrouter/ksync/vnswif_listener_base.cc
Expand Up @@ -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<const VmInterface *>(agent_->vhost_interface());
if (vhost->receive_route_list().list_.size() != 0) {
if (vhost->primary_ip_addr() != Ip4Address(0)) {
return;
}

Expand Down

0 comments on commit f9e1205

Please sign in to comment.