How exactly does linux use prefix length assigned to network interface?

I was exploring direct links between machines, and basically failed to break something.

I assigned IP address 192.168.0.1/24 to eth0 in two ways.

A. Adding 192.168.0.1/24 as usual


<span style="color:#323232;"># ip addr add 192.168.0.1/24 dev eth0
</span><span style="color:#323232;"># ping -c 1 192.168.0.2
</span><span style="color:#323232;">PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
</span><span style="color:#323232;">64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.051 ms
</span><span style="color:#323232;">
</span><span style="color:#323232;">--- 192.168.0.2 ping statistics ---
</span><span style="color:#323232;">1 packets transmitted, 1 received, 0% packet loss, time 0ms
</span><span style="color:#323232;">rtt min/avg/max/mdev = 0.051/0.051/0.051/0.000 ms
</span><span style="color:#323232;">#
</span>

B: Adding 192.168.0.1/32 and adding a /24 route


<span style="color:#323232;"># ip addr add 192.168.0.1/32 dev eth0
</span><span style="color:#323232;"># # 192.168.0.2 should not be reachable.
</span><span style="color:#323232;"># ping -c 1 192.168.0.2
</span><span style="color:#323232;">ping: connect: Network is unreachable
</span><span style="color:#323232;"># # But after adding a route, it is.
</span><span style="color:#323232;"># ip route add 192.168.0.0/24 dev eth0
</span><span style="color:#323232;"># ping -c 1 192.168.0.2
</span><span style="color:#323232;">PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
</span><span style="color:#323232;">64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.053 ms
</span><span style="color:#323232;">
</span><span style="color:#323232;">--- 192.168.0.2 ping statistics ---
</span><span style="color:#323232;">1 packets transmitted, 1 received, 0% packet loss, time 0ms
</span><span style="color:#323232;">rtt min/avg/max/mdev = 0.053/0.053/0.053/0.000 ms
</span><span style="color:#323232;">#
</span>

Does this mean that adding an IP address with prefix is just a shorthand for adding the IP address with /32 prefix and adding a route afterwards? That is, does the prefix length has no meaning and the real work is done by the route entries?

Or is there any functional difference between the two methods?

Here is another case, these two nodes can reach each other via direct connection (no router in between) but don’t share a subnet.

Node 1:


<span style="color:#323232;"># ip addr add 192.168.0.1/24 dev eth0
</span><span style="color:#323232;"># ip route add 192.168.1.0/24 dev eth0
</span><span style="color:#323232;"># # Finish the config on Node B
</span><span style="color:#323232;"># nc 192.168.1.1 8080 &lt;&lt;&lt; "Message from 192.168.0.1"
</span><span style="color:#323232;">Response from 192.168.1.1
</span>

Node 2:


<span style="color:#323232;"># ip addr add 192.168.1.1/24 dev eth0
</span><span style="color:#323232;"># ip route add 192.168.0.0/24 dev eth0
</span><span style="color:#323232;"># # Finish the config on Node A
</span><span style="color:#323232;"># nc -l 0.0.0.0 8080 &lt;&lt;&lt; "Response from 192.168.1.1"
</span><span style="color:#323232;">Message from 192.168.0.1
</span>
istdaslol,

First: it seems you got some things mixed up. 192.168.0.1/24 isn’t a IP address, strictly speaking. It’s Network information wich translates to „your IP is 192.168.0.1 and your subnet mask is 255.255.255.0“. The /dd is the amount of bits set in the subnet mask. An within the first and last address are reserved for network and broadcast. With your /32 assignments you basically told your system, it has no network to talk to.

istdaslol,

Second, a bit of a nitbit. It’s a postfix not a prefix, as it is after the IP address

taladar,

It is called the prefix length because it is the number of 1s at the start of the subnet mask.

istdaslol,

It is a postfix representing the subnet „set bit“ prefix. Can we agree on this ?

unique_hemp,

No, because this is common terminology that has no reason to be messed with, even if it is technically unclear.

taladar,

If there is one thing we can all agree on is that we do not want to go back to writing out the subnet masks manually, especially not with IPv6 ones being 4 times as long.

p1mrx,

IPv6 subnet masks are long, but super easy because of hexadecimal. A bunch of Fs, then [EC8]? then a bunch of 0s.

