lease_cmds.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. // Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <config.h>
  7. #include <config/command_mgr.h>
  8. #include <config/cmds_impl.h>
  9. #include <cc/command_interpreter.h>
  10. #include <cc/data.h>
  11. #include <asiolink/io_address.h>
  12. #include <dhcpsrv/cfgmgr.h>
  13. #include <dhcpsrv/lease_mgr.h>
  14. #include <dhcpsrv/lease_mgr_factory.h>
  15. #include <dhcpsrv/subnet_id.h>
  16. #include <dhcp/duid.h>
  17. #include <hooks/hooks.h>
  18. #include <exceptions/exceptions.h>
  19. #include <lease_cmds.h>
  20. #include <lease_parser.h>
  21. #include <lease_cmds_log.h>
  22. #include <util/encode/hex.h>
  23. #include <util/strutil.h>
  24. #include <boost/bind.hpp>
  25. #include <string>
  26. using namespace isc::dhcp;
  27. using namespace isc::data;
  28. using namespace isc::config;
  29. using namespace isc::asiolink;
  30. using namespace isc::hooks;
  31. using namespace std;
  32. namespace isc {
  33. namespace lease_cmds {
  34. /// @brief Wrapper class around reservation command handlers.
  35. class LeaseCmdsImpl : private CmdsImpl {
  36. public:
  37. /// @brief Parameters specified for lease commands.
  38. class Parameters {
  39. public:
  40. /// @brief specifies type of query (by IP addr, by hwaddr, by DUID)
  41. typedef enum {
  42. TYPE_ADDR, ///< query by IP address (either v4 or v6)
  43. TYPE_HWADDR, ///< query by hardware address (v4 only)
  44. TYPE_DUID, ///< query by DUID (v6 only)
  45. TYPE_CLIENT_ID ///< query by client identifier (v4 only).
  46. } Type;
  47. /// @brief Specifies subnet-id (always used)
  48. SubnetID subnet_id;
  49. /// @brief Specifies IPv4/v6 address (used when query_type is TYPE_ADDR)
  50. IOAddress addr;
  51. /// @brief Specifies hardware address (used when query_type is TYPE_HWADDR)
  52. HWAddrPtr hwaddr;
  53. /// @brief Specifies identifier value (used when query_type is TYPE_DUID)
  54. isc::dhcp::DuidPtr duid;
  55. /// @brief Specifies identifier value (used when query_type is TYPE_CLIENT_ID)
  56. isc::dhcp::ClientIdPtr client_id;
  57. /// @brief Attempts to covert text to one of specified types
  58. ///
  59. /// Supported values are: "address", hw-address and duid.
  60. ///
  61. /// @param txt text to be converted
  62. /// @return value converted to Parameters::Type
  63. /// @throw BadValue if unsupported type is specified
  64. static Type txtToType(const std::string& txt) {
  65. if (txt == "address") {
  66. return (Parameters::TYPE_ADDR);
  67. } else if (txt == "hw-address") {
  68. return (Parameters::TYPE_HWADDR);
  69. } else if (txt == "duid") {
  70. return (Parameters::TYPE_DUID);
  71. } else if (txt == "client-id") {
  72. return (Parameters::TYPE_CLIENT_ID);
  73. } else {
  74. isc_throw(BadValue, "Incorrect identifier type: "
  75. << txt << ", the only supported values are: "
  76. "address, hw-address, duid");
  77. }
  78. }
  79. /// @brief specifies parameter types (true = query by address, false =
  80. /// query by identifier-type,identifier)
  81. Type query_type;
  82. /// @brief Lease type (NA,TA or PD) used for v6 leases
  83. Lease::Type lease_type;
  84. /// @brief IAID identifier used for v6 leases
  85. uint32_t iaid;
  86. /// @brief Default constructor.
  87. Parameters()
  88. :addr("::"), query_type(TYPE_ADDR), lease_type(Lease::TYPE_NA),
  89. iaid(0) {
  90. }
  91. };
  92. public:
  93. /// @brief lease4-add, lease6-add command handler
  94. ///
  95. /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::leaseAddHandler
  96. ///
  97. /// @param handle Callout context - which is expected to contain the
  98. /// add command JSON text in the "command" argument
  99. /// @return 0 upon success, non-zero otherwise
  100. int
  101. leaseAddHandler(CalloutHandle& handle);
  102. /// @brief lease4-get, lease6-get command handler
  103. ///
  104. /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::leaseGetHandler
  105. ///
  106. /// @param handle Callout context - which is expected to contain the
  107. /// get command JSON text in the "command" argument
  108. /// @return 0 upon success, non-zero otherwise
  109. int
  110. leaseGetHandler(CalloutHandle& handle);
  111. /// @brief lease4-del command handler
  112. ///
  113. /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::lease4DelHandler
  114. ///
  115. /// @param handle Callout context - which is expected to contain the
  116. /// delete command JSON text in the "command" argument
  117. /// @return 0 upon success, non-zero otherwise
  118. int
  119. lease4DelHandler(CalloutHandle& handle);
  120. /// @brief lease6-del command handler
  121. ///
  122. /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::lease6DelHandler
  123. ///
  124. /// @param handle Callout context - which is expected to contain the
  125. /// delete command JSON text in the "command" argument
  126. /// @return 0 upon success, non-zero otherwise
  127. int
  128. lease6DelHandler(CalloutHandle& handle);
  129. /// @brief lease4-update handler
  130. ///
  131. /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::lease4UpdateHandler
  132. ///
  133. /// @param handle Callout context - which is expected to contain the
  134. /// update command JSON text in the "command" argument
  135. /// @return 0 upon success, non-zero otherwise
  136. int
  137. lease4UpdateHandler(CalloutHandle& handle);
  138. /// @brief lease6-update handler
  139. ///
  140. /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::lease6UpdateHandler
  141. ///
  142. /// @param handle Callout context - which is expected to contain the
  143. /// update command JSON text in the "command" argument
  144. /// @return 0 upon success, non-zero otherwise
  145. int
  146. lease6UpdateHandler(CalloutHandle& handle);
  147. /// @brief lease4-wipe handler
  148. ///
  149. /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::lease4WipeHandler
  150. ///
  151. /// @param handle Callout context - which is expected to contain the
  152. /// wipe command JSON text in the "command" argument
  153. /// @return 0 upon success, non-zero otherwise
  154. int
  155. lease4WipeHandler(CalloutHandle& handle);
  156. /// @brief lease6-wipe handler
  157. ///
  158. /// Provides the implementation for @ref isc::lease_cmds::LeaseCmds::lease6WipeHandler
  159. ///
  160. /// @param handle Callout context - which is expected to contain the
  161. /// wipe command JSON text in the "command" argument
  162. /// @return 0 upon success, non-zero otherwise
  163. int
  164. lease6WipeHandler(CalloutHandle& handle);
  165. /// @brief Extracts parameters required for reservation-get and reservation-del
  166. ///
  167. /// See @ref Parameters class for detailed description of what is expected
  168. /// in the args structure.
  169. ///
  170. /// @param v6 whether addresses allowed are v4 (false) or v6 (true)
  171. /// @param args arguments passed to command
  172. /// @return parsed parameters
  173. /// @throw BadValue if input arguments don't make sense.
  174. Parameters getParameters(bool v6, const ConstElementPtr& args);
  175. };
  176. int
  177. LeaseCmdsImpl::leaseAddHandler(CalloutHandle& handle) {
  178. // Arbitrary defaulting to DHCPv4 or with other words extractCommand
  179. // below is not expected to throw...
  180. bool v4 = true;
  181. string txt = "malformed command";
  182. try {
  183. extractCommand(handle);
  184. v4 = (cmd_name_ == "lease4-add");
  185. txt = "(missing parameters)";
  186. if (!cmd_args_) {
  187. isc_throw(isc::BadValue, "no parameters specified for the command");
  188. }
  189. txt = cmd_args_->str();
  190. ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
  191. Lease4Ptr lease4;
  192. Lease6Ptr lease6;
  193. if (v4) {
  194. Lease4Parser parser;
  195. lease4 = parser.parse(config, cmd_args_);
  196. // checkLeaseIntegrity(config, lease4);
  197. if (lease4) {
  198. LeaseMgrFactory::instance().addLease(lease4);
  199. }
  200. } else {
  201. Lease6Parser parser;
  202. lease6 = parser.parse(config, cmd_args_);
  203. // checkLeaseIntegrity(config, lease6);
  204. if (lease6) {
  205. LeaseMgrFactory::instance().addLease(lease6);
  206. }
  207. }
  208. } catch (const std::exception& ex) {
  209. LOG_ERROR(lease_cmds_logger, v4 ? LEASE_CMDS_ADD4_FAILED : LEASE_CMDS_ADD6_FAILED)
  210. .arg(txt)
  211. .arg(ex.what());
  212. setErrorResponse(handle, ex.what());
  213. return (1);
  214. }
  215. LOG_INFO(lease_cmds_logger,
  216. v4 ? LEASE_CMDS_ADD4 : LEASE_CMDS_ADD6).arg(txt);
  217. setSuccessResponse(handle, "Lease added.");
  218. return (0);
  219. }
  220. LeaseCmdsImpl::Parameters
  221. LeaseCmdsImpl::getParameters(bool v6, const ConstElementPtr& params) {
  222. Parameters x;
  223. if (!params || params->getType() != Element::map) {
  224. isc_throw(BadValue, "Parameters missing or are not a map.");
  225. }
  226. // We support several sets of parameters for leaseX-get/lease-del:
  227. // lease-get(type, address)
  228. // lease-get(type, subnet-id, identifier-type, identifier)
  229. if (params->contains("type")) {
  230. string t = params->get("type")->stringValue();
  231. if (t == "IA_NA" || t == "0") {
  232. x.lease_type = Lease::TYPE_NA;
  233. } else if (t == "IA_TA" || t == "1") {
  234. x.lease_type = Lease::TYPE_TA;
  235. } else if (t == "IA_PD" || t == "2") {
  236. x.lease_type = Lease::TYPE_PD;
  237. } else if (t == "V4" || t == "3") {
  238. x.lease_type = Lease::TYPE_V4;
  239. } else {
  240. isc_throw(BadValue, "Invalid lease type specified: "
  241. << t << ", only supported values are: IA_NA, IA_TA,"
  242. << " IA_PD and V4");
  243. }
  244. }
  245. ConstElementPtr tmp = params->get("ip-address");
  246. if (tmp) {
  247. if (tmp->getType() != Element::string) {
  248. isc_throw(BadValue, "'ip-address' is not a string.");
  249. }
  250. x.addr = IOAddress(tmp->stringValue());
  251. if ((v6 && !x.addr.isV6()) || (!v6 && !x.addr.isV4())) {
  252. stringstream txt;
  253. txt << "Invalid " << (v6 ? "IPv6" : "IPv4")
  254. << " address specified: " << tmp->stringValue();
  255. isc_throw(BadValue, txt.str());
  256. }
  257. x.query_type = Parameters::TYPE_ADDR;
  258. return (x);
  259. }
  260. tmp = params->get("subnet-id");
  261. if (!tmp) {
  262. isc_throw(BadValue, "Mandatory 'subnet-id' parameter missing.");
  263. }
  264. if (tmp->getType() != Element::integer) {
  265. isc_throw(BadValue, "'subnet-id' parameter is not integer.");
  266. }
  267. x.subnet_id = tmp->intValue();
  268. if (params->contains("iaid")) {
  269. x.iaid = params->get("iaid")->intValue();
  270. }
  271. // No address specified. Ok, so it must be identifier based query.
  272. // "identifier-type": "duid",
  273. // "identifier": "aa:bb:cc:dd:ee:..."
  274. ConstElementPtr type = params->get("identifier-type");
  275. ConstElementPtr ident = params->get("identifier");
  276. if (!type || type->getType() != Element::string) {
  277. isc_throw(BadValue, "No 'ip-address' provided"
  278. " and 'identifier-type' is either missing or not a string.");
  279. }
  280. if (!ident || ident->getType() != Element::string) {
  281. isc_throw(BadValue, "No 'ip-address' provided"
  282. " and 'identifier' is either missing or not a string.");
  283. }
  284. // Got the parameters. Let's see if their values make sense.
  285. // Try to convert identifier-type
  286. x.query_type = Parameters::txtToType(type->stringValue());
  287. switch (x.query_type) {
  288. case Parameters::TYPE_HWADDR: {
  289. HWAddr hw = HWAddr::fromText(ident->stringValue());
  290. x.hwaddr = HWAddrPtr(new HWAddr(hw));
  291. break;
  292. }
  293. case Parameters::TYPE_CLIENT_ID: {
  294. x.client_id = ClientId::fromText(ident->stringValue());
  295. break;
  296. }
  297. case Parameters::TYPE_DUID: {
  298. DUID duid = DUID::fromText(ident->stringValue());
  299. x.duid = DuidPtr(new DUID(duid));
  300. break;
  301. }
  302. case Parameters::TYPE_ADDR: {
  303. // We should never get here. The address clause should have been caught
  304. // earlier.
  305. return (x);
  306. }
  307. default: {
  308. isc_throw(BadValue, "Identifier type " << type->stringValue() <<
  309. " is not supported.");
  310. }
  311. }
  312. return (x);
  313. }
  314. int
  315. LeaseCmdsImpl::leaseGetHandler(CalloutHandle& handle) {
  316. Parameters p;
  317. Lease4Ptr lease4;
  318. Lease6Ptr lease6;
  319. bool v4;
  320. try {
  321. extractCommand(handle);
  322. v4 = (cmd_name_ == "lease4-get");
  323. p = getParameters(!v4, cmd_args_);
  324. switch (p.query_type) {
  325. case Parameters::TYPE_ADDR: {
  326. // Query by address
  327. if (v4) {
  328. lease4 = LeaseMgrFactory::instance().getLease4(p.addr);
  329. } else {
  330. lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, p.addr);
  331. }
  332. break;
  333. }
  334. case Parameters::TYPE_HWADDR:
  335. if (v4) {
  336. if (!p.hwaddr) {
  337. isc_throw(InvalidParameter, "Program error: Query by hw-address "
  338. "requires hwaddr to be specified");
  339. }
  340. lease4 = LeaseMgrFactory::instance().getLease4(*p.hwaddr, p.subnet_id);
  341. } else {
  342. isc_throw(isc::InvalidParameter, "Query by hw-address is not allowed in v6.");
  343. }
  344. break;
  345. case Parameters::TYPE_DUID:
  346. if (!v4) {
  347. if (!p.duid) {
  348. isc_throw(InvalidParameter, "Program error: Query by duid "
  349. "requires duid to be specified");
  350. }
  351. lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, *p.duid,
  352. p.iaid, p.subnet_id);
  353. } else {
  354. isc_throw(InvalidParameter, "Query by duid is not allowed in v4.");
  355. }
  356. break;
  357. case Parameters::TYPE_CLIENT_ID:
  358. if (v4) {
  359. if (!p.client_id) {
  360. isc_throw(InvalidParameter, "Program error: Query by client-id "
  361. "requires client-id to be specified");
  362. }
  363. lease4 = LeaseMgrFactory::instance().getLease4(*p.client_id, p.subnet_id);
  364. } else {
  365. isc_throw(isc::InvalidParameter, "Query by client-id is not allowed in v6.");
  366. }
  367. break;
  368. default: {
  369. isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
  370. break;
  371. }
  372. }
  373. } catch (const std::exception& ex) {
  374. setErrorResponse(handle, ex.what());
  375. return (1);
  376. }
  377. ElementPtr lease_json;
  378. if (v4 && lease4) {
  379. lease_json = lease4->toElement();
  380. ConstElementPtr response = createAnswer(CONTROL_RESULT_SUCCESS,
  381. "IPv4 lease found.", lease_json);
  382. setResponse(handle, response);
  383. } else if (!v4 && lease6) {
  384. lease_json = lease6->toElement();
  385. ConstElementPtr response = createAnswer(CONTROL_RESULT_SUCCESS,
  386. "IPv6 lease found.", lease_json);
  387. setResponse(handle, response);
  388. } else {
  389. // If we got here, the lease has not been found.
  390. setErrorResponse(handle, "Lease not found.", CONTROL_RESULT_EMPTY);
  391. }
  392. return (0);
  393. }
  394. int
  395. LeaseCmdsImpl::lease4DelHandler(CalloutHandle& handle) {
  396. Parameters p;
  397. Lease4Ptr lease4;
  398. IOAddress addr(IOAddress::IPV4_ZERO_ADDRESS());
  399. try {
  400. extractCommand(handle);
  401. p = getParameters(false, cmd_args_);
  402. switch (p.query_type) {
  403. case Parameters::TYPE_ADDR: {
  404. // If address was specified explicitly, let's use it as is.
  405. addr = p.addr;
  406. break;
  407. }
  408. case Parameters::TYPE_HWADDR:
  409. if (!p.hwaddr) {
  410. isc_throw(InvalidParameter, "Program error: Query by hw-address "
  411. "requires hwaddr to be specified");
  412. }
  413. // Let's see if there's such a lease at all.
  414. lease4 = LeaseMgrFactory::instance().getLease4(*p.hwaddr, p.subnet_id);
  415. if (!lease4) {
  416. setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
  417. return (0);
  418. }
  419. // Found it, can use it as is.
  420. addr = lease4->addr_;
  421. break;
  422. case Parameters::TYPE_CLIENT_ID:
  423. if (!p.client_id) {
  424. isc_throw(InvalidParameter, "Program error: Query by client-id "
  425. "requires client-id to be specified");
  426. }
  427. // Let's see if there's such a lease at all.
  428. lease4 = LeaseMgrFactory::instance().getLease4(*p.client_id, p.subnet_id);
  429. if (!lease4) {
  430. setErrorResponse(handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
  431. return (0);
  432. }
  433. // Found it, can use it as is.
  434. addr = lease4->addr_;
  435. break;
  436. case Parameters::TYPE_DUID:
  437. isc_throw(InvalidParameter, "Delete by duid is not allowed in v4.");
  438. break;
  439. default: {
  440. isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
  441. break;
  442. }
  443. }
  444. if (LeaseMgrFactory::instance().deleteLease(addr)) {
  445. setSuccessResponse(handle, "IPv4 lease deleted.");
  446. } else {
  447. setErrorResponse (handle, "IPv4 lease not found.", CONTROL_RESULT_EMPTY);
  448. }
  449. } catch (const std::exception& ex) {
  450. setErrorResponse(handle, ex.what());
  451. return (1);
  452. }
  453. return (0);
  454. }
  455. int
  456. LeaseCmdsImpl::lease6DelHandler(CalloutHandle& handle) {
  457. Parameters p;
  458. Lease6Ptr lease6;
  459. IOAddress addr(IOAddress::IPV6_ZERO_ADDRESS());
  460. try {
  461. extractCommand(handle);
  462. p = getParameters(true, cmd_args_);
  463. switch (p.query_type) {
  464. case Parameters::TYPE_ADDR: {
  465. // If address was specified explicitly, let's use it as is.
  466. addr = p.addr;
  467. break;
  468. }
  469. case Parameters::TYPE_HWADDR:
  470. isc_throw(InvalidParameter, "Delete by hw-address is not allowed in v6.");
  471. break;
  472. case Parameters::TYPE_DUID:
  473. if (!p.duid) {
  474. isc_throw(InvalidParameter, "Program error: Query by duid "
  475. "requires duid to be specified");
  476. }
  477. // Let's see if there's such a lease at all.
  478. lease6 = LeaseMgrFactory::instance().getLease6(p.lease_type, *p.duid,
  479. p.iaid, p.subnet_id);
  480. if (!lease6) {
  481. setErrorResponse(handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
  482. return (0);
  483. }
  484. // Found it, can use it as is.
  485. addr = lease6->addr_;
  486. break;
  487. default: {
  488. isc_throw(InvalidOperation, "Unknown query type: " << static_cast<int>(p.query_type));
  489. break;
  490. }
  491. }
  492. if (LeaseMgrFactory::instance().deleteLease(addr)) {
  493. setSuccessResponse(handle, "IPv6 lease deleted.");
  494. } else {
  495. setErrorResponse (handle, "IPv6 lease not found.", CONTROL_RESULT_EMPTY);
  496. }
  497. } catch (const std::exception& ex) {
  498. setErrorResponse(handle, ex.what());
  499. return (1);
  500. }
  501. return (0);
  502. }
  503. int
  504. LeaseCmdsImpl::lease4UpdateHandler(CalloutHandle& handle) {
  505. try {
  506. extractCommand(handle);
  507. // We need the lease to be specified.
  508. if (!cmd_args_) {
  509. isc_throw(isc::BadValue, "no parameters specified for lease4-update command");
  510. }
  511. // Get the parameters specified by the user first.
  512. ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
  513. Lease4Ptr lease4;
  514. Lease4Parser parser;
  515. // The parser does sanity checks (if the address is in scope, if
  516. // subnet-id is valid, etc)
  517. lease4 = parser.parse(config, cmd_args_);
  518. LeaseMgrFactory::instance().updateLease4(lease4);
  519. setSuccessResponse(handle, "IPv4 lease updated.");
  520. } catch (const std::exception& ex) {
  521. setErrorResponse(handle, ex.what());
  522. return (1);
  523. }
  524. return (0);
  525. }
  526. int
  527. LeaseCmdsImpl::lease6UpdateHandler(CalloutHandle& handle) {
  528. try {
  529. extractCommand(handle);
  530. // We need the lease to be specified.
  531. if (!cmd_args_) {
  532. isc_throw(isc::BadValue, "no parameters specified for lease6-update command");
  533. }
  534. // Get the parameters specified by the user first.
  535. ConstSrvConfigPtr config = CfgMgr::instance().getCurrentCfg();
  536. Lease6Ptr lease6;
  537. Lease6Parser parser;
  538. // The parser does sanity checks (if the address is in scope, if
  539. // subnet-id is valid, etc)
  540. lease6 = parser.parse(config, cmd_args_);
  541. LeaseMgrFactory::instance().updateLease6(lease6);
  542. setSuccessResponse(handle, "IPv6 lease updated.");
  543. } catch (const std::exception& ex) {
  544. setErrorResponse(handle, ex.what());
  545. return (1);
  546. }
  547. return (0);
  548. }
  549. int
  550. LeaseCmdsImpl::lease4WipeHandler(CalloutHandle& handle) {
  551. try {
  552. extractCommand(handle);
  553. // The subnet-id is a mandatory parameter.
  554. if (!cmd_args_) {
  555. isc_throw(isc::BadValue, "no parameters specified for lease4-wipe command");
  556. }
  557. SimpleParser parser;
  558. SubnetID id = parser.getUint32(cmd_args_, "subnet-id");
  559. size_t num = LeaseMgrFactory::instance().wipeLeases4(id);
  560. stringstream tmp;
  561. tmp << "Deleted " << num << " IPv4 lease(s).";
  562. ConstElementPtr response = createAnswer(num ? CONTROL_RESULT_SUCCESS
  563. : CONTROL_RESULT_EMPTY, tmp.str());
  564. setResponse(handle, response);
  565. } catch (const std::exception& ex) {
  566. setErrorResponse(handle, ex.what());
  567. return (1);
  568. }
  569. return (0);
  570. }
  571. int
  572. LeaseCmdsImpl::lease6WipeHandler(CalloutHandle& handle) {
  573. try {
  574. extractCommand(handle);
  575. // The subnet-id is a mandatory parameter.
  576. if (!cmd_args_) {
  577. isc_throw(isc::BadValue, "no parameters specified for lease6-wipe command");
  578. }
  579. SimpleParser parser;
  580. SubnetID id = parser.getUint32(cmd_args_, "subnet-id");
  581. size_t num = LeaseMgrFactory::instance().wipeLeases6(id);
  582. stringstream tmp;
  583. tmp << "Deleted " << num << " IPv6 lease(s).";
  584. ConstElementPtr response = createAnswer(num ? CONTROL_RESULT_SUCCESS
  585. : CONTROL_RESULT_EMPTY, tmp.str());
  586. setResponse(handle, response);
  587. } catch (const std::exception& ex) {
  588. setErrorResponse(handle, ex.what());
  589. return (1);
  590. }
  591. return (0);
  592. }
  593. int
  594. LeaseCmds::leaseAddHandler(CalloutHandle& handle) {
  595. return(impl_->leaseAddHandler(handle));
  596. }
  597. int
  598. LeaseCmds::leaseGetHandler(CalloutHandle& handle) {
  599. return(impl_->leaseGetHandler(handle));
  600. }
  601. int
  602. LeaseCmds::lease4DelHandler(CalloutHandle& handle) {
  603. return(impl_->lease4DelHandler(handle));
  604. }
  605. int
  606. LeaseCmds::lease6DelHandler(CalloutHandle& handle) {
  607. return(impl_->lease6DelHandler(handle));
  608. }
  609. int
  610. LeaseCmds::lease4UpdateHandler(CalloutHandle& handle) {
  611. return(impl_->lease4UpdateHandler(handle));
  612. }
  613. int
  614. LeaseCmds::lease6UpdateHandler(CalloutHandle& handle) {
  615. return(impl_->lease6UpdateHandler(handle));
  616. }
  617. int
  618. LeaseCmds::lease4WipeHandler(CalloutHandle& handle) {
  619. return(impl_->lease4WipeHandler(handle));
  620. }
  621. int
  622. LeaseCmds::lease6WipeHandler(CalloutHandle& handle) {
  623. return(impl_->lease6WipeHandler(handle));
  624. }
  625. LeaseCmds::LeaseCmds()
  626. :impl_(new LeaseCmdsImpl()) {
  627. }
  628. };
  629. };