mavtables  0.2.1
MAVLink router and firewall.
Call.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 "Call.hpp"
26 #include "Chain.hpp"
27 #include "MAVAddress.hpp"
28 #include "Packet.hpp"
29 #include "Rule.hpp"
30 
31 
32 /** Construct a call rule given a chain to delegate to, without a priority.
33  *
34  * A call 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 rule evaluation should continue in the
37  * calling chain.
38  *
39  * \param chain The chain to delegate decisions of whether to accept or reject
40  * a packet/address combination to. nullptr is not valid.
41  * \param condition The condition used to determine the rule matches a
42  * particular packet/address combination given to the \ref action method.
43  * The default is {} which indicates the rule matches any packet/address
44  * combination.
45  * \throws std::invalid_argument if the given \p chain pointer is null.
46  * \sa action
47  */
49  std::shared_ptr<Chain> chain, std::optional<If> condition)
50  : Rule(std::move(condition)), chain_(std::move(chain))
51 {
52  if (chain_ == nullptr)
53  {
54  throw std::invalid_argument("Given chain pointer is null.");
55  }
56 }
57 
58 
59 /** Construct a call rule given a chain to delegate to, with a priority.
60  *
61  * A call rule is used to delegate the decision on whether to accept or reject
62  * a packet/address combination to another filter \ref Chain.
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 `"call <Chain Name> <If Statement>"` or `"call <Chain Name> with
90  * priority <If Statement> with priority <priority>"` if the priority is
91  * given.
92  */
93 std::ostream &Call::print_(std::ostream &os) const
94 {
95  os << "call " << 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  * %If the condition has not been set or it matches the given packet/address
114  * combination then the choice of \ref Action will be delegated to the
115  * contained \ref Chain.
116  *
117  * %If the result from the chain is an accept \ref Action object and no
118  * priority has been set on it but this \ref Rule has a priority then the
119  * priority will be set.
120  */
122  const Packet &packet, const MAVAddress &address) const
123 {
124  if (!condition_ || condition_->check(packet, address))
125  {
126  auto result = chain_->action(packet, address);
127 
128  if (priority_)
129  {
130  // Only has an effect if the action is accept and does not already
131  // have a priority.
132  result.priority(priority_.value());
133  }
134 
135  return result;
136  }
137 
138  return Action::make_continue();
139 }
140 
141 
142 std::unique_ptr<Rule> Call::clone() const
143 {
144  if (priority_)
145  {
146  return std::make_unique<Call>(chain_, priority_.value(), condition_);
147  }
148 
149  return std::make_unique<Call>(chain_, condition_);
150 }
151 
152 
153 /** \copydoc Rule::operator==(const Rule&)const
154  *
155  * Compares the chain and priority (if set) associated with the rule as well.
156  */
157 bool Call::operator==(const Rule &other) const
158 {
159  return typeid(*this) == typeid(other) &&
160  chain_ == static_cast<const Call &>(other).chain_ &&
161  priority_ == static_cast<const Call &>(other).priority_ &&
162  condition_ == static_cast<const Call &>(other).condition_;
163 }
164 
165 
166 /** \copydoc Rule::operator!=(const Rule&)const
167  *
168  * Compares the chain and priority (if set) associated with the rule as well.
169  */
170 bool Call::operator!=(const Rule &other) const
171 {
172  return typeid(*this) != typeid(other) ||
173  chain_ != static_cast<const Call &>(other).chain_ ||
174  priority_ != static_cast<const Call &>(other).priority_ ||
175  condition_ != static_cast<const Call &>(other).condition_;
176 }
Definition: Call.hpp:43
STL namespace.
virtual bool operator!=(const Rule &other) const
Definition: Call.cpp:170
static Action make_continue()
Definition: Action.cpp:126
Definition: Rule.hpp:38
Call(std::shared_ptr< Chain > chain, std::optional< If > condition={})
Definition: Call.cpp:48
std::optional< If > condition_
Definition: Rule.hpp:91
virtual Action action(const Packet &packet, const MAVAddress &address) const
Definition: Call.cpp:121
virtual std::unique_ptr< Rule > clone() const
Definition: Call.cpp:142
virtual bool operator==(const Rule &other) const
Definition: Call.cpp:157
virtual std::ostream & print_(std::ostream &os) const
Definition: Call.cpp:93