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