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.)
272 If we were using Open vSwitch to set up a physical or a virtual
273 switch, then we would naturally test it by sending packets through it
274 one way or another, perhaps with common network testing tools like
275 "ping" and "tcpdump" or more specialized tools like Scapy. That's
276 difficult with our simulated switch, since it's not visible to the
279 But our simulated switch has a few specialized testing tools. The
280 most powerful of these tools is "ofproto/trace". Given a switch and
281 the specification of a flow, "ofproto/trace" shows, step-by-step, how
282 such a flow would be treated as it goes through the switch.
289 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=01:80:c2:00:00:05
291 The output should look something like this:
293 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
294 Rule: table=0 cookie=0 dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0
295 OpenFlow actions=drop
297 Final flow: unchanged
298 Datapath actions: drop
300 The first block of lines describes an OpenFlow table lookup. The
301 first line shows the fields used for the table lookup (which is mostly
302 zeros because that's the default if we don't specify everything). The
303 second line gives the OpenFlow flow that the fields matched (called a
304 "rule" because that is the name used inside Open vSwitch for an
305 OpenFlow flow). In this case, we see that this packet that has a
306 reserved multicast destination address matches the rule that drops
307 those packets. The third line gives the rule's OpenFlow actions.
309 The second block of lines summarizes the results, which are not very
317 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=01:80:c2:00:00:10
319 The output should be:
321 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
322 Rule: table=0 cookie=0 priority=0
323 OpenFlow actions=resubmit(,1)
325 Resubmitted flow: unchanged
326 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
327 Resubmitted odp: drop
330 Final flow: unchanged
331 Datapath actions: drop
333 This time the flow we handed to "ofproto/trace" doesn't match any of
334 our "drop" rules, so it falls through to the low-priority "resubmit"
335 rule, which we see in the rule and the actions selected in the first
336 block. The "resubmit" causes a second lookup in OpenFlow table 1,
337 described by the additional block of indented text in the output. We
338 haven't yet added any flows to OpenFlow table 1, so no flow actually
339 matches in the second lookup. Therefore, the packet is still actually
340 dropped, which means that the externally observable results would be
341 identical to our first example.
344 Implementing Table 1: VLAN Input Processing
345 -------------------------------------------
347 A packet that enters table 1 has already passed basic validation in
348 table 0. The purpose of table 1 is validate the packet's VLAN, based
349 on the VLAN configuration of the switch port through which the packet
350 entered the switch. We will also use it to attach a VLAN header to
351 packets that arrive on an access port, which allows later processing
352 stages to rely on the packet's VLAN always being part of the VLAN
353 header, reducing special cases.
355 Let's start by adding a low-priority flow that drops all packets,
356 before we add flows that pass through acceptable packets. You can
357 think of this as a "default drop" rule:
359 ovs-ofctl add-flow br0 "table=1, priority=0, actions=drop"
361 Our trunk port p1, on OpenFlow port 1, is an easy case. p1 accepts
362 any packet regardless of whether it has a VLAN header or what the VLAN
363 was, so we can add a flow that resubmits everything on input port 1 to
366 ovs-ofctl add-flow br0 \
367 "table=1, priority=99, in_port=1, actions=resubmit(,2)"
369 On the access ports, we want to accept any packet that has no VLAN
370 header, tag it with the access port's VLAN number, and then pass it
371 along to the next stage:
373 ovs-ofctl add-flows br0 - <<'EOF'
374 table=1, priority=99, in_port=2, vlan_tci=0, actions=mod_vlan_vid:20, resubmit(,2)
375 table=1, priority=99, in_port=3, vlan_tci=0, actions=mod_vlan_vid:30, resubmit(,2)
376 table=1, priority=99, in_port=4, vlan_tci=0, actions=mod_vlan_vid:30, resubmit(,2)
379 We don't write any rules that match packets with 802.1Q that enter
380 this stage on any of the access ports, so the "default drop" rule we
381 added earlier causes them to be dropped, which is ordinarily what we
382 want for access ports.
384 >>> Another variation of access ports allows ingress of packets tagged
385 with VLAN 0 (aka 802.1p priority tagged packets). To allow such
386 packets, replace "vlan_tci=0" by "vlan_tci=0/0xfff" above.
391 "ofproto/trace" allows us to test the ingress VLAN rules that we added
395 ### EXAMPLE 1: Packet on Trunk Port
397 Here's a test of a packet coming in on the trunk port:
399 ovs-appctl ofproto/trace br0 in_port=1,vlan_tci=5
401 The output shows the lookup in table 0, the resubmit to table 1, and
402 the resubmit to table 2 (which does nothing because we haven't put
405 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
406 Rule: table=0 cookie=0 priority=0
407 OpenFlow actions=resubmit(,1)
409 Resubmitted flow: unchanged
410 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
411 Resubmitted odp: drop
412 Rule: table=1 cookie=0 priority=99,in_port=1
413 OpenFlow actions=resubmit(,2)
415 Resubmitted flow: unchanged
416 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
417 Resubmitted odp: drop
420 Final flow: unchanged
421 Datapath actions: drop
424 ### EXAMPLE 2: Valid Packet on Access Port
426 Here's a test of a valid packet (a packet without an 802.1Q header)
427 coming in on access port p2:
429 ovs-appctl ofproto/trace br0 in_port=2
431 The output is similar to that for the previous case, except that it
432 additionally tags the packet with p2's VLAN 20 before it passes it
435 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
436 Rule: table=0 cookie=0 priority=0
437 OpenFlow actions=resubmit(,1)
439 Resubmitted flow: unchanged
440 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
441 Resubmitted odp: drop
442 Rule: table=1 cookie=0 priority=99,in_port=2,vlan_tci=0x0000
443 OpenFlow actions=mod_vlan_vid:20,resubmit(,2)
445 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
446 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
447 Resubmitted odp: drop
450 Final flow: unchanged
451 Datapath actions: drop
454 ### EXAMPLE 3: Invalid Packet on Access Port
456 This tests an invalid packet (one that includes an 802.1Q header)
457 coming in on access port p2:
459 ovs-appctl ofproto/trace br0 in_port=2,vlan_tci=5
461 The output shows the packet matching the default drop rule:
463 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
464 Rule: table=0 cookie=0 priority=0
465 OpenFlow actions=resubmit(,1)
467 Resubmitted flow: unchanged
468 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
469 Resubmitted odp: drop
470 Rule: table=1 cookie=0 priority=0
471 OpenFlow actions=drop
473 Final flow: unchanged
474 Datapath actions: drop
477 Implementing Table 2: MAC+VLAN Learning for Ingress Port
478 --------------------------------------------------------
480 This table allows the switch we're implementing to learn that the
481 packet's source MAC is located on the packet's ingress port in the
484 >>> This table is a good example why table 1 added a VLAN tag to
485 packets that entered the switch through an access port. We want
486 to associate a MAC+VLAN with a port regardless of whether the VLAN
487 in question was originally part of the packet or whether it was an
488 assumed VLAN associated with an access port.
490 It only takes a single flow to do this. The following command adds
493 ovs-ofctl add-flow br0 \
494 "table=2 actions=learn(table=10, NXM_OF_VLAN_TCI[0..11], \
495 NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], \
496 load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]), \
499 The "learn" action (an Open vSwitch extension to OpenFlow) modifies a
500 flow table based on the content of the flow currently being processed.
501 Here's how you can interpret each part of the "learn" action above:
505 Modify flow table 10. This will be the MAC learning table.
507 NXM_OF_VLAN_TCI[0..11]
509 Make the flow that we add to flow table 10 match the same VLAN
510 ID that the packet we're currently processing contains. This
511 effectively scopes the MAC learning entry to a single VLAN,
512 which is the ordinary behavior for a VLAN-aware switch.
514 NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]
516 Make the flow that we add to flow table 10 match, as Ethernet
517 destination, the Ethernet source address of the packet we're
518 currently processing.
520 load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]
522 Whereas the preceding parts specify fields for the new flow to
523 match, this specifies an action for the flow to take when it
524 matches. The action is for the flow to load the ingress port
525 number of the current packet into register 0 (a special field
526 that is an Open vSwitch extension to OpenFlow).
528 >>> A real use of "learn" for MAC learning would probably involve two
529 additional elements. First, the "learn" action would specify a
530 hard_timeout for the new flow, to enable a learned MAC to
531 eventually expire if no new packets were seen from a given source
532 within a reasonable interval. Second, one would usually want to
533 limit resource consumption by using the Flow_Table table in the
534 Open vSwitch configuration database to specify a maximum number of
537 This definitely calls for examples.
544 Try the following test command:
546 ovs-appctl ofproto/trace br0 in_port=1,vlan_tci=20,dl_src=50:00:00:00:00:01 -generate
548 The output shows that "learn" was executed, but it isn't otherwise
549 informative, so we won't include it here.
551 The "-generate" keyword is new. Ordinarily, "ofproto/trace" has no
552 side effects: "output" actions do not actually output packets, "learn"
553 actions do not actually modify the flow table, and so on. With
554 "-generate", though, "ofproto/trace" does execute "learn" actions.
555 That's important now, because we want to see the effect of the "learn"
556 action on table 10. You can see that by running:
558 ovs-ofctl dump-flows br0 table=10
560 which (omitting the "duration" and "idle_age" fields, which will vary
561 based on how soon you ran this command after the previous one, as well
562 as some other uninteresting fields) prints something like:
564 NXST_FLOW reply (xid=0x4):
565 table=10, vlan_tci=0x0014/0x0fff,dl_dst=50:00:00:00:00:01 actions=load:0x1->NXM_NX_REG0[0..15]
567 You can see that the packet coming in on VLAN 20 with source MAC
568 50:00:00:00:00:01 became a flow that matches VLAN 20 (written in
569 hexadecimal) and destination MAC 50:00:00:00:00:01. The flow loads
570 port number 1, the input port for the flow we tested, into register 0.
575 Here's a second test command:
577 ovs-appctl ofproto/trace br0 in_port=2,dl_src=50:00:00:00:00:01 -generate
579 The flow that this command tests has the same source MAC and VLAN as
580 example 1, although the VLAN comes from an access port VLAN rather
581 than an 802.1Q header. If we again dump the flows for table 10 with:
583 ovs-ofctl dump-flows br0 table=10
585 then we see that the flow we saw previously has changed to indicate
586 that the learned port is port 2, as we would expect:
588 NXST_FLOW reply (xid=0x4):
589 table=10, vlan_tci=0x0014/0x0fff,dl_dst=50:00:00:00:00:01 actions=load:0x2->NXM_NX_REG0[0..15]
592 Implementing Table 3: Look Up Destination Port
593 ----------------------------------------------
595 This table figures out what port we should send the packet to based on
596 the destination MAC and VLAN. That is, if we've learned the location
597 of the destination (from table 2 processing some previous packet with
598 that destination as its source), then we want to send the packet
601 We need only one flow to do the lookup:
603 ovs-ofctl add-flow br0 \
604 "table=3 priority=50 actions=resubmit(,10), resubmit(,4)"
606 The flow's first action resubmits to table 10, the table that the
607 "learn" action modifies. As you saw previously, the learned flows in
608 this table write the learned port into register 0. If the destination
609 for our packet hasn't been learned, then there will be no matching
610 flow, and so the "resubmit" turns into a no-op. Because registers are
611 initialized to 0, we can use a register 0 value of 0 in our next
612 pipeline stage as a signal to flood the packet.
614 The second action resubmits to table 4, continuing to the next
617 We can add another flow to skip the learning table lookup for
618 multicast and broadcast packets, since those should always be flooded:
620 ovs-ofctl add-flow br0 \
621 "table=3 priority=99 dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 \
622 actions=resubmit(,4)"
624 >>> We don't strictly need to add this flow, because multicast
625 addresses will never show up in our learning table. (In turn,
626 that's because we put a flow into table 0 to drop packets that
627 have a multicast source address.)
634 Here's a command that should cause OVS to learn that f0:00:00:00:00:01
637 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
639 Here's an excerpt from the output that shows (from the "no match"
640 looking up the resubmit to table 10) that the flow's destination was
643 Resubmitted flow: unchanged
644 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
645 Resubmitted odp: drop
646 Rule: table=3 cookie=0 priority=50
647 OpenFlow actions=resubmit(,10),resubmit(,4)
649 Resubmitted flow: unchanged
650 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
651 Resubmitted odp: drop
654 You can verify that the packet's source was learned two ways. The
655 most direct way is to dump the learning table with:
657 ovs-ofctl dump-flows br0 table=10
659 which ought to show roughly the following, with extraneous details
662 table=10, vlan_tci=0x0014/0x0fff,dl_dst=f0:00:00:00:00:01 actions=load:0x1->NXM_NX_REG0[0..15]
664 >>> If you tried the examples for the previous step, or if you did
665 some of your own experiments, then you might see additional flows
666 there. These additional flows are harmless. If they bother you,
667 then you can remove them with "ovs-ofctl del-flows br0 table=10".
669 The other way is to inject a packet to take advantage of the learning
670 entry. For example, we can inject a packet on p2 whose destination is
671 the MAC address that we just learned on p1:
673 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
675 Here's an interesting excerpt from that command's output. This group
676 of lines traces the "resubmit(,10)", showing that the packet matched
677 the learned flow for the first MAC we used, loading the OpenFlow port
678 number for the learned port p1 into register 0:
680 Resubmitted flow: unchanged
681 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
682 Resubmitted odp: drop
683 Rule: table=10 cookie=0 vlan_tci=0x0014/0x0fff,dl_dst=f0:00:00:00:00:01
684 OpenFlow actions=load:0x1->NXM_NX_REG0[0..15]
687 If you read the commands above carefully, then you might have noticed
688 that they simply have the Ethernet source and destination addresses
689 exchanged. That means that if we now rerun the first ovs-appctl
692 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
694 then we see in the output that the destination has now been learned:
696 Resubmitted flow: unchanged
697 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
698 Resubmitted odp: drop
699 Rule: table=10 cookie=0 vlan_tci=0x0014/0x0fff,dl_dst=90:00:00:00:00:01
700 OpenFlow actions=load:0x2->NXM_NX_REG0[0..15]
703 Implementing Table 4: Output Processing
704 ---------------------------------------
706 At entry to stage 4, we know that register 0 contains either the
707 desired output port or is zero if the packet should be flooded. We
708 also know that the packet's VLAN is in its 802.1Q header, even if the
709 VLAN was implicit because the packet came in on an access port.
711 The job of the final pipeline stage is to actually output packets.
712 The job is trivial for output to our trunk port p1:
714 ovs-ofctl add-flow br0 "table=4 reg0=1 actions=1"
716 For output to the access ports, we just have to strip the VLAN header
717 before outputting the packet:
719 ovs-ofctl add-flows br0 - <<'EOF'
720 table=4 reg0=2 actions=strip_vlan,2
721 table=4 reg0=3 actions=strip_vlan,3
722 table=4 reg0=4 actions=strip_vlan,4
725 The only slightly tricky part is flooding multicast and broadcast
726 packets and unicast packets with unlearned destinations. For those,
727 we need to make sure that we only output the packets to the ports that
728 carry our packet's VLAN, and that we include the 802.1Q header in the
729 copy output to the trunk port but not in copies output to access
732 ovs-ofctl add-flows br0 - <<'EOF'
733 table=4 reg0=0 priority=99 dl_vlan=20 actions=1,strip_vlan,2
734 table=4 reg0=0 priority=99 dl_vlan=30 actions=1,strip_vlan,3,4
735 table=4 reg0=0 priority=50 actions=1
738 >>> Our rules rely on the standard OpenFlow behavior that an output
739 action will not forward a packet back out the port it came in on.
740 That is, if a packet comes in on p1, and we've learned that the
741 packet's destination MAC is also on p1, so that we end up with
742 "actions=1" as our actions, the switch will not forward the packet
743 back out its input port. The multicast/broadcast/unknown
744 destination cases above also rely on this behavior.
749 ### EXAMPLE 1: Broadcast, Multicast, and Unknown Destination
751 Try tracing a broadcast packet arriving on p1 in VLAN 30:
753 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=30
755 The interesting part of the output is the final line, which shows that
756 the switch would remove the 802.1Q header and then output the packet to
757 p3 and p4, which are access ports for VLAN 30:
759 Datapath actions: pop_vlan,3,4
761 Similarly, if we trace a broadcast packet arriving on p3:
763 ovs-appctl ofproto/trace br0 in_port=3,dl_dst=ff:ff:ff:ff:ff:ff
765 then we see that it is output to p1 with an 802.1Q tag and then to p4
768 Datapath actions: push_vlan(vid=30,pcp=0),1,pop_vlan,4
770 >>> Open vSwitch could simplify the datapath actions here to just
771 "4,push_vlan(vid=30,pcp=0),1" but it is not smart enough to do so.
773 The following are also broadcasts, but the result is to drop the
774 packets because the VLAN only belongs to the input port:
776 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff
777 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=55
779 Try some other broadcast cases on your own:
781 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=20
782 ovs-appctl ofproto/trace br0 in_port=2,dl_dst=ff:ff:ff:ff:ff:ff
783 ovs-appctl ofproto/trace br0 in_port=4,dl_dst=ff:ff:ff:ff:ff:ff
785 You can see the same behavior with multicast packets and with unicast
786 packets whose destination has not been learned, e.g.:
788 ovs-appctl ofproto/trace br0 in_port=4,dl_dst=01:00:00:00:00:00
789 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=90:12:34:56:78:90,dl_vlan=20
790 ovs-appctl ofproto/trace br0 in_port=1,dl_dst=90:12:34:56:78:90,dl_vlan=30
793 ### EXAMPLE 2: MAC Learning
795 Let's follow the same pattern as we did for table 3. First learn a
796 MAC on port p1 in VLAN 30:
798 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
800 You can see from the last line of output that the packet's destination
801 is unknown, so it gets flooded to both p3 and p4, the other ports in
804 Datapath actions: pop_vlan,3,4
806 Then reverse the MACs and learn the first flow's destination on port
809 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
811 The last line of output shows that the this packet's destination is
812 known to be p1, as learned from our previous command:
814 Datapath actions: push_vlan(vid=30,pcp=0),1
816 Now, if we rerun our first command:
818 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
820 we can see that the result is no longer a flood but to the specified
821 learned destination port p4:
823 Datapath actions: pop_vlan,4
830 http://openvswitch.org/