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;
|
vlan_[i] = 0;
|
||||||
numVlanTags_ = 0;
|
numVlanTags_ = 0;
|
||||||
mac_ = 0;
|
mac_ = 0;
|
||||||
ip4_ = 0;
|
|
||||||
|
ip4_ = ip4Gateway_ = 0;
|
||||||
ip4PrefixLength_ = 0;
|
ip4PrefixLength_ = 0;
|
||||||
|
|
||||||
|
ip6_ = ip6Gateway_ = UInt128(0, 0);
|
||||||
|
ip6PrefixLength_ = 0;
|
||||||
|
|
||||||
clearKey();
|
clearKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,20 +95,33 @@ void Device::setIp4(quint32 address, int prefixLength, quint32 gateway)
|
|||||||
ip4Gateway_ = gateway;
|
ip4Gateway_ = gateway;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Device::setIp6(UInt128 address, int prefixLength, UInt128 gateway)
|
||||||
|
{
|
||||||
|
ip6_ = address;
|
||||||
|
ip6PrefixLength_ = prefixLength;
|
||||||
|
ip6Gateway_ = gateway;
|
||||||
|
}
|
||||||
|
|
||||||
void Device::getConfig(OstEmul::Device *deviceConfig)
|
void Device::getConfig(OstEmul::Device *deviceConfig)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < numVlanTags_; i++)
|
for (int i = 0; i < numVlanTags_; i++)
|
||||||
deviceConfig->add_vlan(vlan_[i]);
|
deviceConfig->add_vlan(vlan_[i]);
|
||||||
|
|
||||||
deviceConfig->set_mac(mac_);
|
deviceConfig->set_mac(mac_);
|
||||||
|
|
||||||
deviceConfig->set_ip4(ip4_);
|
deviceConfig->set_ip4(ip4_);
|
||||||
deviceConfig->set_ip4_prefix_length(ip4PrefixLength_);
|
deviceConfig->set_ip4_prefix_length(ip4PrefixLength_);
|
||||||
deviceConfig->set_ip4_default_gateway(ip4Gateway_);
|
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()
|
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 ?
|
.arg((vlan_[0] >> 16) != kVlanTpid ?
|
||||||
QString("0x%1-%2")
|
QString("0x%1-%2")
|
||||||
.arg(vlan_[0] >> 16, 4, kBaseHex, QChar('0'))
|
.arg(vlan_[0] >> 16, 4, kBaseHex, QChar('0'))
|
||||||
@ -131,7 +148,9 @@ QString Device::config()
|
|||||||
.arg(vlan_[3] & 0xFFFF))
|
.arg(vlan_[3] & 0xFFFF))
|
||||||
.arg(mac_, 12, kBaseHex, QChar('0'))
|
.arg(mac_, 12, kBaseHex, QChar('0'))
|
||||||
.arg(QHostAddress(ip4_).toString())
|
.arg(QHostAddress(ip4_).toString())
|
||||||
.arg(ip4PrefixLength_);
|
.arg(ip4PrefixLength_)
|
||||||
|
.arg(QHostAddress(ip6_.toArray()).toString())
|
||||||
|
.arg(ip6PrefixLength_);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceKey Device::key()
|
DeviceKey Device::key()
|
||||||
@ -234,6 +253,9 @@ void Device::resolveNeighbor(PacketBuffer *pktBuf)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x86dd: // IPv6
|
case 0x86dd: // IPv6
|
||||||
|
sendNeighborSolicit(pktBuf);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -591,6 +613,13 @@ void Device::receiveIcmp4(PacketBuffer *pktBuf)
|
|||||||
qDebug("Sent ICMP Echo Reply");
|
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)
|
bool operator<(const DeviceKey &a1, const DeviceKey &a2)
|
||||||
{
|
{
|
||||||
int i = 0;
|
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/emulproto.pb.h"
|
||||||
#include "../common/protocol.pb.h"
|
#include "../common/protocol.pb.h"
|
||||||
|
#include "../common/uint128.h"
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
@ -45,6 +46,7 @@ public:
|
|||||||
quint64 mac();
|
quint64 mac();
|
||||||
void setMac(quint64 mac);
|
void setMac(quint64 mac);
|
||||||
void setIp4(quint32 address, int prefixLength, quint32 gateway);
|
void setIp4(quint32 address, int prefixLength, quint32 gateway);
|
||||||
|
void setIp6(UInt128 address, int prefixLength, UInt128 gateway);
|
||||||
void getConfig(OstEmul::Device *deviceConfig);
|
void getConfig(OstEmul::Device *deviceConfig);
|
||||||
QString config();
|
QString config();
|
||||||
|
|
||||||
@ -73,6 +75,9 @@ private: // methods
|
|||||||
|
|
||||||
void receiveIcmp4(PacketBuffer *pktBuf);
|
void receiveIcmp4(PacketBuffer *pktBuf);
|
||||||
|
|
||||||
|
void sendNeighborSolicit(PacketBuffer *pktBuf);
|
||||||
|
void sendIp6(PacketBuffer *pktBuf);
|
||||||
|
|
||||||
private: // data
|
private: // data
|
||||||
static const int kMaxVlan = 4;
|
static const int kMaxVlan = 4;
|
||||||
|
|
||||||
@ -81,10 +86,15 @@ private: // data
|
|||||||
int numVlanTags_;
|
int numVlanTags_;
|
||||||
quint32 vlan_[kMaxVlan];
|
quint32 vlan_[kMaxVlan];
|
||||||
quint64 mac_;
|
quint64 mac_;
|
||||||
|
|
||||||
quint32 ip4_;
|
quint32 ip4_;
|
||||||
int ip4PrefixLength_;
|
int ip4PrefixLength_;
|
||||||
quint32 ip4Gateway_;
|
quint32 ip4Gateway_;
|
||||||
|
|
||||||
|
UInt128 ip6_;
|
||||||
|
int ip6PrefixLength_;
|
||||||
|
UInt128 ip6Gateway_;
|
||||||
|
|
||||||
DeviceKey key_;
|
DeviceKey key_;
|
||||||
|
|
||||||
QHash<quint32, quint64> arpTable;
|
QHash<quint32, quint64> arpTable;
|
||||||
|
@ -31,6 +31,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>
|
|||||||
#define __STDC_FORMAT_MACROS
|
#define __STDC_FORMAT_MACROS
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
inline UInt128 UINT128(OstEmul::Ip6Address x)
|
||||||
|
{
|
||||||
|
return UInt128(x.hi(), x.lo());
|
||||||
|
}
|
||||||
|
|
||||||
const quint64 kBcastMac = 0xffffffffffffULL;
|
const quint64 kBcastMac = 0xffffffffffffULL;
|
||||||
|
|
||||||
// XXX: Port owning DeviceManager already uses locks, so we don't use any
|
// 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);
|
enumerateDevices(myDeviceGroup, kDelete);
|
||||||
|
|
||||||
myDeviceGroup->CopyFrom(*deviceGroup);
|
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);
|
enumerateDevices(myDeviceGroup, kAdd);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -329,6 +345,7 @@ void DeviceManager::enumerateDevices(
|
|||||||
|
|
||||||
OstEmul::MacEmulation mac = deviceGroup->GetExtension(OstEmul::mac);
|
OstEmul::MacEmulation mac = deviceGroup->GetExtension(OstEmul::mac);
|
||||||
OstEmul::Ip4Emulation ip4 = deviceGroup->GetExtension(OstEmul::ip4);
|
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
|
* vlanCount[] stores the number of unique vlans at each tag level
|
||||||
@ -410,11 +427,15 @@ void DeviceManager::enumerateDevices(
|
|||||||
Device *device;
|
Device *device;
|
||||||
quint64 macAdd = k * mac.step();
|
quint64 macAdd = k * mac.step();
|
||||||
quint32 ip4Add = k * ip4.step();
|
quint32 ip4Add = k * ip4.step();
|
||||||
|
UInt128 ip6Add = UINT128(ip6.step()) * k;
|
||||||
|
|
||||||
dk.setMac(mac.address() + macAdd);
|
dk.setMac(mac.address() + macAdd);
|
||||||
dk.setIp4(ip4.address() + ip4Add,
|
dk.setIp4(ip4.address() + ip4Add,
|
||||||
ip4.prefix_length(),
|
ip4.prefix_length(),
|
||||||
ip4.default_gateway());
|
ip4.default_gateway());
|
||||||
|
dk.setIp6(UINT128(ip6.address()) + ip6Add,
|
||||||
|
ip6.prefix_length(),
|
||||||
|
UINT128(ip6.default_gateway()));
|
||||||
|
|
||||||
// TODO: fill in other pbDevice data
|
// 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
|
# we assume gateway is the lowest IP host address in the network
|
||||||
gateway = self.network.network_address + 1
|
gateway = self.network.network_address + 1
|
||||||
self.gateway = emul.Ip6Address()
|
self.gateway = emul.Ip6Address()
|
||||||
self.ip6.hi = int(gateway) >> 64
|
self.gateway.hi = int(gateway) >> 64
|
||||||
self.ip6.lo = int(gateway) & 0xffffffffffffffff
|
self.gateway.lo = int(gateway) & 0xffffffffffffffff
|
||||||
|
|
||||||
# ================================================================= #
|
# ================================================================= #
|
||||||
# ----------------------------------------------------------------- #
|
# ----------------------------------------------------------------- #
|
||||||
|
Loading…
Reference in New Issue
Block a user