int BpfLoader::loadBpfObject()

in katran/lib/BpfLoader.cpp [288:368]


int BpfLoader::loadBpfObject(
    ::bpf_object* obj,
    const std::string& name,
    const bpf_prog_type type) {
  if (bpfObjects_.find(name) != bpfObjects_.end()) {
    LOG(ERROR) << "collision while trying to load bpf object w/ name " << name;
    return closeBpfObject(obj);
  }

  ::bpf_program* prog;
  ::bpf_map* map;
  std::set<std::string> loadedProgNames;
  std::set<std::string> loadedMapNames;

  bpf_object__for_each_program(prog, obj) {
    if (progs_.find(::bpf_program__title(prog, false)) != progs_.end()) {
      LOG(ERROR) << "bpf's program name collision: "
                 << ::bpf_program__title(prog, false);
      return closeBpfObject(obj);
    }
    auto prog_type = normalizeBpfProgType(prog, type);
    ::bpf_program__set_type(prog, prog_type);
  }

  bpf_map__for_each(map, obj) {
    auto map_name = ::bpf_map__name(map);
    auto shared_map_iter = sharedMaps_.find(map_name);
    if (shared_map_iter != sharedMaps_.end()) {
      VLOG(2) << "shared map found w/ a name: " << shared_map_iter->first;
      if (::bpf_map__reuse_fd(map, shared_map_iter->second)) {
        LOG(ERROR) << "error while trying to set fd of shared map: "
                   << shared_map_iter->first;
        return closeBpfObject(obj);
      }
      continue;
    }
    if (maps_.find(map_name) != maps_.end()) {
      LOG(ERROR) << "bpf's map name collision";
      return closeBpfObject(obj);
    }
    auto inner_map_iter = innerMapsProto_.find(map_name);
    if (inner_map_iter != innerMapsProto_.end()) {
      VLOG(2) << "setting inner id for map-in-map: " << inner_map_iter->first
              << " fd: " << inner_map_iter->second;
      if (bpf_map__set_inner_map_fd(map, inner_map_iter->second)) {
        LOG(ERROR) << "error while trying to set inner map fd for: "
                   << inner_map_iter->first
                   << " fd: " << inner_map_iter->second;
        return closeBpfObject(obj);
      }
    }
  }

  if (::bpf_object__load(obj)) {
    LOG(ERROR) << "error while trying to load bpf object: " << name;
    return closeBpfObject(obj);
  }

  bpf_object__for_each_program(prog, obj) {
    auto prog_name = ::bpf_program__title(prog, false);
    VLOG(4) << "adding bpf program: " << prog_name
            << " with fd: " << ::bpf_program__fd(prog);
    progs_[prog_name] = ::bpf_program__fd(prog);
    loadedProgNames.insert(prog_name);
  }

  bpf_map__for_each(map, obj) {
    auto map_name = ::bpf_map__name(map);
    VLOG(4) << "adding bpf map: " << map_name
            << " with fd: " << ::bpf_map__fd(map);
    maps_[map_name] = bpf_map__fd(map);
    loadedMapNames.insert(map_name);
  }

  for (auto& progName : loadedProgNames) {
    currentMaps_[progName] = loadedMapNames;
  }

  bpfObjects_[name] = obj;
  return kSuccess;
}