xref: /freebsd/tests/sys/netlink/test_rtnl_iface.py (revision 2d49ff1e21a74b8f641752b63a59dc3ef9e38ddc)
180f03e63SAlexander V. Chernikovimport errno
280f03e63SAlexander V. Chernikovimport socket
380f03e63SAlexander V. Chernikov
480f03e63SAlexander V. Chernikovimport pytest
5fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink_route import IflattrType
6fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink_route import IflinkInfo
7fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink_route import IfLinkInfoDataVlan
8fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink_route import NetlinkIflaMessage
9fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink import NetlinkTestTemplate
10fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.attrs import NlAttrNested
11fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.attrs import NlAttrStr
12fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.attrs import NlAttrStrn
13fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.attrs import NlAttrU16
14fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.attrs import NlAttrU32
15fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.utils import NlConst
16fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.base_headers import NlmBaseFlags
17fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.base_headers import NlmNewFlags
18fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.base_headers import NlMsgType
19fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink_route import NlRtMsgType
20fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink_route import rtnl_ifla_attrs
2180f03e63SAlexander V. Chernikovfrom atf_python.sys.net.vnet import SingleVnetTestTemplate
22089104e0SAlexander V. Chernikovfrom atf_python.sys.net.tools import ToolsHelper
2380f03e63SAlexander V. Chernikov
2480f03e63SAlexander V. Chernikov
259408f366SAlexander V. Chernikovclass TestRtNlIface(NetlinkTestTemplate, SingleVnetTestTemplate):
2680f03e63SAlexander V. Chernikov    def setup_method(self, method):
2780f03e63SAlexander V. Chernikov        super().setup_method(method)
28c1871a33SAlexander V. Chernikov        self.setup_netlink(NlConst.NETLINK_ROUTE)
2980f03e63SAlexander V. Chernikov
3080f03e63SAlexander V. Chernikov    def get_interface_byname(self, ifname):
3180f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_GETLINK.value)
3280f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
3380f03e63SAlexander V. Chernikov            NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
3480f03e63SAlexander V. Chernikov        )
3580f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, ifname))
3680f03e63SAlexander V. Chernikov        self.write_message(msg)
3780f03e63SAlexander V. Chernikov        while True:
3880f03e63SAlexander V. Chernikov            rx_msg = self.read_message()
3980f03e63SAlexander V. Chernikov            if msg.nl_hdr.nlmsg_seq == rx_msg.nl_hdr.nlmsg_seq:
4080f03e63SAlexander V. Chernikov                if rx_msg.is_type(NlMsgType.NLMSG_ERROR):
4180f03e63SAlexander V. Chernikov                    if rx_msg.error_code != 0:
4280f03e63SAlexander V. Chernikov                        raise ValueError("unable to get interface {}".format(ifname))
4380f03e63SAlexander V. Chernikov                elif rx_msg.is_type(NlRtMsgType.RTM_NEWLINK):
4480f03e63SAlexander V. Chernikov                    return rx_msg
4580f03e63SAlexander V. Chernikov                else:
4680f03e63SAlexander V. Chernikov                    raise ValueError("bad message")
4780f03e63SAlexander V. Chernikov
4880f03e63SAlexander V. Chernikov    def test_get_iface_byname_error(self):
4980f03e63SAlexander V. Chernikov        """Tests error on fetching non-existing interface name"""
5080f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_GETLINK.value)
5180f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
5280f03e63SAlexander V. Chernikov            NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
5380f03e63SAlexander V. Chernikov        )
5480f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, "lo10"))
5580f03e63SAlexander V. Chernikov
5680f03e63SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
5780f03e63SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
5880f03e63SAlexander V. Chernikov        assert rx_msg.error_code == errno.ENODEV
5980f03e63SAlexander V. Chernikov
6080f03e63SAlexander V. Chernikov    def test_get_iface_byindex_error(self):
6180f03e63SAlexander V. Chernikov        """Tests error on fetching non-existing interface index"""
6280f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_GETLINK.value)
6380f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
6480f03e63SAlexander V. Chernikov            NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
6580f03e63SAlexander V. Chernikov        )
6680f03e63SAlexander V. Chernikov        msg.base_hdr.ifi_index = 2147483647
6780f03e63SAlexander V. Chernikov
6880f03e63SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
6980f03e63SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
7080f03e63SAlexander V. Chernikov        assert rx_msg.error_code == errno.ENODEV
7180f03e63SAlexander V. Chernikov
7280f03e63SAlexander V. Chernikov    @pytest.mark.require_user("root")
7380f03e63SAlexander V. Chernikov    def test_create_iface_plain(self):
7480f03e63SAlexander V. Chernikov        """Tests loopback creation w/o any parameters"""
7580f03e63SAlexander V. Chernikov        flags = NlmNewFlags.NLM_F_EXCL.value | NlmNewFlags.NLM_F_CREATE.value
7680f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_NEWLINK.value)
7780f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
7880f03e63SAlexander V. Chernikov            flags | NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
7980f03e63SAlexander V. Chernikov        )
8080f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, "lo10"))
8180f03e63SAlexander V. Chernikov        msg.add_nla(
8280f03e63SAlexander V. Chernikov            NlAttrNested(
8380f03e63SAlexander V. Chernikov                IflattrType.IFLA_LINKINFO,
8480f03e63SAlexander V. Chernikov                [
8580f03e63SAlexander V. Chernikov                    NlAttrStrn(IflinkInfo.IFLA_INFO_KIND, "lo"),
8680f03e63SAlexander V. Chernikov                ],
8780f03e63SAlexander V. Chernikov            )
8880f03e63SAlexander V. Chernikov        )
8980f03e63SAlexander V. Chernikov
9080f03e63SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
9180f03e63SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
9280f03e63SAlexander V. Chernikov        assert rx_msg.error_code == 0
9380f03e63SAlexander V. Chernikov
9480f03e63SAlexander V. Chernikov        self.get_interface_byname("lo10")
9580f03e63SAlexander V. Chernikov
9680f03e63SAlexander V. Chernikov    @pytest.mark.require_user("root")
9725c2dd2fSAlexander V. Chernikov    def test_create_iface_plain_retvals(self):
9825c2dd2fSAlexander V. Chernikov        """Tests loopback creation w/o any parameters"""
9925c2dd2fSAlexander V. Chernikov        flags = NlmNewFlags.NLM_F_EXCL.value | NlmNewFlags.NLM_F_CREATE.value
10025c2dd2fSAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_NEWLINK.value)
10125c2dd2fSAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
10225c2dd2fSAlexander V. Chernikov            flags | NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
10325c2dd2fSAlexander V. Chernikov        )
10425c2dd2fSAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, "lo10"))
10525c2dd2fSAlexander V. Chernikov        msg.add_nla(
10625c2dd2fSAlexander V. Chernikov            NlAttrNested(
10725c2dd2fSAlexander V. Chernikov                IflattrType.IFLA_LINKINFO,
10825c2dd2fSAlexander V. Chernikov                [
10925c2dd2fSAlexander V. Chernikov                    NlAttrStrn(IflinkInfo.IFLA_INFO_KIND, "lo"),
11025c2dd2fSAlexander V. Chernikov                ],
11125c2dd2fSAlexander V. Chernikov            )
11225c2dd2fSAlexander V. Chernikov        )
11325c2dd2fSAlexander V. Chernikov
11425c2dd2fSAlexander V. Chernikov        rx_msg = self.get_reply(msg)
11525c2dd2fSAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
11625c2dd2fSAlexander V. Chernikov        assert rx_msg.error_code == 0
11725c2dd2fSAlexander V. Chernikov        assert rx_msg.cookie is not None
11825c2dd2fSAlexander V. Chernikov        nla_list, _ = rx_msg.parse_attrs(bytes(rx_msg.cookie)[4:], rtnl_ifla_attrs)
11925c2dd2fSAlexander V. Chernikov        nla_map = {n.nla_type: n for n in nla_list}
12025c2dd2fSAlexander V. Chernikov        assert IflattrType.IFLA_IFNAME.value in nla_map
12125c2dd2fSAlexander V. Chernikov        assert nla_map[IflattrType.IFLA_IFNAME.value].text == "lo10"
12225c2dd2fSAlexander V. Chernikov        assert IflattrType.IFLA_NEW_IFINDEX.value in nla_map
12325c2dd2fSAlexander V. Chernikov        assert nla_map[IflattrType.IFLA_NEW_IFINDEX.value].u32 > 0
12425c2dd2fSAlexander V. Chernikov
12525c2dd2fSAlexander V. Chernikov        lo_msg = self.get_interface_byname("lo10")
12625c2dd2fSAlexander V. Chernikov        assert (
12725c2dd2fSAlexander V. Chernikov            lo_msg.base_hdr.ifi_index == nla_map[IflattrType.IFLA_NEW_IFINDEX.value].u32
12825c2dd2fSAlexander V. Chernikov        )
12925c2dd2fSAlexander V. Chernikov
13025c2dd2fSAlexander V. Chernikov    @pytest.mark.require_user("root")
13180f03e63SAlexander V. Chernikov    def test_create_iface_attrs(self):
13280f03e63SAlexander V. Chernikov        """Tests interface creation with additional properties"""
13380f03e63SAlexander V. Chernikov        flags = NlmNewFlags.NLM_F_EXCL.value | NlmNewFlags.NLM_F_CREATE.value
13480f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_NEWLINK.value)
13580f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
13680f03e63SAlexander V. Chernikov            flags | NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
13780f03e63SAlexander V. Chernikov        )
13880f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, "lo10"))
13980f03e63SAlexander V. Chernikov        msg.add_nla(
14080f03e63SAlexander V. Chernikov            NlAttrNested(
14180f03e63SAlexander V. Chernikov                IflattrType.IFLA_LINKINFO,
14280f03e63SAlexander V. Chernikov                [
14380f03e63SAlexander V. Chernikov                    NlAttrStrn(IflinkInfo.IFLA_INFO_KIND, "lo"),
14480f03e63SAlexander V. Chernikov                ],
14580f03e63SAlexander V. Chernikov            )
14680f03e63SAlexander V. Chernikov        )
14780f03e63SAlexander V. Chernikov
14880f03e63SAlexander V. Chernikov        # Custom attributes
14980f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFALIAS, "test description"))
15080f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrU32(IflattrType.IFLA_MTU, 1024))
15180f03e63SAlexander V. Chernikov
15280f03e63SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
15380f03e63SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
15480f03e63SAlexander V. Chernikov        assert rx_msg.error_code == 0
15580f03e63SAlexander V. Chernikov
15680f03e63SAlexander V. Chernikov        iface_msg = self.get_interface_byname("lo10")
15780f03e63SAlexander V. Chernikov        assert iface_msg.get_nla(IflattrType.IFLA_IFALIAS).text == "test description"
15880f03e63SAlexander V. Chernikov        assert iface_msg.get_nla(IflattrType.IFLA_MTU).u32 == 1024
15980f03e63SAlexander V. Chernikov
16080f03e63SAlexander V. Chernikov    @pytest.mark.require_user("root")
16180f03e63SAlexander V. Chernikov    def test_modify_iface_attrs(self):
16280f03e63SAlexander V. Chernikov        """Tests interface modifications"""
16380f03e63SAlexander V. Chernikov        flags = NlmNewFlags.NLM_F_EXCL.value | NlmNewFlags.NLM_F_CREATE.value
16480f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_NEWLINK.value)
16580f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
16680f03e63SAlexander V. Chernikov            flags | NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
16780f03e63SAlexander V. Chernikov        )
16880f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, "lo10"))
16980f03e63SAlexander V. Chernikov        msg.add_nla(
17080f03e63SAlexander V. Chernikov            NlAttrNested(
17180f03e63SAlexander V. Chernikov                IflattrType.IFLA_LINKINFO,
17280f03e63SAlexander V. Chernikov                [
17380f03e63SAlexander V. Chernikov                    NlAttrStrn(IflinkInfo.IFLA_INFO_KIND, "lo"),
17480f03e63SAlexander V. Chernikov                ],
17580f03e63SAlexander V. Chernikov            )
17680f03e63SAlexander V. Chernikov        )
17780f03e63SAlexander V. Chernikov
17880f03e63SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
17980f03e63SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
18080f03e63SAlexander V. Chernikov        assert rx_msg.error_code == 0
18180f03e63SAlexander V. Chernikov
18280f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_NEWLINK.value)
18380f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
18480f03e63SAlexander V. Chernikov            NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
18580f03e63SAlexander V. Chernikov        )
18680f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, "lo10"))
18780f03e63SAlexander V. Chernikov
18880f03e63SAlexander V. Chernikov        # Custom attributes
18980f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFALIAS, "test description"))
19080f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrU32(IflattrType.IFLA_MTU, 1024))
19180f03e63SAlexander V. Chernikov
19280f03e63SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
19380f03e63SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
19480f03e63SAlexander V. Chernikov        assert rx_msg.error_code == 0
19580f03e63SAlexander V. Chernikov
19680f03e63SAlexander V. Chernikov        iface_msg = self.get_interface_byname("lo10")
19780f03e63SAlexander V. Chernikov        assert iface_msg.get_nla(IflattrType.IFLA_IFALIAS).text == "test description"
19880f03e63SAlexander V. Chernikov        assert iface_msg.get_nla(IflattrType.IFLA_MTU).u32 == 1024
19980f03e63SAlexander V. Chernikov
20080f03e63SAlexander V. Chernikov    @pytest.mark.require_user("root")
20180f03e63SAlexander V. Chernikov    def test_delete_iface(self):
20280f03e63SAlexander V. Chernikov        """Tests interface modifications"""
20380f03e63SAlexander V. Chernikov        flags = NlmNewFlags.NLM_F_EXCL.value | NlmNewFlags.NLM_F_CREATE.value
20480f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_NEWLINK.value)
20580f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
20680f03e63SAlexander V. Chernikov            flags | NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
20780f03e63SAlexander V. Chernikov        )
20880f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, "lo10"))
20980f03e63SAlexander V. Chernikov        msg.add_nla(
21080f03e63SAlexander V. Chernikov            NlAttrNested(
21180f03e63SAlexander V. Chernikov                IflattrType.IFLA_LINKINFO,
21280f03e63SAlexander V. Chernikov                [
21380f03e63SAlexander V. Chernikov                    NlAttrStrn(IflinkInfo.IFLA_INFO_KIND, "lo"),
21480f03e63SAlexander V. Chernikov                ],
21580f03e63SAlexander V. Chernikov            )
21680f03e63SAlexander V. Chernikov        )
21780f03e63SAlexander V. Chernikov
21880f03e63SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
21980f03e63SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
22080f03e63SAlexander V. Chernikov        assert rx_msg.error_code == 0
22180f03e63SAlexander V. Chernikov
22280f03e63SAlexander V. Chernikov        iface_msg = self.get_interface_byname("lo10")
22380f03e63SAlexander V. Chernikov        iface_idx = iface_msg.base_hdr.ifi_index
22480f03e63SAlexander V. Chernikov
22580f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_DELLINK.value)
22680f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
22780f03e63SAlexander V. Chernikov            NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
22880f03e63SAlexander V. Chernikov        )
22980f03e63SAlexander V. Chernikov        msg.base_hdr.ifi_index = iface_idx
23080f03e63SAlexander V. Chernikov        # msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, "lo10"))
23180f03e63SAlexander V. Chernikov
23280f03e63SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
23380f03e63SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
23480f03e63SAlexander V. Chernikov        assert rx_msg.error_code == 0
23580f03e63SAlexander V. Chernikov
23680f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_GETLINK.value)
23780f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
23880f03e63SAlexander V. Chernikov            NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
23980f03e63SAlexander V. Chernikov        )
24080f03e63SAlexander V. Chernikov        msg.base_hdr.ifi_index = 2147483647
24180f03e63SAlexander V. Chernikov
24280f03e63SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
24380f03e63SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
24480f03e63SAlexander V. Chernikov        assert rx_msg.error_code == errno.ENODEV
24580f03e63SAlexander V. Chernikov
24686fd0bdbSAlexander V. Chernikov    @pytest.mark.require_user("root")
24786fd0bdbSAlexander V. Chernikov    def test_dump_ifaces_many(self):
24886fd0bdbSAlexander V. Chernikov        """Tests if interface dummp is not missing interfaces"""
24986fd0bdbSAlexander V. Chernikov
25086fd0bdbSAlexander V. Chernikov        ifmap = {}
25179748cecSAlexander V. Chernikov        ifmap[socket.if_nametoindex("lo0")] = "lo0"
25286fd0bdbSAlexander V. Chernikov
25386fd0bdbSAlexander V. Chernikov        for i in range(40):
25486fd0bdbSAlexander V. Chernikov            ifname = "lo{}".format(i + 1)
25586fd0bdbSAlexander V. Chernikov            flags = NlmNewFlags.NLM_F_EXCL.value | NlmNewFlags.NLM_F_CREATE.value
25686fd0bdbSAlexander V. Chernikov            msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_NEWLINK.value)
25786fd0bdbSAlexander V. Chernikov            msg.nl_hdr.nlmsg_flags = (
25886fd0bdbSAlexander V. Chernikov                flags | NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
25986fd0bdbSAlexander V. Chernikov            )
26086fd0bdbSAlexander V. Chernikov            msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, ifname))
26186fd0bdbSAlexander V. Chernikov            msg.add_nla(
26286fd0bdbSAlexander V. Chernikov                NlAttrNested(
26386fd0bdbSAlexander V. Chernikov                    IflattrType.IFLA_LINKINFO,
26486fd0bdbSAlexander V. Chernikov                    [
26586fd0bdbSAlexander V. Chernikov                        NlAttrStrn(IflinkInfo.IFLA_INFO_KIND, "lo"),
26686fd0bdbSAlexander V. Chernikov                    ],
26786fd0bdbSAlexander V. Chernikov                )
26886fd0bdbSAlexander V. Chernikov            )
26986fd0bdbSAlexander V. Chernikov
27086fd0bdbSAlexander V. Chernikov            rx_msg = self.get_reply(msg)
27186fd0bdbSAlexander V. Chernikov            assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
27286fd0bdbSAlexander V. Chernikov            nla_list, _ = rx_msg.parse_attrs(bytes(rx_msg.cookie)[4:], rtnl_ifla_attrs)
27386fd0bdbSAlexander V. Chernikov            nla_map = {n.nla_type: n for n in nla_list}
27486fd0bdbSAlexander V. Chernikov            assert nla_map[IflattrType.IFLA_IFNAME.value].text == ifname
27586fd0bdbSAlexander V. Chernikov            ifindex = nla_map[IflattrType.IFLA_NEW_IFINDEX.value].u32
27686fd0bdbSAlexander V. Chernikov            assert ifindex > 0
27786fd0bdbSAlexander V. Chernikov            assert ifindex not in ifmap
27886fd0bdbSAlexander V. Chernikov            ifmap[ifindex] = ifname
27986fd0bdbSAlexander V. Chernikov
28086fd0bdbSAlexander V. Chernikov            # Dump all interfaces and check if the output matches ifmap
28186fd0bdbSAlexander V. Chernikov            kernel_ifmap = {}
28286fd0bdbSAlexander V. Chernikov            msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_GETLINK.value)
28386fd0bdbSAlexander V. Chernikov            msg.nl_hdr.nlmsg_flags = (
28486fd0bdbSAlexander V. Chernikov                NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
28586fd0bdbSAlexander V. Chernikov            )
28686fd0bdbSAlexander V. Chernikov            self.write_message(msg)
28786fd0bdbSAlexander V. Chernikov            while True:
28886fd0bdbSAlexander V. Chernikov                rx_msg = self.read_message()
28986fd0bdbSAlexander V. Chernikov                if msg.nl_hdr.nlmsg_seq != rx_msg.nl_hdr.nlmsg_seq:
29086fd0bdbSAlexander V. Chernikov                    raise ValueError(
29186fd0bdbSAlexander V. Chernikov                        "unexpected seq {}".format(rx_msg.nl_hdr.nlmsg_seq)
29286fd0bdbSAlexander V. Chernikov                    )
29386fd0bdbSAlexander V. Chernikov                if rx_msg.is_type(NlMsgType.NLMSG_ERROR):
29486fd0bdbSAlexander V. Chernikov                    raise ValueError("unexpected message {}".format(rx_msg))
29586fd0bdbSAlexander V. Chernikov                if rx_msg.is_type(NlMsgType.NLMSG_DONE):
29686fd0bdbSAlexander V. Chernikov                    break
29786fd0bdbSAlexander V. Chernikov                if not rx_msg.is_type(NlRtMsgType.RTM_NEWLINK):
29886fd0bdbSAlexander V. Chernikov                    raise ValueError("unexpected message {}".format(rx_msg))
29986fd0bdbSAlexander V. Chernikov
30086fd0bdbSAlexander V. Chernikov                ifindex = rx_msg.base_hdr.ifi_index
30186fd0bdbSAlexander V. Chernikov                assert ifindex == rx_msg.base_hdr.ifi_index
30279748cecSAlexander V. Chernikov                ifname = rx_msg.get_nla(IflattrType.IFLA_IFNAME).text
30379748cecSAlexander V. Chernikov                if ifname.startswith("lo"):
30479748cecSAlexander V. Chernikov                    kernel_ifmap[ifindex] = ifname
30586fd0bdbSAlexander V. Chernikov            assert kernel_ifmap == ifmap
30686fd0bdbSAlexander V. Chernikov
30780f03e63SAlexander V. Chernikov    #
30880f03e63SAlexander V. Chernikov    # *
30980f03e63SAlexander V. Chernikov    # * {len=76, type=RTM_NEWLINK, flags=NLM_F_REQUEST|NLM_F_ACK|NLM_F_EXCL|NLM_F_CREATE, seq=1662892737, pid=0},
31080f03e63SAlexander V. Chernikov    # *  {ifi_family=AF_UNSPEC, ifi_type=ARPHRD_NETROM, ifi_index=0, ifi_flags=0, ifi_change=0},
31180f03e63SAlexander V. Chernikov    # *    {{nla_len=8, nla_type=IFLA_LINK}, 2},
31280f03e63SAlexander V. Chernikov    # *    {{nla_len=12, nla_type=IFLA_IFNAME}, "xvlan22"},
31380f03e63SAlexander V. Chernikov    # *    {{nla_len=24, nla_type=IFLA_LINKINFO},
31480f03e63SAlexander V. Chernikov    # *      {{nla_len=8, nla_type=IFLA_INFO_KIND}, "vlan"...},
315c1871a33SAlexander V. Chernikov    # *      {{nla_len=12, nla_type=IFLA_INFO_DATA}, "\x06\x00\x01\x00\x16\x00\x00\x00"}
31680f03e63SAlexander V. Chernikov    # */
31780f03e63SAlexander V. Chernikov    @pytest.mark.require_user("root")
31880f03e63SAlexander V. Chernikov    def test_create_vlan_plain(self):
31980f03e63SAlexander V. Chernikov        """Creates 802.1Q VLAN interface in vlanXX and ifX fashion"""
320*2d49ff1eSGleb Smirnoff        self.require_module("if_vlan")
32180f03e63SAlexander V. Chernikov        os_ifname = self.vnet.iface_alias_map["if1"].name
32280f03e63SAlexander V. Chernikov        ifindex = socket.if_nametoindex(os_ifname)
32380f03e63SAlexander V. Chernikov
32480f03e63SAlexander V. Chernikov        flags = NlmNewFlags.NLM_F_EXCL.value | NlmNewFlags.NLM_F_CREATE.value
32580f03e63SAlexander V. Chernikov        msg = NetlinkIflaMessage(self.helper, NlRtMsgType.RTM_NEWLINK.value)
32680f03e63SAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
32780f03e63SAlexander V. Chernikov            flags | NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value
32880f03e63SAlexander V. Chernikov        )
329089104e0SAlexander V. Chernikov        msg.base_hdr.ifi_index = ifindex
33080f03e63SAlexander V. Chernikov
33180f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrU32(IflattrType.IFLA_LINK, ifindex))
33280f03e63SAlexander V. Chernikov        msg.add_nla(NlAttrStr(IflattrType.IFLA_IFNAME, "vlan22"))
33380f03e63SAlexander V. Chernikov
33480f03e63SAlexander V. Chernikov        msg.add_nla(
33580f03e63SAlexander V. Chernikov            NlAttrNested(
33680f03e63SAlexander V. Chernikov                IflattrType.IFLA_LINKINFO,
33780f03e63SAlexander V. Chernikov                [
33880f03e63SAlexander V. Chernikov                    NlAttrStrn(IflinkInfo.IFLA_INFO_KIND, "vlan"),
33980f03e63SAlexander V. Chernikov                    NlAttrNested(
34080f03e63SAlexander V. Chernikov                        IflinkInfo.IFLA_INFO_DATA,
34180f03e63SAlexander V. Chernikov                        [
34280f03e63SAlexander V. Chernikov                            NlAttrU16(IfLinkInfoDataVlan.IFLA_VLAN_ID, 22),
34380f03e63SAlexander V. Chernikov                        ],
34480f03e63SAlexander V. Chernikov                    ),
34580f03e63SAlexander V. Chernikov                ],
34680f03e63SAlexander V. Chernikov            )
34780f03e63SAlexander V. Chernikov        )
34880f03e63SAlexander V. Chernikov
34980f03e63SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
35080f03e63SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
35180f03e63SAlexander V. Chernikov        assert rx_msg.error_code == 0
35280f03e63SAlexander V. Chernikov
353089104e0SAlexander V. Chernikov        ToolsHelper.print_net_debug()
35480f03e63SAlexander V. Chernikov        self.get_interface_byname("vlan22")
35580f03e63SAlexander V. Chernikov        # ToolsHelper.print_net_debug()
356