aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2023-02-09 14:53:44 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2023-02-20 14:33:28 +0000
commit72467b39f1db794f2ac54ac9baa1de3166507c6b (patch)
treecd8c9603e22b687bf6a35c705e66e2212c55df53 /tests
parentac40ea6fbb4e6af98a4540fc8fd5a3e824cb181d (diff)
downloadsrc-72467b39f1db794f2ac54ac9baa1de3166507c6b.tar.gz
src-72467b39f1db794f2ac54ac9baa1de3166507c6b.zip
netlink: return optional metadata with the operation result.
Some operations like interface creation may need to return metadata - in this case, interface name - back to the caller if the operation is successful. This change implements attaching an `NLMSGERR_ATTR_COOKIE` nla to the operation reply message via `nlmsg_report_cookie()`. Additionally, on successful interface creation, interface index and interface name are returned in the `IFLA_NEW_IFINDEX` and `IFLA_IFNAME TLVs, encapsulated in the `NLMSGERR_ATTR_COOKIE`. Reviewed By: pauamma Differential Revision: https://reviews.freebsd.org/D38283 MFC after: 1 week (cherry picked from commit 25c2dd2f2c6c6144d59d463c95f0471301d6efaa)
Diffstat (limited to 'tests')
-rw-r--r--tests/atf_python/sys/net/netlink.py134
-rw-r--r--tests/sys/netlink/test_rtnl_iface.py35
2 files changed, 109 insertions, 60 deletions
diff --git a/tests/atf_python/sys/net/netlink.py b/tests/atf_python/sys/net/netlink.py
index 57c8582627cf..ba7d41c7cbf8 100644
--- a/tests/atf_python/sys/net/netlink.py
+++ b/tests/atf_python/sys/net/netlink.py
@@ -950,58 +950,68 @@ def prepare_attrs_map(attrs: List[AttrDescr]) -> Dict[str, Dict]:
return ret
-rtnl_route_attrs = [
- AttrDescr(RtattrType.RTA_DST, NlAttrIp),
- AttrDescr(RtattrType.RTA_SRC, NlAttrIp),
- AttrDescr(RtattrType.RTA_IIF, NlAttrIfindex),
- AttrDescr(RtattrType.RTA_OIF, NlAttrIfindex),
- AttrDescr(RtattrType.RTA_GATEWAY, NlAttrTable),
- AttrDescr(RtattrType.RTA_VIA, NlAttrVia),
- AttrDescr(RtattrType.RTA_NH_ID, NlAttrNhId),
- AttrDescr(
- RtattrType.RTA_METRICS,
- NlAttrNested,
- [
- AttrDescr(NlRtaxType.RTAX_MTU, NlAttrU32),
- ],
- ),
-]
-
-nldone_attrs = []
-
-nlerr_attrs = [
- AttrDescr(NlErrattrType.NLMSGERR_ATTR_MSG, NlAttrStr),
- AttrDescr(NlErrattrType.NLMSGERR_ATTR_OFFS, NlAttrU32),
-]
-
-rtnl_ifla_attrs = [
- AttrDescr(IflattrType.IFLA_ADDRESS, NlAttrMac),
- AttrDescr(IflattrType.IFLA_BROADCAST, NlAttrMac),
- AttrDescr(IflattrType.IFLA_IFNAME, NlAttrStr),
- AttrDescr(IflattrType.IFLA_MTU, NlAttrU32),
- AttrDescr(IflattrType.IFLA_PROMISCUITY, NlAttrU32),
- AttrDescr(IflattrType.IFLA_OPERSTATE, NlAttrU8),
- AttrDescr(IflattrType.IFLA_CARRIER, NlAttrU8),
- AttrDescr(IflattrType.IFLA_IFALIAS, NlAttrStr),
- AttrDescr(IflattrType.IFLA_STATS64, NlAttrIfStats),
- AttrDescr(
- IflattrType.IFLA_LINKINFO,
- NlAttrNested,
- [
- AttrDescr(IflinkInfo.IFLA_INFO_KIND, NlAttrStr),
- AttrDescr(IflinkInfo.IFLA_INFO_DATA, NlAttr),
- ],
- ),
-]
-
-rtnl_ifa_attrs = [
- AttrDescr(IfattrType.IFA_ADDRESS, NlAttrIp),
- AttrDescr(IfattrType.IFA_LOCAL, NlAttrIp),
- AttrDescr(IfattrType.IFA_LABEL, NlAttrStr),
- AttrDescr(IfattrType.IFA_BROADCAST, NlAttrIp),
- AttrDescr(IfattrType.IFA_ANYCAST, NlAttrIp),
- AttrDescr(IfattrType.IFA_FLAGS, NlAttrU32),
-]
+rtnl_route_attrs = prepare_attrs_map(
+ [
+ AttrDescr(RtattrType.RTA_DST, NlAttrIp),
+ AttrDescr(RtattrType.RTA_SRC, NlAttrIp),
+ AttrDescr(RtattrType.RTA_IIF, NlAttrIfindex),
+ AttrDescr(RtattrType.RTA_OIF, NlAttrIfindex),
+ AttrDescr(RtattrType.RTA_GATEWAY, NlAttrTable),
+ AttrDescr(RtattrType.RTA_VIA, NlAttrVia),
+ AttrDescr(RtattrType.RTA_NH_ID, NlAttrNhId),
+ AttrDescr(
+ RtattrType.RTA_METRICS,
+ NlAttrNested,
+ [
+ AttrDescr(NlRtaxType.RTAX_MTU, NlAttrU32),
+ ],
+ ),
+ ]
+)
+
+nldone_attrs = prepare_attrs_map([])
+
+nlerr_attrs = prepare_attrs_map(
+ [
+ AttrDescr(NlErrattrType.NLMSGERR_ATTR_MSG, NlAttrStr),
+ AttrDescr(NlErrattrType.NLMSGERR_ATTR_OFFS, NlAttrU32),
+ AttrDescr(NlErrattrType.NLMSGERR_ATTR_COOKIE, NlAttr),
+ ]
+)
+
+rtnl_ifla_attrs = prepare_attrs_map(
+ [
+ AttrDescr(IflattrType.IFLA_ADDRESS, NlAttrMac),
+ AttrDescr(IflattrType.IFLA_BROADCAST, NlAttrMac),
+ AttrDescr(IflattrType.IFLA_IFNAME, NlAttrStr),
+ AttrDescr(IflattrType.IFLA_MTU, NlAttrU32),
+ AttrDescr(IflattrType.IFLA_PROMISCUITY, NlAttrU32),
+ AttrDescr(IflattrType.IFLA_OPERSTATE, NlAttrU8),
+ AttrDescr(IflattrType.IFLA_CARRIER, NlAttrU8),
+ AttrDescr(IflattrType.IFLA_IFALIAS, NlAttrStr),
+ AttrDescr(IflattrType.IFLA_STATS64, NlAttrIfStats),
+ AttrDescr(IflattrType.IFLA_NEW_IFINDEX, NlAttrU32),
+ AttrDescr(
+ IflattrType.IFLA_LINKINFO,
+ NlAttrNested,
+ [
+ AttrDescr(IflinkInfo.IFLA_INFO_KIND, NlAttrStr),
+ AttrDescr(IflinkInfo.IFLA_INFO_DATA, NlAttr),
+ ],
+ ),
+ ]
+)
+
+rtnl_ifa_attrs = prepare_attrs_map(
+ [
+ AttrDescr(IfattrType.IFA_ADDRESS, NlAttrIp),
+ AttrDescr(IfattrType.IFA_LOCAL, NlAttrIp),
+ AttrDescr(IfattrType.IFA_LABEL, NlAttrStr),
+ AttrDescr(IfattrType.IFA_BROADCAST, NlAttrIp),
+ AttrDescr(IfattrType.IFA_ANYCAST, NlAttrIp),
+ AttrDescr(IfattrType.IFA_FLAGS, NlAttrU32),
+ ]
+)
class BaseNetlinkMessage(object):
@@ -1140,7 +1150,7 @@ class StdNetlinkMessage(BaseNetlinkMessage):
raise
return self
- def _parse_attrs(self, data: bytes, attr_map):
+ def parse_attrs(self, data: bytes, attr_map):
ret = []
off = 0
while len(data) - off >= 4:
@@ -1157,7 +1167,7 @@ class StdNetlinkMessage(BaseNetlinkMessage):
val = v["ad"].cls.from_bytes(data[off : off + nla_len], v["ad"].val)
if "child" in v:
# nested
- attrs, _ = self._parse_attrs(data[off : off + nla_len], v["child"])
+ attrs, _ = self.parse_attrs(data[off : off + nla_len], v["child"])
val = NlAttrNested(raw_nla_type, attrs)
else:
# unknown attribute
@@ -1167,7 +1177,7 @@ class StdNetlinkMessage(BaseNetlinkMessage):
return ret, off
def parse_nla_list(self, data: bytes) -> List[NlAttr]:
- return self._parse_attrs(data, self.nl_attrs_map)
+ return self.parse_attrs(data, self.nl_attrs_map)
def print_message(self):
self.print_nl_header(self.nl_hdr)
@@ -1178,7 +1188,7 @@ class StdNetlinkMessage(BaseNetlinkMessage):
class NetlinkDoneMessage(StdNetlinkMessage):
messages = [NlMsgType.NLMSG_DONE.value]
- nl_attrs_map = prepare_attrs_map(nldone_attrs)
+ nl_attrs_map = nldone_attrs
@property
def error_code(self):
@@ -1197,7 +1207,7 @@ class NetlinkDoneMessage(StdNetlinkMessage):
class NetlinkErrorMessage(StdNetlinkMessage):
messages = [NlMsgType.NLMSG_ERROR.value]
- nl_attrs_map = prepare_attrs_map(nlerr_attrs)
+ nl_attrs_map = nlerr_attrs
@property
def error_code(self):
@@ -1217,6 +1227,10 @@ class NetlinkErrorMessage(StdNetlinkMessage):
return nla.u32
return None
+ @property
+ def cookie(self):
+ return self.get_nla(NlErrattrType.NLMSGERR_ATTR_COOKIE)
+
def parse_base_header(self, data):
if len(data) < sizeof(Nlmsgerr):
raise ValueError("length less than nlmsgerr header")
@@ -1257,7 +1271,7 @@ class NetlinkRtMessage(BaseNetlinkRtMessage):
NlRtMsgType.RTM_DELROUTE.value,
NlRtMsgType.RTM_GETROUTE.value,
]
- nl_attrs_map = prepare_attrs_map(rtnl_route_attrs)
+ nl_attrs_map = rtnl_route_attrs
def __init__(self, helper, nlm_type):
super().__init__(helper, nlm_type)
@@ -1297,7 +1311,7 @@ class NetlinkIflaMessage(BaseNetlinkRtMessage):
NlRtMsgType.RTM_DELLINK.value,
NlRtMsgType.RTM_GETLINK.value,
]
- nl_attrs_map = prepare_attrs_map(rtnl_ifla_attrs)
+ nl_attrs_map = rtnl_ifla_attrs
def __init__(self, helper, nlm_type):
super().__init__(helper, nlm_type)
@@ -1329,7 +1343,7 @@ class NetlinkIfaMessage(BaseNetlinkRtMessage):
NlRtMsgType.RTM_DELADDR.value,
NlRtMsgType.RTM_GETADDR.value,
]
- nl_attrs_map = prepare_attrs_map(rtnl_ifa_attrs)
+ nl_attrs_map = rtnl_ifa_attrs
def __init__(self, helper, nlm_type):
super().__init__(helper, nlm_type)
diff --git a/tests/sys/netlink/test_rtnl_iface.py b/tests/sys/netlink/test_rtnl_iface.py
index 7cff592b1676..ecc932c6213e 100644
--- a/tests/sys/netlink/test_rtnl_iface.py
+++ b/tests/sys/netlink/test_rtnl_iface.py
@@ -17,6 +17,7 @@ from atf_python.sys.net.netlink import NlmBaseFlags
from atf_python.sys.net.netlink import NlmNewFlags
from atf_python.sys.net.netlink import NlMsgType
from atf_python.sys.net.netlink import NlRtMsgType
+from atf_python.sys.net.netlink import rtnl_ifla_attrs
from atf_python.sys.net.vnet import SingleVnetTestTemplate
@@ -92,6 +93,40 @@ class TestRtNlIface(NetlinkTestTemplate, SingleVnetTestTemplate):
self.get_interface_byname("lo10")
@pytest.mark.require_user("root")
+ def test_create_iface_plain_retvals(self):
+ """Tests loopback creation w/o any parameters"""
+ flags = NlmNewFlags.NLM_F_EXCL.value | NlmNewFlags.NLM_F_CREATE.value
+ msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_NEWLINK.value)
+ msg.nl_hdr.nlmsg_flags = (
+ flags | NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
+ )
+ msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, "lo10"))
+ msg.add_nla(
+ NlAttrNested(
+ IflattrType.IFLA_LINKINFO,
+ [
+ NlAttrStrn(IflinkInfo.IFLA_INFO_KIND, "lo"),
+ ],
+ )
+ )
+
+ rx_msg = self.get_reply(msg)
+ assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
+ assert rx_msg.error_code == 0
+ assert rx_msg.cookie is not None
+ nla_list, _ = rx_msg.parse_attrs(bytes(rx_msg.cookie)[4:], rtnl_ifla_attrs)
+ nla_map = {n.nla_type: n for n in nla_list}
+ assert IflattrType.IFLA_IFNAME.value in nla_map
+ assert nla_map[IflattrType.IFLA_IFNAME.value].text == "lo10"
+ assert IflattrType.IFLA_NEW_IFINDEX.value in nla_map
+ assert nla_map[IflattrType.IFLA_NEW_IFINDEX.value].u32 > 0
+
+ lo_msg = self.get_interface_byname("lo10")
+ assert (
+ lo_msg.base_hdr.ifi_index == nla_map[IflattrType.IFLA_NEW_IFINDEX.value].u32
+ )
+
+ @pytest.mark.require_user("root")
def test_create_iface_attrs(self):
"""Tests interface creation with additional properties"""
flags = NlmNewFlags.NLM_F_EXCL.value | NlmNewFlags.NLM_F_CREATE.value