taladar,

That doesn’t sound right, even with hex you would still have 8 possible values (well, 6 if you don’t count all 1 and all 0) for the byte where the netmask switches from 1s to 0s or only 4 (2 if you don’t count all 1 and all 0) for the half-byte.

p1mrx,

I listed the 5 possible digits. What’s missing?

taladar,

Never mind, I didn’t think it through properly earlier. Not quite sure what I was thinking at the time but probably got distracted. Obviously you have 5 possible values between 0 and 4 bits being 1.

1111 = 0xF 1110 = 0xE 1100 = 0xC 1000 = 0x8 0000 = 0x0

gray,
@gray@pawb.social avatar

en.m.wikipedia.org/wiki/Subnet

In both ipv4 and ipv6 the CIDR designation of the subnet is called a “prefix”.

istdaslol,

Third: with your /24 subnet you told your system it has that many address to talk to. With the /32 you told it has none to talk to. With adding a route you gave the additional info „there is another network called … with a subnet of … wich you can talk to“ So your second solution is more or less equivalent but with extra steps. I don’t know how it’s implemented in the backend but it is different as in the second there is no network per default but you add routes to some. In contrast to there is a network and no routing is needed

Trainguyrom,

With your /32 assignments you basically told your system, it has no network to talk to

More accurately you’ve told the device that it is the only device on its network. It’s a network of 1 IP with no broadcast nor network ID. This is very common with public IPs where you get a singular IP.

PowerCrazy, (edited )

This isn’t actually correct. An ip address assignment for a host with an IP requires both the address and the subnet mask. One cannot be assigned without the other. Even more strictly speaking the address by itself isn’t useful to the network stack except as a destination, and isn’t used anywhere in the network stack of the host. There is always a subnet mask, sometimes the mask is assumed to be /32 (255.255.255.255), sometimes /24, whatever. But whenever you are talking about assigning an ip address to any IP speaker, it must include the mask.

The routing table on every IP speaker will include at a minimum a single host-route. That is the IP of the system itself with a /32 mask and the configured interface of that IP. Whether it’s eth0, a bonded interface, a loopback etc.

Once you have that single host route, additional routes can be added as needed. These routes require an address, a subnet, and a next-hop. The next hop can be a directly attached interface, or an IP that the is reachable by another route in the host routing table.

If you have only a host route, as OP has, then the system has no network knowledge, so there are no reachable next hop IPs. So you would have to use a directly connected interface, like the OP did. Once you tell the system 192.168.0.0/24 is reachable through that interface, then any IP Packets that have that network as their destination will use that interface with a source of the one IP it has. In the case of two servers connected back to back, assuming the other server knows where the source of the packet came from, there is no problem sending traffic back.

So to answer the OPs question, there is no difference between one host route, then a static route pointing to an interface, and just a directly connected interface with your server IP on it. They are two different routes that may have different administrative distances, but assuming you aren’t doing anything exotic, for all intents and purposes they are the same.

If you are talking about layer2 concepts like broadcasts, the host-route configured server can still receive broadcasts, but only broadcasts with destination ip of 255.255.255.255, not scoped broadcasts like 192.168.0.255 since it will ignore all traffic that isn’t unscoped broadcast or a full match to it’s own IP address.

Markaos,

Or is there any functional difference between the two methods?

Can’t test right now, but I have a strong suspicion you will have trouble getting IP broadcast to work. Normally broadcast address is calculated by setting all bits after the network prefix to 1, but your computer believes to be in a /32 “network”. It won’t broadcast over routes that are not part of its network.

And even if you calculate the broadcast address successfully (maybe the software you use has /24 hardcoded for whatever reason), no computer configured with a /32 address will receive it - 192.168.0.255 is not within the 192.168.0.1/32 network, so it will probably get forwarded according to your routes if you have forwarding enabled (except it shouldn’t in this case with one network interface, because you never send packets back the way they came from)

akash_rawal, (edited )

Just did some basic testing on broadcast addresses using socat, broadcast is not working at all with /32 addresses. With /24 addresses, broadcast only reaches nodes that share a subnet. Nodes that don’t share the subnet aren’t reachable by broadcast even when they’re reachable via unicast.

