Bug 1928860
| Summary: | allow firewalld to set 16+ char long device names interfaces (like ovs interfaces can be) | |||
|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 8 | Reporter: | Vladimir Benes <vbenes> | |
| Component: | firewalld | Assignee: | Eric Garver <egarver> | |
| Status: | CLOSED ERRATA | QA Contact: | Štěpán Němec <snemec> | |
| Severity: | medium | Docs Contact: | ||
| Priority: | medium | |||
| Version: | 8.3 | CC: | acardace, amusil, atragler, bgalvani, egarver, lrintel, mburman, mperina, mtessun, pelauter, rkhan, sukulkar, thaller, till, todoleza, vbenes, ymankad | |
| Target Milestone: | rc | Keywords: | Triaged, Upstream, ZStream | |
| Target Release: | 8.0 | Flags: | pm-rhel:
mirror+
|
|
| Hardware: | Unspecified | |||
| OS: | Unspecified | |||
| Whiteboard: | ||||
| Fixed In Version: | firewalld-0.9.3-5.el8 | Doc Type: | No Doc Update | |
| Doc Text: | Story Points: | --- | ||
| Clone Of: | 1921107 | |||
| : | 1955594 (view as bug list) | Environment: | ||
| Last Closed: | 2021-11-09 18:55:58 UTC | Type: | Bug | |
| Regression: | --- | Mount Type: | --- | |
| Documentation: | --- | CRM: | ||
| Verified Versions: | Category: | --- | ||
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | ||
| Cloudforms Team: | --- | Target Upstream Version: | ||
| Embargoed: | ||||
| Bug Depends On: | 1921107 | |||
| Bug Blocks: | 1955594 | |||
|
Comment 1
Vladimir Benes
2021-02-15 17:10:06 UTC
I don't know what's expected from firewalld. On a reload firewalld queries NM for the connections in each zone, then adds the associated interfaces to those zones.
It's basically doing:
for interface in nm_get_interfaces():
conn = nm_get_connection_of_interface(interface)
if zone == nm_get_zone_of_connection(conn):
add_interface_to_zone(zone, interface)
I'm guessing ovs-interface-port shouldn't be part of a zone, e.g. default zone `public`, and therefore no assignment should be attempted.
@bgalvani,
Is there more criteria to check? Is this issue a result of the NM python module returning "" for non-assigned connection/interfaces? "" is used to mean the default zone.
The "connection.zone" property of a NM connection is a string and NULL/empty means the default zone. The problem here is that some connections don't have a kernel interface on which firewalld can set the zone. On a RHEL 8.4 VM yesterday I saw that when there is an OVS-port connection active and firewalld configuration is reloaded, firewalld would print an error saying that the interface is invalid, and it looked like I couldn't ping the machine anymore. I tried again on another VM today and I can no longer reproduce this issue. There is no error when I reload the configuration. Maybe yesterday there were some other conditions. What happens if firewalld tries to set the default zone on an interface (like an OVS port) that doesn't have a kernel interface? I withdraw what I said in the previous comment about not-existing kernel interfaces. firewalld seems to work fine with them. The actual problem (which can be seen by using the reproducer from https://bugzilla.redhat.com/show_bug.cgi?id=1921107#c0 ) is when the ovs-interface name is too long. ovs ports can have a name longer than 16 characters; if the name is too long, firewalld fails to reload: [root@localhost ~]# firewall-cmd --reload Error: INVALID_INTERFACE: ovs-interface-port [root@localhost ~]# firewall-cmd --state not running So I guess the fix should be that firewalld ignores such error. (In reply to Beniamino Galvani from comment #4) > I withdraw what I said in the previous comment about not-existing > kernel interfaces. firewalld seems to work fine with them. > > The actual problem (which can be seen by using the reproducer from > https://bugzilla.redhat.com/show_bug.cgi?id=1921107#c0 ) is when the > ovs-interface name is too long. > > ovs ports can have a name longer than 16 characters; if the name is > too long, firewalld fails to reload: > > [root@localhost ~]# firewall-cmd --reload > Error: INVALID_INTERFACE: ovs-interface-port > > [root@localhost ~]# firewall-cmd --state > not running > > So I guess the fix should be that firewalld ignores such error. So a simple workaround is to use an OVS port with a name <= 16 characters ? (In reply to Eric Garver from comment #5) > > So a simple workaround is to use an OVS port with a name <= 16 characters ? Yes, according to my tests, that solves the problem. > IMO, firewalld is doing the correct thing and rejecting the interface name. What do you think? Should the fix be on the NM side, i.e. NM shouldn't be telling firewalld to add an invalid interface name to a zone. (Certain) OVS devices don't have a netdev device. That is, you cannot see them in `ip link`. Consequently, you cannot configure IP addresses on them or iptables/nft. Since https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/737, NM shold never tell firewalld to put such a device into a firewall zone. This isn't so much about the length of the interface name, it's true for all OVS devices (of this kind). If firewalld trips over long (OVS) device names, then it indicates that it uses devices that it should ignore in the first place. As indicated in comment 2, firewalld queries NM for connections/interfaces in the default zone. NM is returning the over-the-length-limit OVS interface - presumably while processing the default zone, e.g. "". If NM does not plan to fix/change anything, then we'll have to check for and ignore over-the-length-limit interface names on the firewalld side. I consider this a hack. IMO NM should not be returning the OVS interfaces. > I consider this a hack. IMO NM should not be returning the OVS interfaces. On the D-Bus API, not all devices are actual devices that you see in `ip link`. That's the case for (certain) OVS devices or for bluetooth/modem devices. There is libnm API nm_device_get_ip_iface(), which gives the name of the interface where IP configuration can be done (or none). Different from nm_device_get_iface(), which is some name that may not be the same as the ip-iface name. firewalld uses nm_client_get_device_by_iface() ([1]), there is no nm_client_get_device_by_ip_iface(): [1] https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/3affccf29b53976a0cef5ea662f913d4913d44c8/src/libnm-client-impl/nm-client.c#L4846 But of course, that function is easy to implement yourself: dev = next((d for d in nmc.get_devices() if d.get_ip_iface() == ip_iface), None) What should be improved is NM's D-Bus API so that it's clearer which devices represent an interface visible in `ip link`. Also, the ifindex should be exposed (which currently isn't). But I don't think that is necessary for firewalld here. Checking for "over-the-length-limit interface names" is not right, because that is not the real problem. (In reply to Thomas Haller from comment #14) Thanks for the info in comment 14. That makes it clear what we should do on the firewalld side. > Checking for "over-the-length-limit interface names" is not right, because > that is not the real problem. It's part of the problem. 1. >=16 char needs to be ignored by firewalld because it's invalid for iptables/nftables 2. we need to make sure there is a real interface Using *get_ip_iface() APIs should solve both. As I understand it #2 guarantees #1. iptables/nftables will let you match interfaces that don't exist. But will reject >=16 char. To be clear, nm_device_get_ip_iface() is supposed to either return NULL or a valid interface name (meaning, no '/', no "..", IFNAMSIZ length limit). Well, almost... if the interface name is not valid UTF-8, like # ip link add $'d\xccf\\c' type dummy then the name will be backslash escaped. That escaping can be undone with g_strcompress(). But if the string contains no ASCII backslash, it's just the plain name in UTF-8. Using reproduce from bug 1921107 yields a failure to bring up the ovs interface. Is up-ing ovs-interface expected to succeed? See line comments (##). # dnf info NetworkManager-ovs Installed Packages Name : NetworkManager-ovs Epoch : 1 Version : 1.32.0 Release : 0.1.el8 # sh /tmp/reproducer.sh Error: unknown connection 'ovs-br'. Error: cannot delete unknown connection(s): 'ovs-br'. Error: unknown connection 'ovs-interface-port'. Error: cannot delete unknown connection(s): 'ovs-interface-port'. Error: unknown connection 'ovs-interface'. Error: cannot delete unknown connection(s): 'ovs-interface'. success running Connection 'ovs-br' (2d8ad18f-48a1-47c1-bed6-3393cf612d04) successfully added. Connection 'ovs-interface-port' (9427ff1d-204d-48ea-8fd8-6f2ea5cce2ac) successfully added. Connection 'ovs-interface' (6bf02828-ed1e-46fe-860a-43219ace350c) successfully added. NAME UUID TYPE DEVICE> ens3 cee908a1-62c0-4919-98e6-e85c5b81fd25 ethernet ens3 > ovs-br 2d8ad18f-48a1-47c1-bed6-3393cf612d04 ovs-bridge ovs-br> ovs-interface-port 9427ff1d-204d-48ea-8fd8-6f2ea5cce2ac ovs-port ovs-in> ovs-interface 6bf02828-ed1e-46fe-860a-43219ace350c ovs-interface -- > Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/20) Connection successfully activated (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/22) Error: Timeout expired (90 seconds) ## Timeout here means "nmcli conn up ovs-interface" fails NAME UUID TYPE DEVICE> ovs-interface 6bf02828-ed1e-46fe-860a-43219ace350c ovs-interface ovs-br> ens3 cee908a1-62c0-4919-98e6-e85c5b81fd25 ethernet ens3 > ovs-br 2d8ad18f-48a1-47c1-bed6-3393cf612d04 ovs-bridge ovs-br> ovs-interface-port 9427ff1d-204d-48ea-8fd8-6f2ea5cce2ac ovs-port ovs-in> Error: INVALID_INTERFACE: ovs-interface-port not running ## firewalld reload fails as expect (this bug) Upstream PR: https://github.com/firewalld/firewalld/pull/791 Will merge after CI completes. Upstream:
7566d3dc5664 ("test(nm): reload: only consider NM connections with a real interface")
f18f1cc96503 ("fix(nm): reload: only consider NM connections with a real interface")
Created attachment 1790167 [details]
test log
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory (firewalld bug fix and enhancement update), and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHBA-2021:4355 |