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