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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
|
..
Licensed under the Apache License, Version 2.0 (the "License"); you may
not use this file except in compliance with the License. You may obtain
a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Convention for heading levels in Open vSwitch documentation:
======= Heading 0 (reserved for the title in a document)
------- Heading 1
~~~~~~~ Heading 2
+++++++ Heading 3
''''''' Heading 4
Avoid deeper levels because they do not render well.
=====
VLANs
=====
Q: What's a VLAN?
A: At the simplest level, a VLAN (short for "virtual LAN") is a way to
partition a single switch into multiple switches. Suppose, for example,
that you have two groups of machines, group A and group B. You want the
machines in group A to be able to talk to each other, and you want the
machine in group B to be able to talk to each other, but you don't want the
machines in group A to be able to talk to the machines in group B. You can
do this with two switches, by plugging the machines in group A into one
switch and the machines in group B into the other switch.
If you only have one switch, then you can use VLANs to do the same thing,
by configuring the ports for machines in group A as VLAN "access ports" for
one VLAN and the ports for group B as "access ports" for a different VLAN.
The switch will only forward packets between ports that are assigned to the
same VLAN, so this effectively subdivides your single switch into two
independent switches, one for each group of machines.
So far we haven't said anything about VLAN headers. With access ports,
like we've described so far, no VLAN header is present in the Ethernet
frame. This means that the machines (or switches) connected to access
ports need not be aware that VLANs are involved, just like in the case
where we use two different physical switches.
Now suppose that you have a whole bunch of switches in your network,
instead of just one, and that some machines in group A are connected
directly to both switches 1 and 2. To allow these machines to talk to each
other, you could add an access port for group A's VLAN to switch 1 and
another to switch 2, and then connect an Ethernet cable between those
ports. That works fine, but it doesn't scale well as the number of
switches and the number of VLANs increases, because you use up a lot of
valuable switch ports just connecting together your VLANs.
This is where VLAN headers come in. Instead of using one cable and two
ports per VLAN to connect a pair of switches, we configure a port on each
switch as a VLAN "trunk port". Packets sent and received on a trunk port
carry a VLAN header that says what VLAN the packet belongs to, so that only
two ports total are required to connect the switches, regardless of the
number of VLANs in use. Normally, only switches (either physical or
virtual) are connected to a trunk port, not individual hosts, because
individual hosts don't expect to see a VLAN header in the traffic that they
receive.
None of the above discussion says anything about particular VLAN numbers.
This is because VLAN numbers are completely arbitrary. One must only
ensure that a given VLAN is numbered consistently throughout a network and
that different VLANs are given different numbers. (That said, VLAN 0 is
usually synonymous with a packet that has no VLAN header, and VLAN 4095 is
reserved.)
Q: VLANs don't work.
A: Many drivers in Linux kernels before version 3.3 had VLAN-related bugs.
If you are having problems with VLANs that you suspect to be driver
related, then you have several options:
- Upgrade to Linux 3.3 or later.
- Build and install a fixed version of the particular driver that is
causing trouble, if one is available.
- Use a NIC whose driver does not have VLAN problems.
- Use "VLAN splinters", a feature in Open vSwitch 1.4 upto 2.5 that works
around bugs in kernel drivers. To enable VLAN splinters on interface
eth0, use the command::
$ ovs-vsctl set interface eth0 other-config:enable-vlan-splinters=true
For VLAN splinters to be effective, Open vSwitch must know which VLANs
are in use. See the "VLAN splinters" section in the Interface table in
ovs-vswitchd.conf.db(5) for details on how Open vSwitch infers in-use
VLANs.
VLAN splinters increase memory use and reduce performance, so use them
only if needed.
- Apply the "vlan workaround" patch from the XenServer kernel patch queue,
build Open vSwitch against this patched kernel, and then use
ovs-vlan-bug-workaround(8) to enable the VLAN workaround for each
interface whose driver is buggy.
(This is a nontrivial exercise, so this option is included only for
completeness.)
It is not always easy to tell whether a Linux kernel driver has buggy VLAN
support. The ovs-vlan-test(8) and ovs-test(8) utilities can help you test.
See their manpages for details. Of the two utilities, ovs-test(8) is newer
and more thorough, but ovs-vlan-test(8) may be easier to use.
Q: VLANs still don't work. I've tested the driver so I know that it's OK.
A: Do you have VLANs enabled on the physical switch that OVS is attached
to? Make sure that the port is configured to trunk the VLAN or VLANs that
you are using with OVS.
Q: Outgoing VLAN-tagged traffic goes through OVS to my physical switch
and to its destination host, but OVS seems to drop incoming return
traffic.
A: It's possible that you have the VLAN configured on your physical switch
as the "native" VLAN. In this mode, the switch treats incoming packets
either tagged with the native VLAN or untagged as part of the native VLAN.
It may also send outgoing packets in the native VLAN without a VLAN tag.
If this is the case, you have two choices:
- Change the physical switch port configuration to tag packets it forwards
to OVS with the native VLAN instead of forwarding them untagged.
- Change the OVS configuration for the physical port to a native VLAN mode.
For example, the following sets up a bridge with port eth0 in
"native-tagged" mode in VLAN 9::
$ ovs-vsctl add-br br0 $ ovs-vsctl add-port br0 eth0 tag=9
vlan_mode=native-tagged
In this situation, "native-untagged" mode will probably work equally
well. Refer to the documentation for the Port table in
ovs-vswitchd.conf.db(5) for more information.
Q: I added a pair of VMs on different VLANs, like this::
$ ovs-vsctl add-br br0
$ ovs-vsctl add-port br0 eth0
$ ovs-vsctl add-port br0 tap0 tag=9
$ ovs-vsctl add-port br0 tap1 tag=10
but the VMs can't access each other, the external network, or the Internet.
A: It is to be expected that the VMs can't access each other. VLANs are a
means to partition a network. When you configured tap0 and tap1 as access
ports for different VLANs, you indicated that they should be isolated from
each other.
As for the external network and the Internet, it seems likely that the
machines you are trying to access are not on VLAN 9 (or 10) and that the
Internet is not available on VLAN 9 (or 10).
Q: I added a pair of VMs on the same VLAN, like this::
$ ovs-vsctl add-br br0
$ ovs-vsctl add-port br0 eth0
$ ovs-vsctl add-port br0 tap0 tag=9
$ ovs-vsctl add-port br0 tap1 tag=9
The VMs can access each other, but not the external network or the Internet.
A: It seems likely that the machines you are trying to access in the
external network are not on VLAN 9 and that the Internet is not available
on VLAN 9. Also, ensure VLAN 9 is set up as an allowed trunk VLAN on the
upstream switch port to which eth0 is connected.
Q: Can I configure an IP address on a VLAN?
A: Yes. Use an "internal port" configured as an access port. For example,
the following configures IP address 192.168.0.7 on VLAN 9. That is, OVS
will forward packets from eth0 to 192.168.0.7 only if they have an 802.1Q
header with VLAN 9. Conversely, traffic forwarded from 192.168.0.7 to eth0
will be tagged with an 802.1Q header with VLAN 9::
$ ovs-vsctl add-br br0
$ ovs-vsctl add-port br0 eth0
$ ovs-vsctl add-port br0 vlan9 tag=9 \
-- set interface vlan9 type=internal
$ ip addr add 192.168.0.7/24 dev vlan9
$ ip link set vlan9 up
See also the following question.
Q: I configured one IP address on VLAN 0 and another on VLAN 9, like this::
$ ovs-vsctl add-br br0
$ ovs-vsctl add-port br0 eth0
$ ip addr add 192.168.0.5/24 dev br0
$ ip link set br0 up
$ ovs-vsctl add-port br0 vlan9 tag=9 -- set interface vlan9 type=internal
$ ip addr add 192.168.0.9/24 dev vlan9
$ ip link set vlan9 up
but other hosts that are only on VLAN 0 can reach the IP address configured on
VLAN 9. What's going on?
A: `RFC 1122 section 3.3.4.2 "Multihoming Requirements"
<https://tools.ietf.org/html/rfc1122>`__ describes two approaches to IP
address handling in Internet hosts:
- In the "Strong ES Model", where an ES is a host ("End System"), an IP
address is primarily associated with a particular interface. The host
discards packets that arrive on interface A if they are destined for an
IP address that is configured on interface B. The host never sends
packets from interface A using a source address configured on interface
B.
- In the "Weak ES Model", an IP address is primarily associated with a
host. The host accepts packets that arrive on any interface if they are
destined for any of the host's IP addresses, even if the address is
configured on some interface other than the one on which it arrived. The
host does not restrict itself to sending packets from an IP address
associated with the originating interface.
Linux uses the weak ES model. That means that when packets destined to the
VLAN 9 IP address arrive on eth0 and are bridged to br0, the kernel IP
stack accepts them there for the VLAN 9 IP address, even though they were
not received on vlan9, the network device for vlan9.
To simulate the strong ES model on Linux, one may add iptables rule to
filter packets based on source and destination address and adjust ARP
configuration with sysctls.
BSD uses the strong ES model.
Q: My OpenFlow controller doesn't see the VLANs that I expect.
A: The configuration for VLANs in the Open vSwitch database (e.g. via
ovs-vsctl) only affects traffic that goes through Open vSwitch's
implementation of the OpenFlow "normal switching" action. By default, when
Open vSwitch isn't connected to a controller and nothing has been manually
configured in the flow table, all traffic goes through the "normal
switching" action. But, if you set up OpenFlow flows on your own, through
a controller or using ovs-ofctl or through other means, then you have to
implement VLAN handling yourself.
You can use "normal switching" as a component of your OpenFlow actions,
e.g. by putting "normal" into the lists of actions on ovs-ofctl or by
outputting to OFPP_NORMAL from an OpenFlow controller. In situations where
this is not suitable, you can implement VLAN handling yourself, e.g.:
- If a packet comes in on an access port, and the flow table needs to send
it out on a trunk port, then the flow can add the appropriate VLAN tag
with the "mod_vlan_vid" action.
- If a packet comes in on a trunk port, and the flow table needs to send it
out on an access port, then the flow can strip the VLAN tag with the
"strip_vlan" action.
Q: I configured ports on a bridge as access ports with different VLAN tags,
like this::
$ ovs-vsctl add-br br0
$ ovs-vsctl set-controller br0 tcp:192.168.0.10:6653
$ ovs-vsctl add-port br0 eth0
$ ovs-vsctl add-port br0 tap0 tag=9
$ ovs-vsctl add-port br0 tap1 tag=10
but the VMs running behind tap0 and tap1 can still communicate, that is, they
are not isolated from each other even though they are on different VLANs.
A: Do you have a controller configured on br0 (as the commands above do)?
If so, then this is a variant on the previous question, "My OpenFlow
controller doesn't see the VLANs that I expect," and you can refer to the
answer there for more information.
Q: How MAC learning works with VLANs?
A: Open vSwitch implements Independent VLAN Learning (IVL) for
``OFPP_NORMAL`` action, e.g. it logically has separate learning tables for
each VLANs.
|