--- Begin Message ---
Package: dibbler-client
Version: 1.0.1-1.1
Severity: normal
Tags: patch
Dear Maintainer,
When you run dibbler-client and configure it to request a prefix
delegation and receive a /60 and want it to be split on 2 interfaces,
the current version of dibbler as packaged by Debian will create 2 /68
prefixes. Because of this you can't use router announcement as an easy
way to get IPv6 configured on the interfaces.
For instance:
21:35 Client Notice PD: Adding prefix 2601:1234:5678:9a00::/60 to all
interfaces (prefix will be split to /68 prefixes if necessary).
^^^
21:35 Client Info PD: Using 2 suitable interface(s):eth2.10 eth2.30
21:35 Client Notice PD: Adding prefix 2601:1234:5678:9a00:9000::/68 on the
eth2.10/9 interface.
21:35 Client Notice PD: Adding prefix 2601:1234:5678:9a00:7000::/68 on the
eth2.30/7 interface.
^^^^
It turns out that upstream code for dibbler-client has already a better
solution with this this commit:
https://github.com/tomaszmrugalski/dibbler/commit/41fa1dbc148331ec1a465ee3be449cf37d05943a
It would be great to fix this in the patched version of dibbler.
-- System Information:
Debian Release: 11.3
APT prefers stable-updates
APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)
Kernel: Linux 5.10.0-13-amd64 (SMP w/2 CPU threads)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
Versions of packages dibbler-client depends on:
ii cdebconf [debconf-2.0] 0.260
ii debconf [debconf-2.0] 1.5.77
ii libc6 2.31-13+deb11u3
ii libgcc-s1 10.2.1-6
ii libstdc++6 10.2.1-6
ii ucf 3.0043
Versions of packages dibbler-client recommends:
pn dibbler-doc <none>
ii resolvconf 1.87
dibbler-client suggests no packages.
-- debconf information:
* dibbler-client/start: true
* dibbler-client/options: dns
* dibbler-client/interfaces: eth1
dibbler-client/title:
diff -ur dibbler-1.0.1.bak/ClntIfaceMgr/ClntIfaceMgr.cpp
dibbler-1.0.1/ClntIfaceMgr/ClntIfaceMgr.cpp
--- dibbler-1.0.1.bak/ClntIfaceMgr/ClntIfaceMgr.cpp 2015-07-30
14:35:53.000000000 -0700
+++ dibbler-1.0.1/ClntIfaceMgr/ClntIfaceMgr.cpp 2022-04-26 22:18:09.259630252
-0700
@@ -433,6 +433,21 @@
return modifyPrefix(iface, prefix, prefixLen, 0, 0, PREFIX_MODIFY_DEL,
params);
}
+/// Returns number of bits required to store specific number of interfaces
+///
+/// @param i
+/// @return ceil(log2(i)) or 0 for 0
+int TClntIfaceMgr::numBits(int i) {
+ int bits = 0;
+ if (i == 0) {
+ return (0);
+ } else {
+ i--;
+ }
+ while (i >>= 1) { ++bits; }
+ return (bits + 1);
+}
+
bool TClntIfaceMgr::modifyPrefix(int iface, SPtr<TIPv6Addr> prefix, int
prefixLen,
unsigned int pref, unsigned int valid,
PrefixModifyMode mode,
@@ -562,66 +577,47 @@
stringstream prefix_split; // textual representation, used to pass as
script
for (TIfaceIfaceLst::const_iterator i=ifaceLst.begin(); i!=ifaceLst.end();
++i) {
- char buf[16];
- int subprefixLen;
- memmove(buf, prefix->getAddr(), 16);
-
- if (ifaceLst.size() == 1) {
- // just one interface - use delegated prefix as is
- subprefixLen = prefixLen;
- } else if (ifaceLst.size()<256) {
- subprefixLen = prefixLen + 8;
- int offset = prefixLen/8;
- if (prefixLen%8 == 0) {
- // that's easy, just put ID in the next octet
- buf[offset] = (*i)->getID();
- } else {
- // here's fun
- uint16_t existing = readUint16(buf+offset);
- uint16_t bitmask = 0xff00;
- uint16_t infixmask = ((uint8_t)(*i)->getID()) << 8;
- bitmask = bitmask >> (prefixLen%8);
- infixmask = infixmask >> (prefixLen%8);
-
- // clear out if there is anything there, i.e. server assigned
prefix
- // with garbage in host section
- existing = existing & (~bitmask);
- existing = existing | (bitmask & infixmask);
- writeUint16(buf+offset, existing);
- }
+ int subprefixLen = 0;
- } else {
+ int numPrefixes = ifaceLst.size();
+
+ if (numPrefixes > 256) {
// users with too much time that play with virtual interfaces are
out of luck
Log(Error) << "Something is wrong. Detected more than 256
interface." << LogEnd;
return false;
}
- SPtr<TIPv6Addr> tmpAddr = new TIPv6Addr(buf, false);
+ SPtr<TIPv6Addr> subprefix = calculateSubprefix(prefix, prefixLen,
+ numPrefixes,
(*i)->getID(), subprefixLen);
- Log(Notice) << "PD: " << action << " prefix " << tmpAddr->getPlain()
<< "/" << subprefixLen
+ Log(Notice) << "PD: " << action << " prefix " << subprefix->getPlain()
<< "/" << subprefixLen
<< " on the " << (*i)->getFullName() << " interface." <<
LogEnd;
- if (params) {
- prefix_split << (*i)->getName() << " " << tmpAddr->getPlain()
- << "/" << subprefixLen << " ";
- }
+ if (params) {
+ prefix_split << (*i)->getName() << " " << subprefix->getPlain()
+ << "/" << subprefixLen << " ";
+ }
switch (mode) {
case PREFIX_MODIFY_ADD:
- status = prefix_add( (*i)->getName(), (*i)->getID(),
tmpAddr->getPlain(), subprefixLen, pref, valid);
+ status = prefix_add( (*i)->getName(), (*i)->getID(),
subprefix->getPlain(),
+ subprefixLen, pref, valid);
break;
case PREFIX_MODIFY_UPDATE:
- status = prefix_update( (*i)->getName(), (*i)->getID(),
tmpAddr->getPlain(), subprefixLen, pref, valid);
+ status = prefix_update( (*i)->getName(), (*i)->getID(),
subprefix->getPlain(),
+ subprefixLen, pref, valid);
break;
case PREFIX_MODIFY_DEL:
- status = prefix_del( (*i)->getName(), (*i)->getID(),
tmpAddr->getPlain(), subprefixLen);
+ status = prefix_del( (*i)->getName(), (*i)->getID(),
subprefix->getPlain(),
+ subprefixLen);
break;
}
if (status==LOWLEVEL_NO_ERROR) {
conf++;
} else {
string tmp = error_message();
- Log(Error) << "Prefix error encountered during " << action << "
operation: " << tmp << LogEnd;
+ Log(Error) << "Prefix error encountered during " << action << "
operation: "
+ << tmp << LogEnd;
}
}
@@ -640,6 +636,68 @@
}
}
+/// @brief Calculates subprefix based on prefix/prefixLen and a given
+/// number of sub-prefixes
+///
+/// @param prefix delegated prefix
+/// @param prefixLen delegated prefix length
+/// @param numPrefixes total number of sub-prefixes
+/// @param i index of the interface
+/// @param [out] subprefixLen This parameter is set to appropriate value
+///
+/// @return Generated subprefix
+SPtr<TIPv6Addr>
+TClntIfaceMgr::calculateSubprefix(const SPtr<TIPv6Addr>& prefix, int prefixLen,
+ int numPrefixes, int i, int& subprefixLen) {
+ if (numPrefixes == 1) {
+ // just one interface - use delegated prefix as is
+ subprefixLen = prefixLen;
+ return (prefix);
+ }
+
+ // Get the prefix in binary form. (we need one octet extra to handle
operations
+ // on very long prefixes: /120 to /127).
+ char buf[17];
+ memset(buf, 0, 17);
+ memmove(buf, prefix->getAddr(), 16);
+
+ // Calculate how many bits are needed for handling this amount of downlink
+ // interfaces.
+ int bit_shift = numBits(numPrefixes);
+
+ subprefixLen = prefixLen + bit_shift;
+ int offset = prefixLen / 8;
+ if (prefixLen%8 == 0) {
+ // that's easy, just put ID in the next octet
+ buf[offset] = i;
+ } else {
+ // here's fun
+ uint16_t existing = readUint16(buf+offset);
+ uint16_t bitmask = 0xff00;
+ uint16_t infixmask = ((uint8_t)i) << 8;
+ bitmask = bitmask >> (prefixLen%8);
+ infixmask = infixmask >> (prefixLen%8);
+
+ // clear out if there is anything there, i.e. server assigned prefix
+ // with garbage in host section
+ existing = existing & (~bitmask);
+ existing = existing | (bitmask & infixmask);
+ writeUint16(buf+offset, existing);
+ }
+
+ // Ok, some users are unhappy if they get prefixes larger than /64,
+ // so trim down downlink prefixes to /64 if we get something larger.
+ // One day this parameter will have to be configurable.
+ if (subprefixLen < 64) {
+ Log(Info) << "PD: Prefix per downlink interface could be /" <<
subprefixLen
+ << ", trimming down to /64" << LogEnd;
+ subprefixLen = 64;
+ }
+
+ SPtr<TIPv6Addr> tmpAddr(new TIPv6Addr(buf, false));
+ return (tmpAddr);
+}
+
void TClntIfaceMgr::redetectIfaces() {
struct iface * ptr;
struct iface * ifaceList;
diff -ur dibbler-1.0.1.bak/ClntIfaceMgr/ClntIfaceMgr.h
dibbler-1.0.1/ClntIfaceMgr/ClntIfaceMgr.h
--- dibbler-1.0.1.bak/ClntIfaceMgr/ClntIfaceMgr.h 2014-02-15
09:37:44.000000000 -0800
+++ dibbler-1.0.1/ClntIfaceMgr/ClntIfaceMgr.h 2022-04-26 22:13:44.358121122
-0700
@@ -79,6 +79,11 @@
void redetectIfaces();
+ int numBits(int i);
+
+ SPtr<TIPv6Addr> calculateSubprefix(const SPtr<TIPv6Addr>& prefix, int
prefixLen,
+ int numPrefixes, int i, int&
subprefixLen);
+
private:
bool modifyPrefix(int iface, SPtr<TIPv6Addr> prefix, int prefixLen,
unsigned int pref, unsigned int valid, PrefixModifyMode
mode,
--- End Message ---