4 ms·
From an operator's perspective, 128 bits is more difficult to troubleshoot compared to the 32 bits of IPv4. RFC5962 makes things easier, though only marginally
by ra1n85 9y ago
From an operator's perspective, 128 bits is more difficult to troubleshoot compared to the 32 bits of IPv4. RFC5962 makes things easier, though only marginally.
- dingo_bat 9y agoNot to mention there is no int128_t in C. You have to use poorly defined byte arrays to pass the thing around. It's irritating af.
- CountSessine 9y agotypedef struct { uint8_t[16] d; } ipv6addr;?
- dingo_bat 9y agoWhich is a byte array. When you pass this to a function, it does not fit in a single register. The equality operator doesn't work, nor do other logical operators. Everything has to be defined. 64 bit would have been so easy. And it would still have been enough. Edit: somebody replied and deleted their comment. Since I had written a response I am editing this comment. > Then your real complaint... is that you don't have 128-bit machine registers Agreed, although my real complaint is more towards IPv6, for not thinking about this real-life limitation. > what the urgent need to pass IPv6 addresses in machine registers It's much slower than IPv4 to deal with! 64 bit addresses wouldn't have had this problem and still would have enough space for everyone on earth. > And how is it "irritating af"? Apart from the speed concerns: > The equality operator doesn't work, nor do other logical operators. Everything has to be defined.
- deleted 9y ago[deleted]
- deathanatos 9y ago> When you pass this to a function, it does not fit in a single register. Depends on the architecture. On amd64 (the architecture I'm typing this comment on), a 128-bit struct, like defined above, will fit in registers — yes, in 64-bit registers. The amd64 ABI[1] will split them across two registers. For example, if we take the above struct and use it, void foo() { ipv6_addr addr = { { 1, 2, 3, 4, 5, 6, 7, 8, }, }; bar(addr); } This compiles to: movabsq $578437695752307201, %rdi xorl %esi, %esi jmp bar The nasty looking number is the initialization; it's easier to see in hex: In [1]: hex(578437695752307201) Out[1]: '0x807060504030201' That ends up in %rdi, the first of the amd64 arg-passing registers. The next half is zeros, so it goes in %rsi (the compiler just zeros it). Then we "call" bar. (There is tail-call optimization here) The non-optimized version is similar, but more drawn out: # for some reason we zero it first movq $0, -16(%rbp) movq $0, -8(%rbp) # then we init it again… okay gcc. movb $1, -16(%rbp) movb $2, -15(%rbp) movb $3, -14(%rbp) movb $4, -13(%rbp) movb $5, -12(%rbp) movb $6, -11(%rbp) movb $7, -10(%rbp) movb $8, -9(%rbp) # move the struct into rdx/rax movq -16(%rbp), %rdx movq -8(%rbp), %rax # just to move it into the arg-passing registers movq %rdx, %rdi movq %rax, %rsi # call the function call bar > It's much slower than IPv4 to deal with! 64 bit addresses wouldn't have had this problem and still would have enough space for everyone on earth. It's twice as wide, yes, but that doesn't necessarily mean you're needing to pass it in memory. > still would have enough space for everyone on earth. IP addresses aren't just numbers assigned to machines. They must also — effectively — encode the route to that machine; you can sort of imagine it as a tree, with each bit giving you successively more local directions on the Internet. Now, of course, that's not exactly how it works, but the point is that some parts of that tree are going to be sparsely populated. Having a wider address space means you can make bigger, but not necessarily full, allocations in the address space, allowing you to keep whole networks together in a common prefixes, which results in simpler routing tables. (At least, that's the idea as I understand it.) And it's not just 1 per person: I have more than one device, and I move between networks during the course of a day. If all of the networks I frequented actually had IPv6, I'd bog down at least 6–8 IPv6 addresses during the course of a boring day, and that's not counting stuff like networking equipment. It's not just a simple question of "are there enough bits to assign each person an address" > The equality operator doesn't work, nor do other logical operators. On amd64 at least, __int128_t exists, I believe, and I think it should come with operators. In higher-level languages, you can define < and == simply enough. Now, I grant that the above is highly architecture specific, and there definitely exist architectures where this doesn't apply. And those, yes, 128-bit will be slower than a theoretical 64-bit. I just don't think it's worth worrying about. [1]: https://software.intel.com/sites/default/files/article/402129/mpx-linux64-abi.pdf https://software.intel.com/sites/default/files/article/40212...
- lloeki 9y ago> <128-bit whining> So what? Didn't you notice that the 128 bits are split in half: {network|host}? Anything that needs to route things around is only concerned about the first 64 bits. Once you're hitting on the local scope the last 64 bits is what matters ~99.9% of the time. So you can have your efficient 64-bit comparison right there for most of the traffic.
- zkms 9y ago> Everything has to be defined. 64 bit would have been so easy. And it would still have been enough I agree. It sucks, 64 bits almost certainly would have worked and languages/libraries/OSes tend to not do their fair share at taking care of IPv6-related stuff. That, along with all the prettyprinting/parsing business with the colons is legitimately annoying. However, IPv6 was designed not just to fix IPv4's sins, but to ensure that there'd never be an address exhaustion issue with IPv6, no matter how many decades it would be in use. That's why there's 128 bits of overkill; the IPv6 designers knew that the IPv4->IPv6 transition would be awful (they even underestimated just how awful it'd be), that IPv6 would keep running for a long time once it got deployed -- and wanted to do their best to avoid subjecting the world to a transition from IPv6.
- zkms 9y agoOf all the various reasons to define address lengths and wire formats (that'll get burned into billions of dollars of ASICs over decades), "C doesn't have a default type for it" is frankly the worst.
- FrozenVoid 9y ago__int128 is supported by GCC,Clang and ICC
- thwarted 9y ago128 bits is more difficult to troubleshoot compared to the 32 bits of IPv4. RFC5962 makes things easier RFC5962 is "Dynamic Extensions to the Presence Information Data Format Location Object (PIDF-LO)" [1] https://tools.ietf.org/html/rfc5962 https://tools.ietf.org/html/rfc5962
- ra1n85 9y agoSorry, RFC 5952: https://tools.ietf.org/html/rfc5952 https://tools.ietf.org/html/rfc5952
- throwaway2048 9y agoMutilevel NAT is a hell of a lot harder to troubleshoot than some extra address bits.
- ra1n85 9y agoWhy would you use multilevel NAT? That sounds like design sadness.
- belorn 9y agoYou can very easy end up with multilevel nat. The last mile (ie a apartment complex) can have one and then the customer router is the second. But that assumes that the ISP has addresses to spare. If not, we have the three layers of nat. ISP->apartment complex->customer router->all customer devices. And then we have intermediates, like ISP->municipal->apartment complex->customer router->customer devices. Now we have four layers of nat. In the really worse case, ISP are split up into multiple ones, and you can get carrier grade NAT in the form of ISP->ISP->municipal->apartment complex->customer router->customer devices. Five layers of nat and up. Multilevel NAT is a form of sadness that NAT never was designed to do.
- zkms 9y agoNAT is also expensive to operate at the scale and reliability that large network operators need. If stateful NAT middleboxes go down, everything goes down -- it's a point of failure that's hard to route around! Also there's the issue that you'll end up having multiple devices with the same RFC1918 addresses, which is an immense pain in the arse to deal with.