1 Open vSwitch Advanced Features Tutorial
2 =======================================
4 Many tutorials cover the basics of OpenFlow. This is not such a
5 tutorial. Rather, a knowledge of the basics of OpenFlow is a
6 prerequisite. If you do not already understand how an OpenFlow flow
7 table works, please go read a basic tutorial and then continue reading
10 It is also important to understand the basics of Open vSwitch before
11 you begin. If you have never used ovs-vsctl or ovs-ofctl before, you
12 should learn a little about them before proceeding.
14 Most of the features covered in this tutorial are Open vSwitch
15 extensions to OpenFlow. Also, most of the features in this tutorial
16 are specific to the software Open vSwitch implementation. If you are
17 using an Open vSwitch port to an ASIC-based hardware switch, this
18 tutorial will not help you.
20 This tutorial does not cover every aspect of the features that it
21 mentions. You can find the details elsewhere in the Open vSwitch
22 documentation, especially ovs-ofctl(8) and the comments in the
23 include/openflow/nicira-ext.h header file.
25 >>> In this tutorial, paragraphs set off like this designate notes
26 with additional information that readers may wish to skip on a
33 This is a hands-on tutorial. To get the most out of it, you will need
34 Open vSwitch binaries. You do not, on the other hand, need any
35 physical networking hardware or even supervisor privilege on your
36 system. Instead, we will use a script called "ovs-sandbox", which
37 accompanies the tutorial, that constructs a software simulated network
38 environment based on Open vSwitch.
40 You can use "ovs-sandbox" three ways:
42 * If you have already installed Open vSwitch on your system, then
43 you should be able to just run "ovs-sandbox" from this directory
46 * If you have not installed Open vSwitch (and you do not want to
47 install it), then you can build Open vSwitch according to the
48 instructions in INSTALL, without installing it. Then run
49 "./ovs-sandbox -b DIRECTORY" from this directory, substituting
50 the Open vSwitch build directory for DIRECTORY.
52 * As a slight variant on the latter, you can run "make sandbox"
53 from an Open vSwitch build directory.
55 When you run ovs-sandbox, it does the following:
57 1. CAUTION: Deletes any subdirectory of the current directory
58 named "sandbox" and any files in that directory.
60 2. Creates a new directory "sandbox" in the current directory.
62 3. Sets up special environment variables that ensure that Open
63 vSwitch programs will look inside the "sandbox" directory
64 instead of in the Open vSwitch installation directory.
66 4. If you are using a built but not installed Open vSwitch,
67 installs the Open vSwitch manpages in a subdirectory of
68 "sandbox" and adjusts the MANPATH environment variable to point
69 to this directory. This means that you can use, for example,
70 "man ovs-vsctl" to see a manpage for the ovs-vsctl program that
73 5. Creates an empty Open vSwitch configuration database under
76 6. Starts ovsdb-server running under "sandbox".
78 7. Starts ovs-vswitchd running under "sandbox", passing special
79 options that enable a special "dummy" mode for testing.
81 8. Starts a nested interactive shell inside "sandbox".
83 At this point, you can run all the usual Open vSwitch utilities from
84 the nested shell environment. You can, for example, use ovs-vsctl to
89 From Open vSwitch's perspective, the bridge that you create this way
90 is as real as any other. You can, for example, connect it to an
91 OpenFlow controller or use "ovs-ofctl" to examine and modify it and
92 its OpenFlow flow table. On the other hand, the bridge is not visible
93 to the operating system's network stack, so "ifconfig" or "ip" cannot
94 see it or affect it, which means that utilities like "ping" and
95 "tcpdump" will not work either. (That has its good side, too: you
96 can't screw up your computer's network stack by manipulating a
99 When you're done using OVS from the sandbox, exit the nested shell (by
100 entering the "exit" shell command or pressing Control+D). This will
101 kill the daemons that ovs-sandbox started, but it leaves the "sandbox"
102 directory and its contents in place.
104 The sandbox directory contains log files for the Open vSwitch dameons.
105 You can examine them while you're running in the sandboxed environment
112 The goal of this tutorial is to demonstrate the power of Open vSwitch
113 flow tables. The tutorial works through the implementation of a
114 MAC-learning switch with VLAN trunk and access ports. Outside of the
115 Open vSwitch features that we will discuss, OpenFlow provides at least
116 two ways to implement such a switch:
118 1. An OpenFlow controller to implement MAC learning in a
119 "reactive" fashion. Whenever a new MAC appears on the switch,
120 or a MAC moves from one switch port to another, the controller
121 adjusts the OpenFlow flow table to match.
123 2. The "normal" action. OpenFlow defines this action to submit a
124 packet to "the traditional non-OpenFlow pipeline of the
125 switch". That is, if a flow uses this action, then the packets
126 in the flow go through the switch in the same way that they
127 would if OpenFlow was not configured on the switch.
129 Each of these approaches has unfortunate pitfalls. In the first
130 approach, using an OpenFlow controller to implement MAC learning, has
131 a significant cost in terms of network bandwidth and latency. It also
132 makes the controller more difficult to scale to large numbers of
133 switches, which is especially important in environments with thousands
134 of hypervisors (each of which contains a virtual OpenFlow switch).
135 MAC learning at an OpenFlow controller also behaves poorly if the
136 OpenFlow controller fails, slows down, or becomes unavailable due to
139 The second approach, using the "normal" action, has different
140 problems. First, little about the "normal" action is standardized, so
141 it behaves differently on switches from different vendors, and the
142 available features and how those features are configured (usually not
143 through OpenFlow) varies widely. Second, "normal" does not work well
144 with other OpenFlow actions. It is "all-or-nothing", with little
145 potential to adjust its behavior slightly or to compose it with other
152 We will construct Open vSwitch flow tables for a VLAN-capable,
153 MAC-learning switch that has four ports:
155 * p1, a trunk port that carries all VLANs, on OpenFlow port 1.
157 * p2, an access port for VLAN 20, on OpenFlow port 2.
159 * p3 and p4, both access ports for VLAN 30, on OpenFlow ports 3
162 >>> The ports' names are not significant. You could call them eth1
163 through eth4, or any other names you like.
165 >>> An OpenFlow switch always has a "local" port as well. This
166 scenario won't use the local port.
168 Our switch design will consist of five main flow tables, each of which
169 implements one stage in the switch pipeline:
171 Table 0: Admission control.
173 Table 1: VLAN input processing.
175 Table 2: Learn source MAC and VLAN for ingress port.
177 Table 3: Look up learned port for destination MAC and VLAN.
179 Table 4: Output processing.
181 The section below describes how to set up the scenario, followed by a
182 section for each OpenFlow table.
184 You can cut and paste the "ovs-vsctl" and "ovs-ofctl" commands in each
185 of the sections below into your "ovs-sandbox" shell. They are also
186 available as shell scripts in this directory, named t-setup, t-stage0,
187 t-stage1, ..., t-stage4. The "ovs-appctl" test commands are intended
188 for cutting and pasting and are not supplied separately.
194 To get started, start "ovs-sandbox". Inside the interactive shell
195 that it starts, run this command:
197 ovs-vsctl add-br br0 -- set Bridge br0 fail-mode=secure
199 This command creates a new bridge "br0" and puts "br0" into so-called
200 "fail-secure" mode. For our purpose, this just means that the
201 OpenFlow flow table starts out empty.
203 >>> If we did not do this, then the flow table would start out with a
204 single flow that executes the "normal" action. We could use that
205 feature to yield a switch that behaves the same as the switch we
206 are currently building, but with the caveats described under
209 The new bridge has only one port on it so far, the "local port" br0.
210 We need to add p1, p2, p3, and p4. A shell "for" loop is one way to
214 ovs-vsctl add-port br0 p$i -- set Interface p$i ofport_request=$i
215 ovs-ofctl mod-port br0 p$i up
218 In addition to adding a port, the ovs-vsctl command above sets its
219 "ofport_request" column to ensure that port p1 is assigned OpenFlow
220 port 1, p2 is assigned OpenFlow port 2, and so on.
222 >>> We could omit setting the ofport_request and let Open vSwitch
223 choose port numbers for us, but it's convenient for the purposes
224 of this tutorial because we can talk about OpenFlow port 1 and
225 know that it corresponds to p1.
227 The ovs-ofctl command above brings up the simulated interfaces, which
228 are down initially, using an OpenFlow request. The effect is similar
229 to "ifconfig up", but the sandbox's interfaces are not visible to the
230 operating system and therefore "ifconfig" would not affect them.
232 We have not configured anything related to VLANs or MAC learning.
233 That's because we're going to implement those features in the flow
236 To see what we've done so far to set up the scenario, you can run a
237 command like "ovs-vsctl show" or "ovs-ofctl show br0".
240 Implementing Table 0: Admission control
241 =======================================
243 Table 0 is where packets enter the switch. We use this stage to
244 discard packets that for one reason or another are invalid. For
245 example, packets with a multicast source address are not valid, so we
246 can add a flow to drop them at ingress to the switch with:
248 ovs-ofctl add-flow br0 \
249 "table=0, dl_src=01:00:00:00:00:00/01:00:00:00:00:00, actions=drop"
251 A switch should also not forward IEEE 802.1D Spanning Tree Protocol
252 (STP) packets, so we can also add a flow to drop those and other
253 packets with reserved multicast protocols:
255 ovs-ofctl add-flow br0 \
256 "table=0, dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0, actions=drop"
258 We could add flows to drop other protocols, but these demonstrate the
261 We need one more flow, with a priority lower than the default, so that
262 flows that don't match either of the "drop" flows we added above go on
263 to pipeline stage 1 in OpenFlow table 1:
265 ovs-ofctl add-flow br0 "table=0, priority=0, actions=resubmit(,1)"
267 (The "resubmit" action is an Open vSwitch extension to OpenFlow.)
273 If we were using Open vSwitch to set up a physical or a virtual
274 switch, then we would naturally test it by sending packets through it
275 one way or another, perhaps with common network testing tools like
276 "ping" and "tcpdump" or more specialized tools like Scapy. That's
277 difficult with our simulated switch, since it's not visible to the
280 But our simulated switch has a few specialized testing tools. The
281 most powerful of these tools is "ofproto/trace". Given a switch and
282 the specification of a flow, "ofproto/trace" shows, step-by-step, how
283 such a flow would be treated as it goes through the switch.
290 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=01:80:c2:00:00:05
292 The output should look something like this:
294 Flow: metadata=0,in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=01:80:c2:00:00:05,dl_type=0x0000
295 Rule: table=0 cookie=0 dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0
296 OpenFlow actions=drop
298 Final flow: unchanged
299 Datapath actions: drop
301 The first block of lines describes an OpenFlow table lookup. The
302 first line shows the fields used for the table lookup (which is mostly
303 zeros because that's the default if we don't specify everything). The
304 second line gives the OpenFlow flow that the fields matched (called a
305 "rule" because that is the name used inside Open vSwitch for an
306 OpenFlow flow). In this case, we see that this packet that has a
307 reserved multicast destination address matches the rule that drops
308 those packets. The third line gives the rule's OpenFlow actions.
310 The second block of lines summarizes the results, which are not very
318 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=01:80:c2:00:00:10
320 The output should be:
322 Flow: metadata=0,in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=01:80:c2:00:00:10,dl_type=0x0000
323 Rule: table=0 cookie=0 priority=0
324 OpenFlow actions=resubmit(,1)
326 Resubmitted flow: unchanged
327 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
328 Resubmitted odp: drop
331 Final flow: unchanged
332 Datapath actions: drop
334 This time the flow we handed to "ofproto/trace" doesn't match any of
335 our "drop" rules, so it falls through to the low-priority "resubmit"
336 rule, which we see in the rule and the actions selected in the first
337 block. The "resubmit" causes a second lookup in OpenFlow table 1,
338 described by the additional block of indented text in the output. We
339 haven't yet added any flows to OpenFlow table 1, so no flow actually
340 matches in the second lookup. Therefore, the packet is still actually
341 dropped, which means that the externally observable results would be
342 identical to our first example.
345 Implementing Table 1: VLAN Input Processing
346 ===========================================
348 A packet that enters table 1 has already passed basic validation in
349 table 0. The purpose of table 1 is validate the packet's VLAN, based
350 on the VLAN configuration of the switch port through which the packet
351 entered the switch. We will also use it to attach a VLAN header to
352 packets that arrive on an access port, which allows later processing
353 stages to rely on the packet's VLAN always being part of the VLAN
354 header, reducing special cases.
356 Let's start by adding a low-priority flow that drops all packets,
357 before we add flows that pass through acceptable packets. You can
358 think of this as a "default drop" rule:
360 ovs-ofctl add-flow br0 "table=1, priority=0, actions=drop"
362 Our trunk port p1, on OpenFlow port 1, is an easy case. p1 accepts
363 any packet regardless of whether it has a VLAN header or what the VLAN
364 was, so we can add a flow that resubmits everything on input port 1 to
367 ovs-ofctl add-flow br0 \
368 "table=1, priority=99, in_port=1, actions=resubmit(,2)"
370 On the access ports, we want to accept any packet that has no VLAN
371 header, tag it with the access port's VLAN number, and then pass it
372 along to the next stage:
374 ovs-ofctl add-flows br0 - <<'EOF'
375 table=1, priority=99, in_port=2, vlan_tci=0, actions=mod_vlan_vid:20, resubmit(,2)
376 table=1, priority=99, in_port=3, vlan_tci=0, actions=mod_vlan_vid:30, resubmit(,2)
377 table=1, priority=99, in_port=4, vlan_tci=0, actions=mod_vlan_vid:30, resubmit(,2)
380 We don't write any rules that match packets with 802.1Q that enter
381 this stage on any of the access ports, so the "default drop" rule we
382 added earlier causes them to be dropped, which is ordinarily what we
383 want for access ports.
385 >>> Another variation of access ports allows ingress of packets tagged
386 with VLAN 0 (aka 802.1p priority tagged packets). To allow such
387 packets, replace "vlan_tci=0" by "vlan_tci=0/0xfff" above.
393 "ofproto/trace" allows us to test the ingress VLAN rules that we added
397 == EXAMPLE 1: Packet on Trunk Port ==
399 Here's a test of a packet coming in on the trunk port:
401 ovs-appctl ofproto/trace br0 in_port=1,vlan_tci=5
403 The output shows the lookup in table 0, the resubmit to table 1, and
404 the resubmit to table 2 (which does nothing because we haven't put
407 Flow: metadata=0,in_port=1,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000
408 Rule: table=0 cookie=0 priority=0
409 OpenFlow actions=resubmit(,1)
411 Resubmitted flow: unchanged
412 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
413 Resubmitted odp: drop
414 Rule: table=1 cookie=0 priority=99,in_port=1
415 OpenFlow actions=resubmit(,2)
417 Resubmitted flow: unchanged
418 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
419 Resubmitted odp: drop
422 Final flow: unchanged
423 Datapath actions: drop
426 == EXAMPLE 2: Valid Packet on Access Port ==
428 Here's a test of a valid packet (a packet without an 802.1Q header)
429 coming in on access port p2:
431 ovs-appctl ofproto/trace br0 in_port=2
433 The output is similar to that for the previous case, except that it
434 additionally tags the packet with p2's VLAN 20 before it passes it
437 Flow: metadata=0,in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000
438 Rule: table=0 cookie=0 priority=0
439 OpenFlow actions=resubmit(,1)
441 Resubmitted flow: unchanged
442 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
443 Resubmitted odp: drop
444 Rule: table=1 cookie=0 priority=99,in_port=2,vlan_tci=0x0000
445 OpenFlow actions=mod_vlan_vid:20,resubmit(,2)
447 Resubmitted flow: metadata=0,in_port=2,dl_vlan=20,dl_vlan_pcp=0,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000
448 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
449 Resubmitted odp: drop
452 Final flow: unchanged
453 Datapath actions: drop
456 == EXAMPLE 3: Invalid Packet on Access Port ==
458 This tests an invalid packet (one that includes an 802.1Q header)
459 coming in on access port p2:
461 ovs-appctl ofproto/trace br0 in_port=2,vlan_tci=5
463 The output shows the packet matching the default drop rule:
465 Flow: metadata=0,in_port=2,vlan_tci=0x0005,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000
466 Rule: table=0 cookie=0 priority=0
467 OpenFlow actions=resubmit(,1)
469 Resubmitted flow: unchanged
470 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
471 Resubmitted odp: drop
472 Rule: table=1 cookie=0 priority=0
473 OpenFlow actions=drop
475 Final flow: unchanged
476 Datapath actions: drop
479 Implementing Table 2: MAC+VLAN Learning for Ingress Port
480 ========================================================
482 This table allows the switch we're implementing to learn that the
483 packet's source MAC is located on the packet's ingress port in the
486 >>> This table is a good example why table 1 added a VLAN tag to
487 packets that entered the switch through an access port. We want
488 to associate a MAC+VLAN with a port regardless of whether the VLAN
489 in question was originally part of the packet or whether it was an
490 assumed VLAN associated with an access port.
492 It only takes a single flow to do this. The following command adds
495 ovs-ofctl add-flow br0 \
496 "table=2 actions=learn(table=10, NXM_OF_VLAN_TCI[0..11], \
497 NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], \
498 load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]), \
501 The "learn" action (an Open vSwitch extension to OpenFlow) modifies a
502 flow table based on the content of the flow currently being processed.
503 Here's how you can interpret each part of the "learn" action above:
507 Modify flow table 10. This will be the MAC learning table.
509 NXM_OF_VLAN_TCI[0..11]
511 Make the flow that we add to flow table 10 match the same VLAN
512 ID that the packet we're currently processing contains. This
513 effectively scopes the MAC learning entry to a single VLAN,
514 which is the ordinary behavior for a VLAN-aware switch.
516 NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]
518 Make the flow that we add to flow table 10 match, as Ethernet
519 destination, the Ethernet source address of the packet we're
520 currently processing.
522 load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]
524 Whereas the preceding parts specify fields for the new flow to
525 match, this specifies an action for the flow to take when it
526 matches. The action is for the flow to load the ingress port
527 number of the current packet into register 0 (a special field
528 that is an Open vSwitch extension to OpenFlow).
530 >>> A real use of "learn" for MAC learning would probably involve two
531 additional elements. First, the "learn" action would specify a
532 hard_timeout for the new flow, to enable a learned MAC to
533 eventually expire if no new packets were seen from a given source
534 within a reasonable interval. Second, one would usually want to
535 limit resource consumption by using the Flow_Table table in the
536 Open vSwitch configuration database to specify a maximum number of
539 This definitely calls for examples.
547 Try the following test command:
549 ovs-appctl ofproto/trace br0 in_port=1,vlan_tci=20,dl_src=50:00:00:00:00:01 -generate
551 The output shows that "learn" was executed, but it isn't otherwise
552 informative, so we won't include it here.
554 The "-generate" keyword is new. Ordinarily, "ofproto/trace" has no
555 side effects: "output" actions do not actually output packets, "learn"
556 actions do not actually modify the flow table, and so on. With
557 "-generate", though, "ofproto/trace" does execute "learn" actions.
558 That's important now, because we want to see the effect of the "learn"
559 action on table 10. You can see that by running:
561 ovs-ofctl dump-flows br0 table=10
563 which (omitting the "duration" and "idle_age" fields, which will vary
564 based on how soon you ran this command after the previous one, as well
565 as some other uninteresting fields) prints something like:
567 NXST_FLOW reply (xid=0x4):
568 table=10, vlan_tci=0x0014/0x0fff,dl_dst=50:00:00:00:00:01 actions=load:0x1->NXM_NX_REG0[0..15]
570 You can see that the packet coming in on VLAN 20 with source MAC
571 50:00:00:00:00:01 became a flow that matches VLAN 20 (written in
572 hexadecimal) and destination MAC 50:00:00:00:00:01. The flow loads
573 port number 1, the input port for the flow we tested, into register 0.
578 Here's a second test command:
580 ovs-appctl ofproto/trace br0 in_port=2,dl_src=50:00:00:00:00:01 -generate
582 The flow that this command tests has the same source MAC and VLAN as
583 example 1, although the VLAN comes from an access port VLAN rather
584 than an 802.1Q header. If we again dump the flows for table 10 with:
586 ovs-ofctl dump-flows br0 table=10
588 then we see that the flow we saw previously has changed to indicate
589 that the learned port is port 2, as we would expect:
591 NXST_FLOW reply (xid=0x4):
592 table=10, vlan_tci=0x0014/0x0fff,dl_dst=50:00:00:00:00:01 actions=load:0x2->NXM_NX_REG0[0..15]
595 Implementing Table 3: Look Up Destination Port
596 ==============================================
598 This table figures out what port we should send the packet to based on
599 the destination MAC and VLAN. That is, if we've learned the location
600 of the destination (from table 2 processing some previous packet with
601 that destination as its source), then we want to send the packet
604 We need only one flow to do the lookup:
606 ovs-ofctl add-flow br0 \
607 "table=3 priority=50 actions=resubmit(,10), resubmit(,4)"
609 The flow's first action resubmits to table 10, the table that the
610 "learn" action modifies. As you saw previously, the learned flows in
611 this table write the learned port into register 0. If the destination
612 for our packet hasn't been learned, then there will be no matching
613 flow, and so the "resubmit" turns into a no-op. Because registers are
614 initialized to 0, we can use a register 0 value of 0 in our next
615 pipeline stage as a signal to flood the packet.
617 The second action resubmits to table 4, continuing to the next
620 We can add another flow to skip the learning table lookup for
621 multicast and broadcast packets, since those should always be flooded:
623 ovs-ofctl add-flow br0 \
624 "table=3 priority=99 dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 \
625 actions=resubmit(,4)"
627 >>> We don't strictly need to add this flow, because multicast
628 addresses will never show up in our learning table. (In turn,
629 that's because we put a flow into table 0 to drop packets that
630 have a multicast source address.)
638 Here's a command that should cause OVS to learn that f0:00:00:00:00:01
641 ovs-appctl ofproto/trace br0 in_port=1,dl_vlan=20,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01 -generate
643 Here's an excerpt from the output that shows (from the "no match"
644 looking up the resubmit to table 10) that the flow's destination was
647 Resubmitted flow: unchanged
648 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
649 Resubmitted odp: drop
650 Rule: table=3 cookie=0 priority=50
651 OpenFlow actions=resubmit(,10),resubmit(,4)
653 Resubmitted flow: unchanged
654 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
655 Resubmitted odp: drop
658 You can verify that the packet's source was learned two ways. The
659 most direct way is to dump the learning table with:
661 ovs-ofctl dump-flows br0 table=10
663 which ought to show roughly the following, with extraneous details
666 table=10, vlan_tci=0x0014/0x0fff,dl_dst=f0:00:00:00:00:01 actions=load:0x1->NXM_NX_REG0[0..15]
668 >>> If you tried the examples for the previous step, or if you did
669 some of your own experiments, then you might see additional flows
670 there. These additional flows are harmless. If they bother you,
671 then you can remove them with "ovs-ofctl del-flows br0 table=10".
673 The other way is to inject a packet to take advantage of the learning
674 entry. For example, we can inject a packet on p2 whose destination is
675 the MAC address that we just learned on p1:
677 ovs-appctl ofproto/trace br0 in_port=2,dl_src=90:00:00:00:00:01,dl_dst=f0:00:00:00:00:01 -generate
679 Here's an interesting excerpt from that command's output. This group
680 of lines traces the "resubmit(,10)", showing that the packet matched
681 the learned flow for the first MAC we used, loading the OpenFlow port
682 number for the learned port p1 into register 0:
684 Resubmitted flow: unchanged
685 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
686 Resubmitted odp: drop
687 Rule: table=10 cookie=0 vlan_tci=0x0014/0x0fff,dl_dst=f0:00:00:00:00:01
688 OpenFlow actions=load:0x1->NXM_NX_REG0[0..15]
691 If you read the commands above carefully, then you might have noticed
692 that they simply have the Ethernet source and destination addresses
693 exchanged. That means that if we now rerun the first ovs-appctl
696 ovs-appctl ofproto/trace br0 in_port=1,dl_vlan=20,dl_src=f0:00:00:00:00:01,dl_dst=90:00:00:00:00:01 -generate
698 then we see in the output that the destination has now been learned:
700 Resubmitted flow: unchanged
701 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
702 Resubmitted odp: drop
703 Rule: table=10 cookie=0 vlan_tci=0x0014/0x0fff,dl_dst=90:00:00:00:00:01
704 OpenFlow actions=load:0x2->NXM_NX_REG0[0..15]
707 Implementing Table 4: Output Processing
708 =======================================
710 At entry to stage 4, we know that register 0 contains either the
711 desired output port or is zero if the packet should be flooded. We
712 also know that the packet's VLAN is in its 802.1Q header, even if the
713 VLAN was implicit because the packet came in on an access port.
715 The job of the final pipeline stage is to actually output packets.
716 The job is trivial for output to our trunk port p1:
718 ovs-ofctl add-flow br0 "table=4 reg0=1 actions=1"
720 For output to the access ports, we just have to strip the VLAN header
721 before outputting the packet:
723 ovs-ofctl add-flows br0 - <<'EOF'
724 table=4 reg0=2 actions=strip_vlan,2
725 table=4 reg0=3 actions=strip_vlan,3
726 table=4 reg0=4 actions=strip_vlan,4
729 The only slightly tricky part is flooding multicast and broadcast
730 packets and unicast packets with unlearned destinations. For those,
731 we need to make sure that we only output the packets to the ports that
732 carry our packet's VLAN, and that we include the 802.1Q header in the
733 copy output to the trunk port but not in copies output to access
736 ovs-ofctl add-flows br0 - <<'EOF'
737 table=4 reg0=0 priority=99 dl_vlan=20 actions=1,strip_vlan,2
738 table=4 reg0=0 priority=99 dl_vlan=30 actions=1,strip_vlan,3,4
739 table=4 reg0=0 priority=50 actions=1
742 >>> Our rules rely on the standard OpenFlow behavior that an output
743 action will not forward a packet back out the port it came in on.
744 That is, if a packet comes in on p1, and we've learned that the
745 packet's destination MAC is also on p1, so that we end up with
746 "actions=1" as our actions, the switch will not forward the packet
747 back out its input port. The multicast/broadcast/unknown
748 destination cases above also rely on this behavior.
754 == EXAMPLE 1: Broadcast, Multicast, and Unknown Destination ==
756 Try tracing a broadcast packet arriving on p1 in VLAN 30:
758 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=30
760 The interesting part of the output is the final line, which shows that
761 the switch would remove the 802.1Q header and then output the packet to
762 p3 and p4, which are access ports for VLAN 30:
764 Datapath actions: pop_vlan,3,4
766 Similarly, if we trace a broadcast packet arriving on p3:
768 ovs-appctl ofproto/trace br0 in_port=3,dl_dst=ff:ff:ff:ff:ff:ff
770 then we see that it is output to p1 with an 802.1Q tag and then to p4
773 Datapath actions: push_vlan(vid=30,pcp=0),1,pop_vlan,4
775 >>> Open vSwitch could simplify the datapath actions here to just
776 "4,push_vlan(vid=30,pcp=0),1" but it is not smart enough to do so.
778 The following are also broadcasts, but the result is to drop the
779 packets because the VLAN only belongs to the input port:
781 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff
782 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=55
784 Try some other broadcast cases on your own:
786 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=20
787 ovs-appctl ofproto/trace br0 in_port=2,dl_dst=ff:ff:ff:ff:ff:ff
788 ovs-appctl ofproto/trace br0 in_port=4,dl_dst=ff:ff:ff:ff:ff:ff
790 You can see the same behavior with multicast packets and with unicast
791 packets whose destination has not been learned, e.g.:
793 ovs-appctl ofproto/trace br0 in_port=4,dl_dst=01:00:00:00:00:00
794 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=90:12:34:56:78:90,dl_vlan=20
795 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=90:12:34:56:78:90,dl_vlan=30
798 == EXAMPLE 2: MAC Learning ==
800 Let's follow the same pattern as we did for table 3. First learn a
801 MAC on port p1 in VLAN 30:
803 ovs-appctl ofproto/trace br0 in_port=1,dl_vlan=30,dl_src=10:00:00:00:00:01,dl_dst=20:00:00:00:00:01 -generate
805 You can see from the last line of output that the packet's destination
806 is unknown, so it gets flooded to both p3 and p4, the other ports in
809 Datapath actions: pop_vlan,3,4
811 Then reverse the MACs and learn the first flow's destination on port
814 ovs-appctl ofproto/trace br0 in_port=4,dl_src=20:00:00:00:00:01,dl_dst=10:00:00:00:00:01 -generate
816 The last line of output shows that the this packet's destination is
817 known to be p1, as learned from our previous command:
819 Datapath actions: push_vlan(vid=30,pcp=0),1
821 Now, if we rerun our first command:
823 ovs-appctl ofproto/trace br0 in_port=1,dl_vlan=30,dl_src=10:00:00:00:00:01,dl_dst=20:00:00:00:00:01 -generate
825 we can see that the result is no longer a flood but to the specified
826 learned destination port p4:
828 Datapath actions: pop_vlan,4
835 http://openvswitch.org/