Skip to content

Commit

Permalink
Flat subnet support in vrouter agent.
Browse files Browse the repository at this point in the history
Take the subnet data from IPAM in case that method is chosen.
Otherwise, pick the same from virtual-network-network-ipam link attribute.

Change-Id: Ic440e29a8a04228e116282ab545d147c05328ad9
closes-bug: #1597455
  • Loading branch information
haripk committed Jun 30, 2016
1 parent 044581b commit d92c4fe
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 27 deletions.
69 changes: 43 additions & 26 deletions src/vnsw/agent/oper/vn.cc
Expand Up @@ -42,7 +42,7 @@ using boost::assign::list_of;
VnTable *VnTable::vn_table_;

VnIpam::VnIpam(const std::string& ip, uint32_t len, const std::string& gw,
const std::string& dns, bool dhcp, std::string &name,
const std::string& dns, bool dhcp, const std::string &name,
const std::vector<autogen::DhcpOptionType> &dhcp_options,
const std::vector<autogen::RouteType> &host_routes)
: plen(len), installed(false), dhcp_enable(dhcp), ipam_name(name) {
Expand Down Expand Up @@ -707,6 +707,32 @@ void VnTable::CfgForwardingFlags(IFMapNode *node, bool *l2, bool *l3,
*l3 = GetLayer3ForwardingConfig(derived_forwarding_mode);
}

void
VnTable::BuildVnIpamData(const std::vector<autogen::IpamSubnetType> &subnets,
const std::string &ipam_name,
std::vector<VnIpam> *vn_ipam) {
for (unsigned int i = 0; i < subnets.size(); ++i) {
// if the DNS server address is not specified, set this
// to be the same as the GW address
std::string dns_server_address = subnets[i].dns_server_address;
boost::system::error_code ec;
IpAddress dns_server =
IpAddress::from_string(dns_server_address, ec);
if (ec.value() || dns_server.is_unspecified()) {
dns_server_address = subnets[i].default_gateway;
}

vn_ipam->push_back
(VnIpam(subnets[i].subnet.ip_prefix,
subnets[i].subnet.ip_prefix_len,
subnets[i].default_gateway,
dns_server_address,
subnets[i].enable_dhcp, ipam_name,
subnets[i].dhcp_option_list.dhcp_option,
subnets[i].host_routes.route));
}
}

VnData *VnTable::BuildData(IFMapNode *node) {
VirtualNetwork *cfg = static_cast <VirtualNetwork *> (node->GetObject());
assert(cfg);
Expand Down Expand Up @@ -761,34 +787,25 @@ VnData *VnTable::BuildData(IFMapNode *node) {
if (IFMapNode *ipam_node = FindTarget(table, adj_node,
"network-ipam")) {
ipam_name = ipam_node->name();

VirtualNetworkNetworkIpam *ipam =
VirtualNetworkNetworkIpam *vnni =
static_cast<VirtualNetworkNetworkIpam *>
(adj_node->GetObject());
assert(ipam);
const VnSubnetsType &subnets = ipam->data();
for (unsigned int i = 0; i < subnets.ipam_subnets.size(); ++i) {
// if the DNS server address is not specified, set this
// to be the same as the GW address
std::string dns_server_address =
subnets.ipam_subnets[i].dns_server_address;
boost::system::error_code ec;
IpAddress dns_server =
IpAddress::from_string(dns_server_address, ec);
if (ec.value() || dns_server.is_unspecified()) {
dns_server_address =
subnets.ipam_subnets[i].default_gateway;
}

vn_ipam.push_back
(VnIpam(subnets.ipam_subnets[i].subnet.ip_prefix,
subnets.ipam_subnets[i].subnet.ip_prefix_len,
subnets.ipam_subnets[i].default_gateway,
dns_server_address,
subnets.ipam_subnets[i].enable_dhcp, ipam_name,
subnets.ipam_subnets[i].dhcp_option_list.dhcp_option,
subnets.ipam_subnets[i].host_routes.route));
VnSubnetsType subnets;
if (vnni)
subnets = vnni->data();

autogen::NetworkIpam *network_ipam =
static_cast<autogen::NetworkIpam *>(ipam_node->GetObject());
const std::string subnet_method =
boost::to_lower_copy(network_ipam->ipam_subnet_method());

if (subnet_method == "flat-subnet") {
BuildVnIpamData(network_ipam->ipam_subnets(),
ipam_name, &vn_ipam);
} else {
BuildVnIpamData(subnets.ipam_subnets, ipam_name, &vn_ipam);
}

VnIpamLinkData ipam_data;
ipam_data.oper_dhcp_options_.set_host_routes(subnets.host_routes.route);
vn_ipam_data.insert(VnData::VnIpamDataPair(ipam_name, ipam_data));
Expand Down
5 changes: 4 additions & 1 deletion src/vnsw/agent/oper/vn.h
Expand Up @@ -39,7 +39,7 @@ struct VnIpam {
OperDhcpOptions oper_dhcp_options;

VnIpam(const std::string& ip, uint32_t len, const std::string& gw,
const std::string& dns, bool dhcp, std::string &name,
const std::string& dns, bool dhcp, const std::string &name,
const std::vector<autogen::DhcpOptionType> &dhcp_options,
const std::vector<autogen::RouteType> &host_routes);

Expand Down Expand Up @@ -287,6 +287,9 @@ class VnTable : public AgentOperDBTable {
void DelHostRoute(VnEntry *vn, const IpAddress &address);
bool ChangeHandler(DBEntry *entry, const DBRequest *req);
bool IsGatewayL2(const string &gateway) const;
void BuildVnIpamData(const std::vector<autogen::IpamSubnetType> &subnets,
const std::string &ipam_name,
std::vector<VnIpam> *vn_ipam);
VnData *BuildData(IFMapNode *node);
IFMapNode *FindTarget(IFMapAgentTable *table, IFMapNode *node,
std::string node_type);
Expand Down
51 changes: 51 additions & 0 deletions src/vnsw/agent/test/test_vn.cc
Expand Up @@ -966,6 +966,57 @@ TEST_F(CfgTest, multicast_fabric_routes) {
WAIT_FOR(1000, 1000, (VrfFind("vrf1") == false));
}

// Check that flat subnet config in an IPAM is used to update VN entries
TEST_F(CfgTest, flat_subnet_config) {
client->Reset();
struct PortInfo input[] = {
{"vnet1", 1, "12.1.1.1", "00:00:00:01:01:11", 1, 1},
};

IpamInfo ipam_info[] = {
{"11.1.1.0", 24, "11.1.1.200", true},
};

char ipam_attr[] = "<network-ipam-mgmt>\n "
"<ipam-dns-method>default-dns-server</ipam-dns-method>\n "
"</network-ipam-mgmt>\n "
"<ipam-subnet-method>flat-subnet</ipam-subnet-method>\n "
"<ipam-subnets>\n "
"<subnets>\n "
"<subnet>\n "
"<ip-prefix> 12.1.0.0 </ip-prefix>\n "
"<ip-prefix-len> 16 </ip-prefix-len>\n "
"</subnet>\n "
"<default-gateway> 12.1.0.1 </default-gateway>\n "
"<dns-server-address> 12.1.0.2 </dns-server-address>\n "
"<enable-dhcp>true</enable-dhcp>\n "
"</subnets>\n "
"</ipam-subnets>\n ";
CreateVmportEnv(input, 1, 0);
client->WaitForIdle();

WAIT_FOR(1000, 1000, (VmPortActive(input, 0) == true));

AddIPAM("vn1", ipam_info, 1, ipam_attr);
client->WaitForIdle();

CheckVnAdd(1, 1);
VnEntry *vn = VnGet(1);
const std::vector<VnIpam> vn_ipam = vn->GetVnIpam();
EXPECT_TRUE(vn_ipam[0].ip_prefix.to_string() == "12.1.0.0");
EXPECT_TRUE(vn_ipam[0].plen == 16);
EXPECT_TRUE(vn_ipam[0].default_gw.to_string() == "12.1.0.1");
EXPECT_TRUE(vn_ipam[0].dns_server.to_string() == "12.1.0.2");
EXPECT_TRUE(vn_ipam[0].dhcp_enable);

client->Reset();
DelIPAM("vn1");
client->WaitForIdle();
DeleteVmportEnv(input, 1, true);
client->WaitForIdle();
WAIT_FOR(1000, 1000, (VrfFind("vrf1") == false));
}

int main(int argc, char **argv) {
GETUSERARGS();

Expand Down

0 comments on commit d92c4fe

Please sign in to comment.