NetworkInterface NetworkInterface::for_address(const IpAddress& addr) { auto map = NetworkInterface::get_interfaces_map(); for (const auto& nic : map) { if (nic.second.supports_ip()) { auto size = nic.second.get_address_list().size(); for (AddressList::size_type i = 0; i < size; ++i) { if (nic.second.get_address(i) == addr) { return nic.second; } } } } throw NetException("NetworkInterface for address " + addr.to_string() + " not found"); }
/** * Function Description: * @brief adds a decap tunnel to ASIC_DB * * Arguments: * @param[in] type - type of tunnel * @param[in] dst_ip - destination ip address to decap * @param[in] src_ip - source ip address to decap * @param[in] dscp - dscp mode (uniform/pipe) * @param[in] ecn - ecn mode (copy_from_outer/standard) * @param[in] ttl - ttl mode (uniform/pipe) * * Return Values: * @return true on success and false if there's an error */ bool TunnelDecapOrch::addDecapTunnel(string key, string type, IpAddresses dst_ip, IpAddress src_ip, string dscp, string ecn, string ttl) { SWSS_LOG_ENTER(); sai_status_t status; // adding tunnel attributes to array and writing to ASIC_DB sai_attribute_t attr; vector<sai_attribute_t> tunnel_attrs; sai_object_id_t overlayIfId; // create the overlay router interface to create a LOOPBACK type router interface (decap) vector<sai_attribute_t> overlay_intf_attrs; sai_attribute_t overlay_intf_attr; overlay_intf_attr.id = SAI_ROUTER_INTERFACE_ATTR_VIRTUAL_ROUTER_ID; overlay_intf_attr.value.oid = gVirtualRouterId; overlay_intf_attrs.push_back(overlay_intf_attr); overlay_intf_attr.id = SAI_ROUTER_INTERFACE_ATTR_TYPE; overlay_intf_attr.value.s32 = SAI_ROUTER_INTERFACE_TYPE_LOOPBACK; overlay_intf_attrs.push_back(overlay_intf_attr); status = sai_router_intfs_api->create_router_interface(&overlayIfId, gSwitchId, (uint32_t)overlay_intf_attrs.size(), overlay_intf_attrs.data()); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("Failed to create overlay router interface %d", status); return false; } SWSS_LOG_NOTICE("Create overlay loopback router interface oid:%lx", overlayIfId); // tunnel type (only ipinip for now) attr.id = SAI_TUNNEL_ATTR_TYPE; attr.value.s32 = SAI_TUNNEL_TYPE_IPINIP; tunnel_attrs.push_back(attr); attr.id = SAI_TUNNEL_ATTR_OVERLAY_INTERFACE; attr.value.oid = overlayIfId; tunnel_attrs.push_back(attr); attr.id = SAI_TUNNEL_ATTR_UNDERLAY_INTERFACE; attr.value.oid = gUnderlayIfId; tunnel_attrs.push_back(attr); // tunnel src ip attr.id = SAI_TUNNEL_ATTR_ENCAP_SRC_IP; copy(attr.value.ipaddr, src_ip.to_string()); tunnel_attrs.push_back(attr); // decap ecn mode (copy from outer/standard) attr.id = SAI_TUNNEL_ATTR_DECAP_ECN_MODE; if (ecn == "copy_from_outer") { attr.value.s32 = SAI_TUNNEL_DECAP_ECN_MODE_COPY_FROM_OUTER; } else if (ecn == "standard") { attr.value.s32 = SAI_TUNNEL_DECAP_ECN_MODE_STANDARD; } tunnel_attrs.push_back(attr); // ttl mode (uniform/pipe) attr.id = SAI_TUNNEL_ATTR_DECAP_TTL_MODE; if (ttl == "uniform") { attr.value.s32 = SAI_TUNNEL_TTL_MODE_UNIFORM_MODEL; } else if (ttl == "pipe") { attr.value.s32 = SAI_TUNNEL_TTL_MODE_PIPE_MODEL; } tunnel_attrs.push_back(attr); // dscp mode (uniform/pipe) attr.id = SAI_TUNNEL_ATTR_DECAP_DSCP_MODE; if (dscp == "uniform") { attr.value.s32 = SAI_TUNNEL_DSCP_MODE_UNIFORM_MODEL; } else if (dscp == "pipe") { attr.value.s32 = SAI_TUNNEL_DSCP_MODE_PIPE_MODEL; } tunnel_attrs.push_back(attr); // write attributes to ASIC_DB sai_object_id_t tunnel_id; status = sai_tunnel_api->create_tunnel(&tunnel_id, gSwitchId, (uint32_t)tunnel_attrs.size(), tunnel_attrs.data()); if (status != SAI_STATUS_SUCCESS) { SWSS_LOG_ERROR("Failed to create tunnel"); return false; } tunnelTable[key] = { tunnel_id, {} }; // TODO: // there should also be "business logic" for netbouncer in the "tunnel application" code, which is a different source file and daemon process // create a decap tunnel entry for every ip if (!addDecapTunnelTermEntries(key, dst_ip, tunnel_id)) { return false; } return true; }