Skip to content

Commit

Permalink
Merge "Allow usage of configured src ip for health check"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed May 30, 2016
2 parents eefdf6c + ebdc5fa commit 233cda6
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 69 deletions.
1 change: 1 addition & 0 deletions src/vnsw/agent/oper/agent.sandesh
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ struct ItfSandeshData {
52: list<string> fat_flow_list;
53: optional string health_check_active;
54: optional string metadata_ip_active;
55: optional string service_health_check_ip;
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/vnsw/agent/oper/health_check.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ HealthCheckService::~HealthCheckService() {
HealthCheckInstance::HealthCheckInstance(HealthCheckService *service,
MetaDataIpAllocator *allocator,
VmInterface *intf) :
service_(NULL), intf_(intf), ip_(new MetaDataIp(allocator, intf)),
service_(NULL), intf_(intf),
ip_(new MetaDataIp(allocator, intf, MetaDataIp::HEALTH_CHECK)),
task_(NULL), last_update_time_("-"), deleted_(false) {
active_ = false;
ip_->set_active(true);
Expand Down
3 changes: 3 additions & 0 deletions src/vnsw/agent/oper/interface.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,9 @@ void Interface::SetItfSandeshData(ItfSandeshData &data) const {
data.set_vrf_assign_acl_uuid(vrf_assign_acl);
}

data.set_service_health_check_ip(
vintf->service_health_check_ip().to_string());

break;
}
case Interface::INET: {
Expand Down
30 changes: 22 additions & 8 deletions src/vnsw/agent/oper/metadata_ip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@

const IpAddress MetaDataIp::kDefaultIp;

MetaDataIp::MetaDataIp(MetaDataIpAllocator *allocator, VmInterface *intf) :
MetaDataIp::MetaDataIp(MetaDataIpAllocator *allocator, VmInterface *intf,
MetaDataIpType type) :
allocator_(allocator), index_(-1), intf_(intf),
intf_label_(MplsTable::kInvalidLabel), service_ip_(), destination_ip_(),
active_(false) {
active_(false), type_(type) {
index_ = allocator_->AllocateIndex(this);
intf->InsertMetaDataIpInfo(this);
}
Expand All @@ -23,7 +24,7 @@ MetaDataIp::MetaDataIp(MetaDataIpAllocator *allocator, VmInterface *intf,
uint16_t index) :
allocator_(allocator), index_(index), intf_(intf),
intf_label_(MplsTable::kInvalidLabel), service_ip_(), destination_ip_(),
active_(false) {
active_(false), type_(LINKLOCAL) {
allocator_->AllocateIndex(this, index_);
intf_->InsertMetaDataIpInfo(this);
}
Expand All @@ -41,13 +42,26 @@ Ip4Address MetaDataIp::GetLinkLocalIp() {
}

IpAddress MetaDataIp::service_ip() {
// check if explicit configuration of service ip is present for
// this metadata ip
if (service_ip_ == kDefaultIp) {
IpAddress service_ip = intf_->GetServiceIp(intf_->primary_ip_addr());
if (service_ip == kDefaultIp) {
// if service IP is not available fallback to MetaData IP
return Ip4Address(METADATA_IP_ADDR);
IpAddress service_ip;
if (type_ == HEALTH_CHECK) {
// for metadata IP type Health Check first verify
// if service health check ip is available on interface
service_ip = intf_->service_health_check_ip();
if (service_ip != kDefaultIp) {
return service_ip;
}
}
// check if service ip on the primary ip addr of interface
// is available
service_ip = intf_->GetServiceIp(intf_->primary_ip_addr());
if (service_ip != kDefaultIp) {
return service_ip;
}
return service_ip;
// if service IP is not available fallback to MetaData IP
return Ip4Address(METADATA_IP_ADDR);
}
return service_ip_;
}
Expand Down
13 changes: 11 additions & 2 deletions src/vnsw/agent/oper/metadata_ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,16 @@ class MetaDataIp {
public:
static const IpAddress kDefaultIp;

MetaDataIp(MetaDataIpAllocator *allocator, VmInterface *intf);
MetaDataIp(MetaDataIpAllocator *allocator, VmInterface *intf, uint16_t index);
enum MetaDataIpType {
LINKLOCAL = 0,
HEALTH_CHECK,
INVALID
};

MetaDataIp(MetaDataIpAllocator *allocator, VmInterface *intf,
MetaDataIpType type);
MetaDataIp(MetaDataIpAllocator *allocator, VmInterface *intf,
uint16_t index);
~MetaDataIp();

Ip4Address GetLinkLocalIp();
Expand Down Expand Up @@ -60,6 +68,7 @@ class MetaDataIp {
IpAddress service_ip_;
IpAddress destination_ip_;
bool active_;
MetaDataIpType type_;
DISALLOW_COPY_AND_ASSIGN(MetaDataIp);
};

Expand Down
70 changes: 70 additions & 0 deletions src/vnsw/agent/oper/test/test_intf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3734,6 +3734,76 @@ TEST_F(IntfTest, MultipleIp3) {
client->Reset();
}

//Addition and deletion of service health check IP
TEST_F(IntfTest, ServiceHealthCheckIP) {
struct PortInfo input1[] = {
{"vnet8", 8, "8.1.1.1", "00:00:00:01:01:01", 1, 1}
};

client->Reset();
CreateVmportEnv(input1, 1, 1);
client->WaitForIdle();
EXPECT_TRUE(VmPortActive(input1, 0));
client->Reset();

AddHealthCheckServiceInstanceIp("instance2", input1[0].vm_id, "1.1.1.10");
AddLink("virtual-machine-interface", input1[0].name,
"instance-ip", "instance2");
client->WaitForIdle();

const VmInterface *vm_intf = static_cast<const VmInterface *>(VmPortGet(8));
const MacAddress mac("00:00:00:01:01:01");
Ip4Address ip = Ip4Address::from_string("8.1.1.1");
Ip4Address service_hc_ip = Ip4Address::from_string("1.1.1.10");
Ip4Address zero_ip = Ip4Address::from_string("0.0.0.0");

EXPECT_TRUE(L2RouteFind("vrf1", mac));
EvpnRouteEntry *evpn_rt = EvpnRouteGet("vrf1", mac, zero_ip,
vm_intf->ethernet_tag());
EXPECT_TRUE(evpn_rt != NULL);
EXPECT_TRUE(evpn_rt->GetActiveNextHop()->PolicyEnabled() == true);

//Verify primary route is found
evpn_rt = EvpnRouteGet("vrf1", mac, ip, vm_intf->ethernet_tag());
EXPECT_TRUE(evpn_rt != NULL);
EXPECT_TRUE(evpn_rt->GetActiveNextHop()->PolicyEnabled() == true);
EXPECT_TRUE(RouteFind("vrf1", ip, 32));

//Verify service health check IP route is found
evpn_rt = EvpnRouteGet("vrf1", mac, service_hc_ip, vm_intf->ethernet_tag());
EXPECT_TRUE(evpn_rt != NULL);
EXPECT_TRUE(evpn_rt->GetActiveNextHop()->PolicyEnabled() == true);
EXPECT_TRUE(RouteFind("vrf1", service_hc_ip, 32));
EXPECT_TRUE(vm_intf->instance_ipv4_list().list_.size() == 2);
EXPECT_TRUE(vm_intf->service_health_check_ip().to_v4() == service_hc_ip);

DelLink("virtual-machine-interface", input1[0].name,
"instance-ip", "instance2");
client->WaitForIdle();

//Verify primary route is found
evpn_rt = EvpnRouteGet("vrf1", mac, ip, vm_intf->ethernet_tag());
EXPECT_TRUE(evpn_rt != NULL);
EXPECT_TRUE(evpn_rt->GetActiveNextHop()->PolicyEnabled() == true);
EXPECT_TRUE(RouteFind("vrf1", ip, 32));

//Verify secondary IP route is not found since link is deleted
evpn_rt = EvpnRouteGet("vrf1", mac, service_hc_ip, vm_intf->ethernet_tag());
EXPECT_TRUE(evpn_rt == NULL);
EXPECT_FALSE(RouteFind("vrf1", service_hc_ip, 32));
EXPECT_TRUE(vm_intf->instance_ipv4_list().list_.size() == 1);
EXPECT_TRUE(vm_intf->service_health_check_ip().to_v4() == zero_ip);

DelInstanceIp("instance2");
DeleteVmportEnv(input1, 1, true, 1);
client->WaitForIdle();
EXPECT_FALSE(VmPortFind(8));
VmInterfaceKey key(AgentKey::ADD_DEL_CHANGE, MakeUuid(8), "");
WAIT_FOR(100, 1000, (Agent::GetInstance()->interface_table()->Find(&key, true)
== NULL));
client->Reset();
}

TEST_F(IntfTest, Add_vmi_with_zero_mac_and_update_with_correct_mac) {
struct PortInfo input[] = {
{"vnet10", 10, "1.1.1.1", "00:00:00:00:00:00", 10, 10},
Expand Down

0 comments on commit 233cda6

Please sign in to comment.