xref: /freebsd/tests/sys/netlink/test_rtnl_route.py (revision effa0f6c0aad54a07917af6986d71cd0a57223b8)
1828d3c6cSAlexander V. Chernikovimport ipaddress
2828d3c6cSAlexander V. Chernikovimport socket
3828d3c6cSAlexander V. Chernikov
4828d3c6cSAlexander V. Chernikovimport pytest
5c57dfd92SAlexander V. Chernikovfrom atf_python.sys.net.tools import ToolsHelper
61db64f89SJose Luis Duranfrom atf_python.sys.net.vnet import IfaceFactory
7828d3c6cSAlexander V. Chernikovfrom atf_python.sys.net.vnet import SingleVnetTestTemplate
8fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.attrs import NlAttrIp
9fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.attrs import NlAttrU32
10fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.base_headers import NlmBaseFlags
11fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.base_headers import NlmGetFlags
12fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.base_headers import NlmNewFlags
13fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.base_headers import NlMsgType
14fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink import NetlinkTestTemplate
15fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink_route import NetlinkRtMessage
16fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink_route import NlRtMsgType
17fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.netlink_route import RtattrType
18fee65b7eSAlexander V. Chernikovfrom atf_python.sys.netlink.utils import NlConst
19828d3c6cSAlexander V. Chernikov
20828d3c6cSAlexander V. Chernikov
21828d3c6cSAlexander V. Chernikovclass TestRtNlRoute(NetlinkTestTemplate, SingleVnetTestTemplate):
22828d3c6cSAlexander V. Chernikov    IPV6_PREFIXES = ["2001:db8::1/64"]
23828d3c6cSAlexander V. Chernikov
24828d3c6cSAlexander V. Chernikov    def setup_method(self, method):
25828d3c6cSAlexander V. Chernikov        super().setup_method(method)
26828d3c6cSAlexander V. Chernikov        self.setup_netlink(NlConst.NETLINK_ROUTE)
27828d3c6cSAlexander V. Chernikov
28c57dfd92SAlexander V. Chernikov    @pytest.mark.timeout(5)
29c57dfd92SAlexander V. Chernikov    def test_add_route6_ll_gw(self):
30c57dfd92SAlexander V. Chernikov        epair_ifname = self.vnet.iface_alias_map["if1"].name
31c57dfd92SAlexander V. Chernikov        epair_ifindex = socket.if_nametoindex(epair_ifname)
32c57dfd92SAlexander V. Chernikov
33c57dfd92SAlexander V. Chernikov        msg = NetlinkRtMessage(self.helper, NlRtMsgType.RTM_NEWROUTE)
34c57dfd92SAlexander V. Chernikov        msg.set_request()
35c57dfd92SAlexander V. Chernikov        msg.add_nlflags([NlmNewFlags.NLM_F_CREATE])
36c57dfd92SAlexander V. Chernikov        msg.base_hdr.rtm_family = socket.AF_INET6
37c57dfd92SAlexander V. Chernikov        msg.base_hdr.rtm_dst_len = 64
38c57dfd92SAlexander V. Chernikov        msg.add_nla(NlAttrIp(RtattrType.RTA_DST, "2001:db8:2::"))
39c57dfd92SAlexander V. Chernikov        msg.add_nla(NlAttrIp(RtattrType.RTA_GATEWAY, "fe80::1"))
40c57dfd92SAlexander V. Chernikov        msg.add_nla(NlAttrU32(RtattrType.RTA_OIF, epair_ifindex))
41c57dfd92SAlexander V. Chernikov
42c57dfd92SAlexander V. Chernikov        rx_msg = self.get_reply(msg)
43c57dfd92SAlexander V. Chernikov        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
44c57dfd92SAlexander V. Chernikov        assert rx_msg.error_code == 0
45c57dfd92SAlexander V. Chernikov
46c57dfd92SAlexander V. Chernikov        ToolsHelper.print_net_debug()
47c57dfd92SAlexander V. Chernikov        ToolsHelper.print_output("netstat -6onW")
48c57dfd92SAlexander V. Chernikov
491db64f89SJose Luis Duran    @pytest.mark.timeout(5)
501db64f89SJose Luis Duran    def test_add_route6_ll_if_gw(self):
51*effa0f6cSGleb Smirnoff        self.require_module("if_tun")
521db64f89SJose Luis Duran        tun_ifname = IfaceFactory().create_iface("", "tun")[0].name
531db64f89SJose Luis Duran        tun_ifindex = socket.if_nametoindex(tun_ifname)
541db64f89SJose Luis Duran
551db64f89SJose Luis Duran        msg = NetlinkRtMessage(self.helper, NlRtMsgType.RTM_NEWROUTE)
561db64f89SJose Luis Duran        msg.set_request()
571db64f89SJose Luis Duran        msg.add_nlflags([NlmNewFlags.NLM_F_CREATE])
581db64f89SJose Luis Duran        msg.base_hdr.rtm_family = socket.AF_INET6
591db64f89SJose Luis Duran        msg.base_hdr.rtm_dst_len = 64
601db64f89SJose Luis Duran        msg.add_nla(NlAttrIp(RtattrType.RTA_DST, "2001:db8:2::"))
611db64f89SJose Luis Duran        msg.add_nla(NlAttrU32(RtattrType.RTA_OIF, tun_ifindex))
621db64f89SJose Luis Duran
631db64f89SJose Luis Duran        rx_msg = self.get_reply(msg)
641db64f89SJose Luis Duran        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
651db64f89SJose Luis Duran        assert rx_msg.error_code == 0
661db64f89SJose Luis Duran
671db64f89SJose Luis Duran        ToolsHelper.print_net_debug()
681db64f89SJose Luis Duran        ToolsHelper.print_output("netstat -6onW")
691db64f89SJose Luis Duran
701db64f89SJose Luis Duran    @pytest.mark.timeout(5)
711db64f89SJose Luis Duran    def test_add_route4_ll_if_gw(self):
72*effa0f6cSGleb Smirnoff        self.require_module("if_tun")
731db64f89SJose Luis Duran        tun_ifname = IfaceFactory().create_iface("", "tun")[0].name
741db64f89SJose Luis Duran        tun_ifindex = socket.if_nametoindex(tun_ifname)
751db64f89SJose Luis Duran
761db64f89SJose Luis Duran        msg = NetlinkRtMessage(self.helper, NlRtMsgType.RTM_NEWROUTE)
771db64f89SJose Luis Duran        msg.set_request()
781db64f89SJose Luis Duran        msg.add_nlflags([NlmNewFlags.NLM_F_CREATE])
791db64f89SJose Luis Duran        msg.base_hdr.rtm_family = socket.AF_INET
801db64f89SJose Luis Duran        msg.base_hdr.rtm_dst_len = 32
811db64f89SJose Luis Duran        msg.add_nla(NlAttrIp(RtattrType.RTA_DST, "192.0.2.1"))
821db64f89SJose Luis Duran        msg.add_nla(NlAttrU32(RtattrType.RTA_OIF, tun_ifindex))
831db64f89SJose Luis Duran
841db64f89SJose Luis Duran        rx_msg = self.get_reply(msg)
851db64f89SJose Luis Duran        assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
861db64f89SJose Luis Duran        assert rx_msg.error_code == 0
871db64f89SJose Luis Duran
881db64f89SJose Luis Duran        ToolsHelper.print_net_debug()
891db64f89SJose Luis Duran        ToolsHelper.print_output("netstat -4onW")
901db64f89SJose Luis Duran
91828d3c6cSAlexander V. Chernikov    @pytest.mark.timeout(20)
92828d3c6cSAlexander V. Chernikov    def test_buffer_override(self):
93828d3c6cSAlexander V. Chernikov        msg_flags = (
94828d3c6cSAlexander V. Chernikov            NlmBaseFlags.NLM_F_ACK.value
95828d3c6cSAlexander V. Chernikov            | NlmBaseFlags.NLM_F_REQUEST.value
96828d3c6cSAlexander V. Chernikov            | NlmNewFlags.NLM_F_CREATE.value
97828d3c6cSAlexander V. Chernikov        )
98828d3c6cSAlexander V. Chernikov
99828d3c6cSAlexander V. Chernikov        num_routes = 1000
100828d3c6cSAlexander V. Chernikov        base_address = bytearray(ipaddress.ip_address("2001:db8:ffff::").packed)
101828d3c6cSAlexander V. Chernikov        for i in range(num_routes):
102828d3c6cSAlexander V. Chernikov            base_address[7] = i % 256
103828d3c6cSAlexander V. Chernikov            base_address[6] = i // 256
104828d3c6cSAlexander V. Chernikov            prefix_address = ipaddress.IPv6Address(bytes(base_address))
105828d3c6cSAlexander V. Chernikov
106828d3c6cSAlexander V. Chernikov            msg = NetlinkRtMessage(self.helper, NlRtMsgType.RTM_NEWROUTE.value)
107828d3c6cSAlexander V. Chernikov            msg.nl_hdr.nlmsg_flags = msg_flags
108828d3c6cSAlexander V. Chernikov            msg.base_hdr.rtm_family = socket.AF_INET6
109828d3c6cSAlexander V. Chernikov            msg.base_hdr.rtm_dst_len = 65
110828d3c6cSAlexander V. Chernikov            msg.add_nla(NlAttrIp(RtattrType.RTA_DST, str(prefix_address)))
111828d3c6cSAlexander V. Chernikov            msg.add_nla(NlAttrIp(RtattrType.RTA_GATEWAY, "2001:db8::2"))
112828d3c6cSAlexander V. Chernikov
113828d3c6cSAlexander V. Chernikov            self.write_message(msg, silent=True)
114828d3c6cSAlexander V. Chernikov            rx_msg = self.read_message(silent=True)
115828d3c6cSAlexander V. Chernikov            assert rx_msg.is_type(NlMsgType.NLMSG_ERROR)
116828d3c6cSAlexander V. Chernikov            assert msg.nl_hdr.nlmsg_seq == rx_msg.nl_hdr.nlmsg_seq
117828d3c6cSAlexander V. Chernikov            assert rx_msg.error_code == 0
118828d3c6cSAlexander V. Chernikov        # Now, dump
119828d3c6cSAlexander V. Chernikov        msg = NetlinkRtMessage(self.helper, NlRtMsgType.RTM_GETROUTE.value)
120828d3c6cSAlexander V. Chernikov        msg.nl_hdr.nlmsg_flags = (
121828d3c6cSAlexander V. Chernikov            NlmBaseFlags.NLM_F_ACK.value
122828d3c6cSAlexander V. Chernikov            | NlmBaseFlags.NLM_F_REQUEST.value
123828d3c6cSAlexander V. Chernikov            | NlmGetFlags.NLM_F_ROOT.value
124828d3c6cSAlexander V. Chernikov            | NlmGetFlags.NLM_F_MATCH.value
125828d3c6cSAlexander V. Chernikov        )
126828d3c6cSAlexander V. Chernikov        msg.base_hdr.rtm_family = socket.AF_INET6
127828d3c6cSAlexander V. Chernikov        self.write_message(msg)
128828d3c6cSAlexander V. Chernikov        num_received = 0
129828d3c6cSAlexander V. Chernikov        while True:
130828d3c6cSAlexander V. Chernikov            rx_msg = self.read_message(silent=True)
131828d3c6cSAlexander V. Chernikov            if msg.nl_hdr.nlmsg_seq == rx_msg.nl_hdr.nlmsg_seq:
132828d3c6cSAlexander V. Chernikov                if rx_msg.is_type(NlMsgType.NLMSG_ERROR):
133828d3c6cSAlexander V. Chernikov                    if rx_msg.error_code != 0:
134828d3c6cSAlexander V. Chernikov                        raise ValueError(
135828d3c6cSAlexander V. Chernikov                            "unable to dump routes: error {}".format(rx_msg.error_code)
136828d3c6cSAlexander V. Chernikov                        )
137828d3c6cSAlexander V. Chernikov                if rx_msg.is_type(NlMsgType.NLMSG_DONE):
138828d3c6cSAlexander V. Chernikov                    break
139828d3c6cSAlexander V. Chernikov                if rx_msg.is_type(NlRtMsgType.RTM_NEWROUTE):
140828d3c6cSAlexander V. Chernikov                    if rx_msg.base_hdr.rtm_dst_len == 65:
141828d3c6cSAlexander V. Chernikov                        num_received += 1
142828d3c6cSAlexander V. Chernikov        assert num_routes == num_received
143