summaryrefslogtreecommitdiff
path: root/tests/vmtests/test_network_mtu.py
blob: 67d5d0149f86fb1b18086e5f7fdf52010dacaf59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
# This file is part of curtin. See LICENSE file for copyright and license info.

from .releases import base_vm_classes as relbase
from .releases import centos_base_vm_classes as centos_relbase
from .test_network_ipv6 import TestNetworkIPV6Abs

import textwrap
import unittest


NETWORKD_NO_AUTO_RAISE_MTU = (
    "networkd does not support auto raising iface mtu")


class TestNetworkMtuAbs(TestNetworkIPV6Abs):
    """ Test that the mtu of the ipv6 address is properly set.

    1.  devices default MTU to 1500, test if mtu under
        inet6 stanza can be set separately from device
        mtu (works newer ifupdown), check via sysctl.

    2.  if ipv6 mtu is > than underlying device, this fails
        and is unnoticed, ifupdown/hook should fix by changing
        mtu of underlying device to the same size as the ipv6
        mtu.  This only works in ifupdown renderers.

    3.  order of the v4 vs. v6 stanzas could affect final mtu
        ipv6 first, then ipv4 with mtu.
    """
    conf_file = "examples/tests/network_mtu.yaml"
    extra_collect_scripts = TestNetworkIPV6Abs.extra_collect_scripts + [
        textwrap.dedent("""
        cd OUTPUT_COLLECT_D
        # restart networkd after all interfaces are up
        # systemctl restart systemd-networkd.service
        [ -e /usr/local/bin/capture-mtu ] && /usr/local/bin/capture-mtu
        echo "collecting mtu now"
        proc_v6="/proc/sys/net/ipv6/conf"
        for f in `seq 0 7`; do
            echo "WARK: checking interface${f} MTU values"
            cat /sys/class/net/interface${f}/mtu |tee -a interface${f}_dev_mtu;
            cat $proc_v6/interface${f}/mtu |tee -a interface${f}_ipv6_mtu;
        done
        if [ -e /var/log/upstart ]; then
          cp -a /var/log/upstart ./var_log_upstart
        fi

        exit 0
        """)]

    def _load_mtu_data(self, ifname):
        """ load mtu related files by interface name.
            returns a dictionary with the follwing
            keys:  'device', and 'ipv6'.  """

        mtu_fn = {
            'device': "%s_dev_mtu" % ifname,
            'ipv6': "%s_ipv6_mtu" % ifname,
        }
        mtu_val = {}
        for fnk in mtu_fn.keys():
            mtu_val.update({fnk: int(self.load_collect_file(mtu_fn[fnk]))})

        return mtu_val

    def _skip_if_not_ifupdown(self, reason):
        if self._network_renderer() != "ifupdown":
            raise unittest.SkipTest(reason)

    def _check_subnet_mtu(self, subnet, iface):
        mtu_data = self._load_mtu_data(iface['name'])
        print('subnet:%s' % subnet)
        print('mtu_data:%s' % mtu_data)
        # ipv4 address mtu changes *device* mtu
        if '.' in subnet['address']:
            print('subnet_mtu=%s device_mtu=%s' % (int(subnet['mtu']),
                                                   int(mtu_data['device'])))
            self.assertEqual(int(subnet['mtu']),
                             int(mtu_data['device']))
        # ipv6 address mtu changes *protocol* mtu
        elif ':' in subnet['address']:
            print('subnet_mtu=%s ipv6_mtu=%s' % (int(subnet['mtu']),
                                                 int(mtu_data['device'])))
            self.assertEqual(int(subnet['mtu']),
                             int(mtu_data['ipv6']))

    def _check_iface_subnets(self, ifname):
        network_state = self.get_network_state()
        interfaces = network_state.get('interfaces')

        iface = interfaces.get(ifname)
        subnets = iface.get('subnets')
        print('iface=%s subnets=%s' % (iface['name'], subnets))
        for subnet in subnets:
            if 'mtu' in subnet:
                self._check_subnet_mtu(subnet, iface)

    def _disabled_ipv4_and_ipv6_mtu_all(self):
        """ we don't pass all tests, skip for now """
        network_state = self.get_network_state()
        interfaces = network_state.get('interfaces')

        for iface in interfaces.values():
            subnets = iface.get('subnets', {})
            if subnets:
                for index, subnet in zip(range(0, len(subnets)), subnets):
                    print("iface=%s subnet=%s" % (iface['name'], subnet))
                    if 'mtu' in subnet:
                        self._check_subnet_mtu(subnet, iface)

    def test_ipv6_mtu_smaller_than_ipv4_non_default(self):
        self._check_iface_subnets('interface0')

    def test_ipv6_mtu_equal_ipv4_non_default(self):
        self._check_iface_subnets('interface1')

    def test_ipv6_mtu_higher_than_default_no_ipv4_mtu(self):
        self._skip_if_not_ifupdown(NETWORKD_NO_AUTO_RAISE_MTU)
        self._check_iface_subnets('interface2')

    def test_ipv6_mtu_higher_than_default_no_ipv4_iface_up(self):
        self._skip_if_not_ifupdown(NETWORKD_NO_AUTO_RAISE_MTU)
        self._check_iface_subnets('interface3')

    def test_ipv6_mtu_smaller_than_ipv4_v6_iface_first(self):
        self._check_iface_subnets('interface4')

    def test_ipv6_mtu_equal_ipv4_non_default_v6_iface_first(self):
        self._check_iface_subnets('interface5')

    def test_ipv6_mtu_higher_than_default_no_ipv4_mtu_v6_iface_first(self):
        self._skip_if_not_ifupdown(NETWORKD_NO_AUTO_RAISE_MTU)
        self._check_iface_subnets('interface6')

    def test_ipv6_mtu_higher_than_default_no_ipv4_iface_v6_iface_first(self):
        self._skip_if_not_ifupdown(NETWORKD_NO_AUTO_RAISE_MTU)
        self._check_iface_subnets('interface7')


