nm.wired: add support to accept-all-mac-addresses

This patch is introducing the `accept-all-mac-addresses` interface
property in Nmstate. The new property is a boolean, when True the NIC
will accept all packets.

It is supported only with NetworkManager 1.31 or greater.

Example:

```
---
interfaces:
- name: eth1
  type: ethernet
  state: up
  accept-all-mac-addresses: true
```

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
This commit is contained in:
Fernando Fernandez Mancera 2021-04-08 12:50:54 +02:00
parent c8b10e3024
commit 2df9c6aa4e
7 changed files with 62 additions and 5 deletions

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2020 Red Hat, Inc.
# Copyright (c) 2020-2021 Red Hat, Inc.
#
# This file is part of nmstate
#
@ -28,6 +28,7 @@ from libnmstate.schema import InterfaceType
DEFAULT_MAC_ADDRESS = "00:00:00:00:00:00"
PROMISC_FLAG = "promisc"
class NisporPluginBaseIface:
@ -67,6 +68,14 @@ class NisporPluginBaseIface:
)
return InterfaceState.DOWN
@property
def accept_all_mac_addresses(self):
np_flags = self._np_iface.flags
if PROMISC_FLAG in np_flags:
return True
return False
def _ip_info(self, config_only):
return {
Interface.IPV4: NisporPlugintIpState(
@ -83,6 +92,7 @@ class NisporPluginBaseIface:
Interface.TYPE: self.type,
Interface.STATE: self.state,
Interface.MAC: self.mac,
Interface.ACCEPT_ALL_MAC_ADDRESSES: self.accept_all_mac_addresses,
}
if self.mtu:
iface_info[Interface.MTU] = self.mtu

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2018-2020 Red Hat, Inc.
# Copyright (c) 2018-2021 Red Hat, Inc.
#
# This file is part of nmstate
#
@ -30,6 +30,9 @@ class WiredSetting:
def __init__(self, state):
self.mtu = state.get(Interface.MTU)
self.mac = state.get(Interface.MAC)
self.accept_all_mac_addrs = state.get(
Interface.ACCEPT_ALL_MAC_ADDRESSES
)
ethernet = state.get(Ethernet.CONFIG_SUBTREE, {})
self.speed = ethernet.get(Ethernet.SPEED)
@ -49,6 +52,7 @@ class WiredSetting:
return bool(
self.mac
or self.mtu
or (self.accept_all_mac_addrs is not None)
or self.speed
or self.duplex
or (self.auto_negotiation is not None)
@ -58,6 +62,7 @@ class WiredSetting:
return (
self.mtu,
self.mac,
self.accept_all_mac_addrs,
self.speed,
self.duplex,
self.auto_negotiation,
@ -85,6 +90,13 @@ def create_setting(iface_state, base_con_profile):
if setting.mtu:
nm_wired_setting.props.mtu = setting.mtu
if setting.accept_all_mac_addrs is not None and hasattr(
nm_wired_setting.props, "accept_all_mac_addresses"
):
nm_wired_setting.props.accept_all_mac_addresses = (
setting.accept_all_mac_addrs
)
if setting.auto_negotiation:
nm_wired_setting.props.auto_negotiate = True
if not setting.speed and not setting.duplex:

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2018-2020 Red Hat, Inc.
# Copyright (c) 2018-2021 Red Hat, Inc.
#
# This file is part of nmstate
#
@ -47,6 +47,7 @@ class Interface:
MAC = "mac-address"
MTU = "mtu"
COPY_MAC_FROM = "copy-mac-from"
ACCEPT_ALL_MAC_ADDRESSES = "accept-all-mac-addresses"
class Route:

View File

@ -110,6 +110,8 @@ definitions:
mtu:
type: integer
minimum: 0
accept-all-mac-addresses:
type: boolean
ro:
properties:
if-index:

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2019-2020 Red Hat, Inc.
# Copyright (c) 2019-2021 Red Hat, Inc.
#
# This file is part of nmstate
#
@ -32,6 +32,9 @@ from libnmstate.schema import InterfaceIPv4
from libnmstate.schema import InterfaceIPv6
from libnmstate.schema import InterfaceState
from .testlib.env import nm_major_minor_version
DUMMY_INTERFACE = "dummy_test"
@ -98,3 +101,21 @@ def test_take_over_virtual_interface_and_rollback(ip_link_dummy):
current_state = statelib.show_only((DUMMY_INTERFACE,))
assert len(current_state[Interface.KEY]) == 1
@pytest.mark.skipif(
nm_major_minor_version() < 1.31,
reason="Modifying accept-all-mac-addresses is not supported on NM.",
)
def test_enable_and_disable_accept_all_mac_addresses(eth1_up):
desired_state = eth1_up
desired_state[Interface.KEY][0][Interface.ACCEPT_ALL_MAC_ADDRESSES] = True
libnmstate.apply(desired_state)
current_state = statelib.show_only(("eth1",))
assert current_state[Interface.KEY][0][Interface.ACCEPT_ALL_MAC_ADDRESSES]
desired_state[Interface.KEY][0][Interface.ACCEPT_ALL_MAC_ADDRESSES] = False
libnmstate.apply(desired_state)
current_state = statelib.show_only(("eth1",))
eth1_state = current_state[Interface.KEY][0]
assert not eth1_state[Interface.ACCEPT_ALL_MAC_ADDRESSES]

View File

@ -42,6 +42,7 @@ LOOPBACK_JSON_CONFIG = """ {
"name": "lo",
"type": "unknown",
"state": "up",
"accept-all-mac-addresses": false,
"ipv4": {
"enabled": true,
"address": [
@ -67,6 +68,7 @@ LOOPBACK_JSON_CONFIG = """ {
LOOPBACK_YAML_CONFIG = """- name: lo
type: unknown
state: up
accept-all-mac-addresses: false
ipv4:
enabled: true
address:
@ -84,6 +86,7 @@ ETH1_YAML_CONFIG = b"""interfaces:
- name: eth1
state: up
type: ethernet
accept-all-mac-addresses: false
ipv4:
address:
- ip: 192.0.2.250

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2018-2020 Red Hat, Inc.
# Copyright (c) 2018-2021 Red Hat, Inc.
#
# This file is part of nmstate
#
@ -214,6 +214,14 @@ class TestIfaceMacAddress:
libnmstate.validator.schema_validate(default_data)
class TestIfaceAcceptAllMacAddresses:
@pytest.mark.parametrize("valid_values", [True, False])
def test_valid_accept_all_mac_addresses(self, default_data, valid_values):
ACCEPT_MAC_ADDRS = Interface.ACCEPT_ALL_MAC_ADDRESSES
default_data[Interface.KEY][0][ACCEPT_MAC_ADDRS] = valid_values
libnmstate.validator.schema_validate(default_data)
class TestIfaceTypeEthernet:
def test_valid_ethernet_with_auto_neg(self, default_data):
default_data[INTERFACES][0].update(