Edit1: Did more testing, it seems like broadcast traffic ignores routing tables.

On 192.168.0.2, I am running socat -u udp-recv:8000,reuseaddr - to print UDP messages.

Case 1: add 192.168.0.1/24


<span style="color:#323232;"># ip addr add 192.168.0.1/24 dev eth0
</span><span style="color:#323232;"># # Testing unicast
</span><span style="color:#323232;"># socat - udp-sendto:192.168.0.2:8000 &lt;&lt;&lt; "Message"
</span><span style="color:#323232;"># # Worked
</span><span style="color:#323232;"># socat - udp-sendto:192.168.0.255:8000,broadcast &lt;&lt;&lt; "Message"
</span><span style="color:#323232;"># # Worked
</span>

Case 2: Same as above but delete 192.168.0.0/24 route


<span style="color:#323232;"># ip addr add 192.168.0.1/24 dev eth0
</span><span style="color:#323232;"># ip route del 192.168.0.0/24 dev eth0
</span><span style="color:#323232;"># # Testing unicast
</span><span style="color:#323232;"># socat - udp-sendto:192.168.0.2:8000 &lt;&lt;&lt; "Message"
</span><span style="color:#323232;">2024/02/13 22:00:23 socat[90844] E sendto(5, 0x5d3cdaa2b000, 8, 0, AF=2 192.168.0.2:8000, 16): Network is unreachable
</span><span style="color:#323232;"># # Testing broadcast
</span><span style="color:#323232;"># socat - udp-sendto:192.168.0.255:8000,broadcast &lt;&lt;&lt; "Message"
</span><span style="color:#323232;"># # Worked
</span>
Bitrot,
@Bitrot@lemmy.sdf.org avatar

One of the functions of a router is splitting broadcast domains. You would not expect a broadcast to reach a different subnet.

biscuitswalrus,

IP and Routing is layer 3, broadcast is layer 2 with Mac addresses being shared within a broadcast domain (often a vlan/lan) and the only requirement for layer 2 is a switch you don’t need routers. Devices on a lan talk only via switches which switch based on Mac address tables. You don’t learn Mac addresses of devices past your broadcast domain, that’s what a router handles.

So in network practice (nothing Linux related) if you are on a broadcast network that’s a /24 subnet, what should happen is all devices within that subnet talk to each other without using a router, instead they learn a mac address and the associated ip from a broadcast from the device which owns it.

If you tell your device that it’s only on a /32 then it should discard every arp it hears as invalid. Which means it won’t learn any neighbouring lan devices.

While your network on your single device with the /32 probably works ok to get to other networks (routed networks like internet or other vlans), because other networks ask the router, and the router probably learned your mac and ip on whatever vlan/interface your device is connected via.

But unless you’re trying to do something unconventional, devices on a lan should match the routers expected subnet. This way devices can trust their assumption that within their subnet they communicate to other local devices by learning other network devices network address via arp, and communicate directly in unicast via learned ips from that arp. If it’s outside the subnet they then look to the gateway. They trust the gateway. The gateway should route to the right interface or next hop.

If you really wanted to make this work though, usually routers can proxy arp. So in this case, you tell the router to ‘oroxy’ and broadcast your arp to other devices. Those devices on your lan looking for your ip will find the routers Mac address, then using destination network address translation you can redirect the incoming connection from a lan device to your device via your router. Then your /32 ip can probably work. Usually this is done when someone has put a static ip on a device with a wrong subnet ip on a vlan with another subnet. So the device which arps is ignored by the router and the other network devices. If you use the router to proxy arp you can basically give the local lan devices an ip to hit that they expect, which then you can translate to the misconfigured device. This generally is considered a bandaid solution temporary until a vendor or technician can fix their misconfiguration. I do not recommend.

18+ B97,
@B97@mastodon.social avatar

@biscuitswalrus @akash_rawal
Layer 3 decides if and where broadcasts go.
Layer 2 is mainly point to point.

PowerCrazy,

Layer3 decides where broadcasts stop (at the boundary between two networks, i.e. a router)

Layer2 is where broadcasts go.

  • All
  • Subscribed
  • Moderated
  • Favorites
  • linux@lemmy.ml
  • fightinggames
  • All magazines