]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2834] Initial code of relayed v6 opts
authorPiotrek Zadroga <piotrek@isc.org>
Fri, 12 May 2023 09:51:10 +0000 (11:51 +0200)
committerPiotrek Zadroga <piotrek@isc.org>
Fri, 26 May 2023 13:20:31 +0000 (15:20 +0200)
src/bin/perfdhcp/command_options.cc
src/bin/perfdhcp/command_options.h

index 9e5e1dc8a697ea4ab92dbafb1d507ae3a24d5fa7..945b88a28e30a2afe9a7f74e2a8da908ca7f22e9 100644 (file)
@@ -163,6 +163,10 @@ CommandOptions::reset() {
         single_thread_mode_ = false;
     }
     scenario_ = Scenario::BASIC;
+    for (uint8_t i = 1; i <= RELAY_OPTIONS_MAX_ENCAPSULATION ; i++) {
+        OptionCollection option_collection;
+        relay_opts_[i] = option_collection;
+    }
 }
 
 bool
@@ -212,6 +216,7 @@ CommandOptions::parse(int argc, char** const argv, bool print_cmd_line) {
 }
 
 const int LONG_OPT_SCENARIO = 300;
+const int LONG_OPT_RELAY_1_OPTION = 400;
 
 bool
 CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) {
@@ -232,6 +237,7 @@ CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) {
 
     struct option long_options[] = {
         {"scenario", required_argument, 0, LONG_OPT_SCENARIO},
+        {"o1r", required_argument, 0, LONG_OPT_RELAY_1_OPTION},
         {0,          0,                 0, 0}
     };
 
@@ -593,6 +599,55 @@ CommandOptions::initialize(int argc, char** argv, bool print_cmd_line) {
             }
             break;
         }
+
+        case LONG_OPT_RELAY_1_OPTION: {
+            // for now this is only available for v6
+            // and must be used together with -A option.
+            check((ipversion_ != 6),
+                  "-6 must be explicitly specified before --o1r is used.");
+            check((ipversion_ == 4),
+                  "--o1r can be only used with -6 option");
+            if (v6_relay_encapsulation_level_ != 1) {
+                isc_throw(isc::InvalidParameter, "-A must be explicitly specified before --o1r is used.");
+            }
+
+            // custom option (expected format: code,hexstring)
+            std::string opt_text = std::string(optarg);
+            size_t coma_loc = opt_text.find(',');
+            check(coma_loc == std::string::npos,
+                  "--o1r option must provide option code, a coma and hexstring for"
+                  " the option content, e.g. --o1r60,646f63736973 for sending option"
+                  " 60 (class-id) with the value 'docsis'");
+            int code = 0;
+
+            // Try to parse the option code
+            try {
+                code = boost::lexical_cast<int>(opt_text.substr(0,coma_loc));
+                check(code <= 0, "Option code can't be negative");
+            } catch (const boost::bad_lexical_cast&) {
+                isc_throw(InvalidParameter, "Invalid option code specified for "
+                                            "--o1r option, expected format: --o1r<integer>,<hexstring>");
+            }
+
+            // Now try to interpret the hexstring
+            opt_text = opt_text.substr(coma_loc + 1);
+            std::vector<uint8_t> bin;
+            try {
+                isc::util::encode::decodeHex(opt_text, bin);
+            } catch (const BadValue& e) {
+                isc_throw(InvalidParameter, "Error during encoding option --o1r:"
+                                                << e.what());
+            }
+
+            // Create and remember the option.
+            OptionPtr option(new Option(Option::V6, code, bin));
+            // For now, only 1 level of encapsulation is allowed for relay options,
+            // thus 1 key is hardcoded below. But in future, if needed, level of
+            // encapsulation of relay option could be taken from command option.
+            auto relay_1_opts = relay_opts_.find(1);
+            relay_1_opts->second.insert(make_pair(code, option));
+            break;
+        }
         default:
             isc_throw(isc::InvalidParameter, "wrong command line option");
         }
index ab8ea5a40f3314b248f8fd2e1b7d934e6d521537..9515e7e3089993028df7072841f052d6387287aa 100644 (file)
@@ -41,6 +41,9 @@ public:
     /// @brief A vector holding MAC addresses.
     typedef std::vector<std::vector<uint8_t> > MacAddrsVector;
 
+    /// @brief Maximum allowed level of encapsulation of added relay options.
+    const static uint8_t RELAY_OPTIONS_MAX_ENCAPSULATION = 1;
+
     /// \brief A class encapsulating the type of lease being requested from the
     /// server.
     ///
@@ -751,6 +754,9 @@ private:
     /// @brief Extra options to be sent in each packet.
     isc::dhcp::OptionCollection extra_opts_;
 
+    /// @brief Map of relay options to be sent per encapsulation level.
+    std::map<uint8_t, isc::dhcp::OptionCollection> relay_opts_;
+
     /// @brief Option to switch modes between single-threaded and multi-threaded.
     bool single_thread_mode_;