1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
|
<?xml version="1.0" encoding="utf-8"?>
<manpage program="ovn-northd" section="8" title="ovn-northd">
<h1>Name</h1>
<p>ovn-northd -- Open Virtual Network central control daemon</p>
<h1>Synopsis</h1>
<p><code>ovn-northd</code> [<var>options</var>]</p>
<h1>Description</h1>
<p>
<code>ovn-northd</code> is a centralized daemon responsible for
translating the high-level OVN configuration into logical
configuration consumable by daemons such as
<code>ovn-controller</code>. It translates the logical network
configuration in terms of conventional network concepts, taken
from the OVN Northbound Database (see <code>ovn-nb</code>(5)),
into logical datapath flows in the OVN Southbound Database (see
<code>ovn-sb</code>(5)) below it.
</p>
<h1>Configuration</h1>
<p>
<code>ovn-northd</code> requires a connection to the Northbound
and Southbound databases. The defaults are <code>ovnnb_db.sock</code>
and <code>ovnsb_db.sock</code> respectively
in the local Open vSwitch's "run" directory. This may be
overridden with the following commands:
</p>
<ul>
<li>
<p>
<code>--ovnnb-db=<var>database</var></code>
</p>
<p>
The database containing the OVN Northbound Database.
</p>
</li>
<li>
<p>
<code>--ovnsb-db=<var>database</var></code>
</p>
<p>
The database containing the OVN Southbound Database.
</p>
</li>
</ul>
<p>
The <var>database</var> argument must take one of the following forms:
</p>
<ul>
<li>
<p>
<code>ssl:<var>ip</var>:<var>port</var></code>
</p>
<p>
The specified SSL <var>port</var> on the host at the given
<var>ip</var>, which must be expressed as an IP address (not a DNS
name) in IPv4 or IPv6 address format. If <var>ip</var> is an IPv6
address, then wrap <var>ip</var> with square brackets, e.g.:
<code>ssl:[::1]:6640</code>. The <code>--private-key</code>,
<code>--certificate</code>, and <code>--ca-cert</code> options are
mandatory when this form is used.
</p>
</li>
<li>
<p>
<code>tcp:<var>ip</var>:<var>port</var></code>
</p>
<p>
Connect to the given TCP <var>port</var> on <var>ip</var>, where
<var>ip</var> can be IPv4 or IPv6 address. If <var>ip</var> is an
IPv6 address, then wrap <var>ip</var> with square brackets, e.g.:
<code>tcp:[::1]:6640</code>.
</p>
</li>
<li>
<p>
<code>unix:<var>file</var></code>
</p>
<p>
On POSIX, connect to the Unix domain server socket named
<var>file</var>.
</p>
<p>
On Windows, connect to a localhost TCP port whose value is written
in <var>file</var>.
</p>
</li>
</ul>
<h1>Runtime Management Commands</h1>
<p>
<code>ovs-appctl</code> can send commands to a running
<code>ovn-northd</code> process. The currently supported commands
are described below.
<dl>
<dt><code>exit</code></dt>
<dd>
Causes <code>ovn-northd</code> to gracefully terminate.
</dd>
</dl>
</p>
<h1>Logical Flow Table Structure</h1>
<p>
One of the main purposes of <code>ovn-northd</code> is to populate the
<code>Logical_Flow</code> table in the <code>OVN_Southbound</code>
database. This section describes how <code>ovn-northd</code> does this
for switch and router logical datapaths.
</p>
<h2>Logical Switch Datapaths</h2>
<h3>Ingress Table 0: Admission Control and Ingress Port Security - L2</h3>
<p>
Ingress table 0 contains these logical flows:
</p>
<ul>
<li>
Priority 100 flows to drop packets with VLAN tags or multicast Ethernet
source addresses.
</li>
<li>
Priority 50 flows that implement ingress port security for each enabled
logical port. For logical ports on which port security is enabled,
these match the <code>inport</code> and the valid <code>eth.src</code>
address(es) and advance only those packets to the next flow table. For
logical ports on which port security is not enabled, these advance all
packets that match the <code>inport</code>.
</li>
</ul>
<p>
There are no flows for disabled logical ports because the default-drop
behavior of logical flow tables causes packets that ingress from them to
be dropped.
</p>
<h3>Ingress Table 1: Ingress Port Security - IP</h3>
<p>
Ingress table 1 contains these logical flows:
</p>
<ul>
<li>
<p>
For each element in the port security set having one or more IPv4 or
IPv6 addresses (or both),
</p>
<ul>
<li>
Priority 90 flow to allow IPv4 traffic if it has IPv4 addresses
which match the <code>inport</code>, valid <code>eth.src</code>
and valid <code>ip4.src</code> address(es).
</li>
<li>
Priority 90 flow to allow IPv4 DHCP discovery traffic if it has a
valid <code>eth.src</code>. This is necessary since DHCP discovery
messages are sent from the unspecified IPv4 address (0.0.0.0) since
the IPv4 address has not yet been assigned.
</li>
<li>
Priority 90 flow to allow IPv6 traffic if it has IPv6 addresses
which match the <code>inport</code>, valid <code>eth.src</code> and
valid <code>ip6.src</code> address(es).
</li>
<li>
Priority 90 flow to allow IPv6 DAD (Duplicate Address Detection)
traffic if it has a valid <code>eth.src</code>. This is is
necessary since DAD include requires joining an multicast group and
sending neighbor solicitations for the newly assigned address. Since
no address is yet assigned, these are sent from the unspecified
IPv6 address (::).
</li>
<li>
Priority 80 flow to drop IP (both IPv4 and IPv6) traffic which
match the <code>inport</code> and valid <code>eth.src</code>.
</li>
</ul>
</li>
<li>
One priority-0 fallback flow that matches all packets and advances to
table 2.
</li>
</ul>
<h3>Ingress Table 2: Ingress Port Security - Neighbor discovery</h3>
<p>
Ingress table 2 contains these logical flows:
</p>
<ul>
<li>
<p>
For each element in the port security set,
</p>
<ul>
<li>
Priority 90 flow to allow ARP traffic which match the
<code>inport</code> and valid <code>eth.src</code> and
<code>arp.sha</code>. If the element has one or more
IPv4 addresses, then it also matches the valid
<code>arp.spa</code>.
</li>
<li>
Priority 90 flow to allow IPv6 Neighbor Solicitation and
Advertisement traffic which match the <code>inport</code>,
valid <code>eth.src</code> and
<code>nd.sll</code>/<code>nd.tll</code>.
If the element has one or more IPv6 addresses, then it also
matches the valid <code>nd.target</code> address(es) for Neighbor
Advertisement traffic.
</li>
<li>
Priority 80 flow to drop ARP and IPv6 Neighbor Solicitation and
Advertisement traffic which match the <code>inport</code> and
valid <code>eth.src</code>.
</li>
</ul>
</li>
<li>
One priority-0 fallback flow that matches all packets and advances to
table 3.
</li>
</ul>
<h3>Ingress Table 3: <code>from-lport</code> Pre-ACLs</h3>
<p>
Ingress table 3 prepares flows for possible stateful ACL processing
in table 4. It contains a priority-0 flow that simply moves
traffic to table 4. If stateful ACLs are used in the logical
datapath, a priority-100 flow is added that sends IP packets to
the connection tracker before advancing to table 4.
</p>
<h3>Ingress table 4: <code>from-lport</code> ACLs</h3>
<p>
Logical flows in this table closely reproduce those in the
<code>ACL</code> table in the <code>OVN_Northbound</code> database
for the <code>from-lport</code> direction. <code>allow</code>
ACLs translate into logical flows with the <code>next;</code>
action, <code>allow-related</code> ACLs translate into logical
flows with the <code>ct_commit; next;</code> actions, other ACLs
translate to <code>drop;</code>. The <code>priority</code> values
from the <code>ACL</code> table have a limited range and have 1000
added to them to leave room for OVN default flows at both higher
and lower priorities.
</p>
<p>
Ingress table 4 also contains a priority 0 flow with action
<code>next;</code>, so that ACLs allow packets by default. If the
logical datapath has a statetful ACL, the following flows will
also be added:
</p>
<ul>
<li>
A priority-1 flow to commit IP traffic to the connection
tracker. This is needed for the default allow policy because,
while the initiater's direction may not have any stateful rules,
the server's may and then its return traffic would not be known
and marked as invalid.
</li>
<li>
A priority-65535 flow that allows any traffic that has been
committed to the connection tracker (i.e., established flows).
</li>
<li>
A priority-65535 flow that allows any traffic that is considered
related to a committed flow in the connection tracker (e.g., an
ICMP Port Unreachable from a non-listening UDP port).
</li>
<li>
A priority-65535 flow that drops all traffic marked by the
connection tracker as invalid.
</li>
</ul>
<h3>Ingress Table 5: ARP responder</h3>
<p>
This table implements ARP responder for known IPs. It contains these
logical flows:
</p>
<ul>
<li>
Priority-100 flows to skip ARP responder if inport is of type
<code>localnet</code>, and advances directly to table 6.
</li>
<li>
<p>
Priority-50 flows that matches ARP requests to each known IP address
<var>A</var> of logical port <var>P</var>, and respond with ARP
replies directly with corresponding Ethernet address <var>E</var>:
</p>
<pre>
eth.dst = eth.src;
eth.src = <var>E</var>;
arp.op = 2; /* ARP reply. */
arp.tha = arp.sha;
arp.sha = <var>E</var>;
arp.tpa = arp.spa;
arp.spa = <var>A</var>;
outport = <var>P</var>;
inport = ""; /* Allow sending out inport. */
output;
</pre>
<p>
These flows are omitted for logical ports (other than router ports)
that are down.
</p>
</li>
<li>
One priority-0 fallback flow that matches all packets and advances to
table 6.
</li>
</ul>
<h3>Ingress Table 6: Destination Lookup</h3>
<p>
This table implements switching behavior. It contains these logical
flows:
</p>
<ul>
<li>
A priority-100 flow that outputs all packets with an Ethernet broadcast
or multicast <code>eth.dst</code> to the <code>MC_FLOOD</code>
multicast group, which <code>ovn-northd</code> populates with all
enabled logical ports.
</li>
<li>
One priority-50 flow that matches each known Ethernet address against
<code>eth.dst</code> and outputs the packet to the single associated
output port.
</li>
<li>
One priority-0 fallback flow that matches all packets and outputs them
to the <code>MC_UNKNOWN</code> multicast group, which
<code>ovn-northd</code> populates with all enabled logical ports that
accept unknown destination packets. As a small optimization, if no
logical ports accept unknown destination packets,
<code>ovn-northd</code> omits this multicast group and logical flow.
</li>
</ul>
<h3>Egress Table 0: <code>to-lport</code> Pre-ACLs</h3>
<p>
This is similar to ingress table 3 except for <code>to-lport</code>
traffic.
</p>
<h3>Egress Table 1: <code>to-lport</code> ACLs</h3>
<p>
This is similar to ingress table 4 except for <code>to-lport</code> ACLs.
</p>
<h3>Egress Table 2: Egress Port Security - IP</h3>
<p>
This is similar to the ingress port security logic in table 1 except
that <code>outport</code>, <code>eth.dst</code>, <code>ip4.dst</code>
and <code>ip6.dst</code> are checked instead of <code>inport</code>,
<code>eth.src</code>, <code>ip4.src</code> and <code>ip6.src</code>
</p>
<h3>Egress Table 3: Egress Port Security - L2</h3>
<p>
This is similar to the ingress port security logic in ingress table 0,
but with important differences. Most obviously, <code>outport</code> and
<code>eth.dst</code> are checked instead of <code>inport</code> and
<code>eth.src</code>. Second, packets directed to broadcast or multicast
<code>eth.dst</code> are always accepted instead of being subject to the
port security rules; this is implemented through a priority-100 flow that
matches on <code>eth.mcast</code> with action <code>output;</code>.
Finally, to ensure that even broadcast and multicast packets are not
delivered to disabled logical ports, a priority-150 flow for each
disabled logical <code>outport</code> overrides the priority-100 flow
with a <code>drop;</code> action.
</p>
<h2>Logical Router Datapaths</h2>
<p>
Logical router datapaths will only exist for <ref table="Logical_Router"
db="OVN_Northbound"/> rows in the <ref db="OVN_Northbound"/> database
that do not have <ref column="enabled" table="Logical_Router"
db="OVN_Northbound"/> set to <code>false</code>
</p>
<h3>Ingress Table 0: L2 Admission Control</h3>
<p>
This table drops packets that the router shouldn't see at all based on
their Ethernet headers. It contains the following flows:
</p>
<ul>
<li>
Priority-100 flows to drop packets with VLAN tags or multicast Ethernet
source addresses.
</li>
<li>
For each enabled router port <var>P</var> with Ethernet address
<var>E</var>, a priority-50 flow that matches <code>inport ==
<var>P</var> && (eth.mcast || eth.dst ==
<var>E</var></code>), with action <code>next;</code>.
</li>
</ul>
<p>
Other packets are implicitly dropped.
</p>
<h3>Ingress Table 1: IP Input</h3>
<p>
This table is the core of the logical router datapath functionality. It
contains the following flows to implement very basic IP host
functionality.
</p>
<ul>
<li>
<p>
L3 admission control: A priority-100 flow drops packets that match
any of the following:
</p>
<ul>
<li>
<code>ip4.src[28..31] == 0xe</code> (multicast source)
</li>
<li>
<code>ip4.src == 255.255.255.255</code> (broadcast source)
</li>
<li>
<code>ip4.src == 127.0.0.0/8 || ip4.dst == 127.0.0.0/8</code>
(localhost source or destination)
</li>
<li>
<code>ip4.src == 0.0.0.0/8 || ip4.dst == 0.0.0.0/8</code> (zero
network source or destination)
</li>
<li>
<code>ip4.src</code> is any IP address owned by the router.
</li>
<li>
<code>ip4.src</code> is the broadcast address of any IP network
known to the router.
</li>
</ul>
</li>
<li>
<p>
ICMP echo reply. These flows reply to ICMP echo requests received
for the router's IP address. Let <var>A</var> be an IP address or
broadcast address owned by a router port. Then, for each
<var>A</var>, a priority-90 flow matches on <code>ip4.dst ==
<var>A</var></code> and <code>icmp4.type == 8 && icmp4.code
== 0</code> (ICMP echo request). These flows use the following
actions where, if <var>A</var> is unicast, then <var>S</var> is
<var>A</var>, and if <var>A</var> is broadcast, <var>S</var> is the
router's IP address in <var>A</var>'s network:
</p>
<pre>
ip4.dst = ip4.src;
ip4.src = <var>S</var>;
ip.ttl = 255;
icmp4.type = 0;
inport = ""; /* Allow sending out inport. */
next;
</pre>
<p>
Similar flows match on <code>ip4.dst == 255.255.255.255</code> and
each individual <code>inport</code>, and use the same actions in
which <var>S</var> is a function of <code>inport</code>.
</p>
</li>
<li>
<p>
Reply to ARP requests.
</p>
<p>
These flows reply to ARP requests for the router's own IP address.
For each router port <var>P</var> that owns IP address <var>A</var>
and Ethernet address <var>E</var>, a priority-90 flow matches
<code>inport == <var>P</var> && arp.op == 1 &&
arp.tpa == <var>A</var></code> (ARP request) with the following
actions:
</p>
<pre>
eth.dst = eth.src;
eth.src = <var>E</var>;
arp.op = 2; /* ARP reply. */
arp.tha = arp.sha;
arp.sha = <var>E</var>;
arp.tpa = arp.spa;
arp.spa = <var>A</var>;
outport = <var>P</var>;
inport = ""; /* Allow sending out inport. */
output;
</pre>
</li>
<li>
<p>
These flows reply to ARP requests for the virtual IP addresses
configured in the router for DNAT. For a configured DNAT IP address
<var>A</var>, for each router port <var>P</var> with Ethernet
address <var>E</var>, a priority-90 flow matches
<code>inport == <var>P</var> && arp.op == 1 &&
arp.tpa == <var>A</var></code> (ARP request)
with the following actions:
</p>
<pre>
eth.dst = eth.src;
eth.src = <var>E</var>;
arp.op = 2; /* ARP reply. */
arp.tha = arp.sha;
arp.sha = <var>E</var>;
arp.tpa = arp.spa;
arp.spa = <var>A</var>;
outport = <var>P</var>;
inport = ""; /* Allow sending out inport. */
output;
</pre>
</li>
<li>
ARP reply handling. These flows use ARP replies to populate the
logical router's ARP table. A priority-90 flow with match <code>arp.op
== 2</code> has actions <code>put_arp(inport, arp.spa,
arp.sha);</code>.
</li>
<li>
<p>
UDP port unreachable. Priority-80 flows generate ICMP port
unreachable messages in reply to UDP datagrams directed to the
router's IP address. The logical router doesn't accept any UDP
traffic so it always generates such a reply.
</p>
<p>
These flows should not match IP fragments with nonzero offset.
</p>
<p>
Details TBD. Not yet implemented.
</p>
</li>
<li>
<p>
TCP reset. Priority-80 flows generate TCP reset messages in reply to
TCP datagrams directed to the router's IP address. The logical
router doesn't accept any TCP traffic so it always generates such a
reply.
</p>
<p>
These flows should not match IP fragments with nonzero offset.
</p>
<p>
Details TBD. Not yet implemented.
</p>
</li>
<li>
<p>
Protocol unreachable. Priority-70 flows generate ICMP protocol
unreachable messages in reply to packets directed to the router's IP
address on IP protocols other than UDP, TCP, and ICMP.
</p>
<p>
These flows should not match IP fragments with nonzero offset.
</p>
<p>
Details TBD. Not yet implemented.
</p>
</li>
<li>
Drop other IP traffic to this router. These flows drop any other
traffic destined to an IP address of this router that is not already
handled by one of the flows above, which amounts to ICMP (other than
echo requests) and fragments with nonzero offsets. For each IP address
<var>A</var> owned by the router, a priority-60 flow matches
<code>ip4.dst == <var>A</var></code> and drops the traffic.
</li>
</ul>
<p>
The flows above handle all of the traffic that might be directed to the
router itself. The following flows (with lower priorities) handle the
remaining traffic, potentially for forwarding:
</p>
<ul>
<li>
Drop Ethernet local broadcast. A priority-50 flow with match
<code>eth.bcast</code> drops traffic destined to the local Ethernet
broadcast address. By definition this traffic should not be forwarded.
</li>
<li>
Drop IP multicast. A priority-50 flow with match
<code>ip4.mcast</code> drops IP multicast traffic.
</li>
<li>
<p>
ICMP time exceeded. For each router port <var>P</var>, whose IP
address is <var>A</var>, a priority-40 flow with match <code>inport
== <var>P</var> && ip.ttl == {0, 1} &&
!ip.later_frag</code> matches packets whose TTL has expired, with the
following actions to send an ICMP time exceeded reply:
</p>
<pre>
icmp4 {
icmp4.type = 11; /* Time exceeded. */
icmp4.code = 0; /* TTL exceeded in transit. */
ip4.dst = ip4.src;
ip4.src = <var>A</var>;
ip.ttl = 255;
next;
};
</pre>
<p>
Not yet implemented.
</p>
</li>
<li>
TTL discard. A priority-30 flow with match <code>ip.ttl == {0,
1}</code> and actions <code>drop;</code> drops other packets whose TTL
has expired, that should not receive a ICMP error reply (i.e. fragments
with nonzero offset).
</li>
<li>
Next table. A priority-0 flows match all packets that aren't already
handled and uses actions <code>next;</code> to feed them to the ingress
table for routing.
</li>
</ul>
<h3>Ingress Table 2: UNSNAT</h3>
<p>
This is for already established connections' reverse traffic.
i.e., SNAT has already been done in egress pipeline and now the
packet has entered the ingress pipeline as part of a reply. It is
unSNATted here.
</p>
<ul>
<li>
<p>
For each configuration in the OVN Northbound database, that asks
to change the source IP address of a packet from <var>A</var> to
<var>B</var>, a priority-100 flow matches <code>ip &&
ip4.dst == <var>B</var></code> with an action
<code>ct_snat; next;</code>.
</p>
<p>
A priority-0 logical flow with match <code>1</code> has actions
<code>next;</code>.
</p>
</li>
</ul>
<h3>Ingress Table 3: DNAT</h3>
<p>
Packets enter the pipeline with destination IP address that needs to
be DNATted from a virtual IP address to a real IP address. Packets
in the reverse direction needs to be unDNATed.
</p>
<ul>
<li>
<p>
For each configuration in the OVN Northbound database, that asks
to change the destination IP address of a packet from <var>A</var> to
<var>B</var>, a priority-100 flow matches <code>ip &&
ip4.dst == <var>A</var></code> with an action <code>inport = "";
ct_dnat(<var>B</var>);</code>.
</p>
<p>
For all IP packets of a Gateway router, a priority-50 flow with an
action <code>inport = ""; ct_dnat;</code>.
</p>
<p>
A priority-0 logical flow with match <code>1</code> has actions
<code>next;</code>.
</p>
</li>
</ul>
<h3>Ingress Table 4: IP Routing</h3>
<p>
A packet that arrives at this table is an IP packet that should be routed
to the address in <code>ip4.dst</code>. This table implements IP
routing, setting <code>reg0</code> to the next-hop IP address (leaving
<code>ip4.dst</code>, the packet's final destination, unchanged) and
advances to the next table for ARP resolution. It also sets
<code>reg1</code> to the IP address owned by the selected router port
(which is used later in table 6 as the IP source address for an ARP
request, if needed).
</p>
<p>
This table contains the following logical flows:
</p>
<ul>
<li>
<p>
Routing table. For each route to IPv4 network <var>N</var> with
netmask <var>M</var>, on router port <var>P</var> with IP address
<var>A</var> and Ethernet
address <var>E</var>, a logical flow with match <code>ip4.dst ==
<var>N</var>/<var>M</var></code>, whose priority is the number of
1-bits in <var>M</var>, has the following actions:
</p>
<pre>
ip.ttl--;
reg0 = <var>G</var>;
reg1 = <var>A</var>;
eth.src = <var>E</var>;
outport = <var>P</var>;
next;
</pre>
<p>
(Ingress table 1 already verified that <code>ip.ttl--;</code> will
not yield a TTL exceeded error.)
</p>
<p>
If the route has a gateway, <var>G</var> is the gateway IP address.
Instead, if the route is from a configured static route, <var>G</var>
is the next hop IP address. Else it is <code>ip4.dst</code>.
</p>
</li>
<li>
<p>
Destination unreachable. For each router port <var>P</var>, which
owns IP address <var>A</var>, a priority-0 logical flow with match
<code>in_port == <var>P</var> && !ip.later_frag &&
!icmp</code> has the following actions:
</p>
<pre>
icmp4 {
icmp4.type = 3; /* Destination unreachable. */
icmp4.code = 0; /* Network unreachable. */
ip4.dst = ip4.src;
ip4.src = <var>A</var>;
ip.ttl = 255;
next(2);
};
</pre>
<p>
(The <code>!icmp</code> check prevents recursion if the destination
unreachable message itself cannot be routed.)
</p>
<p>
These flows are omitted if the logical router has a default route,
that is, a route with netmask 0.0.0.0.
</p>
</li>
</ul>
<h3>Ingress Table 5: ARP Resolution</h3>
<p>
Any packet that reaches this table is an IP packet whose next-hop IP
address is in <code>reg0</code>. (<code>ip4.dst</code> is the final
destination.) This table resolves the IP address in <code>reg0</code>
into an output port in <code>outport</code> and an Ethernet address in
<code>eth.dst</code>, using the following flows:
</p>
<ul>
<li>
<p>
Static MAC bindings. MAC bindings can be known statically based on
data in the <code>OVN_Northbound</code> database. For router ports
connected to logical switches, MAC bindings can be known statically
from the <code>addresses</code> column in the
<code>Logical_Switch_Port</code> table. For router ports
connected to other logical routers, MAC bindings can be known
statically from the <code>mac</code> and <code>network</code>
column in the <code>Logical_Router_Port</code> table.
</p>
<p>
For each IP address <var>A</var> whose host is known to have Ethernet
address <var>E</var> on router port <var>P</var>, a priority-100 flow
with match <code>outport === <var>P</var> && reg0 ==
<var>A</var></code> has actions <code>eth.dst = <var>E</var>;
next;</code>.
</p>
<p>
For each logical router port with an IP address <var>A</var> and
a mac address of <var>E</var> that is reachable via a different
logical router port <var>P</var>, a priority-100 flow with
match <code>outport === <var>P</var> && reg0 ==
<var>A</var></code> has actions <code>eth.dst = <var>E</var>;
next;</code>.
</p>
</li>
<li>
<p>
Dynamic MAC bindings. This flows resolves MAC-to-IP bindings that
have become known dynamically through ARP. (The next table will
issue an ARP request for cases where the binding is not yet known.)
</p>
<p>
A priority-0 logical flow with match <code>1</code> has actions
<code>get_arp(outport, reg0); next;</code>.
</p>
</li>
</ul>
<h3>Ingress Table 6: ARP Request</h3>
<p>
In the common case where the Ethernet destination has been resolved, this
table outputs the packet. Otherwise, it composes and sends an ARP
request. It holds the following flows:
</p>
<ul>
<li>
<p>
Unknown MAC address. A priority-100 flow with match <code>eth.dst ==
00:00:00:00:00:00</code> has the following actions:
</p>
<pre>
arp {
eth.dst = ff:ff:ff:ff:ff:ff;
arp.spa = reg1;
arp.op = 1; /* ARP request. */
output;
};
</pre>
<p>
(Ingress table 4 initialized <code>reg1</code> with the IP address
owned by <code>outport</code>.)
</p>
<p>
The IP packet that triggers the ARP request is dropped.
</p>
</li>
<li>
Known MAC address. A priority-0 flow with match <code>1</code> has
actions <code>output;</code>.
</li>
</ul>
<h3>Egress Table 0: SNAT</h3>
<p>
Packets that are configured to be SNATed get their source IP address
changed based on the configuration in the OVN Northbound database.
</p>
<ul>
<li>
<p>
For each configuration in the OVN Northbound database, that asks
to change the source IP address of a packet from an IP address of
<var>A</var> or to change the source IP address of a packet that
belongs to network <var>A</var> to <var>B</var>, a flow matches
<code>ip && ip4.src == <var>A</var></code> with an action
<code>ct_snat(<var>B</var>);</code>. The priority of the flow
is calculated based on the mask of <var>A</var>, with matches
having larger masks getting higher priorities.
</p>
<p>
A priority-0 logical flow with match <code>1</code> has actions
<code>next;</code>.
</p>
</li>
</ul>
<h3>Egress Table 1: Delivery</h3>
<p>
Packets that reach this table are ready for delivery. It contains
priority-100 logical flows that match packets on each enabled logical
router port, with action <code>output;</code>.
</p>
</manpage>
|