ovs-sandbox: Add an option to allow running ovs-vswitchd under gdb
[cascardo/ovs.git] / tutorial / Tutorial.md
1 Open vSwitch Advanced Features Tutorial
2 =======================================
3
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
8 here afterward.
9
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,
12 you should learn a little about them before proceeding.
13
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.
19
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.
24
25 > In this tutorial, paragraphs set off like this designate notes
26 > with additional information that readers may wish to skip on a
27 > first read.
28
29 Getting Started
30 ---------------
31
32 This is a hands-on tutorial.  To get the most out of it, you will need
33 Open vSwitch binaries.  You do not, on the other hand, need any
34 physical networking hardware or even supervisor privilege on your
35 system.  Instead, we will use a script called `ovs-sandbox`, which
36 accompanies the tutorial, that constructs a software simulated network
37 environment based on Open vSwitch.
38
39 You can use `ovs-sandbox` three ways:
40
41   * If you have already installed Open vSwitch on your system, then
42     you should be able to just run `ovs-sandbox` from this directory
43     without any options.
44
45   * If you have not installed Open vSwitch (and you do not want to
46     install it), then you can build Open vSwitch according to the
47     instructions in [INSTALL.md], without installing it.  Then run
48     `./ovs-sandbox -b DIRECTORY` from this directory, substituting
49     the Open vSwitch build directory for `DIRECTORY`.
50
51   * As a slight variant on the latter, you can run `make sandbox`
52     from an Open vSwitch build directory.
53
54 When you run `ovs-sandbox`, it does the following:
55
56   1. **CAUTION:** Deletes any subdirectory of the current directory
57      named "sandbox" and any files in that directory.
58
59   2. Creates a new directory "sandbox" in the current directory.
60
61   3. Sets up special environment variables that ensure that Open
62      vSwitch programs will look inside the "sandbox" directory
63      instead of in the Open vSwitch installation directory.
64
65   4. If you are using a built but not installed Open vSwitch,
66      installs the Open vSwitch manpages in a subdirectory of
67      "sandbox" and adjusts the `MANPATH` environment variable to point
68      to this directory.  This means that you can use, for example,
69      `man ovs-vsctl` to see a manpage for the `ovs-vsctl` program that
70      you built.
71
72   5. Creates an empty Open vSwitch configuration database under
73      "sandbox".
74
75   6. Starts `ovsdb-server` running under "sandbox".
76
77   7. Starts `ovs-vswitchd` running under "sandbox", passing special
78      options that enable a special "dummy" mode for testing.
79
80   8. Starts a nested interactive shell inside "sandbox".
81
82 At this point, you can run all the usual Open vSwitch utilities from
83 the nested shell environment.  You can, for example, use `ovs-vsctl`
84 to create a bridge:
85
86     ovs-vsctl add-br br0
87
88 From Open vSwitch's perspective, the bridge that you create this way
89 is as real as any other.  You can, for example, connect it to an
90 OpenFlow controller or use `ovs-ofctl` to examine and modify it and
91 its OpenFlow flow table.  On the other hand, the bridge is not visible
92 to the operating system's network stack, so `ifconfig` or `ip` cannot
93 see it or affect it, which means that utilities like `ping` and
94 `tcpdump` will not work either.  (That has its good side, too: you
95 can't screw up your computer's network stack by manipulating a
96 sandboxed OVS.)
97
98 When you're done using OVS from the sandbox, exit the nested shell (by
99 entering the "exit" shell command or pressing Control+D).  This will
100 kill the daemons that `ovs-sandbox` started, but it leaves the "sandbox"
101 directory and its contents in place.
102
103 The sandbox directory contains log files for the Open vSwitch dameons.
104 You can examine them while you're running in the sandboxed environment
105 or after you exit.
106
107 Using GDB
108 ---------
109
110 GDB support is not required to go through the tutorial. It is added in case
111 user wants to explore the internals of OVS programs.
112
113 GDB can already be used to debug any running process, with the usual
114 'gdb <program> <process-id>' command.
115
116 'ovs-sandbox' also has a '-g' option for launching ovs-vswitchd under GDB.
117 This option can be handy for setting break points before ovs-vswitchd runs,
118 or for catching early segfaults.
119
120 To avoid GDB mangling with the sandbox sub shell terminal, 'ovs-sandbox'
121 starts a new xterm to run each GDB session.  For systems that do not support
122 X windows, GDB support is effectively disabled.
123
124 When launching sandbox through the build tree's make file, the '-g' option
125 can be passed via the 'SANDBOXFLAGS' environment variable.
126 'make sandbox SANDBOXFLAGS=-g' will start the sandbox with ovs-vswitchd
127 running under GDB in its own xterm if X is available.
128
129 Motivation
130 ----------
131
132 The goal of this tutorial is to demonstrate the power of Open vSwitch
133 flow tables.  The tutorial works through the implementation of a
134 MAC-learning switch with VLAN trunk and access ports.  Outside of the
135 Open vSwitch features that we will discuss, OpenFlow provides at least
136 two ways to implement such a switch:
137
138   1. An OpenFlow controller to implement MAC learning in a
139      "reactive" fashion.  Whenever a new MAC appears on the switch,
140      or a MAC moves from one switch port to another, the controller
141      adjusts the OpenFlow flow table to match.
142
143   2. The "normal" action.  OpenFlow defines this action to submit a
144      packet to "the traditional non-OpenFlow pipeline of the
145      switch".  That is, if a flow uses this action, then the packets
146      in the flow go through the switch in the same way that they
147      would if OpenFlow was not configured on the switch.
148
149 Each of these approaches has unfortunate pitfalls.  In the first
150 approach, using an OpenFlow controller to implement MAC learning, has
151 a significant cost in terms of network bandwidth and latency.  It also
152 makes the controller more difficult to scale to large numbers of
153 switches, which is especially important in environments with thousands
154 of hypervisors (each of which contains a virtual OpenFlow switch).
155 MAC learning at an OpenFlow controller also behaves poorly if the
156 OpenFlow controller fails, slows down, or becomes unavailable due to
157 network problems.
158
159 The second approach, using the "normal" action, has different
160 problems.  First, little about the "normal" action is standardized, so
161 it behaves differently on switches from different vendors, and the
162 available features and how those features are configured (usually not
163 through OpenFlow) varies widely.  Second, "normal" does not work well
164 with other OpenFlow actions.  It is "all-or-nothing", with little
165 potential to adjust its behavior slightly or to compose it with other
166 features.
167
168
169 Scenario
170 --------
171
172 We will construct Open vSwitch flow tables for a VLAN-capable,
173 MAC-learning switch that has four ports:
174
175   * p1, a trunk port that carries all VLANs, on OpenFlow port 1.
176
177   * p2, an access port for VLAN 20, on OpenFlow port 2.
178
179   * p3 and p4, both access ports for VLAN 30, on OpenFlow ports 3
180     and 4, respectively.
181
182 > The ports' names are not significant.  You could call them eth1
183 > through eth4, or any other names you like.
184
185 > An OpenFlow switch always has a "local" port as well.  This
186 > scenario won't use the local port.
187
188 Our switch design will consist of five main flow tables, each of which
189 implements one stage in the switch pipeline:
190
191   Table 0: Admission control.
192
193   Table 1: VLAN input processing.
194
195   Table 2: Learn source MAC and VLAN for ingress port.
196
197   Table 3: Look up learned port for destination MAC and VLAN.
198
199   Table 4: Output processing.
200
201 The section below describes how to set up the scenario, followed by a
202 section for each OpenFlow table.
203
204 You can cut and paste the `ovs-vsctl` and `ovs-ofctl` commands in each
205 of the sections below into your `ovs-sandbox` shell.  They are also
206 available as shell scripts in this directory, named `t-setup`, `t-stage0`,
207 `t-stage1`, ..., `t-stage4`.  The `ovs-appctl` test commands are intended
208 for cutting and pasting and are not supplied separately.
209
210
211 Setup
212 -----
213
214 To get started, start `ovs-sandbox`.  Inside the interactive shell
215 that it starts, run this command:
216
217     ovs-vsctl add-br br0 -- set Bridge br0 fail-mode=secure
218
219 This command creates a new bridge "br0" and puts "br0" into so-called
220 "fail-secure" mode.  For our purpose, this just means that the
221 OpenFlow flow table starts out empty.
222
223 > If we did not do this, then the flow table would start out with a
224 > single flow that executes the "normal" action.  We could use that
225 > feature to yield a switch that behaves the same as the switch we
226 > are currently building, but with the caveats described under
227 > "Motivation" above.)
228
229 The new bridge has only one port on it so far, the "local port" br0.
230 We need to add p1, p2, p3, and p4.  A shell "for" loop is one way to
231 do it:
232
233     for i in 1 2 3 4; do
234         ovs-vsctl add-port br0 p$i -- set Interface p$i ofport_request=$i
235               ovs-ofctl mod-port br0 p$i up
236     done
237
238 In addition to adding a port, the `ovs-vsctl` command above sets its
239 "ofport_request" column to ensure that port p1 is assigned OpenFlow
240 port 1, p2 is assigned OpenFlow port 2, and so on.
241
242 > We could omit setting the ofport_request and let Open vSwitch
243 > choose port numbers for us, but it's convenient for the purposes
244 > of this tutorial because we can talk about OpenFlow port 1 and
245 > know that it corresponds to p1.
246
247 The `ovs-ofctl` command above brings up the simulated interfaces, which
248 are down initially, using an OpenFlow request.  The effect is similar
249 to `ifconfig up`, but the sandbox's interfaces are not visible to the
250 operating system and therefore `ifconfig` would not affect them.
251
252 We have not configured anything related to VLANs or MAC learning.
253 That's because we're going to implement those features in the flow
254 table.
255
256 To see what we've done so far to set up the scenario, you can run a
257 command like `ovs-vsctl show` or `ovs-ofctl show br0`.
258
259
260 Implementing Table 0: Admission control
261 ---------------------------------------
262
263 Table 0 is where packets enter the switch.  We use this stage to
264 discard packets that for one reason or another are invalid.  For
265 example, packets with a multicast source address are not valid, so we
266 can add a flow to drop them at ingress to the switch with:
267
268     ovs-ofctl add-flow br0 \
269         "table=0, dl_src=01:00:00:00:00:00/01:00:00:00:00:00, actions=drop"
270
271 A switch should also not forward IEEE 802.1D Spanning Tree Protocol
272 (STP) packets, so we can also add a flow to drop those and other
273 packets with reserved multicast protocols:
274
275     ovs-ofctl add-flow br0 \
276         "table=0, dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0, actions=drop"
277
278 We could add flows to drop other protocols, but these demonstrate the
279 pattern.
280
281 We need one more flow, with a priority lower than the default, so that
282 flows that don't match either of the "drop" flows we added above go on
283 to pipeline stage 1 in OpenFlow table 1:
284
285     ovs-ofctl add-flow br0 "table=0, priority=0, actions=resubmit(,1)"
286
287 (The "resubmit" action is an Open vSwitch extension to OpenFlow.)
288
289
290 ### Testing Table 0
291
292 If we were using Open vSwitch to set up a physical or a virtual
293 switch, then we would naturally test it by sending packets through it
294 one way or another, perhaps with common network testing tools like
295 `ping` and `tcpdump` or more specialized tools like Scapy.  That's
296 difficult with our simulated switch, since it's not visible to the
297 operating system.
298
299 But our simulated switch has a few specialized testing tools.  The
300 most powerful of these tools is `ofproto/trace`.  Given a switch and
301 the specification of a flow, `ofproto/trace` shows, step-by-step, how
302 such a flow would be treated as it goes through the switch.
303
304
305 ### EXAMPLE 1
306
307 Try this command:
308
309     ovs-appctl ofproto/trace br0 in_port=1,dl_dst=01:80:c2:00:00:05
310
311 The output should look something like this:
312
313     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
314     Rule: table=0 cookie=0 dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0
315     OpenFlow actions=drop
316
317     Final flow: unchanged
318     Datapath actions: drop
319
320 The first block of lines describes an OpenFlow table lookup.  The
321 first line shows the fields used for the table lookup (which is mostly
322 zeros because that's the default if we don't specify everything).  The
323 second line gives the OpenFlow flow that the fields matched (called a
324 "rule" because that is the name used inside Open vSwitch for an
325 OpenFlow flow).  In this case, we see that this packet that has a
326 reserved multicast destination address matches the rule that drops
327 those packets.  The third line gives the rule's OpenFlow actions.
328
329 The second block of lines summarizes the results, which are not very
330 interesting here.
331
332
333 ### EXAMPLE 2
334
335 Try another command:
336
337     ovs-appctl ofproto/trace br0 in_port=1,dl_dst=01:80:c2:00:00:10
338
339 The output should be:
340
341     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
342     Rule: table=0 cookie=0 priority=0
343     OpenFlow actions=resubmit(,1)
344
345             Resubmitted flow: unchanged
346             Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
347             Resubmitted  odp: drop
348             No match
349
350     Final flow: unchanged
351     Datapath actions: drop
352
353 This time the flow we handed to `ofproto/trace` doesn't match any of
354 our "drop" rules, so it falls through to the low-priority "resubmit"
355 rule, which we see in the rule and the actions selected in the first
356 block.  The "resubmit" causes a second lookup in OpenFlow table 1,
357 described by the additional block of indented text in the output.  We
358 haven't yet added any flows to OpenFlow table 1, so no flow actually
359 matches in the second lookup.  Therefore, the packet is still actually
360 dropped, which means that the externally observable results would be
361 identical to our first example.
362
363
364 Implementing Table 1: VLAN Input Processing
365 -------------------------------------------
366
367 A packet that enters table 1 has already passed basic validation in
368 table 0.  The purpose of table 1 is validate the packet's VLAN, based
369 on the VLAN configuration of the switch port through which the packet
370 entered the switch.  We will also use it to attach a VLAN header to
371 packets that arrive on an access port, which allows later processing
372 stages to rely on the packet's VLAN always being part of the VLAN
373 header, reducing special cases.
374
375 Let's start by adding a low-priority flow that drops all packets,
376 before we add flows that pass through acceptable packets.  You can
377 think of this as a "default drop" rule:
378
379     ovs-ofctl add-flow br0 "table=1, priority=0, actions=drop"
380
381 Our trunk port p1, on OpenFlow port 1, is an easy case.  p1 accepts
382 any packet regardless of whether it has a VLAN header or what the VLAN
383 was, so we can add a flow that resubmits everything on input port 1 to
384 the next table:
385
386     ovs-ofctl add-flow br0 \
387         "table=1, priority=99, in_port=1, actions=resubmit(,2)"
388
389 On the access ports, we want to accept any packet that has no VLAN
390 header, tag it with the access port's VLAN number, and then pass it
391 along to the next stage:
392
393     ovs-ofctl add-flows br0 - <<'EOF'
394           table=1, priority=99, in_port=2, vlan_tci=0, actions=mod_vlan_vid:20, resubmit(,2)
395           table=1, priority=99, in_port=3, vlan_tci=0, actions=mod_vlan_vid:30, resubmit(,2)
396           table=1, priority=99, in_port=4, vlan_tci=0, actions=mod_vlan_vid:30, resubmit(,2)
397     EOF
398
399 We don't write any rules that match packets with 802.1Q that enter
400 this stage on any of the access ports, so the "default drop" rule we
401 added earlier causes them to be dropped, which is ordinarily what we
402 want for access ports.
403
404 > Another variation of access ports allows ingress of packets tagged
405 > with VLAN 0 (aka 802.1p priority tagged packets).  To allow such
406 > packets, replace "vlan_tci=0" by "vlan_tci=0/0xfff" above.
407
408
409 ### Testing Table 1
410
411 `ofproto/trace` allows us to test the ingress VLAN rules that we added
412 above.
413
414
415 ### EXAMPLE 1: Packet on Trunk Port
416
417 Here's a test of a packet coming in on the trunk port:
418
419     ovs-appctl ofproto/trace br0 in_port=1,vlan_tci=5
420
421 The output shows the lookup in table 0, the resubmit to table 1, and
422 the resubmit to table 2 (which does nothing because we haven't put
423 anything there yet):
424
425     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
426     Rule: table=0 cookie=0 priority=0
427     OpenFlow actions=resubmit(,1)
428
429             Resubmitted flow: unchanged
430             Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
431             Resubmitted  odp: drop
432             Rule: table=1 cookie=0 priority=99,in_port=1
433             OpenFlow actions=resubmit(,2)
434
435                     Resubmitted flow: unchanged
436                     Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
437                     Resubmitted  odp: drop
438                     No match
439
440     Final flow: unchanged
441     Datapath actions: drop
442
443
444 ### EXAMPLE 2: Valid Packet on Access Port
445
446 Here's a test of a valid packet (a packet without an 802.1Q header)
447 coming in on access port p2:
448
449     ovs-appctl ofproto/trace br0 in_port=2
450
451 The output is similar to that for the previous case, except that it
452 additionally tags the packet with p2's VLAN 20 before it passes it
453 along to table 2:
454
455     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
456     Rule: table=0 cookie=0 priority=0
457     OpenFlow actions=resubmit(,1)
458
459             Resubmitted flow: unchanged
460             Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
461             Resubmitted  odp: drop
462             Rule: table=1 cookie=0 priority=99,in_port=2,vlan_tci=0x0000
463             OpenFlow actions=mod_vlan_vid:20,resubmit(,2)
464
465                     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
466                     Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
467                     Resubmitted  odp: drop
468                     No match
469
470     Final flow: unchanged
471     Datapath actions: drop
472
473
474 ### EXAMPLE 3: Invalid Packet on Access Port
475
476 This tests an invalid packet (one that includes an 802.1Q header)
477 coming in on access port p2:
478
479     ovs-appctl ofproto/trace br0 in_port=2,vlan_tci=5
480
481 The output shows the packet matching the default drop rule:
482
483     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
484     Rule: table=0 cookie=0 priority=0
485     OpenFlow actions=resubmit(,1)
486
487             Resubmitted flow: unchanged
488             Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
489             Resubmitted  odp: drop
490             Rule: table=1 cookie=0 priority=0
491             OpenFlow actions=drop
492
493     Final flow: unchanged
494     Datapath actions: drop
495
496
497 Implementing Table 2: MAC+VLAN Learning for Ingress Port
498 --------------------------------------------------------
499
500 This table allows the switch we're implementing to learn that the
501 packet's source MAC is located on the packet's ingress port in the
502 packet's VLAN.
503
504 > This table is a good example why table 1 added a VLAN tag to
505 > packets that entered the switch through an access port.  We want
506 > to associate a MAC+VLAN with a port regardless of whether the VLAN
507 > in question was originally part of the packet or whether it was an
508 > assumed VLAN associated with an access port.
509
510 It only takes a single flow to do this.  The following command adds
511 it:
512
513     ovs-ofctl add-flow br0 \
514         "table=2 actions=learn(table=10, NXM_OF_VLAN_TCI[0..11], \
515                                NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[], \
516                                load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]), \
517                          resubmit(,3)"
518
519 The "learn" action (an Open vSwitch extension to OpenFlow) modifies a
520 flow table based on the content of the flow currently being processed.
521 Here's how you can interpret each part of the "learn" action above:
522
523     table=10
524
525         Modify flow table 10.  This will be the MAC learning table.
526
527     NXM_OF_VLAN_TCI[0..11]
528
529         Make the flow that we add to flow table 10 match the same VLAN
530         ID that the packet we're currently processing contains.  This
531         effectively scopes the MAC learning entry to a single VLAN,
532         which is the ordinary behavior for a VLAN-aware switch.
533
534     NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]
535
536         Make the flow that we add to flow table 10 match, as Ethernet
537         destination, the Ethernet source address of the packet we're
538         currently processing.
539
540     load:NXM_OF_IN_PORT[]->NXM_NX_REG0[0..15]
541
542         Whereas the preceding parts specify fields for the new flow to
543         match, this specifies an action for the flow to take when it
544         matches.  The action is for the flow to load the ingress port
545         number of the current packet into register 0 (a special field
546         that is an Open vSwitch extension to OpenFlow).
547
548 > A real use of "learn" for MAC learning would probably involve two
549 > additional elements.  First, the "learn" action would specify a
550 > hard_timeout for the new flow, to enable a learned MAC to
551 > eventually expire if no new packets were seen from a given source
552 > within a reasonable interval.  Second, one would usually want to
553 > limit resource consumption by using the Flow_Table table in the
554 > Open vSwitch configuration database to specify a maximum number of
555 > flows in table 10.
556
557 This definitely calls for examples.
558
559
560 ### Testing Table 2
561
562 ### EXAMPLE 1
563
564 Try the following test command:
565
566     ovs-appctl ofproto/trace br0 in_port=1,vlan_tci=20,dl_src=50:00:00:00:00:01 -generate
567
568 The output shows that "learn" was executed, but it isn't otherwise
569 informative, so we won't include it here.
570
571 The `-generate` keyword is new.  Ordinarily, `ofproto/trace` has no
572 side effects: "output" actions do not actually output packets, "learn"
573 actions do not actually modify the flow table, and so on.  With
574 `-generate`, though, `ofproto/trace` does execute "learn" actions.
575 That's important now, because we want to see the effect of the "learn"
576 action on table 10.  You can see that by running:
577
578     ovs-ofctl dump-flows br0 table=10
579
580 which (omitting the "duration" and "idle_age" fields, which will vary
581 based on how soon you ran this command after the previous one, as well
582 as some other uninteresting fields) prints something like:
583
584     NXST_FLOW reply (xid=0x4):
585      table=10, vlan_tci=0x0014/0x0fff,dl_dst=50:00:00:00:00:01 actions=load:0x1->NXM_NX_REG0[0..15]
586
587 You can see that the packet coming in on VLAN 20 with source MAC
588 50:00:00:00:00:01 became a flow that matches VLAN 20 (written in
589 hexadecimal) and destination MAC 50:00:00:00:00:01.  The flow loads
590 port number 1, the input port for the flow we tested, into register 0.
591
592
593 ### EXAMPLE 2
594
595 Here's a second test command:
596
597     ovs-appctl ofproto/trace br0 in_port=2,dl_src=50:00:00:00:00:01 -generate
598
599 The flow that this command tests has the same source MAC and VLAN as
600 example 1, although the VLAN comes from an access port VLAN rather
601 than an 802.1Q header.  If we again dump the flows for table 10 with:
602
603     ovs-ofctl dump-flows br0 table=10
604
605 then we see that the flow we saw previously has changed to indicate
606 that the learned port is port 2, as we would expect:
607
608     NXST_FLOW reply (xid=0x4):
609      table=10, vlan_tci=0x0014/0x0fff,dl_dst=50:00:00:00:00:01 actions=load:0x2->NXM_NX_REG0[0..15]
610
611
612 Implementing Table 3: Look Up Destination Port
613 ----------------------------------------------
614
615 This table figures out what port we should send the packet to based on
616 the destination MAC and VLAN.  That is, if we've learned the location
617 of the destination (from table 2 processing some previous packet with
618 that destination as its source), then we want to send the packet
619 there.
620
621 We need only one flow to do the lookup:
622
623     ovs-ofctl add-flow br0 \
624         "table=3 priority=50 actions=resubmit(,10), resubmit(,4)"
625
626 The flow's first action resubmits to table 10, the table that the
627 "learn" action modifies.  As you saw previously, the learned flows in
628 this table write the learned port into register 0.  If the destination
629 for our packet hasn't been learned, then there will be no matching
630 flow, and so the "resubmit" turns into a no-op.  Because registers are
631 initialized to 0, we can use a register 0 value of 0 in our next
632 pipeline stage as a signal to flood the packet.
633
634 The second action resubmits to table 4, continuing to the next
635 pipeline stage.
636
637 We can add another flow to skip the learning table lookup for
638 multicast and broadcast packets, since those should always be flooded:
639
640     ovs-ofctl add-flow br0 \
641         "table=3 priority=99 dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 \
642           actions=resubmit(,4)"
643
644 > We don't strictly need to add this flow, because multicast
645 > addresses will never show up in our learning table.  (In turn,
646 > that's because we put a flow into table 0 to drop packets that
647 > have a multicast source address.)
648
649
650 ### Testing Table 3
651
652 ### EXAMPLE
653
654 Here's a command that should cause OVS to learn that f0:00:00:00:00:01
655 is on p1 in VLAN 20:
656
657     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
658
659 Here's an excerpt from the output that shows (from the "no match"
660 looking up the resubmit to table 10) that the flow's destination was
661 unknown:
662
663                         Resubmitted flow: unchanged
664                         Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
665                         Resubmitted  odp: drop
666                         Rule: table=3 cookie=0 priority=50
667                         OpenFlow actions=resubmit(,10),resubmit(,4)
668
669                                 Resubmitted flow: unchanged
670                                 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
671                                 Resubmitted  odp: drop
672                                 No match
673
674 You can verify that the packet's source was learned two ways.  The
675 most direct way is to dump the learning table with:
676
677     ovs-ofctl dump-flows br0 table=10
678
679 which ought to show roughly the following, with extraneous details
680 removed:
681
682     table=10, vlan_tci=0x0014/0x0fff,dl_dst=f0:00:00:00:00:01 actions=load:0x1->NXM_NX_REG0[0..15]
683
684 > If you tried the examples for the previous step, or if you did
685 > some of your own experiments, then you might see additional flows
686 > there.  These additional flows are harmless.  If they bother you,
687 > then you can remove them with `ovs-ofctl del-flows br0 table=10`.
688
689 The other way is to inject a packet to take advantage of the learning
690 entry.  For example, we can inject a packet on p2 whose destination is
691 the MAC address that we just learned on p1:
692
693     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
694
695 Here's an interesting excerpt from that command's output.  This group
696 of lines traces the "resubmit(,10)", showing that the packet matched
697 the learned flow for the first MAC we used, loading the OpenFlow port
698 number for the learned port p1 into register 0:
699
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=f0:00:00:00:00:01
704                                 OpenFlow actions=load:0x1->NXM_NX_REG0[0..15]
705
706
707 If you read the commands above carefully, then you might have noticed
708 that they simply have the Ethernet source and destination addresses
709 exchanged.  That means that if we now rerun the first `ovs-appctl`
710 command above, e.g.:
711
712     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
713
714 then we see in the output that the destination has now been learned:
715
716                                 Resubmitted flow: unchanged
717                                 Resubmitted regs: reg0=0x0 reg1=0x0 reg2=0x0 reg3=0x0 reg4=0x0 reg5=0x0 reg6=0x0 reg7=0x0
718                                 Resubmitted  odp: drop
719                                 Rule: table=10 cookie=0 vlan_tci=0x0014/0x0fff,dl_dst=90:00:00:00:00:01
720                                 OpenFlow actions=load:0x2->NXM_NX_REG0[0..15]
721
722
723 Implementing Table 4: Output Processing
724 ---------------------------------------
725
726 At entry to stage 4, we know that register 0 contains either the
727 desired output port or is zero if the packet should be flooded.  We
728 also know that the packet's VLAN is in its 802.1Q header, even if the
729 VLAN was implicit because the packet came in on an access port.
730
731 The job of the final pipeline stage is to actually output packets.
732 The job is trivial for output to our trunk port p1:
733
734     ovs-ofctl add-flow br0 "table=4 reg0=1 actions=1"
735
736 For output to the access ports, we just have to strip the VLAN header
737 before outputting the packet:
738
739     ovs-ofctl add-flows br0 - <<'EOF'
740     table=4 reg0=2 actions=strip_vlan,2
741     table=4 reg0=3 actions=strip_vlan,3
742     table=4 reg0=4 actions=strip_vlan,4
743     EOF
744
745 The only slightly tricky part is flooding multicast and broadcast
746 packets and unicast packets with unlearned destinations.  For those,
747 we need to make sure that we only output the packets to the ports that
748 carry our packet's VLAN, and that we include the 802.1Q header in the
749 copy output to the trunk port but not in copies output to access
750 ports:
751
752     ovs-ofctl add-flows br0 - <<'EOF'
753     table=4 reg0=0 priority=99 dl_vlan=20 actions=1,strip_vlan,2
754     table=4 reg0=0 priority=99 dl_vlan=30 actions=1,strip_vlan,3,4
755     table=4 reg0=0 priority=50            actions=1
756     EOF
757
758 > Our rules rely on the standard OpenFlow behavior that an output
759 > action will not forward a packet back out the port it came in on.
760 > That is, if a packet comes in on p1, and we've learned that the
761 > packet's destination MAC is also on p1, so that we end up with
762 > "actions=1" as our actions, the switch will not forward the packet
763 > back out its input port.  The multicast/broadcast/unknown
764 > destination cases above also rely on this behavior.
765
766
767 ### Testing Table 4
768
769 ### EXAMPLE 1: Broadcast, Multicast, and Unknown Destination
770
771 Try tracing a broadcast packet arriving on p1 in VLAN 30:
772
773     ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=30
774
775 The interesting part of the output is the final line, which shows that
776 the switch would remove the 802.1Q header and then output the packet to
777 p3 and p4, which are access ports for VLAN 30:
778
779     Datapath actions: pop_vlan,3,4
780
781 Similarly, if we trace a broadcast packet arriving on p3:
782
783     ovs-appctl ofproto/trace br0 in_port=3,dl_dst=ff:ff:ff:ff:ff:ff
784
785 then we see that it is output to p1 with an 802.1Q tag and then to p4
786 without one:
787
788     Datapath actions: push_vlan(vid=30,pcp=0),1,pop_vlan,4
789
790 > Open vSwitch could simplify the datapath actions here to just
791 > "4,push_vlan(vid=30,pcp=0),1" but it is not smart enough to do so.
792
793 The following are also broadcasts, but the result is to drop the
794 packets because the VLAN only belongs to the input port:
795
796     ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff
797     ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=55
798
799 Try some other broadcast cases on your own:
800
801     ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff,dl_vlan=20
802     ovs-appctl ofproto/trace br0 in_port=2,dl_dst=ff:ff:ff:ff:ff:ff
803     ovs-appctl ofproto/trace br0 in_port=4,dl_dst=ff:ff:ff:ff:ff:ff
804
805 You can see the same behavior with multicast packets and with unicast
806 packets whose destination has not been learned, e.g.:
807
808     ovs-appctl ofproto/trace br0 in_port=4,dl_dst=01:00:00:00:00:00
809     ovs-appctl ofproto/trace br0 in_port=1,dl_dst=90:12:34:56:78:90,dl_vlan=20
810     ovs-appctl ofproto/trace br0 in_port=1,dl_dst=90:12:34:56:78:90,dl_vlan=30
811
812
813 ### EXAMPLE 2: MAC Learning
814
815 Let's follow the same pattern as we did for table 3.  First learn a
816 MAC on port p1 in VLAN 30:
817
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
819
820 You can see from the last line of output that the packet's destination
821 is unknown, so it gets flooded to both p3 and p4, the other ports in
822 VLAN 30:
823
824     Datapath actions: pop_vlan,3,4
825
826 Then reverse the MACs and learn the first flow's destination on port
827 p4:
828
829     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
830
831 The last line of output shows that the this packet's destination is
832 known to be p1, as learned from our previous command:
833
834     Datapath actions: push_vlan(vid=30,pcp=0),1
835
836 Now, if we rerun our first command:
837
838     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
839
840 we can see that the result is no longer a flood but to the specified
841 learned destination port p4:
842
843     Datapath actions: pop_vlan,4
844
845
846 Contact 
847 =======
848
849 bugs@openvswitch.org
850 http://openvswitch.org/
851
852 [INSTALL.md]:../INSTALL.md