Line data Source code
1 : /*
2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
3 : */
4 :
5 : #ifndef vnsw_agent_dns_proto_hpp
6 : #define vnsw_agent_dns_proto_hpp
7 :
8 : #include "pkt/proto.h"
9 : #include "services/dns_handler.h"
10 : #include "vnc_cfg_types.h"
11 :
12 : class VmInterface;
13 : class IFMapNode;
14 :
15 : class DnsProto : public Proto {
16 :
17 : static const Ip4Address ip4_unspec_;
18 : static const Ip6Address ip6_unspec_;
19 :
20 : public:
21 : static const uint32_t kDnsDefaultTtl = 84600;
22 : static const uint32_t kDnsDefaultSlistInterval =
23 : 10 * 60 * 1000; //10 minutes
24 :
25 : enum InterTaskMessage {
26 : DNS_NONE,
27 : DNS_DEFAULT_RESPONSE,
28 : DNS_BIND_RESPONSE,
29 : DNS_TIMER_EXPIRED,
30 : DNS_XMPP_SEND_UPDATE,
31 : DNS_XMPP_SEND_UPDATE_ALL,
32 : DNS_XMPP_UPDATE_RESPONSE,
33 : DNS_XMPP_MODIFY_VDNS,
34 : };
35 :
36 : struct DnsIpc : InterTaskMsg {
37 0 : DnsIpc(uint8_t *msg, std::size_t len, uint16_t id,
38 : DnsHandler *h, InterTaskMessage cmd)
39 0 : : InterTaskMsg(cmd), resp(msg), length(len), xid(id), handler(h) {}
40 :
41 0 : virtual ~DnsIpc() {
42 0 : if (resp)
43 0 : delete [] resp;
44 0 : if (handler)
45 0 : delete handler;
46 0 : }
47 :
48 : uint8_t *resp;
49 : std::size_t length;
50 : uint16_t xid;
51 : DnsHandler *handler;
52 : };
53 :
54 : struct DnsUpdateIpc : InterTaskMsg {
55 0 : DnsUpdateIpc(const VmInterface *vm, const std::string &nvdns,
56 : const std::string &ovdns, const std::string &dom,
57 : uint32_t ttl_value, bool is_floating)
58 0 : : InterTaskMsg(DNS_XMPP_MODIFY_VDNS), xmpp_data(NULL),
59 0 : itf(vm), floatingIp(is_floating), ttl(ttl_value),
60 0 : new_vdns(nvdns), old_vdns(ovdns), new_domain(dom) {}
61 :
62 60 : DnsUpdateIpc(DnsAgentXmpp::XmppType type, DnsUpdateData *data,
63 : const VmInterface *vm, bool floating)
64 120 : : InterTaskMsg(DNS_NONE), xmpp_data(data), itf(vm),
65 60 : floatingIp(floating), ttl(0) {
66 60 : if (type == DnsAgentXmpp::Update)
67 60 : cmd = DNS_XMPP_SEND_UPDATE;
68 0 : else if (type == DnsAgentXmpp::UpdateResponse)
69 0 : cmd = DNS_XMPP_UPDATE_RESPONSE;
70 60 : }
71 :
72 120 : virtual ~DnsUpdateIpc() {
73 60 : if (xmpp_data)
74 0 : delete xmpp_data;
75 120 : }
76 :
77 : DnsUpdateData *xmpp_data;
78 : const VmInterface *itf;
79 : bool floatingIp;
80 : uint32_t ttl;
81 : std::string new_vdns;
82 : std::string old_vdns;
83 : std::string new_domain;
84 : };
85 :
86 : struct UpdateCompare {
87 0 : bool operator() (DnsUpdateIpc *const &lhs, DnsUpdateIpc *const &rhs) const {
88 0 : if (!lhs || !rhs)
89 0 : return lhs < rhs;
90 0 : if (lhs->itf != rhs->itf)
91 0 : return lhs->itf < rhs->itf;
92 0 : if (lhs->floatingIp != rhs->floatingIp)
93 0 : return lhs->floatingIp < rhs->floatingIp;
94 : DnsUpdateData::Compare tmp;
95 0 : return tmp(lhs->xmpp_data, rhs->xmpp_data);
96 : }
97 : };
98 :
99 : struct DnsUpdateAllIpc : InterTaskMsg {
100 0 : DnsUpdateAllIpc(AgentDnsXmppChannel *ch)
101 0 : : InterTaskMsg(DNS_XMPP_SEND_UPDATE_ALL), channel(ch) {}
102 :
103 : AgentDnsXmppChannel *channel;
104 : };
105 :
106 : struct DnsStats {
107 17 : DnsStats() { Reset(); }
108 42 : void Reset() {
109 42 : requests = resolved = retransmit_reqs = unsupported = fail = drop = 0;
110 42 : }
111 :
112 : uint32_t requests;
113 : uint32_t resolved;
114 : uint32_t retransmit_reqs;
115 : uint32_t unsupported;
116 : uint32_t fail;
117 : uint32_t drop;
118 : };
119 :
120 : struct DnsFipEntry {
121 : DnsFipEntry(const VnEntry *vn, const IpAddress &fip,
122 : const VmInterface *itf);
123 : virtual ~DnsFipEntry();
124 : bool IsLess(const DnsFipEntry *rhs) const;
125 : const VnEntry *vn_;
126 : IpAddress floating_ip_;
127 : const VmInterface *interface_;
128 : std::string vdns_name_;
129 : std::string fip_name_;
130 : };
131 :
132 : typedef boost::shared_ptr<DnsFipEntry> DnsFipEntryPtr;
133 :
134 : class DnsFipEntryCmp {
135 : public:
136 : bool operator()(const DnsFipEntryPtr &lhs, const DnsFipEntryPtr &rhs) const;
137 : };
138 : typedef std::set<DnsFipEntryPtr, DnsFipEntryCmp> DnsFipSet;
139 : typedef std::map<uint32_t, DnsHandler *> DnsBindQueryMap;
140 : typedef std::pair<uint32_t, DnsHandler *> DnsBindQueryPair;
141 : typedef std::set<DnsHandler::QueryKey> DnsVmRequestSet;
142 : typedef std::set<DnsUpdateIpc *, UpdateCompare> DnsUpdateSet;
143 : typedef std::map<uint32_t, std::string> IpVdnsMap;
144 : typedef std::pair<uint32_t, std::string> IpVdnsPair;
145 : typedef std::map<const VmInterface *, IpVdnsMap> VmDataMap;
146 : typedef std::pair<const VmInterface *, IpVdnsMap> VmDataPair;
147 : // Map of transaction id and BindServer Index
148 : typedef std::map<uint32_t, int16_t> DnsBindQueryIndexMap;
149 : typedef std::pair<uint32_t, int16_t> DnsBindQueryIndexPair;
150 : typedef std::vector<IpAddress> DefaultServerList;
151 :
152 : void ConfigInit();
153 : void Shutdown();
154 : void IoShutdown();
155 : DnsProto(Agent *agent, boost::asio::io_context &io);
156 : virtual ~DnsProto();
157 : ProtoHandler *AllocProtoHandler(boost::shared_ptr<PktInfo> info,
158 : boost::asio::io_context &io);
159 : bool SendUpdateDnsEntry(const VmInterface *vmitf, const std::string &name,
160 : const Ip4Address &ip, uint32_t plen,
161 : const Ip6Address &ip6, uint32_t plen6,
162 : const std::string &vdns_name,
163 : const autogen::VirtualDnsType &vdns_type,
164 : bool is_floating, bool is_delete);
165 : bool UpdateFloatingIp(const VmInterface *vmitf, const VnEntry *vn,
166 : const IpAddress &ip, bool is_deleted);
167 : void IpamNotify(IFMapNode *node);
168 : void VdnsNotify(IFMapNode *node);
169 : uint16_t GetTransId();
170 :
171 : void SendDnsIpc(uint8_t *pkt, std::size_t length);
172 : void SendDnsIpc(InterTaskMessage cmd, uint16_t xid,
173 : uint8_t *msg, DnsHandler *handler);
174 : void SendDnsUpdateIpc(DnsUpdateData *data, DnsAgentXmpp::XmppType type,
175 : const VmInterface *vm, bool floating);
176 : void SendDnsUpdateIpc(const VmInterface *vm, const std::string &new_vdns,
177 : const std::string &old_vdns,
178 : const std::string &new_dom,
179 : uint32_t ttl, bool is_floating);
180 : void SendDnsUpdateIpc(AgentDnsXmppChannel *channel);
181 :
182 0 : const DnsUpdateSet &update_set() const { return update_set_; }
183 0 : void AddUpdateRequest(DnsUpdateIpc *ipc) { update_set_.insert(ipc); }
184 0 : void DelUpdateRequest(DnsUpdateIpc *ipc) { update_set_.erase(ipc); }
185 60 : DnsUpdateIpc *FindUpdateRequest(DnsUpdateIpc *ipc) {
186 60 : DnsUpdateSet::iterator it = update_set_.find(ipc);
187 60 : if (it != update_set_.end())
188 0 : return *it;
189 60 : return NULL;
190 : }
191 :
192 : void AddDnsQuery(uint16_t xid, DnsHandler *handler);
193 : void DelDnsQuery(uint16_t xid);
194 : void DelDnsQueryHandler(DnsHandler *handler);
195 : bool IsDnsQueryInProgress(uint16_t xid);
196 : bool IsDnsHandlerInUse(DnsHandler *handler);
197 : DnsHandler *GetDnsQueryHandler(uint16_t xid);
198 : bool BuildDefaultServerList();
199 : DefaultServerList BuildDefaultServerListImpl();
200 : DefaultServerList GetDefaultServerList();
201 :
202 : void AddDnsQueryIndex(uint16_t xid, int16_t srv_idx);
203 : void DelDnsQueryIndex(uint16_t xid);
204 : int16_t GetDnsQueryServerIndex(uint16_t xid);
205 :
206 : void AddVmRequest(DnsHandler::QueryKey *key);
207 : void DelVmRequest(DnsHandler::QueryKey *key);
208 : bool IsVmRequestDuplicate(DnsHandler::QueryKey *key);
209 :
210 0 : uint32_t timeout() const { return timeout_; }
211 6 : void set_timeout(uint32_t timeout) { timeout_ = timeout; }
212 0 : uint32_t max_retries() const { return max_retries_; }
213 6 : void set_max_retries(uint32_t retries) { max_retries_ = retries; }
214 :
215 0 : void IncrStatsReq() { stats_.requests++; }
216 0 : void IncrStatsRetransmitReq() { stats_.retransmit_reqs++; }
217 0 : void IncrStatsRes() { stats_.resolved++; }
218 0 : void IncrStatsUnsupp() { stats_.unsupported++; }
219 0 : void IncrStatsFail() { stats_.fail++; }
220 0 : void IncrStatsDrop() { stats_.drop++; }
221 61 : const DnsStats &GetStats() const { return stats_; }
222 25 : void ClearStats() { stats_.Reset(); }
223 0 : const VmDataMap& all_vms() const { return all_vms_; }
224 4 : const DnsFipSet& fip_list() const { return fip_list_; }
225 :
226 : private:
227 : void InterfaceNotify(DBEntryBase *entry);
228 : void VnNotify(DBEntryBase *entry);
229 : void VrfNotify(DBEntryBase *entry);
230 : void ProcessNotify(std::string name, bool is_deleted, bool is_ipam);
231 : void CheckForUpdate(IpVdnsMap &ipvdns, const VmInterface *vmitf,
232 : const VnEntry *vn, const Ip4Address &ip,
233 : const Ip6Address &ip6, std::string &vdns_name,
234 : const autogen::VirtualDnsType &vdns_type);
235 : void CheckForFipUpdate(DnsFipEntry *entry, std::string &vdns_name,
236 : const autogen::VirtualDnsType &vdns_type);
237 : bool UpdateDnsEntry(const VmInterface *vmitf, const VnEntry *vn,
238 : const std::string &vm_name,
239 : const std::string &vdns_name,
240 : const Ip4Address &ip,
241 : const Ip6Address &ip6,
242 : bool is_floating, bool is_deleted);
243 : bool MoveVDnsEntry(const VmInterface *vmitf,
244 : std::string &new_vdns_name,
245 : std::string &old_vdns_name,
246 : const autogen::VirtualDnsType &vdns_type,
247 : bool is_floating);
248 : bool GetVdnsData(const VnEntry *vn, const Ip4Address &v4_addr,
249 : const Ip6Address &v6_addr, std::string &vdns_name,
250 : autogen::VirtualDnsType &vdns_type);
251 : bool GetFipName(const VmInterface *vmitf,
252 : const autogen::VirtualDnsType &vdns_type,
253 : const IpAddress &ip, std::string &fip_name) const;
254 :
255 : uint16_t xid_;
256 : DnsUpdateSet update_set_;
257 : DnsBindQueryMap dns_query_map_;
258 : DnsVmRequestSet curr_vm_requests_;
259 : DnsBindQueryIndexMap dns_query_index_map_;
260 : DefaultServerList def_server_list_;
261 : DnsStats stats_;
262 : uint32_t timeout_; // milli seconds
263 : uint32_t max_retries_;
264 : Timer *default_slist_timer_;
265 :
266 : VmDataMap all_vms_;
267 : DnsFipSet fip_list_;
268 : DBTableBase::ListenerId lid_;
269 : DBTableBase::ListenerId Vnlid_;
270 : DBTableBase::ListenerId vrf_table_listener_id_;
271 :
272 : DISALLOW_COPY_AND_ASSIGN(DnsProto);
273 : };
274 :
275 : #endif // vnsw_agent_dns_proto_hpp
|