Line data Source code
1 : /* 2 : * Copyright (c) 2015 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #include <uve/agent_uve_base.h> 6 : #include <ifmap/ifmap_node.h> 7 : #include <vnc_cfg_types.h> 8 : #include <base/address_util.h> 9 : #include <oper/operdb_init.h> 10 : #include <oper/route_common.h> 11 : #include <oper/route_leak.h> 12 : #include <oper/vrouter.h> 13 : #include <oper/vrf.h> 14 : #include <oper/config_manager.h> 15 : #include <sandesh/sandesh_trace.h> 16 : #include <vrouter/stats_collector/agent_stats_collector.h> 17 : #include <init/agent_param.h> 18 : 19 0 : VRouterSubnet::VRouterSubnet(const std::string& ip, uint8_t prefix_len) { 20 0 : boost::system::error_code ec; 21 0 : ip_prefix = IpAddress::from_string(ip, ec); 22 0 : plen = prefix_len; 23 0 : } 24 : 25 0 : bool VRouterSubnet::operator==(const VRouterSubnet& rhs) const { 26 0 : if (plen != rhs.plen) { 27 0 : return false; 28 : } 29 0 : if (ip_prefix != rhs.ip_prefix) { 30 0 : return false; 31 : } 32 0 : return true; 33 : } 34 : 35 0 : bool VRouterSubnet::IsLess(const VRouterSubnet *rhs) const { 36 0 : if (ip_prefix != rhs->ip_prefix) { 37 0 : return ip_prefix < rhs->ip_prefix; 38 : } 39 0 : return (plen < rhs->plen); 40 : } 41 : 42 0 : bool VRouterSubnet::operator() (const VRouterSubnet &lhs, 43 : const VRouterSubnet &rhs) const { 44 0 : return lhs.IsLess(&rhs); 45 : } 46 : 47 2 : VRouter::VRouter(Agent *agent) : OperIFMapTable(agent) { 48 2 : } 49 : 50 4 : VRouter::~VRouter() { 51 4 : } 52 : 53 0 : void VRouter::Insert(const VRouterSubnet *rhs) { 54 0 : AddRoute(*rhs); 55 0 : subnet_list_.insert(*rhs); 56 0 : } 57 : 58 0 : void VRouter::Remove(VRouterSubnetSet::iterator &it) { 59 0 : DeleteRoute(*it); 60 0 : subnet_list_.erase(it); 61 0 : } 62 : 63 0 : void VRouter::ConfigDelete(IFMapNode *node) { 64 0 : return; 65 : } 66 : 67 0 : IFMapNode *VRouter::FindTarget(IFMapNode *node, std::string node_type) const { 68 0 : IFMapAgentTable *table = static_cast<IFMapAgentTable *>(node->table()); 69 0 : for (DBGraphVertex::adjacency_iterator it = node->begin(table->GetGraph()); 70 0 : it != node->end(table->GetGraph()); ++it) { 71 0 : IFMapNode *adj_node = static_cast<IFMapNode *>(it.operator->()); 72 0 : if (adj_node->table()->Typename() == node_type) 73 0 : return adj_node; 74 : } 75 0 : return NULL; 76 : } 77 : 78 2 : void VRouter::ClearSubnets() { 79 2 : if (SubnetCount() == 0) { 80 2 : return; 81 : } 82 0 : DeleteSubnetRoutes(); 83 0 : subnet_list_.clear(); 84 0 : agent()->oper_db()->route_leak_manager()->ReEvaluateRouteExports(); 85 : } 86 : 87 0 : void VRouter::ConfigAddChange(IFMapNode *node) { 88 : autogen::VirtualRouter *cfg = static_cast<autogen::VirtualRouter *> 89 0 : (node->GetObject()); 90 0 : VRouterSubnetSet new_subnet_list; 91 0 : if (node->IsDeleted()) { 92 0 : ClearSubnets(); 93 0 : return; 94 : } 95 : 96 : const std::vector<autogen::KeyValuePair> &tblengths = 97 0 : cfg->tracebuffer_length(); 98 : int new_buf_size; 99 0 : for (const auto& kv_pair : tblengths) { 100 : try { 101 0 : new_buf_size = boost::lexical_cast<int>(kv_pair.value); 102 0 : } catch (const boost::bad_lexical_cast& e) { 103 0 : continue; 104 0 : } 105 0 : if (new_buf_size <= 0) { 106 0 : continue; 107 : } 108 0 : SandeshTraceBufferResetSize(kv_pair.key, new_buf_size); 109 : } 110 : 111 0 : agent()->uve()->set_default_interval(cfg->agent_uve_default_interval()); 112 0 : agent()->uve()->set_incremental_interval( 113 0 : cfg->agent_uve_incremental_interval()); 114 0 : if (cfg->agent_stats_collector_interval() > 0) { 115 0 : agent()->stats_collector()->set_expiry_time( 116 0 : cfg->agent_stats_collector_interval()); 117 : } else { 118 0 : agent()->stats_collector()->set_expiry_time( 119 : agent()->params()->agent_stats_interval()); 120 : } 121 : 122 0 : name_ = node->name(); 123 0 : display_name_ = cfg->display_name(); 124 : IFMapNode *vr_ipam_link = agent()->config_manager()-> 125 0 : FindAdjacentIFMapNode(node, "virtual-router-network-ipam"); 126 : /* If the link is deleted, clear the subnets configured earlier */ 127 0 : if (!vr_ipam_link) { 128 0 : ClearSubnets(); 129 0 : return; 130 : } 131 : autogen::VirtualRouterNetworkIpam *vr_ipam = 132 : static_cast<autogen::VirtualRouterNetworkIpam *> 133 0 : (vr_ipam_link->GetObject()); 134 0 : const autogen::VirtualRouterNetworkIpamType &data = vr_ipam->data(); 135 : std::vector<autogen::SubnetType>::const_iterator it = 136 0 : data.subnet.begin(); 137 0 : while (it != data.subnet.end()) { 138 0 : VRouterSubnet subnet(it->ip_prefix, it->ip_prefix_len); 139 0 : new_subnet_list.insert(subnet); 140 0 : ++it; 141 : } 142 : 143 0 : if (new_subnet_list != subnet_list_) { 144 : bool changed = AuditList<VRouter, VRouterSubnetSet::iterator> 145 0 : (*this, subnet_list_.begin(), subnet_list_.end(), 146 : new_subnet_list.begin(), new_subnet_list.end()); 147 0 : if (changed) { 148 : agent()->oper_db()->route_leak_manager()-> 149 0 : ReEvaluateRouteExports(); 150 : } 151 : } 152 0 : } 153 : 154 0 : void VRouter::DeleteSubnetRoutes() { 155 0 : VRouterSubnetSet::iterator it = subnet_list_.begin(); 156 0 : while (it != subnet_list_.end()) { 157 0 : DeleteRoute(*it); 158 0 : ++it; 159 : } 160 0 : } 161 : 162 0 : void VRouter::AddRoute(const VRouterSubnet &subnet) { 163 0 : VrfEntry *vrf = agent()->fabric_vrf(); 164 : static_cast<InetUnicastAgentRouteTable *>(vrf-> 165 0 : GetInet4UnicastRouteTable())->AddVrouterSubnetRoute(subnet.ip_prefix, 166 0 : subnet.plen); 167 0 : } 168 : 169 0 : void VRouter::DeleteRoute(const VRouterSubnet &subnet) { 170 0 : VrfEntry *vrf = agent()->fabric_vrf(); 171 0 : if (subnet.ip_prefix.is_v4()) { 172 : static_cast<InetUnicastAgentRouteTable *>(vrf-> 173 0 : GetInet4UnicastRouteTable())->DeleteReq 174 0 : (agent()->fabric_rt_export_peer(), vrf->GetName(), 175 0 : subnet.ip_prefix, subnet.plen, NULL); 176 0 : } else if (subnet.ip_prefix.is_v6()) { 177 : static_cast<InetUnicastAgentRouteTable *>(vrf-> 178 0 : GetInet6UnicastRouteTable())->DeleteReq 179 0 : (agent()->fabric_rt_export_peer(), vrf->GetName(), 180 0 : subnet.ip_prefix, subnet.plen, NULL); 181 : } 182 0 : } 183 : 184 0 : void VRouter::ConfigManagerEnqueue(IFMapNode *node) { 185 0 : agent()->config_manager()->AddVirtualRouterNode(node); 186 0 : return; 187 : } 188 : 189 5 : bool VRouter::IsSubnetMember(const IpAddress &addr) const { 190 5 : bool v4 = false; 191 5 : if (addr.is_v4()) { 192 5 : v4 = true; 193 : } 194 5 : VRouterSubnetSet::iterator it = subnet_list_.begin(); 195 5 : while (it != subnet_list_.end()) { 196 0 : if (v4 && it->ip_prefix.is_v4()) { 197 0 : if (IsIp4SubnetMember(addr.to_v4(), it->ip_prefix.to_v4(), 198 0 : it->plen)) { 199 0 : return true; 200 : } 201 0 : } else if (!v4 && it->ip_prefix.is_v6()) { 202 0 : if (IsIp6SubnetMember(addr.to_v6(), it->ip_prefix.to_v6(), 203 0 : it->plen)) { 204 0 : return true; 205 : } 206 : } 207 0 : ++it; 208 : } 209 5 : return false; 210 : } 211 : 212 2 : void VRouter::Shutdown() { 213 2 : ClearSubnets(); 214 2 : } 215 : 216 : ///////////////////////////////////////////////////////////////////////////// 217 : // Introspect routines 218 : ///////////////////////////////////////////////////////////////////////////// 219 0 : void VRouter::FillSandeshInfo(VrouterInfoResp *resp) { 220 0 : resp->set_name(name_); 221 0 : resp->set_display_name(display_name_); 222 0 : vector<VnIpamData> list; 223 0 : VRouterSubnetSet::iterator it = subnet_list_.begin(); 224 0 : while (it != subnet_list_.end()) { 225 0 : VnIpamData item; 226 0 : item.set_ip_prefix(it->ip_prefix.to_string()); 227 0 : item.set_prefix_len(it->plen); 228 0 : list.push_back(item); 229 0 : ++it; 230 0 : } 231 0 : resp->set_subnet_list(list); 232 0 : } 233 : 234 0 : void VrouterInfoReq::HandleRequest() const { 235 0 : Agent *agent = Agent::GetInstance(); 236 0 : VRouter *vr = agent->oper_db()->vrouter(); 237 0 : VrouterInfoResp *resp = new VrouterInfoResp(); 238 0 : resp->set_context(context()); 239 0 : if (!vr) { 240 0 : resp->set_more(false); 241 0 : resp->Response(); 242 0 : return; 243 : } 244 0 : vr->FillSandeshInfo(resp); 245 0 : resp->set_more(false); 246 0 : resp->Response(); 247 0 : return; 248 : }