68c51867fa6d5b9408050f42f1715f5a398a9977
[vpp.git] / extras / vom / vom / igmp_listen.cpp
1 /*
2  * Copyright (c) 2018 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include "vom/igmp_listen.hpp"
17 #include "vom/igmp_listen_cmds.hpp"
18 #include "vom/singular_db_funcs.hpp"
19
20 namespace VOM {
21 singular_db<igmp_listen::key_t, igmp_listen> igmp_listen::m_db;
22
23 igmp_listen::event_handler igmp_listen::m_evh;
24
25 /**
26  * Construct a new object matching the desried state
27  */
28 igmp_listen::igmp_listen(const igmp_binding& igmp_bind,
29                          const boost::asio::ip::address& gaddr,
30                          const igmp_listen::src_addrs_t& saddrs)
31   : m_igmp_bind(igmp_bind.singular())
32   , m_gaddr(gaddr)
33   , m_saddrs(saddrs)
34   , m_listen(true, rc_t::NOOP)
35 {
36 }
37
38 igmp_listen::igmp_listen(const igmp_listen& o)
39   : m_igmp_bind(o.m_igmp_bind)
40   , m_gaddr(o.m_gaddr)
41   , m_saddrs(o.m_saddrs)
42   , m_listen(o.m_listen)
43 {
44 }
45
46 igmp_listen::~igmp_listen()
47 {
48   sweep();
49
50   // not in the DB anymore.
51   m_db.release(key(), this);
52 }
53
54 bool
55 igmp_listen::operator==(const igmp_listen& l) const
56 {
57   return ((m_gaddr == l.m_gaddr) && (*m_igmp_bind == *l.m_igmp_bind) &&
58           (m_saddrs == l.m_saddrs));
59 }
60
61 const igmp_listen::key_t
62 igmp_listen::key() const
63 {
64   return (make_pair(m_igmp_bind->itf()->key(), m_gaddr));
65 }
66
67 void
68 igmp_listen::sweep()
69 {
70   if (m_listen) {
71     HW::enqueue(new igmp_listen_cmds::unlisten_cmd(
72       m_listen, m_igmp_bind->itf()->handle(), m_gaddr));
73   }
74   HW::write();
75 }
76
77 void
78 igmp_listen::replay()
79 {
80   if (m_listen) {
81     HW::enqueue(new igmp_listen_cmds::listen_cmd(
82       m_listen, m_igmp_bind->itf()->handle(), m_gaddr, m_saddrs));
83   }
84 }
85
86 std::string
87 igmp_listen::to_string() const
88 {
89   auto addr = m_saddrs.cbegin();
90
91   std::ostringstream s;
92   s << "igmp-listen:[" << m_igmp_bind->to_string() << " group:" << m_gaddr
93     << " src-addrs: [";
94   while (addr != m_saddrs.cend()) {
95     s << " " << *addr;
96     ++addr;
97   }
98   s << " ] " << m_listen.to_string() << "]";
99
100   return (s.str());
101 }
102
103 void
104 igmp_listen::update(const igmp_listen& desired)
105 {
106   /*
107    * no updates for the listen. chaning the interface or the group addr is a
108    * change to the key, hence a new object
109    */
110   if (!m_listen) {
111     HW::enqueue(new igmp_listen_cmds::listen_cmd(
112       m_listen, m_igmp_bind->itf()->handle(), m_gaddr, m_saddrs));
113   }
114 }
115
116 std::shared_ptr<igmp_listen>
117 igmp_listen::find_or_add(const igmp_listen& temp)
118 {
119   return (m_db.find_or_add(temp.key(), temp));
120 }
121
122 std::shared_ptr<igmp_listen>
123 igmp_listen::find(const key_t& k)
124 {
125   return (m_db.find(k));
126 }
127
128 std::shared_ptr<igmp_listen>
129 igmp_listen::singular() const
130 {
131   return find_or_add(*this);
132 }
133
134 void
135 igmp_listen::dump(std::ostream& os)
136 {
137   db_dump(m_db, os);
138 }
139
140 igmp_listen::event_handler::event_handler()
141 {
142   OM::register_listener(this);
143   inspect::register_handler({ "igmp-listen" }, "igmp listener", this);
144 }
145
146 void
147 igmp_listen::event_handler::handle_replay()
148 {
149   m_db.replay();
150 }
151
152 void
153 igmp_listen::event_handler::handle_populate(const client_db::key_t& key)
154 {
155   /**
156    * This is done while populating the interfaces
157    */
158 }
159
160 dependency_t
161 igmp_listen::event_handler::order() const
162 {
163   return (dependency_t::ENTRY);
164 }
165
166 void
167 igmp_listen::event_handler::show(std::ostream& os)
168 {
169   db_dump(m_db, os);
170 }
171 }
172
173 /*
174  * fd.io coding-style-patch-verification: ON
175  *
176  * Local Variables:
177  * eval: (c-set-style "mozilla")
178  * End:
179  */