Device Emulation (contd.) - Implemented IPv6 device creation and deletion
This commit is contained in:
parent
ea68b42059
commit
aaf6dbcbf2
83
common/uint128.h
Normal file
83
common/uint128.h
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
Copyright (C) 2015 Srivats P.
|
||||
|
||||
This file is part of "Ostinato"
|
||||
|
||||
This is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#ifndef _UINT128_H
|
||||
#define _UINT128_H
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <qendian.h>
|
||||
|
||||
class UInt128
|
||||
{
|
||||
public:
|
||||
UInt128();
|
||||
UInt128(quint64 hi, quint64 lo);
|
||||
|
||||
quint8* toArray() const;
|
||||
|
||||
UInt128 operator+(const UInt128 &other);
|
||||
UInt128 operator*(const uint &other);
|
||||
|
||||
private:
|
||||
quint64 hi_;
|
||||
quint64 lo_;
|
||||
quint8 array_[16];
|
||||
};
|
||||
|
||||
inline UInt128::UInt128()
|
||||
{
|
||||
// Do nothing - value will be garbage like any other uint
|
||||
}
|
||||
|
||||
inline UInt128::UInt128(quint64 hi, quint64 lo)
|
||||
{
|
||||
hi_ = hi;
|
||||
lo_ = lo;
|
||||
}
|
||||
|
||||
inline quint8* UInt128::toArray() const
|
||||
{
|
||||
*(quint64*)(array_ + 0) = qToBigEndian<quint64>(hi_);
|
||||
*(quint64*)(array_ + 8) = qToBigEndian<quint64>(lo_);
|
||||
|
||||
return (quint8*)array_;
|
||||
}
|
||||
|
||||
inline UInt128 UInt128::operator+(const UInt128 &other)
|
||||
{
|
||||
UInt128 sum;
|
||||
|
||||
sum.lo_ = lo_ + other.lo_;
|
||||
sum.hi_ = hi_ + other.hi_ + (sum.lo_ < lo_);
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
inline UInt128 UInt128::operator*(const uint &other)
|
||||
{
|
||||
UInt128 product;
|
||||
|
||||
// FIXME
|
||||
product.hi_ = 0;
|
||||
product.lo_ = lo_ * other;
|
||||
|
||||
return product;
|
||||
}
|
||||
|
||||
#endif
|
@ -45,9 +45,13 @@ Device::Device(DeviceManager *deviceManager)
|
||||
vlan_[i] = 0;
|
||||
numVlanTags_ = 0;
|
||||
mac_ = 0;
|
||||
ip4_ = 0;
|
||||
|
||||
ip4_ = ip4Gateway_ = 0;
|
||||
ip4PrefixLength_ = 0;
|
||||
|
||||
ip6_ = ip6Gateway_ = UInt128(0, 0);
|
||||
ip6PrefixLength_ = 0;
|
||||
|
||||
clearKey();
|
||||
}
|
||||
|
||||
@ -91,20 +95,33 @@ void Device::setIp4(quint32 address, int prefixLength, quint32 gateway)
|
||||
ip4Gateway_ = gateway;
|
||||
}
|
||||
|
||||
void Device::setIp6(UInt128 address, int prefixLength, UInt128 gateway)
|
||||
{
|
||||
ip6_ = address;
|
||||
ip6PrefixLength_ = prefixLength;
|
||||
ip6Gateway_ = gateway;
|
||||
}
|
||||
|
||||
void Device::getConfig(OstEmul::Device *deviceConfig)
|
||||
{
|
||||
for (int i = 0; i < numVlanTags_; i++)
|
||||
deviceConfig->add_vlan(vlan_[i]);
|
||||
|
||||
deviceConfig->set_mac(mac_);
|
||||
|
||||
deviceConfig->set_ip4(ip4_);
|
||||
deviceConfig->set_ip4_prefix_length(ip4PrefixLength_);
|
||||
deviceConfig->set_ip4_default_gateway(ip4Gateway_);
|
||||
|
||||
#if 0 // FIXME
|
||||
deviceConfig->set_ip6(ip6_);
|
||||
deviceConfig->set_ip6_prefix_length(ip6PrefixLength_);
|
||||
deviceConfig->set_ip6_default_gateway(ip6Gateway_);
|
||||
#endif
|
||||
}
|
||||
|
||||
QString Device::config()
|
||||
{
|
||||
return QString("<vlans=%1/%2/%3/%4 mac=%5 ip4=%6/%7>")
|
||||
return QString("<vlans=%1/%2/%3/%4 mac=%5 ip4=%6/%7 ip6=%8/%9>")
|
||||
.arg((vlan_[0] >> 16) != kVlanTpid ?
|
||||
QString("0x%1-%2")
|
||||
.arg(vlan_[0] >> 16, 4, kBaseHex, QChar('0'))
|
||||
@ -131,7 +148,9 @@ QString Device::config()
|
||||
.arg(vlan_[3] & 0xFFFF))
|
||||
.arg(mac_, 12, kBaseHex, QChar('0'))
|
||||
.arg(QHostAddress(ip4_).toString())
|
||||
.arg(ip4PrefixLength_);
|
||||
.arg(ip4PrefixLength_)
|
||||
.arg(QHostAddress(ip6_.toArray()).toString())
|
||||
.arg(ip6PrefixLength_);
|
||||
}
|
||||
|
||||
DeviceKey Device::key()
|
||||
@ -234,6 +253,9 @@ void Device::resolveNeighbor(PacketBuffer *pktBuf)
|
||||
break;
|
||||
|
||||
case 0x86dd: // IPv6
|
||||
sendNeighborSolicit(pktBuf);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -591,6 +613,13 @@ void Device::receiveIcmp4(PacketBuffer *pktBuf)
|
||||
qDebug("Sent ICMP Echo Reply");
|
||||
}
|
||||
|
||||
// Send NS for the IPv6 packet in pktBuf
|
||||
// pktBuf points to start of IP header
|
||||
void Device::sendNeighborSolicit(PacketBuffer *pktBuf)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
bool operator<(const DeviceKey &a1, const DeviceKey &a2)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -22,6 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
|
||||
#include "../common/emulproto.pb.h"
|
||||
#include "../common/protocol.pb.h"
|
||||
#include "../common/uint128.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QHash>
|
||||
@ -45,6 +46,7 @@ public:
|
||||
quint64 mac();
|
||||
void setMac(quint64 mac);
|
||||
void setIp4(quint32 address, int prefixLength, quint32 gateway);
|
||||
void setIp6(UInt128 address, int prefixLength, UInt128 gateway);
|
||||
void getConfig(OstEmul::Device *deviceConfig);
|
||||
QString config();
|
||||
|
||||
@ -73,6 +75,9 @@ private: // methods
|
||||
|
||||
void receiveIcmp4(PacketBuffer *pktBuf);
|
||||
|
||||
void sendNeighborSolicit(PacketBuffer *pktBuf);
|
||||
void sendIp6(PacketBuffer *pktBuf);
|
||||
|
||||
private: // data
|
||||
static const int kMaxVlan = 4;
|
||||
|
||||
@ -81,10 +86,15 @@ private: // data
|
||||
int numVlanTags_;
|
||||
quint32 vlan_[kMaxVlan];
|
||||
quint64 mac_;
|
||||
|
||||
quint32 ip4_;
|
||||
int ip4PrefixLength_;
|
||||
quint32 ip4Gateway_;
|
||||
|
||||
UInt128 ip6_;
|
||||
int ip6PrefixLength_;
|
||||
UInt128 ip6Gateway_;
|
||||
|
||||
DeviceKey key_;
|
||||
|
||||
QHash<quint32, quint64> arpTable;
|
||||
|
@ -31,6 +31,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
#define __STDC_FORMAT_MACROS
|
||||
#include <inttypes.h>
|
||||
|
||||
inline UInt128 UINT128(OstEmul::Ip6Address x)
|
||||
{
|
||||
return UInt128(x.hi(), x.lo());
|
||||
}
|
||||
|
||||
const quint64 kBcastMac = 0xffffffffffffULL;
|
||||
|
||||
// XXX: Port owning DeviceManager already uses locks, so we don't use any
|
||||
@ -125,7 +130,18 @@ bool DeviceManager::modifyDeviceGroup(const OstProto::DeviceGroup *deviceGroup)
|
||||
}
|
||||
|
||||
enumerateDevices(myDeviceGroup, kDelete);
|
||||
|
||||
myDeviceGroup->CopyFrom(*deviceGroup);
|
||||
// If mac step is 0, silently override to 1 - otherwise we won't have
|
||||
// unique DeviceKeys
|
||||
if (myDeviceGroup->GetExtension(OstEmul::mac).step() == 0)
|
||||
myDeviceGroup->MutableExtension(OstEmul::mac)->set_step(1);
|
||||
// Default value for ip6 step should be 1 (not 0)
|
||||
if (myDeviceGroup->HasExtension(OstEmul::ip6)
|
||||
&& !myDeviceGroup->GetExtension(OstEmul::ip6).has_step())
|
||||
myDeviceGroup->MutableExtension(OstEmul::ip6)
|
||||
->mutable_step()->set_lo(1);
|
||||
|
||||
enumerateDevices(myDeviceGroup, kAdd);
|
||||
|
||||
return true;
|
||||
@ -329,6 +345,7 @@ void DeviceManager::enumerateDevices(
|
||||
|
||||
OstEmul::MacEmulation mac = deviceGroup->GetExtension(OstEmul::mac);
|
||||
OstEmul::Ip4Emulation ip4 = deviceGroup->GetExtension(OstEmul::ip4);
|
||||
OstEmul::Ip6Emulation ip6 = deviceGroup->GetExtension(OstEmul::ip6);
|
||||
|
||||
/*
|
||||
* vlanCount[] stores the number of unique vlans at each tag level
|
||||
@ -410,11 +427,15 @@ void DeviceManager::enumerateDevices(
|
||||
Device *device;
|
||||
quint64 macAdd = k * mac.step();
|
||||
quint32 ip4Add = k * ip4.step();
|
||||
UInt128 ip6Add = UINT128(ip6.step()) * k;
|
||||
|
||||
dk.setMac(mac.address() + macAdd);
|
||||
dk.setIp4(ip4.address() + ip4Add,
|
||||
ip4.prefix_length(),
|
||||
ip4.default_gateway());
|
||||
dk.setIp6(UINT128(ip6.address()) + ip6Add,
|
||||
ip6.prefix_length(),
|
||||
UINT128(ip6.default_gateway()));
|
||||
|
||||
// TODO: fill in other pbDevice data
|
||||
|
||||
|
@ -88,8 +88,8 @@ class ip6_address(ipaddress.IPv6Interface):
|
||||
# we assume gateway is the lowest IP host address in the network
|
||||
gateway = self.network.network_address + 1
|
||||
self.gateway = emul.Ip6Address()
|
||||
self.ip6.hi = int(gateway) >> 64
|
||||
self.ip6.lo = int(gateway) & 0xffffffffffffffff
|
||||
self.gateway.hi = int(gateway) >> 64
|
||||
self.gateway.lo = int(gateway) & 0xffffffffffffffff
|
||||
|
||||
# ================================================================= #
|
||||
# ----------------------------------------------------------------- #
|
||||
|
Loading…
Reference in New Issue
Block a user