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