Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AddrAdd shouldn't add broadcast address if not directly asked to #329

Open
jjastrze-ovh opened this issue Feb 12, 2018 · 6 comments
Open

Comments

@jjastrze-ovh
Copy link

Let's consider following code:

	link := &netlink.Dummy{
		LinkAttrs: netlink.LinkAttrs{
			Flags: net.FlagUp,
			Name:  "ntest",
		},
	}

	if err := netlink.LinkAdd(link); err != nil {
		fmt.Println("add", err)
		return
	}

	addr := &netlink.Addr{
		IPNet: &net.IPNet{
			IP:   net.ParseIP("192.168.22.19"),
			Mask: net.CIDRMask(24, 32),
		},
	}

	if err := netlink.AddrAdd(link, addr); err != nil {
		fmt.Println("add addr", err)
		return
	}

The code should add 192.168.22.19 address to device ntest, but it also adds broadcast address, which is some scenarios breaks eg. adding routes with error=invalid argument.

[root@machine] ip -4 a s ntest
6488: ntest: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default 
    inet 192.168.22.19/24 brd 192.168.22.255 scope global ntest
       valid_lft forever preferred_lft forever

For me presented code should be equivalent to what following ip command does:

[root@root@machine] ip l a ntest type dummy
[root@root@machine] ip a a 192.168.22.19/24 dev ntest
[root@root@machine] ip -4 a s ntest
6489: ntest: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default 
    inet 192.168.22.19/24 scope global ntest
       valid_lft forever preferred_lft forever

Not to this:

[root@root@machine] ip a a 192.168.22.19/24 brd 192.168.22.255 dev ntest
[root@root@machine] ip -4 a s ntest
6489: ntest: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default 
    inet 192.168.22.19/24 brd 192.168.22.255 scope global ntest
       valid_lft forever preferred_lft forever

iptool makes end user responsibility to specify broadcast address if it is needed.
In my opinion this library should behave in the same way

The proposal for this issue is:
jjastrze-ovh@9a85a61

@jjastrze-ovh
Copy link
Author

@aboch @vishvananda any comments?

@aboch
Copy link
Collaborator

aboch commented Mar 14, 2018

@jjastrze-ovh sorry for missing this.

Please go ahead and feel free to open a PR with your proposed change. No need to wait for an ACK.

Please be aware of #248 which added the automatic brd addition.
The behavior has been there for more than a year, therefore we cannot revert it now.

I'd suggest you to look for a way to extend the Addr structure so that clients can ask not to auto compute the brd.

I know it would be the opposite of what iproute2 does. But I do not see another solution ATM.

Thanks

@dannyk81
Copy link

dannyk81 commented Jan 21, 2019

@aboch, @vishvananda

As part of kubernetes/dns#282, it seems we've hit an issue with the current implementation of broadcast address auto-calculation.

Specifically, the issue is with /32 prefixlen addresses.

In the linked issue above, you can see that when adding a /32 address using iproute2 commands, the IFA_BROADCAST attribute is not sent to NETLINK (as expected).

However, when using the netlink package an incorrect IFA_BROADCAST is calculated and send to NETLINK, which in the case of CoreOS based systems seems to prevent from the IP address to be added to the interface.

Here are the decoded messages sent to NETLINK using iproute2 vs. netlink pkg:

iproute2:

28:00:00:00:14:00:05:06:21:d2:45:5c:00:00:00:00:02:20:00:00:b5:01:00:00:08:00:02:00:0a:0a:0a:0a:08:00:01:00:0a:0a:0a:0a
{'attrs': [('IFA_LOCAL', '10.10.10.10'), ('IFA_ADDRESS', '10.10.10.10')],
 'family': 2,
 'flags': 0,
 'header': {'flags': 1541,
            'length': 40,
            'pid': 0,
            'sequence_number': 1548079649,
            'type': 20},
 'index': 437,
 'prefixlen': 32,
 'scope': 0}
........................................

Go netlink:

30:00:00:00:14:00:05:06:07:00:00:00:00:00:00:00:02:20:00:00:19:00:00:00:08:00:02:00:0a:0a:0a:0a:08:00:01:00:0a:0a:0a:0a:08:00:04:00:0a:0a:0a:00
{'attrs': [('IFA_LOCAL', '10.10.10.10'),
           ('IFA_ADDRESS', '10.10.10.10'),
           ('IFA_BROADCAST', '10.10.10.0')],
 'family': 2,
 'flags': 0,
 'header': {'flags': 1541,
            'length': 48,
            'pid': 0,
            'sequence_number': 7,
            'type': 20},
 'index': 25,
 'prefixlen': 32,
 'scope': 0}
........................................

