shared_ptr<Interface> ThriftConfigApplier::updateInterface(
    const shared_ptr<Interface>& orig,
    const cfg::Interface* config,
    const Interface::Addresses& addrs) {
    CHECK_EQ(orig->getID(), config->intfID);

    cfg::NdpConfig ndp;
    if (config->__isset.ndp) {
        ndp = config->ndp;
    }
    auto name = getInterfaceName(config);
    auto mac = getInterfaceMac(config);
    auto mtu = config->__isset.mtu ? config->mtu : Interface::kDefaultMtu;
    if (orig->getRouterID() == RouterID(config->routerID) &&
            orig->getVlanID() == VlanID(config->vlanID) &&
            orig->getName() == name &&
            orig->getMac() == mac &&
            orig->getAddresses() == addrs &&
            orig->getNdpConfig() == ndp &&
            orig->getMtu() == mtu) {
        // No change
        return nullptr;
    }

    auto newIntf = orig->clone();
    newIntf->setRouterID(RouterID(config->routerID));
    newIntf->setVlanID(VlanID(config->vlanID));
    newIntf->setName(name);
    newIntf->setMac(mac);
    newIntf->setAddresses(addrs);
    newIntf->setNdpConfig(ndp);
    newIntf->setMtu(mtu);
    return newIntf;
}
shared_ptr<Port> ThriftConfigApplier::updatePort(const shared_ptr<Port>& orig,
        const cfg::Port* cfg) {
    CHECK_EQ(orig->getID(), cfg->logicalID);

    auto vlans = portVlans_[orig->getID()];
    if (cfg->state == orig->getState() &&
            VlanID(cfg->ingressVlan) == orig->getIngressVlan() &&
            vlans == orig->getVlans() &&
            cfg->speed == orig->getSpeed() &&
            (cfg->name.empty() || cfg->name == orig->getName())) {
        return nullptr;
    }

    auto newPort = orig->clone();
    newPort->setState(cfg->state);
    newPort->setIngressVlan(VlanID(cfg->ingressVlan));
    newPort->setVlans(vlans);
    newPort->setSpeed(cfg->speed);
    // If the port name isn't set in the config (it's optional),
    // leave it with the default value.
    if (!cfg->name.empty()) {
        newPort->setName(cfg->name);
    }
    return newPort;
}
Example #3
0
BcmRxPacket::BcmRxPacket(const opennsl_pkt_t* pkt)
  : unit_(pkt->unit) {
  // The BCM RX code always uses a single buffer.
  // As long as there is just a single buffer, we don't need to allocate
  // a separate array of opennsl_pkt_blk_t objects.
  CHECK_EQ(pkt->blk_count, 1);
  CHECK_EQ(pkt->pkt_data, &pkt->_pkt_data);

  // The BCM RX code always uses a single buffer.
  // Therefore we don't bother checking to see if we need to create a chain of
  // IOBufs rather than just one.
  CHECK_EQ(pkt->blk_count, 1);
  // The packet contains Ethernet FCS (frame check sequence) at the end before
  // interpacket gap, which we are not interested in.
  uint32_t length = std::max(pkt->pkt_len - 4, 0);
  buf_ = IOBuf::takeOwnership(
      pkt->pkt_data->data,             // void* buf
      length,
      freeRxBuf,                       // FreeFunction freeFn
      reinterpret_cast<void*>(unit_)); // void* userData

  // TODO(aeckert): fix sdk bug where the src_port is a signed 8-bit
  // int.  This causes issues when the logical port numbers exceed
  // 127. For now we work around the issue by casting to an 8-bit
  // unsigned port id, but we should fix this in the sdk.
  srcPort_ = PortID(static_cast<uint8_t>(pkt->src_port));
  srcVlan_ = VlanID(pkt->vlan);
  len_ = length;
}
Example #4
0
VlanFields VlanFields::fromFollyDynamic(const folly::dynamic& vlanJson) {
  VlanFields vlan(VlanID(vlanJson[kVlanId].asInt()),
      vlanJson[kVlanName].asString().toStdString());
  vlan.mtu = vlanJson[kVlanMtu].asInt();
  vlan.dhcpV4Relay = folly::IPAddressV4(
      vlanJson[kDhcpV4Relay].stringPiece());
  vlan.dhcpV6Relay = folly::IPAddressV6(
      vlanJson[kDhcpV6Relay].stringPiece());
  for (const auto& o: vlanJson[kDhcpV4RelayOverrides].items()) {
    vlan.dhcpRelayOverridesV4[MacAddress(o.first.asString().toStdString())] =
        folly::IPAddressV4(o.second.stringPiece());
  }
  for (const auto& o: vlanJson[kDhcpV6RelayOverrides].items()) {
    vlan.dhcpRelayOverridesV6[MacAddress(o.first.asString().toStdString())] =
        folly::IPAddressV6(o.second.stringPiece());
  }
  for (const auto& portInfo: vlanJson[kMemberPorts].items()) {
    vlan.ports.emplace(PortID(to<uint16_t>(portInfo.first.asString())),
          PortInfo::fromFollyDynamic(portInfo.second));
  }
  vlan.arpTable = ArpTable::fromFollyDynamic(vlanJson[kArpTable]);
  vlan.ndpTable = NdpTable::fromFollyDynamic(vlanJson[kNdpTable]);
  vlan.arpResponseTable = ArpResponseTable::fromFollyDynamic(
      vlanJson[kArpResponseTable]);
  vlan.ndpResponseTable = NdpResponseTable::fromFollyDynamic(
      vlanJson[kNdpResponseTable]);
  return vlan;
}
shared_ptr<Vlan> ThriftConfigApplier::createVlan(const cfg::Vlan* config) {
    const auto& ports = vlanPorts_[VlanID(config->id)];
    auto vlan = make_shared<Vlan>(config, ports);
    updateNeighborResponseTables(vlan.get(), config);
    updateDhcpOverrides(vlan.get(), config);
    return vlan;
}
Example #6
0
PortFields PortFields::fromFollyDynamic(const folly::dynamic& portJson) {
  PortFields port(PortID(portJson[kPortId].asInt()),
      portJson[kPortName].asString().toStdString());
  auto itr_state  = cfg::_PortState_NAMES_TO_VALUES.find(
      portJson[kPortState].asString().c_str());
  CHECK(itr_state != cfg::_PortState_NAMES_TO_VALUES.end());
  port.state = cfg::PortState(itr_state->second);
  port.ingressVlan = VlanID(portJson[kIngressVlan].asInt());
  auto itr_speed  = cfg::_PortSpeed_NAMES_TO_VALUES.find(
      portJson[kPortSpeed].asString().c_str());
  CHECK(itr_speed != cfg::_PortSpeed_NAMES_TO_VALUES.end());
  port.speed = cfg::PortSpeed(itr_speed->second);
  for (const auto& vlanInfo: portJson[kVlanMemberships].items()) {
    port.vlans.emplace(VlanID(to<uint32_t>(vlanInfo.first.asString())),
      VlanInfo::fromFollyDynamic(vlanInfo.second));
  }
  return port;
}
Example #7
0
SwitchStateFields
SwitchStateFields::fromFollyDynamic(const folly::dynamic& swJson) {
  SwitchStateFields switchState;
  switchState.interfaces = InterfaceMap::fromFollyDynamic(
        swJson[kInterfaces]);
  switchState.ports = PortMap::fromFollyDynamic(swJson[kPorts]);
  switchState.vlans = VlanMap::fromFollyDynamic(swJson[kVlans]);
  switchState.routeTables = RouteTableMap::fromFollyDynamic(
      swJson[kRouteTables]);
  switchState.acls = AclMap::fromFollyDynamic(swJson[kAcls]);
  switchState.defaultVlan = VlanID(swJson[kDefaultVlan].asInt());
  //TODO verify that created state here is internally consistent t4155406
  return switchState;
}
Example #8
0
InterfaceFields InterfaceFields::fromFollyDynamic(const folly::dynamic& json) {
  auto intfFields =
    InterfaceFields(InterfaceID(json[kIntfId].asInt()),
      RouterID(json[kRouterId].asInt()), VlanID(json[kVlanId].asInt()),
      json[kName].asString(), MacAddress(json[kMac].asString()));
  ThriftSerializerJson<cfg::NdpConfig> serializer;
  for (const auto& addr: json[kAddresses]) {
    auto cidr = IPAddress::createNetwork(addr.asString(),
          -1 /*use /32 for v4 and /128 for v6*/,
        false /*don't apply mask*/);
    intfFields.addrs[cidr.first] = cidr.second;
  }
  serializer.deserialize(toJson(json[kNdpConfig]),
      &intfFields.ndp);
  return intfFields;
}
shared_ptr<Interface> ThriftConfigApplier::createInterface(
    const cfg::Interface* config,
    const Interface::Addresses& addrs) {
    auto name = getInterfaceName(config);
    auto mac = getInterfaceMac(config);
    auto mtu = config->__isset.mtu ? config->mtu : Interface::kDefaultMtu;
    auto intf = make_shared<Interface>(InterfaceID(config->intfID),
                                       RouterID(config->routerID),
                                       VlanID(config->vlanID),
                                       name,
                                       mac,
                                       mtu);
    intf->setAddresses(addrs);
    if (config->__isset.ndp) {
        intf->setNdpConfig(config->ndp);
    }
    return intf;
}
Example #10
0
BcmRxPacket::BcmRxPacket(const opennsl_pkt_t* pkt)
  : unit_(pkt->unit) {
  // The BCM RX code always uses a single buffer.
  // As long as there is just a single buffer, we don't need to allocate
  // a separate array of opennsl_pkt_blk_t objects.
  CHECK_EQ(pkt->blk_count, 1);
  CHECK_EQ(pkt->pkt_data, &pkt->_pkt_data);

  // The BCM RX code always uses a single buffer.
  // Therefore we don't bother checking to see if we need to create a chain of
  // IOBufs rather than just one.
  CHECK_EQ(pkt->blk_count, 1);
  buf_ = IOBuf::takeOwnership(
      pkt->pkt_data->data,             // void* buf
      pkt->pkt_len,                    // uint32_t capacity
      freeRxBuf,                       // FreeFunction freeFn
      reinterpret_cast<void*>(unit_)); // void* userData
  srcPort_ = PortID(pkt->src_port);
  srcVlan_ = VlanID(pkt->vlan);
  len_ = pkt->pkt_len;
}
Example #11
0
BcmRxPacket::BcmRxPacket(const opennsl_pkt_t* pkt)
  : unit_(pkt->unit) {
  // The BCM RX code always uses a single buffer.
  // As long as there is just a single buffer, we don't need to allocate
  // a separate array of opennsl_pkt_blk_t objects.
  CHECK_EQ(pkt->blk_count, 1);
  CHECK_EQ(pkt->pkt_data, &pkt->_pkt_data);

  // The packet contains Ethernet FCS (frame check sequence) at the end before
  // interpacket gap, which we are not interested in.
  uint32_t length = std::max(pkt->pkt_len - 4, 0);
  buf_ = IOBuf::takeOwnership(
      pkt->pkt_data->data,             // void* buf
      length,
      freeRxBuf,                       // FreeFunction freeFn
      reinterpret_cast<void*>(unit_)); // void* userData

  srcPort_ = PortID(pkt->src_port);
  srcVlan_ = VlanID(pkt->vlan);
  len_ = length;
}
Example #12
0
SwitchStateFields
SwitchStateFields::fromFollyDynamic(const folly::dynamic& swJson) {
  SwitchStateFields switchState;
  switchState.interfaces = InterfaceMap::fromFollyDynamic(
        swJson[kInterfaces]);
  switchState.ports = PortMap::fromFollyDynamic(swJson[kPorts]);
  switchState.vlans = VlanMap::fromFollyDynamic(swJson[kVlans]);
  switchState.routeTables = RouteTableMap::fromFollyDynamic(
      swJson[kRouteTables]);
  switchState.acls = AclMap::fromFollyDynamic(swJson[kAcls]);
  if (swJson.count(kSflowCollectors) > 0) {
    switchState.sFlowCollectors = SflowCollectorMap::fromFollyDynamic(
      swJson[kSflowCollectors]);
  }
  switchState.defaultVlan = VlanID(swJson[kDefaultVlan].asInt());
  if (swJson.find(kControlPlane) != swJson.items().end()) {
    switchState.controlPlane = ControlPlane::fromFollyDynamic(
      swJson[kControlPlane]);
  }
  //TODO verify that created state here is internally consistent t4155406
  return switchState;
}
Example #13
0
uint32_t NeighborUpdater::flushEntry(VlanID vlan, IPAddress ip) {
  // clone caches_ so we don't need to hold the lock while flushing entries
  boost::container::flat_map<VlanID, std::shared_ptr<NeighborCaches>> caches;
  {
    std::lock_guard<std::mutex> g(cachesMutex_);
    caches = caches_;
  }

  uint32_t count{0};
  if (vlan == VlanID(0)) {
    for (auto it = caches.begin(); it != caches.end(); ++it) {
      if (flushEntryImpl(it->first, ip)) {
        ++count;
      }
    }
  } else {
    if (flushEntryImpl(vlan, ip)) {
      ++count;
    }
  }
  return count;
}
Example #14
0
Vlan::Vlan(const cfg::Vlan* config, uint32_t mtu, MemberPorts ports)
  : NodeBaseT(VlanID(config->id),
              config->name,
              mtu,
              (config->__isset.dhcpRelayAddressV4 ?
               IPAddressV4(config->dhcpRelayAddressV4) : IPAddressV4()),
              (config->__isset.dhcpRelayAddressV6 ?
               IPAddressV6(config->dhcpRelayAddressV6) : IPAddressV6()),
               std::move(ports)) {

  DhcpV4OverrideMap map4;
  for (const auto& o: config->dhcpRelayOverridesV4) {
    map4[MacAddress(o.first)] = folly::IPAddressV4(o.second);
  }
  setDhcpV4RelayOverrides(map4);

  DhcpV6OverrideMap map6;
  for (const auto& o: config->dhcpRelayOverridesV6) {
    map6[MacAddress(o.first)] = folly::IPAddressV6(o.second);
  }
  setDhcpV6RelayOverrides(map6);
}