Line data Source code
1 : /* 2 : * Copyright (c) 2016 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef vnsw_agent_bgp_as_service_hpp 6 : #define vnsw_agent_bgp_as_service_hpp 7 : 8 : #include "oper/interface_common.h" 9 : #include <base/index_allocator.h> 10 : #include "oper/global_system_config.h" 11 : 12 : //////////////////////////////////////////////////////////////////////////// 13 : // BGP as a service 14 : // 15 : // Function: 16 : // This service enables a VM tries to establish BGP session to control-node. 17 : // It will not try to connect to control-node directly as its unaware of same, 18 : // instaead it will try to connect to its gateway or DNS ip. 19 : // For example in subnet of 1.1.1.0/24, VM will try to connect on well defined 20 : // BGP port to either 1.1.1.1(=gw) or 1.1.1.2(=DNS). Agent sees this traffic and 21 : // creates a NAT. The calculation of NAT is done as follows: 22 : // Pkt from VM: 23 : // source: VM-SIP, destination: DIP(gw/dns), source port: VM-sport, destination 24 : // port: BGP-port. 25 : // 26 : // After NAT: 27 : // source: vrouter IP, destination: Control-node#1(if DIP was gw), 28 : // Control-node#2(if DIP was DNS), source port: BGP-router port, 29 : // destination port: BGP-port. 30 : // 31 : // This way VM is nat'd to control-node. 32 : // Config object(bgp-router) will provide BGP-router port used in NAT. 33 : // If new set of control-node changes flows should use new set given. 34 : // 35 : // What all is done here? 36 : // 37 : // 1) Reserves a set of BGP port which can potentially be used in 38 : // bgp-router object. 39 : // This is provided via contrail-vrouter-agent.conf and agents binds on 40 : // to these ports, so that host does not use it. 41 : // 42 : // 2) Handles config changes. ProcessConfig is called from VM interfaces. 43 : // It traverses the link from VM to bgp-as-a-service to get peer ip which VM 44 : // may use to peer with control-node. Note: This may be VM IP or additional 45 : // IP provisioned for bgp in VM. From bgp-as-a-service config of bgp-router 46 : // is taken and that will tell the port number used for source nat'ng VM 47 : // traffic to control-node. Lastly it takes VRF from bgp-router to validate 48 : // that bgp-router and bgp-as-a-service belong to same VRF as of VM. 49 : // 50 : // 3) Validators - Flow uses these to verify if a flow can be catgorised for 51 : // BGP service or not. It also provides the control-node to be used for 52 : // nat'ng based on VM destination. 53 : //////////////////////////////////////////////////////////////////////////// 54 : 55 : #define BGP_ROUTER_CONFIG_NAME "bgp-router" 56 : #define BGP_AS_SERVICE_CONFIG_NAME "bgp-as-a-service" 57 : #define BGPAAS_CONTROL_NODE_ZONE_CONFIG_NAME "bgpaas-control-node-zone" 58 : #define VALID_BGP_ROUTER_TYPE "bgpaas-client" 59 : 60 : extern SandeshTraceBufferPtr BgpAsAServiceTraceBuf; 61 : #define BGPASASERVICETRACE(obj, ...) \ 62 : do { \ 63 : BgpAsAService##obj::TraceMsg(BgpAsAServiceTraceBuf, __FILE__, __LINE__, __VA_ARGS__);\ 64 : } while (false) 65 : 66 : class IFMapNode; 67 : class BgpAsAService { 68 : public: 69 : static const uint32_t DefaultBgpPort = 179; 70 : typedef boost::function<void(boost::uuids::uuid, uint32_t)> ServiceDeleteCb; 71 : typedef boost::function<void(const boost::uuids::uuid &, uint32_t, 72 : const boost::uuids::uuid &, bool)> HealthCheckCb; 73 : 74 : //Keep the BGP as a service data here. 75 : //Is used when flow is established or when CN is updated. 76 : struct BgpAsAServiceEntry : public VmInterface::ListEntry { 77 : BgpAsAServiceEntry(); 78 : BgpAsAServiceEntry(const BgpAsAServiceEntry &rhs); 79 : BgpAsAServiceEntry(const IpAddress &local_peer_ip, 80 : uint32_t source_port, 81 : uint32_t dest_port, 82 : bool health_check_configured, 83 : const boost::uuids::uuid &health_check_uuid, 84 : bool is_shared, 85 : uint64_t hc_delay_usecs, 86 : uint64_t hc_timeout_usecs, 87 : uint32_t hc_retries, 88 : const std::string &primary_control_node_zone, 89 : const std::string &secondary_control_node_zone); 90 : ~BgpAsAServiceEntry(); 91 : bool operator == (const BgpAsAServiceEntry &rhs) const; 92 : bool operator() (const BgpAsAServiceEntry &lhs, 93 : const BgpAsAServiceEntry &rhs) const; 94 : bool IsLess(const BgpAsAServiceEntry *rhs) const; 95 : 96 0 : bool IsControlNodeZoneConfigured() const { 97 0 : return (primary_control_node_zone_.size() || 98 0 : secondary_control_node_zone_.size()); 99 : } 100 : 101 : bool installed_; 102 : IpAddress local_peer_ip_; 103 : uint32_t source_port_; 104 : mutable uint32_t dest_port_; 105 : mutable bool health_check_configured_; 106 : mutable boost::uuids::uuid health_check_uuid_; 107 : // the following three are used to invoke add / delete of health check 108 : // after health check audit is done 109 : mutable bool new_health_check_add_; 110 : mutable bool old_health_check_delete_; 111 : mutable boost::uuids::uuid old_health_check_uuid_; 112 : mutable uint64_t hc_delay_usecs_; 113 : mutable uint64_t hc_timeout_usecs_; 114 : mutable uint32_t hc_retries_; 115 : bool is_shared_; 116 : mutable std::string primary_control_node_zone_; 117 : mutable std::string secondary_control_node_zone_; 118 : mutable std::string primary_bgp_peer_; 119 : mutable std::string secondary_bgp_peer_; 120 : }; 121 : typedef std::set<BgpAsAServiceEntry, BgpAsAServiceEntry> BgpAsAServiceEntryList; 122 : typedef BgpAsAServiceEntryList::iterator BgpAsAServiceEntryListIterator; 123 : typedef BgpAsAServiceEntryList::const_iterator BgpAsAServiceEntryListConstIterator; 124 : 125 : struct BgpAsAServiceList { 126 : BgpAsAServiceList() : list_() { } 127 0 : BgpAsAServiceList(BgpAsAServiceEntryList list) : list_(list) { }; 128 0 : ~BgpAsAServiceList() { } 129 : void Insert(const BgpAsAServiceEntry *rhs); 130 : void Update(const BgpAsAServiceEntry *lhs, 131 : const BgpAsAServiceEntry *rhs); 132 : void Remove(BgpAsAServiceEntryListIterator &it); 133 : void Flush(); 134 : 135 : BgpAsAServiceEntryList list_; 136 : }; 137 : typedef std::map<boost::uuids::uuid, BgpAsAServiceList*> BgpAsAServiceEntryMap; 138 : typedef BgpAsAServiceEntryMap::iterator BgpAsAServiceEntryMapIterator; 139 : typedef BgpAsAServiceEntryMap::const_iterator BgpAsAServiceEntryMapConstIterator; 140 : 141 : typedef std::map<uint32_t, IndexVector<boost::uuids::uuid>* > BgpAsAServicePortMap; 142 : typedef BgpAsAServicePortMap::iterator BgpAsAServicePortMapIterator; 143 : typedef BgpAsAServicePortMap::const_iterator BgpAsAServicePortMapConstIterator; 144 : 145 : BgpAsAService(const Agent *agent); 146 : ~BgpAsAService(); 147 : 148 : bool IsBgpService(const VmInterface *vm_intf, 149 : const IpAddress &source_ip, 150 : const IpAddress &dest_ip) const; 151 : bool GetBgpRouterServiceDestination(const VmInterface *vm_intf, 152 : const IpAddress &source, 153 : const IpAddress &dest, 154 : IpAddress *nat_server, 155 : uint32_t *sport, uint32_t *dport) const; 156 : bool GetBgpHealthCheck(const VmInterface *vm_intf, 157 : boost::uuids::uuid *health_check_uuid) const; 158 : size_t AllocateBgpVmiServicePortIndex(const uint32_t sport, 159 : const boost::uuids::uuid vm_uuid); 160 : void FreeBgpVmiServicePortIndex(const uint32_t sport); 161 : uint32_t AddBgpVmiServicePortIndex(const uint32_t source_port, 162 : const boost::uuids::uuid vm_uuid); 163 : void ProcessConfig(const std::string &vrf_name, 164 : std::list<IFMapNode *> &bgp_router_node_list, 165 : std::list<IFMapNode *> &bgp_as_service_node_list, 166 : const boost::uuids::uuid &vmi_uuid); 167 : void DeleteVmInterface(const boost::uuids::uuid &vmi_uuid); 168 : const BgpAsAService::BgpAsAServiceEntryMap &bgp_as_a_service_map() const; 169 : const BgpAsAService::BgpAsAServicePortMap &bgp_as_a_service_port_map() const; 170 3 : void RegisterServiceDeleteCb(ServiceDeleteCb callback) { 171 3 : service_delete_cb_list_.push_back(callback); 172 3 : } 173 3 : void RegisterHealthCheckCb(HealthCheckCb callback) { 174 3 : health_check_cb_list_.push_back(callback); 175 3 : } 176 : 177 32 : bool IsConfigured() { 178 32 : if (bgp_as_a_service_entry_map_.size()) { 179 16 : return true; 180 : } else { 181 16 : return false; 182 : } 183 : } 184 : BGPaaServiceParameters::BGPaaServicePortRangePair 185 0 : bgp_as_a_service_port_range() const { 186 0 : return std::make_pair(bgp_as_a_service_parameters_.port_start, 187 0 : bgp_as_a_service_parameters_.port_end); 188 : } 189 : void UpdateBgpAsAServiceSessionInfo(); 190 : 191 : private: 192 : void StartHealthCheck(const boost::uuids::uuid &vm_uuid, 193 : const BgpAsAServiceEntryList &list); 194 : void BuildBgpAsAServiceInfo(IFMapNode *bgp_as_a_service_node, 195 : std::list<IFMapNode *> &bgp_router_nodes, 196 : BgpAsAServiceEntryList &new_list, 197 : const std::string &vrf_name, 198 : const boost::uuids::uuid &vm_uuid); 199 : 200 : const Agent *agent_; 201 : BgpAsAServiceEntryMap bgp_as_a_service_entry_map_; 202 : BgpAsAServicePortMap bgp_as_a_service_port_map_; 203 : std::vector<ServiceDeleteCb> service_delete_cb_list_; 204 : std::vector<HealthCheckCb> health_check_cb_list_; 205 : BGPaaServiceParameters bgp_as_a_service_parameters_; 206 : DISALLOW_COPY_AND_ASSIGN(BgpAsAService); 207 : }; 208 : #endif