So I understand that the subnet mask provides information about the length of the routing prefix (NID). It can be applied to a given IP address to extract the most significant bits allocated for the routing prefix and “zero out” the host identifier.

But why do we need the bitwise AND for that, specifically? I understand the idea, but would it not be easier to only parse the IP address string sequence of bits only for the first n bits and then disregard the remainder (the host identifier)? Because the information necessary for that is already available from the subnet mask WITHOUT the bitwise AND, e.g., with 255.255.255.0 or 1111 1111.1111 1111.1111 1111.0000 0000, you count the amount of 1s, which in this case is 24 and corresponds to that appendix in the CIDR notation. At this point, you already know that you only need to consider those first 24 bits from the IP address, making the subsequent bitwise AND redundant.

In the case of 192.168.2.150/24, for example, with subnet mask 255.255.255.0, you would get 192.168.2.0 (1100 0000.1010 1000.0000 0010.0000 0000) as the routing prefix or network identifier when represented as the first address of the network, however, the last eight bits are redundant, making the NID effectively only 192.168.2.

Now let’s imagine an example where we create two subnets for the 192.168.2.0 network by taking one bit from the host identifier and appending it to the routing prefix. The corresponding subnet mask for these two subnets is 255.255.255.128, as we now have 25 bits making up the NID and 7 bits constituting the HID. So host A from subnet 192.168.2.5/25 (HID 5, final octet 0000 0101) now wants to send a request to 192.168.2.133/25 (HID 5, final octet 1000 0101). In order to identify the network to route to, the router needs the NID for the destination, and it gets that by either discarding the 7 least significant bits or by zeroing them out with a bitwise AND operation. Now, my point is, for identifying the network of which the destination host is part of (in this case, the host is B), the bitwise AND is redundant, is it not?

So why doesn’t the router just store the NID with only the bits that are strictly required? Is it because the routing table entries are always of a fixed size of 32 bits for IPv4? Or is it because the bitwise AND operation is more efficiently computable?

  • macniel
    link
    fedilink
    arrow-up
    23
    ·
    edit-2
    9 days ago

    But why do we need the bitwise AND for that, specifically? I understand the idea, but would it not be easier to only parse the IP address string of bits only for the first n bits and then disregard the remainder (the host identifier)?

    Essentially it boils down to:

    bit operations are stupid fast and efficient, String operations are super slow.

    Also, IP addresses are always stored as int32/int64, so applying String operations would require them to be converted first.

    • ricdeh@lemmy.worldOP
      link
      fedilink
      English
      arrow-up
      5
      ·
      9 days ago

      Though I would like to clarify that maybe my wording was a bit confusing. By “string of bits”, I did not mean the term as it is typically used in programming language environments, but rather a raw binary sequence, e.g., the first 24 bits of an IP address, therefore allocating 3 bytes of memory for storing the NID.

      • macniel
        link
        fedilink
        arrow-up
        10
        ·
        9 days ago

        but rather a raw binary sequence, e.g., the first 24 bits of an IP address, therefore allocating 3 bytes of memory for storing the NID.

        That would require dynamic memory allocation, since you can never know what CIDR your stack encounters. It could be a nibble, a byte, a byte and a nibble, …, 4 bytes. So you would allocate a int32/int64 anyway to be on the safe side.

        • ricdeh@lemmy.worldOP
          link
          fedilink
          English
          arrow-up
          2
          ·
          9 days ago

          Yep, I agree. Though one could make a hypothetical argument for expanding the array dynamically when needed. Of course, due to the varying sizes of NIDs resulting from CIDR (which you correctly mentioned), you would need to have a second array that can store the length of each NID, with 5 bits per element, leaving you with 3 bits “saved” per IP address.

          That can end up wasting more memory than the 32-bit per NID approach, e.g., when the host identifier is smaller than 5 bits. And there’s the slowness of memory allocation and copying from one array to another that comes on-top of that.

          I think that it is theoretically possible to deploy a NID-extracting and tracking program that is a tiny bit more memory efficient than the 32-bit implementation, but would probably come at a performance overhead and depend on you knowing the range of your expected IP addresses really well. So, not useful at all, lol

          Anyway, thanks for your contributions.

          • macniel
            link
            fedilink
            arrow-up
            4
            ·
            9 days ago

            sure thing buddy, and never feel discouraged to ask “stupid questions”, it’s how we learn after all :)