From a83d9d67113dc75d21a68dba14891ed5e1bea7ec Mon Sep 17 00:00:00 2001 From: Neale Ranns Date: Wed, 19 Jun 2019 08:30:46 -0700 Subject: Initial Commit of VPP OPflex Renderer Change-Id: I6264537538ad2646cddfa404de38a6bbf3abaa35 Signed-off-by: Neale Ranns --- src/VppExtItfManager.cpp | 188 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 src/VppExtItfManager.cpp (limited to 'src/VppExtItfManager.cpp') diff --git a/src/VppExtItfManager.cpp b/src/VppExtItfManager.cpp new file mode 100644 index 0000000..eb8fa9b --- /dev/null +++ b/src/VppExtItfManager.cpp @@ -0,0 +1,188 @@ +/* -*- C++ -*-; c-basic-offset: 4; indent-tabs-mode: nil */ +/* + * Copyright (c) 2018 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "VppEndPointGroupManager.hpp" +#include "VppExtItfManager.hpp" +#include "VppLog.hpp" +#include "VppRouteManager.hpp" +#include "VppUtil.hpp" + +using namespace VOM; + +namespace VPP +{ +ExtItfManager::ExtItfManager(Runtime &runtime) + : m_runtime(runtime) +{ +} + +void +ExtItfManager::handle_update(const opflex::modb::URI &uri) +{ + OM::mark_n_sweep ms(uri.toString()); + const std::string &uuid = uri.toString(); + + boost::optional> ext_itf = + modelgbp::gbp::ExternalInterface::resolve( + m_runtime.agent.getFramework(), uri); + + if (!ext_itf) + { + VLOGD << "External-Interface; delete: " << uri; + return; + } + VLOGD << "External-Interface; update: " << uri; + + boost::optional> + op_bd = m_runtime.policy_manager().getBDForExternalInterface(uri); + + if (!op_bd) + { + VLOGE << "External-Interface; no ExternalBridgeDomain: " << uri; + return; + } + + boost::optional> op_rd = + m_runtime.policy_manager().getRDForExternalInterface(uri); + + if (!op_rd) + { + VLOGE << "External-Interface; no RouteDomain: " << uri; + return; + } + + uint32_t rd_id = m_runtime.id_gen.get( + modelgbp::gbp::RoutingDomain::CLASS_ID, op_rd.get()->getURI()); + + route_domain rd(rd_id); + OM::write(uuid, rd); + + uint32_t bd_id = m_runtime.id_gen.get(modelgbp::gbp::BridgeDomain::CLASS_ID, + op_bd.get()->getURI()); + + bridge_domain bd(bd_id, bridge_domain::learning_mode_t::OFF); + OM::write(uuid, bd); + + /* + * Create a BVI interface for the EPG and add it to the bridge-domain + */ + std::shared_ptr bvi = EndPointGroupManager::mk_bvi( + m_runtime, uuid, bd, rd, mac_from_modb(ext_itf.get()->getMac())); + + /* + * Add the mcast tunnels for flooding + */ + boost::optional maddr = + m_runtime.policy_manager().getBDMulticastIPForExternalInterface(uri); + boost::optional bd_vnid = + m_runtime.policy_manager().getBDVnidForExternalInterface(uri); + boost::optional rd_vnid = + m_runtime.policy_manager().getRDVnidForExternalInterface(uri); + + if (!(rd_vnid && bd_vnid && maddr)) + { + VLOGE << "External-Interface; no VNI/mcast-address: " << uri; + return; + } + + std::shared_ptr vt_mc = EndPointGroupManager::mk_mcast_tunnel( + m_runtime, uuid, bd_vnid.get(), maddr.get()); + + /* + * there's no leanring of EPs in an external BD + */ + gbp_bridge_domain gbd( + bd, *bvi, {}, vt_mc, gbp_bridge_domain::flags_t::DO_NOT_LEARN); + OM::write(uuid, gbd); + std::shared_ptr grd = + EndPointGroupManager::mk_gbp_rd(m_runtime, uuid, rd, rd_vnid.get()); + + /* + * the encap on the external-interface is a vlan ID + */ + boost::optional vlan_id = ext_itf.get()->getEncap(); + + if (vlan_id) + ; + + /* + * Add the /32 to the BVI + */ + boost::optional s_addr = ext_itf.get()->getAddress(); + + if (!s_addr) + { + VLOGI << "External-Interface; no prefix: " << uri; + return; + } + boost::asio::ip::address p_addr = + boost::asio::ip::address::from_string(s_addr.get()); + + l3_binding l3b(*bvi, {p_addr}); + OM::write(uuid, l3b); + + bridge_domain_arp_entry bae(bd, p_addr, bvi->l2_address().to_mac()); + OM::write(uuid, bae); + + opflexagent::PolicyManager::subnet_vector_t subnets; + + m_runtime.policy_manager().getSubnetsForExternalInterface(uri, subnets); + + for (auto sn : subnets) + { + if (!sn->getPrefixLen() || !sn->getAddress()) continue; + + route::prefix_t pfx(sn->getAddress().get(), sn->getPrefixLen().get()); + + route::ip_route ipr(rd, pfx, {route::path::special_t::DROP}); + OM::write(uuid, ipr); + } + + /* + * This BVI is the ExternalInterface + */ + gbp_ext_itf gei(*bvi, gbd, *grd); + OM::write(uuid, gei); + + /* + * Add any external networks + */ + boost::optional> ext_dom = + m_runtime.policy_manager().getExternalDomainForExternalInterface(uri); + + if (!ext_dom) + { + VLOGI << "External-Interface; no ExternalDomain: " << uri; + return; + } + + RouteManager::mk_ext_nets(m_runtime, rd, uri, ext_dom.get()); +} + +}; // namepsace VPP + +/* + * Local Variables: + * eval: (c-set-style "llvm.org") + * End: + */ -- cgit 1.2.3-korg