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
|
# Copyright 2019 VyOS maintainers and contributors <maintainers@vyos.io>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library. If not, see <http://www.gnu.org/licenses/>.
import os
import re
from vyos.ifconfig.interface import Interface
# This is an internal implementation class
class VLAN:
"""
This class handels the creation and removal of a VLAN interface. It serves
as base class for BondIf and EthernetIf.
"""
_novlan_remove = lambda : None
@classmethod
def enable (cls,adaptee):
adaptee._novlan_remove = adaptee.remove
adaptee.remove = cls.remove
adaptee.add_vlan = cls.add_vlan
adaptee.del_vlan = cls.del_vlan
adaptee.definition['vlan'] = True
return adaptee
def remove(self):
"""
Remove interface from operating system. Removing the interface
deconfigures all assigned IP addresses and clear possible DHCP(v6)
client processes.
Example:
>>> from vyos.ifconfig import Interface
>>> i = Interface('eth0')
>>> i.remove()
"""
ifname = self.config['ifname']
# Do we have sub interfaces (VLANs)? We apply a regex matching
# subinterfaces (indicated by a .) of a parent interface.
#
# As interfaces need to be deleted "in order" starting from Q-in-Q
# we delete them first.
vlan_ifs = [f for f in os.listdir(r'/sys/class/net')
if re.match(ifname + r'(?:\.\d+)(?:\.\d+)', f)]
for vlan in vlan_ifs:
Interface(vlan).remove()
# After deleting all Q-in-Q interfaces delete other VLAN interfaces
# which probably acted as parent to Q-in-Q or have been regular 802.1q
# interface.
vlan_ifs = [f for f in os.listdir(r'/sys/class/net')
if re.match(ifname + r'(?:\.\d+)', f)]
for vlan in vlan_ifs:
# self.__class__ is already VLAN.enabled
self.__class__(vlan)._novlan_remove()
# All subinterfaces are now removed, continue on the physical interface
self._novlan_remove()
def add_vlan(self, vlan_id, ethertype='', ingress_qos='', egress_qos=''):
"""
A virtual LAN (VLAN) is any broadcast domain that is partitioned and
isolated in a computer network at the data link layer (OSI layer 2).
Use this function to create a new VLAN interface on a given physical
interface.
This function creates both 802.1q and 802.1ad (Q-in-Q) interfaces. Proto
parameter is used to indicate VLAN type.
A new object of type VLANIf is returned once the interface has been
created.
@param ethertype: If specified, create 802.1ad or 802.1q Q-in-Q VLAN
interface
@param ingress_qos: Defines a mapping of VLAN header prio field to the
Linux internal packet priority on incoming frames.
@param ingress_qos: Defines a mapping of Linux internal packet priority
to VLAN header prio field but for outgoing frames.
Example:
>>> from vyos.ifconfig import MACVLANIf
>>> i = MACVLANIf('eth0')
>>> i.add_vlan(10)
"""
vlan_ifname = self.config['ifname'] + '.' + str(vlan_id)
if not os.path.exists(f'/sys/class/net/{vlan_ifname}'):
self._vlan_id = int(vlan_id)
if ethertype:
self._ethertype = ethertype
ethertype = 'proto {}'.format(ethertype)
# Optional ingress QOS mapping
opt_i = ''
if ingress_qos:
opt_i = 'ingress-qos-map ' + ingress_qos
# Optional egress QOS mapping
opt_e = ''
if egress_qos:
opt_e = 'egress-qos-map ' + egress_qos
# create interface in the system
cmd = 'ip link add link {ifname} name {ifname}.{vlan} type vlan {proto} id {vlan} {opt_e} {opt_i}' \
.format(ifname=self.config['ifname'], vlan=self._vlan_id, proto=ethertype, opt_e=opt_e, opt_i=opt_i)
self._cmd(cmd)
# return new object mapping to the newly created interface
# we can now work on this object for e.g. IP address setting
# or interface description and so on
return self.__class__(vlan_ifname)
def del_vlan(self, vlan_id):
"""
Remove VLAN interface from operating system. Removing the interface
deconfigures all assigned IP addresses and clear possible DHCP(v6)
client processes.
Example:
>>> from vyos.ifconfig import MACVLANIf
>>> i = MACVLANIf('eth0.10')
>>> i.del_vlan()
"""
ifname = self.config['ifname']
self.__class__(f'{ifname}.{vlan_id}')._novlan_remove()
|