mavtables  0.2.1
MAVLink router and firewall.
GoTo.cpp
Go to the documentation of this file.
1 // MAVLink router and firewall.
2 // Copyright (C) 2018 Michael R. Shannon <mrshannon.aerospace@gmail.com>
3 //
4 // This program is free software; you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation; either version 2 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
16 
17 
18 #include <memory>
19 #include <optional>
20 #include <ostream>
21 #include <typeinfo>
22 #include <utility>
23 
24 #include "Action.hpp"
25 #include "Chain.hpp"
26 #include "GoTo.hpp"
27 #include "MAVAddress.hpp"
28 #include "Packet.hpp"
29 #include "Rule.hpp"
30 
31 
32 /** Construct a goto rule given a chain to delegate to, without a priority.
33  *
34  * A goto rule is used to delegate the decision on whether to accept or reject
35  * a packet/address combination to another filter \ref Chain. If this called
36  * chain does not make a decision then the default action should be taken.
37  *
38  * \param chain The chain to delegate decisions of whether to accept or reject
39  * a packet/address combination to. nullptr is not valid.
40  * \param condition The condition used to determine the rule matches a
41  * particular packet/address combination given to the \ref action method.
42  * The default is {} which indicates the rule matches any packet/address
43  * combination.
44  * \throws std::invalid_argument if the given pointer is null.
45  * \sa action
46  */
48  std::shared_ptr<Chain> chain, std::optional<If> condition)
49  : Rule(std::move(condition)), chain_(std::move(chain))
50 {
51  if (chain_ == nullptr)
52  {
53  throw std::invalid_argument("Given chain pointer is null.");
54  }
55 }
56 
57 
58 /** Construct a goto rule given a chain to delegate to, with a priority.
59  *
60  * A goto rule is used to delegate the decision on whether to accept or reject
61  * a packet/address combination to another filter \ref Chain. If this called
62  * chain does not make a decision then the default action should be taken.
63  *
64  * \param chain The chain to delegate decisions of whether to accept or reject
65  * a packet/address combination to. nullptr is not valid.
66  * \param priority The priority to accept packets with. A higher number is
67  * more important and will be routed first.
68  * \param condition The condition used to determine the rule matches a
69  * particular packet/address combination given to the \ref action method.
70  * The default is {} which indicates the rule matches any packet/address
71  * combination.
72  * \throws std::invalid_argument if the given pointer is null.
73  * \sa action
74  */
76  std::shared_ptr<Chain> chain, int priority,
77  std::optional<If> condition)
78  : Rule(std::move(condition)), chain_(std::move(chain)), priority_(priority)
79 {
80  if (chain_ == nullptr)
81  {
82  throw std::invalid_argument("Given chain pointer is null.");
83  }
84 }
85 
86 
87 /** \copydoc Rule::print_(std::ostream &os)const
88  *
89  * Prints `"goto <Chain Name> <If Statement>"` or `"goto <Chain Name> with
90  * priority <If Statement> with priority <priority>"` if the priority is
91  * given.
92  */
93 std::ostream &GoTo::print_(std::ostream &os) const
94 {
95  os << "goto " << chain_->name();
96 
97  if (priority_)
98  {
99  os << " with priority " << priority_.value();
100  }
101 
102  if (condition_)
103  {
104  os << " " << condition_.value();
105  }
106 
107  return os;
108 }
109 
110 
111 /** \copydoc Rule::action(const Packet&,const MAVAddress&)const
112  *
113  * The GoTo class delegates the action choice to the contained \ref Chain. %If
114  * the \ref Chain decides on the continue action this method will return the
115  * default instead since final decision for a \ref GoTo should be with the
116  * contained \ref Chain or with the default action. In other words, once a
117  * GoTo rule matches, no further rule in the chain should ever be ran,
118  * regardless of the contained chain.
119  */
121  const Packet &packet, const MAVAddress &address) const
122 {
123  if (!condition_ || condition_->check(packet, address))
124  {
125  auto result = chain_->action(packet, address);
126 
127  if (priority_)
128  {
129  // Only has an effect if the action is accept and does not already
130  // have a priority.
131  result.priority(priority_.value());
132  }
133 
134  // Rewrite continue actions into default actions.
135  if (result.action() == Action::CONTINUE)
136  {
137  return Action::make_default();
138  }
139 
140  return result;
141  }
142 
143  return Action::make_continue();
144 }
145 
146 
147 std::unique_ptr<Rule> GoTo::clone() const
148 {
149  if (priority_)
150  {
151  return std::make_unique<GoTo>(chain_, priority_.value(), condition_);
152  }
153 
154  return std::make_unique<GoTo>(chain_, condition_);
155 }
156 
157 
158 /** \copydoc Rule::operator==(const Rule &) const
159  *
160  * Compares the chain and priority (if set) associated with the rule as well.
161  */
162 bool GoTo::operator==(const Rule &other) const
163 {
164  return typeid(*this) == typeid(other) &&
165  chain_ == static_cast<const GoTo &>(other).chain_ &&
166  priority_ == static_cast<const GoTo &>(other).priority_ &&
167  condition_ == static_cast<const GoTo &>(other).condition_;
168 }
169 
170 
171 /** \copydoc Rule::operator!=(const Rule &) const
172  *
173  * Compares the chain and priority (if set) associated with the rule as well.
174  */
175 bool GoTo::operator!=(const Rule &other) const
176 {
177  return typeid(*this) != typeid(other) ||
178  chain_ != static_cast<const GoTo &>(other).chain_ ||
179  priority_ != static_cast<const GoTo &>(other).priority_ ||
180  condition_ != static_cast<const GoTo &>(other).condition_;
181 }
Continue evaluating rules.
Definition: Action.hpp:39
virtual bool operator==(const Rule &other) const
Definition: GoTo.cpp:162
STL namespace.
virtual Action action(const Packet &packet, const MAVAddress &address) const
Definition: GoTo.cpp:120
static Action make_continue()
Definition: Action.cpp:126
virtual std::unique_ptr< Rule > clone() const
Definition: GoTo.cpp:147
static Action make_default()
Definition: Action.cpp:140
Definition: Rule.hpp:38
virtual std::ostream & print_(std::ostream &os) const
Definition: GoTo.cpp:93
std::optional< If > condition_
Definition: Rule.hpp:91
Definition: GoTo.hpp:44
GoTo(std::shared_ptr< Chain > chain, std::optional< If > condition={})
Definition: GoTo.cpp:47
virtual bool operator!=(const Rule &other) const
Definition: GoTo.cpp:175