12 #include "services/services_types.h"
18 #include <boost/assign/list_of.hpp>
19 #include <boost/scoped_array.hpp>
22 using namespace boost::assign;
25 boost::asio::io_context &io)
26 :
ProtoHandler(agent, info, io), vm_itf_(NULL), vm_itf_index_(-1),
27 option_(NULL), flags_(), dns_enable_(true),
28 host_routes_level_(Invalid) {
37 option_->WriteData(option, 0, NULL, &opt_len);
43 const std::string &input) {
44 std::stringstream value(input);
47 if (value.bad() || value.fail() || data > 0xFF) {
49 input <<
"is invalid");
51 uint8_t byte = (uint8_t)data;
52 option_->WriteData(option, 1, &byte, &opt_len);
59 const std::string &input) {
60 option_->WriteData(option, 0, NULL, &opt_len);
61 std::stringstream value(input);
65 while (!value.bad() && !value.fail() && byte <= 0xFF) {
66 option_->AppendData(1, &byte, &opt_len);
75 if (!
option_->GetLen() || !done) {
77 input <<
"is invalid");
86 const std::string &input) {
87 std::stringstream value(input);
90 if (value.fail() || value.bad() || data > 0xFF) {
92 input <<
"is invalid");
96 uint8_t byte = (uint8_t)data;
99 option_->WriteData(option, 1, &byte, &opt_len);
100 option_->AppendData(str.length(), str.c_str(), &opt_len);
107 const std::string &input) {
108 std::stringstream value(input);
111 uint8_t byte = (uint8_t)data;
113 if (value.fail() || value.bad() || data > 0xFF) {
115 input <<
"is invalid");
119 option_->WriteData(option, 1, &byte, &opt_len);
120 while (value.good()) {
123 opt_len =
AddIP(opt_len, ipstr);
129 input <<
"is invalid");
138 const std::string &input) {
139 option_->WriteData(option, input.length(), input.c_str(), &opt_len);
145 const std::string &input) {
146 std::stringstream value(input);
149 if (value.bad() || value.fail()) {
151 input <<
"is invalid");
154 option_->WriteData(option, 4, &data, &opt_len);
161 const std::string &input,
163 option_->WriteData(option, 0, NULL, &opt_len);
164 std::stringstream value(input);
167 while (!value.bad() && !value.fail()) {
169 option_->AppendData(2, &data, &opt_len);
170 if (!array || value.eof())
break;
175 if (!
option_->GetLen() || !value.eof()) {
177 input <<
"is invalid");
187 boost::system::error_code ec;
192 uint32_t ip = Ip4Address::from_string(ipstr, ec).to_ulong();
193 if(!ec.value() && !ip) {
202 IpAddress ip = IpAddress::from_string(ipstr, ec);
203 if (!ec.value() && ip.is_unspecified()) {
213 const std::string &ipstr) {
214 boost::system::error_code ec;
215 IpAddress ip = IpAddress::from_string(ipstr, ec);
220 if (ip.is_unspecified()) {
233 const std::string &input,
237 option_->WriteData(option, 0, NULL, &opt_len);
238 std::stringstream value(input);
239 while (value.good()) {
245 opt_len =
AddIP(opt_len, ipstr);
256 if (min_count &&
option_->GetLen() < min_count * 4) {
258 input <<
"is invalid");
263 if (max_count &&
option_->GetLen() > max_count * 4) {
265 input <<
"is invalid");
270 if (multiples &&
option_->GetLen() % (multiples * 4)) {
272 input <<
"is invalid");
281 const std::string &input,
bool list) {
282 option_->WriteData(option, 0, NULL, &opt_len);
283 std::stringstream value(input);
284 while (value.good()) {
290 opt_len =
AddIP(opt_len, ipstr);
296 DHCPV6_TRACE(Error,
"Invalid DHCP option " << option <<
" for VM " <<
307 const std::string &input,
309 option_->WriteData(option, 0, NULL, &opt_len);
310 std::stringstream value(input);
311 while (value.good()) {
322 input <<
"is invalid");
332 const std::string &input) {
333 option_->WriteData(option, 0, NULL, &opt_len);
335 std::stringstream value(input);
338 if (value.bad() || value.fail() || data > 0xFF) {
340 input <<
"is invalid");
343 uint8_t byte = (uint8_t)data;
344 option_->WriteData(option, 1, &byte, &opt_len);
349 if (value.bad() || value.fail() || !str.size()) {
351 input <<
"is invalid");
358 const std::string &input) {
359 boost::scoped_array<uint8_t> name(
new uint8_t[input.size() * 2 + 2]);
362 option_->AppendData(len, name.get(), &opt_len);
369 if (
ipam_type_.ipam_dns_method ==
"default-dns-server" ||
370 ipam_type_.ipam_dns_method ==
"virtual-dns-server" ||
376 }
else if (
ipam_type_.ipam_dns_method ==
"tenant-dns-server") {
377 for (
unsigned int i = 0; i <
ipam_type_.ipam_dns_server.
378 tenant_dns_server_address.ip_address.size(); ++i) {
380 tenant_dns_server_address.ip_address[i]);
389 const std::string &input) {
390 std::stringstream value(input);
391 while (value.good()) {
396 (
int *)&host_route.
plen_);
397 if (ec || host_route.
plen_ > 32 || !value.good()) {
399 "has to be list of <subnet/plen gw>");
404 host_route.
gw_ = Ip4Address::from_string(snetstr, ec);
422 std::vector<OperDhcpOptions::HostRoute> host_routes;
440 for (index = 0; index < vn_ipam.size(); ++index) {
441 if (vn_ipam[index].IsSubnetMember(ip)) {
445 if (index < vn_ipam.size()) {
448 if (vn_ipam[index].oper_dhcp_options.are_host_routes_set()) {
449 host_routes = vn_ipam[index].oper_dhcp_options.host_routes();
461 if (host_routes.size() > 0)
477 if (host_routes.size()) {
479 uint8_t *ptr =
option_->GetData();
481 for (uint32_t i = 0; i < host_routes.size(); ++i) {
482 uint32_t prefix = host_routes[i].prefix_.to_ulong();
483 uint32_t plen = host_routes[i].plen_;
484 uint32_t gw = host_routes[i].gw_.to_ulong();
487 for (
unsigned int j = 0; plen && j <= (plen - 1) / 8; ++j) {
488 *ptr++ = (prefix >> 8 * (3 - j)) & 0xFF;
493 *(uint32_t *)ptr = htonl(gw);
496 ptr +=
sizeof(uint32_t);
497 len +=
sizeof(uint32_t);
508 std::vector<autogen::DhcpOptionType> &
options,
510 for (
unsigned int i = 0; i < options.size(); ++i) {
512 uint32_t option =
OptionCode(options[i].dhcp_option_name);
515 options[i].dhcp_option_name);
523 uint16_t old_opt_len = opt_len;
525 option_->SetNextOptionPtr(opt_len);
528 std::string &opt_value = options[i].dhcp_option_value;
529 if (!options[i].dhcp_option_value_bytes.empty() &&
532 opt_value = options[i].dhcp_option_value_bytes;
546 options[i].dhcp_option_value);
555 options[i].dhcp_option_value);
560 options[i].dhcp_option_value);
565 options[i].dhcp_option_value);
574 options[i].dhcp_option_value);
579 options[i].dhcp_option_value,
585 options[i].dhcp_option_value,
591 options[i].dhcp_option_value, 1, 1, 0);
596 options[i].dhcp_option_value, 0, 0, 0);
602 routers_ = options[i].dhcp_option_value;
606 options[i].dhcp_option_value,
613 options[i].dhcp_option_value, 2, 0, 2);
618 options[i].dhcp_option_value,
624 options[i].dhcp_option_value,
630 options[i].dhcp_option_value);
641 options[i].dhcp_option_value,
647 options[i].dhcp_option_value,
653 options[i].dhcp_option_value);
658 options[i].dhcp_option_name);
664 boost::system::error_code ec;
666 Ip4Address::from_string(options[i].dhcp_option_value, ec);
671 if (opt_len != old_opt_len)
683 std::vector<autogen::DhcpOptionType>
options;
707 if (
ipam_type_.ipam_dns_method !=
"virtual-dns-server" ||
709 virtual_dns_server_name,
716 " doesnt match with configured domain " <<
724 <<
vdns_type_.domain_name <<
"; Client name = "
bool GetIpamDhcpOptions(std::vector< autogen::DhcpOptionType > *options, bool ipv6) const
void ReadClasslessRoute(uint32_t option, uint16_t opt_len, const std::string &input)
bool are_host_routes_set() const
const std::vector< HostRoute > & host_routes() const
uint16_t AddNoDataOption(uint32_t option, uint16_t opt_len)
uint16_t AddByteOption(uint32_t option, uint16_t opt_len, const std::string &input)
bool IsValidIpOption(uint32_t option, const std::string &ipstr, bool is_v4)
virtual uint16_t AddIP(uint16_t opt_len, const std::string &input)=0
void FindDomainName(const IpAddress &vm_addr)
boost::system::error_code Ip4PrefixParse(const string &str, Ip4Address *addr, int *plen)
uint16_t AddConfigDhcpOptions(uint16_t opt_len, bool is_v6)
#define DHCP_OPTION_TFTP_SERVER_NAME
boost::scoped_ptr< DhcpOptionHandler > option_
bool GetSubnetDhcpOptions(std::vector< autogen::DhcpOptionType > *options, bool ipv6) const
#define DHCP_OPTION_IP_LEASE_TIME
boost::asio::ip::address IpAddress
bool GetInterfaceDhcpOptions(std::vector< autogen::DhcpOptionType > *options) const
uint16_t AddIntegerOption(uint32_t option, uint16_t opt_len, const std::string &input)
#define DHCPV6_OPTION_DNS_SERVERS
std::vector< OperDhcpOptions::HostRoute > host_routes_
uint16_t AddCompressedName(uint16_t opt_len, const std::string &input)
#define DHCP_BASE_TRACE(arg)
uint16_t AddByteCompressedNameOption(uint32_t option, uint16_t opt_len, const std::string &input)
uint16_t AddDnsServers(uint16_t opt_len)
uint16_t AddClasslessRouteOption(uint16_t opt_len)
bool IsValidDnsOption(uint32_t option, const std::string &ipstr)
virtual DhcpOptionCategory OptionCategory(uint32_t option) const =0
static uint8_t * AddName(uint8_t *ptr, const std::string &addr, uint16_t plen, uint16_t offset, uint16_t &length)
bool GetVnHostRoutes(const std::string &ipam, std::vector< OperDhcpOptions::HostRoute > *routes) const
DhcpOptionLevel host_routes_level_
uint16_t AddCompressedNameOption(uint32_t option, uint16_t opt_len, const std::string &input, bool list)
const OperDhcpOptions & oper_dhcp_options() const
bool CanOverrideWithBytes(DhcpOptionCategory category)
uint16_t AddByteArrayOption(uint32_t option, uint16_t opt_len, const std::string &input)
const std::vector< VnIpam > & GetVnIpam() const
const VnEntry * vn() const
uint16_t AddByteIPOption(uint32_t option, uint16_t opt_len, const std::string &input)
uint16_t AddIpv4Option(uint32_t option, uint16_t opt_len, const std::string &input, uint8_t min_count, uint8_t max_count, uint8_t multiples)
boost::asio::ip::address_v4 Ip4Address
uint16_t AddIpv6Option(uint32_t option, uint16_t opt_len, const std::string &input, bool list)
void update_host_routes(const HostOptionsList &host_routes)
#define DHCPV6_TRACE(obj, arg)
uint16_t AddByteStringOption(uint32_t option, uint16_t opt_len, const std::string &input)
virtual uint32_t OptionCode(const std::string &option) const =0
DhcpHandlerBase(Agent *agent, boost::shared_ptr< PktInfo > info, boost::asio::io_context &io)
autogen::VirtualDnsType vdns_type_
virtual ~DhcpHandlerBase()
uint16_t AddShortArrayOption(uint32_t option, uint16_t opt_len, const std::string &input, bool array)
uint16_t AddStringOption(uint32_t option, uint16_t opt_len, const std::string &input)
void set_flag(uint8_t flag)
autogen::IpamType ipam_type_
#define DHCP_OPTION_CLASSLESS_ROUTE
uint16_t AddDhcpOptions(uint16_t opt_len, std::vector< autogen::DhcpOptionType > &options, DhcpOptionLevel level)
bool is_flag_set(uint8_t flag) const
#define DHCP_OPTION_ROUTER
bool GetIpamData(const IpAddress &vm_addr, std::string *ipam_name, autogen::IpamType *ipam_type) const