class TestNetworkMtuNetworkdAbs(TestNetworkMtuAbs):
    conf_file = "examples/tests/network_mtu_networkd.yaml"


class CentosTestNetworkMtuAbs(TestNetworkMtuAbs):
    conf_file = "examples/tests/network_mtu.yaml"
    extra_collect_scripts = TestNetworkMtuAbs.extra_collect_scripts + [
        textwrap.dedent("""
            cd OUTPUT_COLLECT_D
            cp -a /etc/sysconfig/network-scripts .
            cp -a /var/log/cloud-init* .
            cp -a /var/lib/cloud ./var_lib_cloud
            cp -a /run/cloud-init ./run_cloud-init

            exit 0
        """)]

    def test_etc_network_interfaces(self):
        pass

    def test_etc_resolvconf(self):
        pass

    @unittest.skip("Sysconfig does not support mixed v4/v6 MTU: LP:#1706973")
    def test_ip_output(self):
        pass

    @unittest.skip("Sysconfig does not support mixed v4/v6 MTU: LP:#1706973")
    def test_ipv6_mtu_smaller_than_ipv4_v6_iface_first(self):
        pass

    @unittest.skip("Sysconfig does not support mixed v4/v6 MTU: LP:#1706973")
    def test_ipv6_mtu_smaller_than_ipv4_non_default(self):
        pass

    @unittest.skip("Sysconfig does not support mixed v4/v6 MTU: LP:#1706973")
    def test_ipv6_mtu_higher_than_default_no_ipv4_iface_up(self):
        pass

    @unittest.skip("Sysconfig does not support mixed v4/v6 MTU: LP:#1706973")
    def test_ipv6_mtu_higher_than_default_no_ipv4_iface_v6_iface_first(self):
        pass


class TestNetworkMtu(relbase.xenial, TestNetworkMtuAbs):
    __test__ = True


class BionicTestNetworkMtu(relbase.bionic, TestNetworkMtuNetworkdAbs):
    __test__ = True


class FocalTestNetworkMtu(relbase.focal, TestNetworkMtuNetworkdAbs):
    __test__ = True


class JammyTestNetworkMtu(relbase.jammy, TestNetworkMtuNetworkdAbs):
    __test__ = True


class Centos70TestNetworkMtu(centos_relbase.centos70_xenial,
                             CentosTestNetworkMtuAbs):
    __test__ = True

# vi: ts=4 expandtab syntax=python