Kea  1.9.9-git
flex_option.h
Go to the documentation of this file.
1 // Copyright (C) 2019-2021 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 
7 #ifndef FLEX_OPTION_H
8 #define FLEX_OPTION_H
9 
10 #include <cc/data.h>
11 #include <dhcp/libdhcp++.h>
12 #include <dhcp/option.h>
13 #include <dhcp/option_definition.h>
14 #include <dhcp/std_option_defs.h>
15 #include <eval/evaluate.h>
16 #include <eval/token.h>
17 #include <util/strutil.h>
18 
19 #include <boost/algorithm/string/split.hpp>
20 #include <boost/algorithm/string/classification.hpp>
21 
22 #include <map>
23 #include <string>
24 
25 namespace isc {
26 namespace flex_option {
27 
35 public:
36 
43  enum Action {
45  ADD,
48  };
49 
53  class OptionConfig {
54  public:
59  OptionConfig(uint16_t code, isc::dhcp::OptionDefinitionPtr def);
60 
62  virtual ~OptionConfig();
63 
67  uint16_t getCode() const {
68  return (code_);
69  }
70 
75  return (def_);
76  }
77 
81  void setAction(Action action) {
82  action_ = action;
83  }
84 
88  Action getAction() const {
89  return (action_);
90  }
91 
95  void setText(const std::string& text) {
96  text_ = text;
97  };
98 
102  const std::string& getText() const {
103  return (text_);
104  }
105 
109  void setExpr(const isc::dhcp::ExpressionPtr& expr) {
110  expr_ = expr;
111  }
112 
117  return (expr_);
118  }
119 
120  private:
122  uint16_t code_;
123 
127 
129  Action action_;
130 
132  std::string text_;
133 
136  };
137 
139  typedef boost::shared_ptr<OptionConfig> OptionConfigPtr;
140 
142  typedef std::map<uint16_t, OptionConfigPtr> OptionConfigMap;
143 
145  FlexOptionImpl();
146 
148  ~FlexOptionImpl();
149 
153  const OptionConfigMap& getOptionConfigMap() const {
154  return (option_config_map_);
155  }
156 
162 
169  template <typename PktType>
171  PktType query, PktType response) {
172  for (auto pair : getOptionConfigMap()) {
173  const OptionConfigPtr& opt_cfg = pair.second;
174  std::string value;
176  isc::dhcp::OptionPtr opt = response->getOption(opt_cfg->getCode());
177  isc::dhcp::OptionDefinitionPtr def = opt_cfg->getOptionDef();
178  switch (opt_cfg->getAction()) {
179  case NONE:
180  break;
181  case ADD:
182  // Don't add if option is already there.
183  if (opt) {
184  break;
185  }
186  value = isc::dhcp::evaluateString(*opt_cfg->getExpr(), *query);
187  // Do nothing is the expression evaluates to empty.
188  if (value.empty()) {
189  break;
190  }
191  // Set the value.
192  if (def) {
193  std::vector<std::string> split_vec =
194  isc::util::str::tokens(value, ",", true);
195  opt = def->optionFactory(universe, opt_cfg->getCode(),
196  split_vec);
197  } else {
198  buffer.assign(value.begin(), value.end());
199  opt.reset(new isc::dhcp::Option(universe,
200  opt_cfg->getCode(),
201  buffer));
202  }
203  // Add the option.
204  response->addOption(opt);
205  logAction(ADD, opt_cfg->getCode(), value);
206  break;
207  case SUPERSEDE:
208  // Do nothing is the expression evaluates to empty.
209  value = isc::dhcp::evaluateString(*opt_cfg->getExpr(), *query);
210  if (value.empty()) {
211  break;
212  }
213  // Remove the option if already there.
214  while (opt) {
215  response->delOption(opt_cfg->getCode());
216  opt = response->getOption(opt_cfg->getCode());
217  }
218  // Set the value.
219  if (def) {
220  std::vector<std::string> split_vec =
221  isc::util::str::tokens(value, ",", true);
222  opt = def->optionFactory(universe, opt_cfg->getCode(),
223  split_vec);
224  } else {
225  buffer.assign(value.begin(), value.end());
226  opt.reset(new isc::dhcp::Option(universe,
227  opt_cfg->getCode(),
228  buffer));
229  }
230  // Add the option.
231  response->addOption(opt);
232  logAction(SUPERSEDE, opt_cfg->getCode(), value);
233  break;
234  case REMOVE:
235  // Nothing to remove if option is not present.
236  if (!opt) {
237  break;
238  }
239  // Do nothing is the expression evaluates to false.
240  if (!isc::dhcp::evaluateBool(*opt_cfg->getExpr(), *query)) {
241  break;
242  }
243  // Remove the option.
244  while (opt) {
245  response->delOption(opt_cfg->getCode());
246  opt = response->getOption(opt_cfg->getCode());
247  }
248  logAction(REMOVE, opt_cfg->getCode(), "");
249  break;
250  }
251  }
252  }
253 
259  void logAction(Action action, uint16_t code, const std::string& value) const;
260 
261 protected:
265  OptionConfigMap& getMutableOptionConfigMap() {
266  return (option_config_map_);
267  }
268 
269 private:
271  OptionConfigMap option_config_map_;
272 
277  void parseOptionConfig(isc::data::ConstElementPtr option);
278 
279 };
280 
282 typedef boost::shared_ptr<FlexOptionImpl> FlexOptionImplPtr;
283 
284 } // end of namespace flex_option
285 } // end of namespace isc
286 #endif
boost::shared_ptr< FlexOptionImpl > FlexOptionImplPtr
The type of shared pointers to Flex Option implementations.
Definition: flex_option.h:282
std::map< uint16_t, OptionConfigPtr > OptionConfigMap
The type of the option config map.
Definition: flex_option.h:142
std::string evaluateString(const Expression &expr, Pkt &pkt)
Definition: evaluate.cc:28
OptionConfig(uint16_t code, isc::dhcp::OptionDefinitionPtr def)
Constructor.
Definition: flex_option.cc:77
void setAction(Action action)
Set action.
Definition: flex_option.h:81
boost::shared_ptr< Option > OptionPtr
Definition: option.h:36
Universe
defines option universe DHCPv4 or DHCPv6
Definition: option.h:82
void setText(const std::string &text)
Set textual expression.
Definition: flex_option.h:95
boost::shared_ptr< OptionConfig > OptionConfigPtr
The type of shared pointers to option config.
Definition: flex_option.h:139
void process(isc::dhcp::Option::Universe universe, PktType query, PktType response)
Process a query / response pair.
Definition: flex_option.h:170
std::vector< uint8_t > OptionBuffer
buffer types used in DHCP code.
Definition: option.h:24
const isc::dhcp::ExpressionPtr & getExpr() const
Get match expression.
Definition: flex_option.h:116
const std::string & getText() const
Get textual expression.
Definition: flex_option.h:102
void configure(isc::data::ConstElementPtr options)
Configure the Flex Option implementation.
Definition: flex_option.cc:93
uint16_t getCode() const
Return option code.
Definition: flex_option.h:67
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:23
Action getAction() const
Return action.
Definition: flex_option.h:88
void setExpr(const isc::dhcp::ExpressionPtr &expr)
Set match expression.
Definition: flex_option.h:109
vector< string > tokens(const std::string &text, const std::string &delim, bool escape)
Split String into Tokens.
Definition: strutil.cc:77
const OptionConfigMap & getOptionConfigMap() const
Get the option config map.
Definition: flex_option.h:153
isc::dhcp::OptionDefinitionPtr getOptionDef() const
Return option definition.
Definition: flex_option.h:74
bool evaluateBool(const Expression &expr, Pkt &pkt)
Evaluate a RPN expression for a v4 or v6 packet and return a true or false decision.
Definition: evaluate.cc:14
Defines the logger used by the top-level component of kea-dhcp-ddns.
OptionConfigMap & getMutableOptionConfigMap()
Get a mutable reference to the option config map.
Definition: flex_option.h:265
Flex Option implementation.
Definition: flex_option.h:34
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
void logAction(Action action, uint16_t code, const std::string &value) const
Log the action.
Definition: flex_option.cc:244
boost::shared_ptr< Expression > ExpressionPtr
Definition: token.h:30