#include <utility>
#include <vector>
+// Specialize macros for DHCPv4
+
+#define MYSQL_GET_OPTION(table_prefix, ...) \
+ MYSQL_GET_OPTION_COMMON(table_prefix, "", __VA_ARGS__)
+
+#define MYSQL_INSERT_OPTION(table_prefix) \
+ MYSQL_INSERT_OPTION_COMMON(table_prefix, "", "")
+
+#define MYSQL_UPDATE_OPTION(table_prefix, ...) \
+ MYSQL_UPDATE_OPTION_COMMON(table_prefix, "", __VA_ARGS__)
+
using namespace isc::cb;
using namespace isc::db;
using namespace isc::data;
// statement.
MySqlBindingCollection out_bindings = {
MySqlBinding::createInteger<uint32_t>(), // subnet_id
- MySqlBinding::createString(SUBNET_PREFIX_BUF_LENGTH), // subnet_prefix
+ MySqlBinding::createString(SUBNET4_PREFIX_BUF_LENGTH), // subnet_prefix
MySqlBinding::createString(DHCP4O6_INTERFACE_BUF_LENGTH), // 4o6_interface
MySqlBinding::createString(DHCP4O6_INTERFACE_ID_BUF_LENGTH), // 4o6_interface_id
MySqlBinding::createString(DHCP4O6_SUBNET_BUF_LENGTH), // 4o6_subnet
if (require_element) {
if (require_element->getType() != Element::list) {
isc_throw(BadValue, "invalid require_client_classes value "
- << out_bindings[14]->getString());
+ << out_bindings[9]->getString());
}
for (auto i = 0; i < require_element->size(); ++i) {
auto require_item = require_element->get(i);
const std::string& space) {
MySqlBindingCollection in_bindings = {
- MySqlBinding::createInteger<uint8_t>(static_cast<uint8_t>(code)),
+ MySqlBinding::createInteger<uint16_t>(code),
MySqlBinding::createString(space)
};
// statement.
MySqlBindingCollection out_bindings = {
MySqlBinding::createInteger<uint64_t>(), // option_id
- MySqlBinding::createInteger<uint8_t>(), // code
+ // code will go here.
MySqlBinding::createBlob(OPTION_VALUE_BUF_LENGTH), // value
MySqlBinding::createString(FORMATTED_OPTION_VALUE_BUF_LENGTH), // formatted_value
MySqlBinding::createString(OPTION_SPACE_BUF_LENGTH), // space
MySqlBinding::createInteger<uint8_t>(), // persistent
- MySqlBinding::createInteger<uint32_t>(), // dhcp4_subnet_id
+ MySqlBinding::createInteger<uint32_t>(), // dhcp[46]_subnet_id
MySqlBinding::createInteger<uint8_t>(), // scope_id
MySqlBinding::createString(USER_CONTEXT_BUF_LENGTH), // user_context
MySqlBinding::createString(SHARED_NETWORK_NAME_BUF_LENGTH), // shared_network_name
MySqlBinding::createInteger<uint64_t>(), // pool_id
- MySqlBinding::createTimestamp() //modification_ts
+ // pd_pool_id in DHCPv6
+ MySqlBinding::createTimestamp() // modification_ts
};
+ // Insert code in the second position.
+ if (universe == Option::V4) {
+ out_bindings.insert(out_bindings.begin() + 1,
+ MySqlBinding::createInteger<uint8_t>());
+ } else {
+ out_bindings.insert(out_bindings.begin() + 1,
+ MySqlBinding::createInteger<uint16_t>());
+ }
+
+ // Insert pd_pool_id before the modification_ts / last field
+ if (universe == Option::V6) {
+ out_bindings.insert(out_bindings.end() - 1,
+ MySqlBinding::createInteger<uint64_t>());
+ }
+
uint64_t last_option_id = 0;
conn_.selectQuery(index, in_bindings, out_bindings,
// first thing to do is to see if there is a definition for our
// parsed option. The option code and space is needed for it.
std::string space = (*(first_binding + 4))->getString();
- uint16_t code = (*(first_binding + 1))->getInteger<uint8_t>();
+ uint16_t code;
+ if (universe == Option::V4) {
+ code = (*(first_binding + 1))->getInteger<uint8_t>();
+ } else {
+ code = (*(first_binding + 1))->getInteger<uint16_t>();
+ }
// See if the option has standard definition.
OptionDefinitionPtr def = LibDHCP::getOptionDef(space, code);
// its option space and timestamp.
OptionDescriptorPtr desc(new OptionDescriptor(option, persistent, formatted_value));
desc->space_name_ = space;
- desc->setModificationTime((*(first_binding + 11))->getTimestamp());
+ // In DHCPv6 the pd_pool_id field shifts the position of the
+ // modification_ts field by one.
+ size_t ts_idx = (universe == Option::V4 ? 11 : 12);
+ desc->setModificationTime((*(first_binding + ts_idx))->getTimestamp());
return (desc);
}
" ORDER BY s.subnet_id, p.id, x.option_id, o.option_id"
#endif
+#ifndef MYSQL_GET_SUBNET6
+#define MYSQL_GET_SUBNET6(...) \
+ "SELECT" \
+ " s.subnet_id," \
+ " s.subnet_prefix," \
+ " s.client_class," \
+ " s.interface," \
+ " s.modification_ts," \
+ " s.preferred_lifetime," \
+ " s.rapid_commit," \
+ " s.rebind_timer," \
+ " s.relay," \
+ " s.renew_timer," \
+ " s.require_client_classes," \
+ " s.reservation_mode," \
+ " s.shared_network_name," \
+ " s.user_context," \
+ " s.valid_lifetime," \
+ " p.id," \
+ " p.start_address," \
+ " p.end_address," \
+ " p.subnet_id," \
+ " p.modification_ts," \
+ " d.id," \
+ " d.prefix," \
+ " d.prefix_length," \
+ " d.delegated_prefix_length," \
+ " d.dhcp6_subnet_id," \
+ " d.modification_ts," \
+ " x.option_id," \
+ " x.code," \
+ " x.value," \
+ " x.formatted_value," \
+ " x.space," \
+ " x.persistent," \
+ " x.dhcp6_subnet_id," \
+ " x.scope_id," \
+ " x.user_context," \
+ " x.shared_network_name," \
+ " x.pool_id," \
+ " x.pd_pool_id," \
+ " x.modification_ts," \
+ " y.option_id," \
+ " y.code," \
+ " y.value," \
+ " y.formatted_value," \
+ " y.space," \
+ " y.persistent," \
+ " y.dhcp6_subnet_id," \
+ " y.scope_id," \
+ " y.user_context," \
+ " y.shared_network_name," \
+ " y.pool_id," \
+ " y.pd_pool_id," \
+ " y.modification_ts," \
+ " o.option_id," \
+ " o.code," \
+ " o.value," \
+ " o.formatted_value," \
+ " o.space," \
+ " o.persistent," \
+ " o.dhcp6_subnet_id," \
+ " o.scope_id," \
+ " o.user_context," \
+ " o.shared_network_name," \
+ " o.pool_id," \
+ " o.pd_pool_id," \
+ " o.modification_ts " \
+ "FROM dhcp6_subnet AS s " \
+ "INNER JOIN dhcp6_subnet_server AS a " \
+ " ON s.subnet_id = a.subnet_id " \
+ "INNER JOIN dhcp6_server AS srv " \
+ " ON (a.server_id = srv.id) OR (a.server_id = 1) " \
+ "LEFT JOIN dhcp6_pool AS p ON s.subnet_id = p.subnet_id " \
+ "LEFT JOIN dhcp6_pd_pool AS d ON s.subnet_id = d.dhcp6_subnet_id " \
+ "LEFT JOIN dhcp6_options AS x ON x.scope_id = 5 AND p.id = x.pool_id " \
+ "LEFT JOIN dhcp6_options AS y ON y.scope_id = 6 AND d.id = y.pd_pool_id " \
+ "LEFT JOIN dhcp6_options AS o ON o.scope_id = 1 AND s.subnet_id = o.dhcp6_subnet_id " \
+ "WHERE (srv.tag = ? OR srv.id = 1) " #__VA_ARGS__ \
+ " ORDER BY s.subnet_id, p.id, x.option_id, o.option_id"
+#endif
+
#ifndef MYSQL_GET_SHARED_NETWORK4
#define MYSQL_GET_SHARED_NETWORK4(...) \
"SELECT" \
" ORDER BY n.id, o.option_id"
#endif
+#ifndef MYSQL_GET_SHARED_NETWORK6
+#define MYSQL_GET_SHARED_NETWORK6(...) \
+ "SELECT" \
+ " n.id," \
+ " n.name," \
+ " n.client_class," \
+ " n.interface," \
+ " n.modification_ts," \
+ " n.preferred_lifetime," \
+ " n.rapid_commit," \
+ " n.rebind_timer," \
+ " n.relay," \
+ " n.renew_timer," \
+ " n.require_client_classes," \
+ " n.reservation_mode," \
+ " n.user_context," \
+ " n.valid_lifetime," \
+ " o.option_id," \
+ " o.code," \
+ " o.value," \
+ " o.formatted_value," \
+ " o.space," \
+ " o.persistent," \
+ " o.dhcp6_subnet_id," \
+ " o.scope_id," \
+ " o.user_context," \
+ " o.shared_network_name," \
+ " o.pool_id," \
+ " o.pd_pool_id," \
+ " o.modification_ts " \
+ "FROM dhcp6_shared_network AS n " \
+ "INNER JOIN dhcp6_shared_network_server AS a " \
+ " ON n.id = a.shared_network_id " \
+ "INNER JOIN dhcp6_server AS s " \
+ " ON (a.server_id = s.id) OR (a.server_id = 1) " \
+ "LEFT JOIN dhcp6_options AS o ON o.scope_id = 4 AND n.name = o.shared_network_name " \
+ "WHERE (s.tag = ? OR s.id = 1) " #__VA_ARGS__ \
+ " ORDER BY n.id, o.option_id"
+#endif
+
#ifndef MYSQL_GET_OPTION_DEF
#define MYSQL_GET_OPTION_DEF(table_prefix, ...) \
"SELECT" \
" ORDER BY d.id"
#endif
-#ifndef MYSQL_GET_OPTION
-#define MYSQL_GET_OPTION(table_prefix, ...) \
+#ifndef MYSQL_GET_OPTION_COMMON
+#define MYSQL_GET_OPTION_COMMON(table_prefix, pd_pool_id, ...) \
"SELECT" \
" o.option_id," \
" o.code," \
" o.formatted_value," \
" o.space," \
" o.persistent," \
- " o.dhcp4_subnet_id," \
+ " o." #table_prefix "_subnet_id," \
" o.scope_id," \
" o.user_context," \
" o.shared_network_name," \
" o.pool_id," \
+ pd_pool_id \
" o.modification_ts " \
"FROM " #table_prefix "_options AS o " \
"INNER JOIN " #table_prefix "_options_server AS a" \
") VALUES (?, ?, ?, ?)"
#endif
+#ifndef MYSQL_INSERT_PD_POOL
+#define MYSQL_INSERT_PD_POOL() \
+ "INSERT INTO dhcp6_pd_pool(" \
+ " prefix," \
+ " prefix_length," \
+ " delegated_prefix_length," \
+ " dhcp6_subnet_id," \
+ " modification_ts" \
+ ") VALUES (?, ?, ?, ?, ?)"
+#endif
+
#ifndef MYSQL_INSERT_SHARED_NETWORK_SERVER
#define MYSQL_INSERT_SHARED_NETWORK_SERVER(table_prefix) \
"INSERT INTO " #table_prefix "_shared_network_server(" \
") VALUES (?, (SELECT id FROM " #table_prefix "_server WHERE tag = ?), ?)"
#endif
-#ifndef MYSQL_INSERT_OPTION
-#define MYSQL_INSERT_OPTION(table_prefix) \
+#ifndef MYSQL_INSERT_OPTION_COMMON
+#define MYSQL_INSERT_OPTION_COMMON(table_prefix, pd_pool_id, last) \
"INSERT INTO " #table_prefix "_options (" \
" code," \
" value," \
" user_context," \
" shared_network_name," \
" pool_id," \
+ pd_pool_id \
" modification_ts" \
- ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
+ ") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?" last ")"
#endif
#ifndef MYSQL_INSERT_OPTION_SERVER
"WHERE s.tag = ? AND d.code = ? AND d.space = ?"
#endif
-#ifndef MYSQL_UPDATE_OPTION
-#define MYSQL_UPDATE_OPTION(table_prefix, ...) \
+#ifndef MYSQL_UPDATE_OPTION_COMMON
+#define MYSQL_UPDATE_OPTION_COMMON(table_prefix, pd_pool_id, ...) \
"UPDATE " #table_prefix "_options AS o " \
"INNER JOIN " #table_prefix "_options_server AS a" \
" ON o.option_id = a.option_id " \
" o.user_context = ?," \
" o.shared_network_name = ?," \
" o.pool_id = ?," \
+ pd_pool_id \
" o.modification_ts = ? " \
"WHERE s.tag = ? " #__VA_ARGS__
#endif
"WHERE subnet_id = ?"
#endif
+#ifndef MYSQL_DELETE_PD_POOLS
+#define MYSQL_DELETE_PD_POOLS() \
+ "DELETE FROM dhcp6_pd_pool " \
+ "WHERE subnet_id = ?"
+#endif
+
#ifndef MYSQL_DELETE_SHARED_NETWORK
#define MYSQL_DELETE_SHARED_NETWORK(table_prefix, ...) \
"DELETE n FROM " #table_prefix "_shared_network AS n " \
" WHERE start_address = ? AND end_address = ?)"
#endif
+#ifndef MYSQL_DELETE_OPTION_PD_POOL
+#define MYSQL_DELETE_OPTION_PD_POOL(...) \
+ "DELETE o FROM dhcp6_options AS o " \
+ "INNER JOIN dhcp6_options_server AS a" \
+ " ON o.option_id = a.option_id " \
+ "INNER JOIN dhcp6_server AS s" \
+ " ON a.server_id = s.id " \
+ "WHERE s.tag = ? " #__VA_ARGS__ \
+ " AND o.pd_pool_id = " \
+ " (SELECT id FROM dhcp6_pd_pool" \
+ " WHERE prefix = ? AND prefix_length = ?)"
+#endif
+
} // end of anonymous namespace
} // end of namespace isc::dhcp