Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef vnsw_agent_metadata_proxy_h_ 6 : #define vnsw_agent_metadata_proxy_h_ 7 : 8 : #include <map> 9 : #include <mutex> 10 : 11 : #include "http/client/http_client.h" 12 : #include "http/http_session.h" 13 : #include "oper/vm_interface.h" 14 : 15 : class MetadataServer; 16 : class MetadataClient; 17 : 18 : class MetadataProxy { 19 : public: 20 : struct SessionData { 21 0 : SessionData(HttpConnection *c, bool conn_close) 22 0 : : conn(c), content_len(0), data_sent(0), 23 0 : close_req(conn_close), header_end(false) {} 24 : 25 : HttpConnection *conn; 26 : uint32_t content_len; 27 : uint32_t data_sent; 28 : bool close_req; 29 : bool header_end; 30 : }; 31 : 32 : struct MetadataStats { 33 7 : MetadataStats() { Reset(); } 34 13 : void Reset() { requests = responses = proxy_sessions = internal_errors = 0; } 35 : 36 : uint32_t requests; 37 : uint32_t responses; 38 : uint32_t proxy_sessions; 39 : uint32_t internal_errors; 40 : }; 41 : 42 : typedef std::map<HttpSession *, SessionData> SessionMap; 43 : typedef std::pair<HttpSession *, SessionData> SessionPair; 44 : typedef std::map<HttpConnection *, HttpSession *> ConnectionSessionMap; 45 : typedef std::pair<HttpConnection *, HttpSession *> ConnectionSessionPair; 46 : typedef boost::intrusive_ptr<HttpSession> HttpSessionPtr; 47 : 48 : MetadataProxy(ServicesModule *module, const std::string &secret); 49 : virtual ~MetadataProxy(); 50 : void CloseSessions(); 51 : void Shutdown(); 52 : 53 : void HandleMetadataRequest(HttpSession *session, const HttpRequest *request); 54 : void HandleMetadataResponse(HttpConnection *conn, HttpSessionPtr session, 55 : std::string &msg, boost::system::error_code &ec); 56 : 57 : void OnServerSessionEvent(HttpSession *session, TcpSession::Event event); 58 : void OnClientSessionEvent(HttpClientSession *session, TcpSession::Event event); 59 : 60 1744 : const MetadataStats &metadatastats() const { return metadata_stats_; } 61 6 : void ClearStats() { metadata_stats_.Reset(); } 62 : 63 : /// @brief Returns index of a network device that is specified by vhost_name 64 : /// @param vhost_name is a name of a network device 65 : /// @return integer index of a network device 66 : int VhostIndex(const std::string& vhost_name); 67 : 68 : /// @brief Adds an IP address specified in vhost_ll_ip to vhost0 interface 69 : /// inet6 addresses 70 : /// @param vhost_ll_ip is a new IP address for vhost0 interface 71 : /// @return true if address has been successfully bound to the 72 : /// interface and false otherwise 73 : bool NetlinkGetVhostIp(Ip6Address& vhost_ll_ip); 74 : 75 : /// @brief Adds a new neighbour (an arp entry) with given IP and MAC 76 : /// addresses 77 : /// @param nb_ip - the IP address of a neighbour 78 : /// @param via_mac - the MAC address of a neighbour 79 : void NetlinkAddVhostNb(const IpAddress& nb_ip, const MacAddress& via_mac); 80 : 81 : /// @brief Adds routes to internal addresses of VM's interfaces 82 : /// @param intf_addr - the internal IP address assigned to an interface 83 : /// (metadata IP) 84 : void NetlinkAddInterfaceRoute(const IpAddress& intf_addr); 85 : 86 : /// @brief Advertises routes to a given vm-interface via a given IPv6 87 : /// address. Routes are announced in the fabric VRF entry and in a given 88 : /// VRF entry. 89 : /// @param vm is a pointer to the vm interface 90 : /// @param ll_ip is an IPv6 address (prefix) to announce route to 91 : /// @param intf_vrf is a pointer to the VRF entry to which the 92 : /// vm interface belongs to 93 : void AdvertiseMetaDataLinkLocalRoutes(const VmInterface* vm, 94 : const Ip6Address& ll_ip, const VrfEntry* intf_vrf); 95 : 96 : /// @brief Deletes an announced earlier route to a vm interface via 97 : /// a given IPv6 address 98 : /// @param vm_intf is a pointer to the vm interface for which route 99 : /// should be deleted 100 : void DeleteMetaDataLinkLocalRoute(const VmInterface* vm_intf); 101 : 102 : /// @brief Returns an IPv6 address of the Metadata TF link local service 103 : /// @return Ip6Address structure containing the IPv6 address 104 : const Ip6Address& Ipv6ServiceAddress() const; 105 : 106 : /// @brief Initializes an HTTP server for IPv6 requests 107 : void InitializeHttp6Server(const VmInterface *vhost0); 108 : 109 : /// @brief Advertises the LL route to vhost0 interface in the fabric VRF 110 : /// instance 111 : void AdvertiseVhostRoute(); 112 : 113 : 114 : /// @brief Deletes the LL route to vhost0 interface in the fabric VRF 115 : /// instance 116 : void DeleteVhostRoute(); 117 : 118 : /// @brief A callback that is invoked each time when a VRF entry is 119 : /// modified: added, changed or deleted 120 : /// @param part is a pointer to a table partititon containing corresponding 121 : /// VRF entry 122 : /// @param e is a pointer to the modified VrfEntry 123 : void OnAVrfChange(DBTablePartBase *part, DBEntryBase *e); 124 : 125 : /// @brief A callback that is invoked each time when a route is modified 126 : /// in the fabric policy VRF inet4 unicast table. The callback is used 127 : /// to update IPv6 address of the metadata link local service. IPv6 address 128 : /// of the service is calculated as: FE80 + IPv4 address, e.g. for 129 : /// IPv4 169.254.169.254, the IPv6 address is FE80::A9FE:A9FE 130 : /// @param part is a pointer to a table partititon containing corresponding 131 : /// modified route 132 : /// @param e is a pointer to the modified InetUnicastRouteEntry 133 : void OnAFabricRouteChange(DBTablePartBase *part, DBEntryBase *e); 134 : 135 : /// @brief A callback which is invoked everytime any vm interface is 136 : /// changed. 137 : /// Handles deletion of routes associated with a deleted vm interface. 138 : /// @param part is a pointer to a table partititon containing corresponding 139 : /// vm interface 140 : /// @param e is a pointer to the vm interface 141 : void OnAnInterfaceChange(DBTablePartBase *part, DBEntryBase *e); 142 : 143 : /// @brief Registers callbacks to intercept Agent's events emerging when a 144 : /// VRF entry is modified or an Interface is modified 145 : void RegisterListeners(); 146 : 147 : /// @brief Unregisters all callbacks that were registered earlier to 148 : /// intercept Agent's events: MetadataProxy::OnAVrfChange, 149 : /// MetadataProxy::OnAFabricPolicyRouteChange, 150 : /// MetadataProxy::OnAnInterfaceChange 151 : void UnregisterListeners(); 152 : 153 : private: 154 : HttpConnection *GetProxyConnection(HttpSession *session, 155 : bool conn_close, 156 : std::string *nova_hostname); 157 : void CloseServerSession(HttpSession *session); 158 : void CloseClientSession(HttpConnection *conn); 159 : void ErrorClose(HttpSession *sesion, uint16_t error); 160 : 161 : ServicesModule *services_; 162 : std::string shared_secret_; 163 : 164 : /// @brief A pointer to a HTTP server listening on a IPv4 socket 165 : /// for Metadata requests from tenants / virtual machines 166 : MetadataServer *http_server_; 167 : 168 : /// @brief A pointer to a HTTP server listening on a IPv6 socket 169 : /// for Metadata requests from tenants / virtual machines 170 : MetadataServer *http_server6_; 171 : 172 : MetadataClient *http_client_; 173 : SessionMap metadata_sessions_; 174 : ConnectionSessionMap metadata_proxy_sessions_; 175 : MetadataStats metadata_stats_; 176 : 177 : /// @brief An IPv6 address on which Metadata6 link local service listens on. 178 : /// We use it instead of IPv4 compute IP. 179 : Ip6Address ipv6_service_address_; 180 : 181 : /// @brief an ID of a listener (callback) that acts when the VRF Table is 182 : /// modified 183 : DBTableBase::ListenerId vrf_table_notify_id_; 184 : 185 : /// @brief an ID of a listener (callback) that acts when a Fabric Policy 186 : /// VRF entry is modified 187 : DBTableBase::ListenerId fabric_notify_id_; 188 : 189 : /// @brief an ID of a listener (callback) that acts when an InterfaceTable 190 : ///entry is modified 191 : DBTableBase::ListenerId intf_table_notify_id_; 192 : 193 : /// @brief A correspondence table between a name of a vm interface, which 194 : /// requests a data from the service and the vm interface link local IPv6 195 : /// address. The table is needed to obtain a link local address of vm 196 : /// interface in the MetadataProxy::DeleteMetaDataLinkLocalRoute function. 197 : std::map<std::string, Ip6Address> ll_ipv6_addresses_; 198 : 199 : /// @brief A mutex which prevents simultaneous access to 200 : /// MetadataProxy::ll_ipv6_addresses_ table and member functions: 201 : /// MetadataProxy::DeleteMetaDataLinkLocalRoute, 202 : /// MetadataProxy::AdvertiseMetaDataLinkLocalRoutes 203 : std::mutex ll_ipv6_addr_mutex_; 204 : 205 : DISALLOW_COPY_AND_ASSIGN(MetadataProxy); 206 : }; 207 : 208 : #endif // vnsw_agent_metadata_proxy_h_