as you can see, the calculated broadcast address 'IFA_BROADCAST', '10.10.10.0' that is submitted is incorrect, considering 'IFA_ADDRESS', '10.10.10.10' and prefixlen of 32, it can't actually have a broadcast address (or more accurately it's IFA_BROADCAST == IFA_ADDRESS).

Considering the above, perhaps the if here

if addr.Broadcast == nil {
should be modified to ensure that prefixlen < 31

@aboch
Copy link
Collaborator

aboch commented Jan 23, 2019

Thank you @dannyk81. Feel free to open a PR with the fix.

brandt added a commit to brandt/netlink that referenced this issue Oct 30, 2019
Since [vishvananda#248](vishvananda#248), adding an address automatically sets the broadcast if the broadcast address was not specified. This is undesirable when adding an IP with a prefixlen of /31 or /32. (Additional details in the issues linked below.)

This changes the behavior so that the broadcast is only automatically set if the prefixlen is /30 or larger.

Issue reported in:

- vishvananda#329
- vishvananda#471

See also:

- [RFC 3021](http://tools.ietf.org/html/rfc3021)

Alternatives to this PR:

A. vishvananda#472 - Adds `AddrAddWithoutCalculatedBroadcast`.
B. jjastrze-ovh@9a85a61 - Breaking change to make auto-setting the broadcast address an opt-in feature.
C. <no existing PR> - Suppress sending of the broadcast to netlink when `addr` has a broadcast set to `0.0.0.0`.
brandt added a commit to brandt/netlink that referenced this issue Oct 30, 2019
Since [vishvananda#248](vishvananda#248), adding an address automatically sets the broadcast if the broadcast address was not specified. This is undesirable when adding an IP with a prefixlen of /31 or /32. (Additional details in the issues linked below.)

This changes the behavior so that the broadcast is only automatically set if the prefixlen is /30 or larger.

Issue reported in:

- vishvananda#329
- vishvananda#471

See also:

- [RFC 3021](http://tools.ietf.org/html/rfc3021)

Alternatives to this PR:

A. vishvananda#472 - Adds `AddrAddWithoutCalculatedBroadcast`.
B. jjastrze-ovh@9a85a61 - Breaking change to make auto-setting the broadcast address an opt-in feature.
C. already works - Suppress setting the broadcast when addr's broadcast address is set to `0.0.0.0`. (This works today, but I'm not sure the behavior can be relied upon as a public API.)
vishvananda pushed a commit that referenced this issue Nov 13, 2019
Since [#248](#248), adding an address automatically sets the broadcast if the broadcast address was not specified. This is undesirable when adding an IP with a prefixlen of /31 or /32. (Additional details in the issues linked below.)

This changes the behavior so that the broadcast is only automatically set if the prefixlen is /30 or larger.

Issue reported in:

- #329
- #471

See also:

- [RFC 3021](http://tools.ietf.org/html/rfc3021)

Alternatives to this PR:

A. #472 - Adds `AddrAddWithoutCalculatedBroadcast`.
B. jjastrze-ovh@9a85a61 - Breaking change to make auto-setting the broadcast address an opt-in feature.
C. already works - Suppress setting the broadcast when addr's broadcast address is set to `0.0.0.0`. (This works today, but I'm not sure the behavior can be relied upon as a public API.)
gkodali-zededa pushed a commit to gkodali-zededa/netlink that referenced this issue May 21, 2021
Since [vishvananda#248](vishvananda#248), adding an address automatically sets the broadcast if the broadcast address was not specified. This is undesirable when adding an IP with a prefixlen of /31 or /32. (Additional details in the issues linked below.)

This changes the behavior so that the broadcast is only automatically set if the prefixlen is /30 or larger.

Issue reported in:

- vishvananda#329
- vishvananda#471

See also:

- [RFC 3021](http://tools.ietf.org/html/rfc3021)

Alternatives to this PR:

A. vishvananda#472 - Adds `AddrAddWithoutCalculatedBroadcast`.
B. jjastrze-ovh@9a85a61 - Breaking change to make auto-setting the broadcast address an opt-in feature.
C. already works - Suppress setting the broadcast when addr's broadcast address is set to `0.0.0.0`. (This works today, but I'm not sure the behavior can be relied upon as a public API.)
@alexanderstephan
Copy link

alexanderstephan commented Dec 26, 2022

I had a case where I don't want to have any brodcast IP at all, even if prefixlen < 31. To achieve this, I just set addr.Broadcast = net.IPv4Zero before calling netlink.AddrAdd.

I think this comment should get updated. For me, calling ip addr add $addr dev $link does not add the broadcast IP, so it is presumably not equalivalent.

@aboch
Copy link
Collaborator

aboch commented Dec 26, 2022

@alexanderstephan
Feel free to open a PR for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants