-
Notifications
You must be signed in to change notification settings - Fork 236
/
ovn-northd.8.xml
3249 lines (2835 loc) · 118 KB
/
ovn-northd.8.xml
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
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?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>Options</h1>
<dl>
<dt><code>--ovnnb-db=<var>database</var></code></dt>
<dd>
The OVSDB database containing the OVN Northbound Database. If the
<env>OVN_NB_DB</env> environment variable is set, its value is used
as the default. Otherwise, the default is
<code>unix:@RUNDIR@/ovnnb_db.sock</code>.
</dd>
<dt><code>--ovnsb-db=<var>database</var></code></dt>
<dd>
The OVSDB database containing the OVN Southbound Database. If the
<env>OVN_SB_DB</env> environment variable is set, its value is used
as the default. Otherwise, the default is
<code>unix:@RUNDIR@/ovnsb_db.sock</code>.
</dd>
</dl>
<p>
<var>database</var> in the above options must be an OVSDB active or
passive connection method, as described in <code>ovsdb</code>(7).
</p>
<h2>Daemon Options</h2>
<xi:include href="lib/daemon.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
<h2>Logging Options</h2>
<xi:include href="lib/vlog.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
<h2>PKI Options</h2>
<p>
PKI configuration is required in order to use SSL for the connections to
the Northbound and Southbound databases.
</p>
<xi:include href="lib/ssl.xml" xmlns:xi="http://www.w3.org/2003/XInclude"/>
<h2>Other Options</h2>
<xi:include href="lib/unixctl.xml"
xmlns:xi="http://www.w3.org/2003/XInclude"/>
<h3></h3>
<xi:include href="lib/common.xml"
xmlns:xi="http://www.w3.org/2003/XInclude"/>
<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>
<dt><code>pause</code></dt>
<dd>
Pauses the ovn-northd operation from processing any Northbound and
Southbound database changes. This will also instruct ovn-northd to
drop any lock on SB DB.
</dd>
<dt><code>resume</code></dt>
<dd>
Resumes the ovn-northd operation to process Northbound and
Southbound database contents and generate logical flows. This will
also instruct ovn-northd to aspire for the lock on SB DB.
</dd>
<dt><code>is-paused</code></dt>
<dd>
Returns "true" if ovn-northd is currently paused, "false" otherwise.
</dd>
<dt><code>status</code></dt>
<dd>
Prints this server's status. Status will be "active" if ovn-northd has
acquired OVSDB lock on SB DB, "standby" if it has not or "paused" if
this instance is paused.
</dd>
</dl>
</p>
<h1>Active-Standby for High Availability</h1>
<p>
You may run <code>ovn-northd</code> more than once in an OVN deployment.
When connected to a standalone or clustered DB setup, OVN will
automatically ensure that only one of them is active at a time.
If multiple instances of <code>ovn-northd</code> are running and the
active <code>ovn-northd</code> fails, one of the hot standby instances
of <code>ovn-northd</code> will automatically take over.
</p>
<h2> Active-Standby with multiple OVN DB servers</h2>
<p>
You may run multiple OVN DB servers in an OVN deployment with:
<ul>
<li>
OVN DB servers deployed in active/passive mode with one active
and multiple passive ovsdb-servers.
</li>
<li>
<code>ovn-northd</code> also deployed on all these nodes,
using unix ctl sockets to connect to the local OVN DB servers.
</li>
</ul>
</p>
<p>
In such deployments, the ovn-northds on the passive nodes will process
the DB changes and compute logical flows to be thrown out later,
because write transactions are not allowed by the passive ovsdb-servers.
It results in unnecessary CPU usage.
</p>
<p>
With the help of runtime management command <code>pause</code>, you can
pause <code>ovn-northd</code> on these nodes. When a passive node
becomes master, you can use the runtime management command
<code>resume</code> to resume the <code>ovn-northd</code> to process the
DB changes.
</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
the next table.
</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
the next table.
</li>
</ul>
<h3>Ingress Table 3: <code>from-lport</code> Pre-ACLs</h3>
<p>
This table prepares flows for possible stateful ACL processing in
ingress table <code>ACLs</code>. It contains a priority-0 flow that
simply moves traffic to the next table. If stateful ACLs are used in the
logical datapath, a priority-100 flow is added that sets a hint
(with <code>reg0[0] = 1; next;</code>) for table
<code>Pre-stateful</code> to send IP packets to the connection tracker
before eventually advancing to ingress table <code>ACLs</code>. If
special ports such as route ports or localnet ports can't use ct(), a
priority-110 flow is added to skip over stateful ACLs.
</p>
<p>
This table also has a priority-110 flow with the match
<code>eth.dst == <var>E</var></code> for all logical switch
datapaths to move traffic to the next table. Where <var>E</var>
is the service monitor mac defined in the
<ref column="options:svc_monitor_mac" table="NB_Global"
db="OVN_Northbound"/> colum of <ref table="NB_Global"
db="OVN_Northbound"/> table.
</p>
<h3>Ingress Table 4: Pre-LB</h3>
<p>
This table prepares flows for possible stateful load balancing processing
in ingress table <code>LB</code> and <code>Stateful</code>. It contains
a priority-0 flow that simply moves traffic to the next table. Moreover
it contains a priority-110 flow to move IPv6 Neighbor Discovery traffic
to the next table. If load balancing rules with virtual IP addresses
(and ports) are configured in <code>OVN_Northbound</code> database for a
logical switch datapath, a priority-100 flow is added for each configured
virtual IP address <var>VIP</var>. For IPv4 <var>VIPs</var>, the match is
<code>ip && ip4.dst == <var>VIP</var></code>. For IPv6
<var>VIPs</var>, the match is <code>ip &&
ip6.dst == <var>VIP</var></code>. The flow sets an action
<code>reg0[0] = 1; next;</code> to act as a hint for table
<code>Pre-stateful</code> to send IP packets to the connection tracker
for packet de-fragmentation before eventually advancing to ingress table
<code>LB</code>.
If controller_event has been enabled and load balancing rules with
empty backends have been added in <code>OVN_Northbound</code>, a 130 flow
is added to trigger ovn-controller events whenever the chassis receives a
packet for that particular VIP. If <code>event-elb</code> meter has been
previously created, it will be associated to the empty_lb logical flow
</p>
<p>
This table also has a priority-110 flow with the match
<code>eth.dst == <var>E</var></code> for all logical switch
datapaths to move traffic to the next table. Where <var>E</var>
is the service monitor mac defined in the
<ref column="options:svc_monitor_mac" table="NB_Global"
db="OVN_Northbound"/> colum of <ref table="NB_Global"
db="OVN_Northbound"/> table.
</p>
<h3>Ingress Table 5: Pre-stateful</h3>
<p>
This table prepares flows for all possible stateful processing
in next tables. It contains a priority-0 flow that simply moves
traffic to the next table. A priority-100 flow sends the packets to
connection tracker based on a hint provided by the previous tables
(with a match for <code>reg0[0] == 1</code>) by using the
<code>ct_next;</code> action.
</p>
<h3>Ingress table 6: <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. 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>
<ul>
<li>
<code>allow</code> ACLs translate into logical flows with
the <code>next;</code> action. If there are any stateful ACLs
on this datapath, then <code>allow</code> ACLs translate to
<code>ct_commit; next;</code> (which acts as a hint for the next tables
to commit the connection to conntrack),
</li>
<li>
<code>allow-related</code> ACLs translate into logical
flows with the <code>ct_commit(ct_label=0/1); next;</code> actions
for new connections and <code>reg0[1] = 1; next;</code> for existing
connections.
</li>
<li>
<code>reject</code> ACLs translate into logical
flows with the
<code>tcp_reset { output <-> inport;
next(pipeline=egress,table=5);}</code>
action for TCP connections and <code>icmp4/icmp6</code> action
for UDP connections.
</li>
<li>
Other ACLs translate to <code>drop;</code> for new or untracked
connections and <code>ct_commit(ct_label=1/1);</code> for known
connections. Setting <code>ct_label</code> marks a connection
as one that was previously allowed, but should no longer be
allowed due to a policy change.
</li>
</ul>
<p>
This table 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 that sets the hint to commit IP traffic to the
connection tracker (with action <code>reg0[1] = 1; next;</code>). This
is needed for the default allow policy because, while the initiator'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 in the reply
direction for a connection that has been committed to the
connection tracker (i.e., established flows), as long as
the committed flow does not have <code>ct_label.blocked</code> set.
We only handle traffic in the reply direction here because
we want all packets going in the request direction to still
go through the flows that implement the currently defined
policy based on ACLs. If a connection is no longer allowed by
policy, <code>ct_label.blocked</code> will get set and packets in the
reply direction will no longer be allowed, either.
</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), as long
as the committed flow does not have <code>ct_label.blocked</code> set.
</li>
<li>
A priority-65535 flow that drops all traffic marked by the
connection tracker as invalid.
</li>
<li>
A priority-65535 flow that drops all traffic in the reply direction
with <code>ct_label.blocked</code> set meaning that the connection
should no longer be allowed due to a policy change. Packets
in the request direction are skipped here to let a newly created
ACL re-allow this connection.
</li>
<li>
A priority-65535 flow that allows IPv6 Neighbor solicitation,
Neighbor discover, Router solicitation and Router advertisement
packets.
</li>
<li>
A priority 34000 logical flow is added for each logical switch datapath
with the match <code>eth.dst = <var>E</var></code> to allow the service
monitor reply packet destined to <code>ovn-controller</code>
with the action <code>next</code>, where <var>E</var> is the
service monitor mac defined in the
<ref column="options:svc_monitor_mac" table="NB_Global"
db="OVN_Northbound"/> colum of <ref table="NB_Global"
db="OVN_Northbound"/> table.
</li>
</ul>
<h3>Ingress Table 7: <code>from-lport</code> QoS Marking</h3>
<p>
Logical flows in this table closely reproduce those in the
<code>QoS</code> table with the <code>action</code> column set in
the <code>OVN_Northbound</code> database for the
<code>from-lport</code> direction.
</p>
<ul>
<li>
For every qos_rules entry in a logical switch with DSCP marking
enabled, a flow will be added at the priority mentioned in the
QoS table.
</li>
<li>
One priority-0 fallback flow that matches all packets and advances to
the next table.
</li>
</ul>
<h3>Ingress Table 8: <code>from-lport</code> QoS Meter</h3>
<p>
Logical flows in this table closely reproduce those in the
<code>QoS</code> table with the <code>bandwidth</code> column set
in the <code>OVN_Northbound</code> database for the
<code>from-lport</code> direction.
</p>
<ul>
<li>
For every qos_rules entry in a logical switch with metering
enabled, a flow will be added at the priorirty mentioned in the
QoS table.
</li>
<li>
One priority-0 fallback flow that matches all packets and advances to
the next table.
</li>
</ul>
<h3>Ingress Table 9: LB</h3>
<p>
It contains a priority-0 flow that simply moves traffic to the next
table. For established connections a priority 100 flow matches on
<code>ct.est && !ct.rel && !ct.new &&
!ct.inv</code> and sets an action <code>reg0[2] = 1; next;</code> to act
as a hint for table <code>Stateful</code> to send packets through
connection tracker to NAT the packets. (The packet will automatically
get DNATed to the same IP address as the first packet in that
connection.)
</p>
<h3>Ingress Table 10: Stateful</h3>
<ul>
<li>
For all the configured load balancing rules for a switch in
<code>OVN_Northbound</code> database that includes a L4 port
<var>PORT</var> of protocol <var>P</var> and IP address
<var>VIP</var>, a priority-120 flow is added. For IPv4 <var>VIPs
</var>, the flow matches <code>ct.new && ip &&
ip4.dst == <var>VIP</var> && <var>P</var> &&
<var>P</var>.dst == <var>PORT</var></code>. For IPv6 <var>VIPs</var>,
the flow matches <code>ct.new && ip && ip6.dst == <var>
VIP </var>&& <var>P</var> && <var>P</var>.dst == <var>
PORT</var></code>. The flow's action is <code>ct_lb(<var>args</var>)
</code>, where <var>args</var> contains comma separated IP addresses
(and optional port numbers) to load balance to. The address family of
the IP addresses of <var>args</var> is the same as the address family
of <var>VIP</var>. If health check is enabled, then <var>args</var>
will only contain those endpoints whose service monitor status entry
in <code>OVN_Southbound</code> db is either <code>online</code> or
empty.
</li>
<li>
For all the configured load balancing rules for a switch in
<code>OVN_Northbound</code> database that includes just an IP address
<var>VIP</var> to match on, OVN adds a priority-110 flow. For IPv4
<var>VIPs</var>, the flow matches <code>ct.new && ip &&
ip4.dst == <var>VIP</var></code>. For IPv6 <var>VIPs</var>,
the flow matches <code>ct.new && ip && ip6.dst == <var>
VIP</var></code>. The action on this flow is <code>
ct_lb(<var>args</var>)</code>, where <var>args</var> contains comma
separated IP addresses of the same address family as <var>VIP</var>.
</li>
<li>
A priority-100 flow commits packets to connection tracker using
<code>ct_commit; next;</code> action based on a hint provided by
the previous tables (with a match for <code>reg0[1] == 1</code>).
</li>
<li>
A priority-100 flow sends the packets to connection tracker using
<code>ct_lb;</code> as the action based on a hint provided by the
previous tables (with a match for <code>reg0[2] == 1</code>).
</li>
<li>
A priority-0 flow that simply moves traffic to the next table.
</li>
</ul>
<h3>Ingress Table 11: Pre-Hairpin</h3>
<ul>
<li>
For all configured load balancer VIPs a priority-2 flow that
matches on traffic that needs to be hairpinned, i.e., after load
balancing the destination IP matches the source IP, which sets
<code>reg0[6] = 1 </code> and executes <code>ct_snat(VIP)</code>
to force replies to these packets to come back through OVN.
</li>
<li>
For all configured load balancer VIPs a priority-1 flow that
matches on replies to hairpinned traffic, i.e., destination IP is VIP,
source IP is the backend IP and source L4 port is backend port, which
sets <code>reg0[6] = 1 </code> and executes <code>ct_snat;</code>.
</li>
<li>
A priority-0 flow that simply moves traffic to the next table.
</li>
</ul>
<h3>Ingress Table 12: Hairpin</h3>
<ul>
<li>
A priority-1 flow that hairpins traffic matched by non-default
flows in the Pre-Hairpin table. Hairpinning is done at L2, Ethernet
addresses are swapped and the packets are looped back on the input
port.
</li>
<li>
A priority-0 flow that simply moves traffic to the next table.
</li>
</ul>
<h3>Ingress Table 13: ARP/ND responder</h3>
<p>
This table implements ARP/ND responder in a logical switch for known
IPs. The advantage of the ARP responder flow is to limit ARP
broadcasts by locally responding to ARP requests without the need to
send to other hypervisors. One common case is when the inport is a
logical port associated with a VIF and the broadcast is responded to
on the local hypervisor rather than broadcast across the whole
network and responded to by the destination VM. This behavior is
proxy ARP.
</p>
<p>
ARP requests arrive from VMs from a logical switch inport of type
default. For this case, the logical switch proxy ARP rules can be
for other VMs or logical router ports. Logical switch proxy ARP
rules may be programmed both for mac binding of IP addresses on
other logical switch VIF ports (which are of the default logical
switch port type, representing connectivity to VMs or containers),
and for mac binding of IP addresses on logical switch router type
ports, representing their logical router port peers. In order to
support proxy ARP for logical router ports, an IP address must be
configured on the logical switch router type port, with the same
value as the peer logical router port. The configured MAC addresses
must match as well. When a VM sends an ARP request for a distributed
logical router port and if the peer router type port of the attached
logical switch does not have an IP address configured, the ARP request
will be broadcast on the logical switch. One of the copies of the ARP
request will go through the logical switch router type port to the
logical router datapath, where the logical router ARP responder will
generate a reply. The MAC binding of a distributed logical router,
once learned by an associated VM, is used for all that VM's
communication needing routing. Hence, the action of a VM re-arping for
the mac binding of the logical router port should be rare.
</p>
<p>
Logical switch ARP responder proxy ARP rules can also be hit when
receiving ARP requests externally on a L2 gateway port. In this case,
the hypervisor acting as an L2 gateway, responds to the ARP request on
behalf of a destination VM.
</p>
<p>
Note that ARP requests received from <code>localnet</code> or
<code>vtep</code> logical inports can either go directly to VMs, in
which case the VM responds or can hit an ARP responder for a logical
router port if the packet is used to resolve a logical router port
next hop address. In either case, logical switch ARP responder rules
will not be hit. It contains these logical flows:
</p>
<ul>
<li>
Priority-100 flows to skip the ARP responder if inport is of type
<code>localnet</code> or <code>vtep</code> and advances directly
to the next table. ARP requests sent to <code>localnet</code> or
<code>vtep</code> ports can be received by multiple hypervisors.
Now, because the same mac binding rules are downloaded to all
hypervisors, each of the multiple hypervisors will respond. This
will confuse L2 learning on the source of the ARP requests. ARP
requests received on an inport of type <code>router</code> are not
expected to hit any logical switch ARP responder flows. However,
no skip flows are installed for these packets, as there would be
some additional flow cost for this and the value appears limited.
</li>
<li>
<p>
If inport <code>V</code> is of type <code>virtual</code> adds a
priority-100 logical flow for each <var>P</var> configured in the
<ref table="Logical_Switch_Port" column="options:virtual-parents"/>
column with the match
</p>
<pre>
<code>inport == <var>P</var> && && ((arp.op == 1 && arp.spa == <var>VIP</var> && arp.tpa == <var>VIP</var>) || (arp.op == 2 && arp.spa == <var>VIP</var>))</code>
</pre>
<p>
and applies the action
</p>
<pre>
<code>bind_vport(<var>V</var>, inport);</code>
</pre>
<p>
and advances the packet to the next table.
</p>
<p>
Where <var>VIP</var> is the virtual ip configured in the column
<ref table="Logical_Switch_Port" column="options:virtual-ip"/>.
</p>
</li>
<li>
<p>
Priority-50 flows that match ARP requests to each known IP address
<var>A</var> of every logical switch port, 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 = inport;
flags.loopback = 1;
output;
</pre>
<p>
These flows are omitted for logical ports (other than router ports or
<code>localport</code> ports) that are down, for logical ports of
type <code>virtual</code> and for logical ports with 'unknown'
address set.
</p>
</li>
<li>
<p>
Priority-50 flows that match IPv6 ND neighbor solicitations to
each known IP address <var>A</var> (and <var>A</var>'s
solicited node address) of every logical switch port except of type
router, and respond with neighbor advertisements directly with
corresponding Ethernet address <var>E</var>:
</p>
<pre>
nd_na {
eth.src = <var>E</var>;
ip6.src = <var>A</var>;
nd.target = <var>A</var>;
nd.tll = <var>E</var>;
outport = inport;
flags.loopback = 1;
output;
};
</pre>
<p>
Priority-50 flows that match IPv6 ND neighbor solicitations to
each known IP address <var>A</var> (and <var>A</var>'s
solicited node address) of logical switch port of type router, and
respond with neighbor advertisements directly with
corresponding Ethernet address <var>E</var>:
</p>
<pre>
nd_na_router {
eth.src = <var>E</var>;
ip6.src = <var>A</var>;
nd.target = <var>A</var>;
nd.tll = <var>E</var>;
outport = inport;
flags.loopback = 1;
output;
};
</pre>
<p>
These flows are omitted for logical ports (other than router ports or
<code>localport</code> ports) that are down and for logical ports of
type <code>virtual</code>.
</p>
</li>
<li>
<p>
Priority-100 flows with match criteria like the ARP and ND flows
above, except that they only match packets from the
<code>inport</code> that owns the IP addresses in question, with
action <code>next;</code>. These flows prevent OVN from replying to,
for example, an ARP request emitted by a VM for its own IP address.
A VM only makes this kind of request to attempt to detect a duplicate
IP address assignment, so sending a reply will prevent the VM from
accepting the IP address that it owns.
</p>
<p>
In place of <code>next;</code>, it would be reasonable to use
<code>drop;</code> for the flows' actions. If everything is working
as it is configured, then this would produce equivalent results,
since no host should reply to the request. But ARPing for one's own
IP address is intended to detect situations where the network is not
working as configured, so dropping the request would frustrate that
intent.
</p>
</li>
<li>
<p>
For each <var>SVC_MON_SRC_IP</var> defined in the value of
the <ref column="ip_port_mappings:ENDPOINT_IP"
table="Load_Balancer" db="OVN_Northbound"/> column of
<ref table="Load_Balancer" db="OVN_Northbound"/> table, priority-110
logical flow is added with the match
<code>arp.tpa == <var>SVC_MON_SRC_IP</var>
&& && arp.op == 1</code> and applies the action
</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 = inport;
flags.loopback = 1;
output;
</pre>
<p>
where <var>E</var> is the service monitor source mac defined in
the <ref column="options:svc_monitor_mac" table="NB_Global"
db="OVN_Northbound"/> column in the <ref table="NB_Global"
db="OVN_Northbound"/> table. This mac is used as the source mac
in the service monitor packets for the load balancer endpoint IP
health checks.
</p>
<p>
<var>SVC_MON_SRC_IP</var> is used as the source ip in the
service monitor IPv4 packets for the load balancer endpoint IP
health checks.
</p>
<p>
These flows are required if an ARP request is sent for the IP
<var>SVC_MON_SRC_IP</var>.
</p>
</li>
<li>
<p>
For each <var>VIP</var> configured in the table
<ref table="Forwarding_Group" db="OVN_Northbound"/>
a priority-50 logical flow is added with the match
<code>arp.tpa == <var>vip</var> && && arp.op == 1
</code> and applies the action
</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 = inport;
flags.loopback = 1;
output;
</pre>
<p>
where <var>E</var> is the forwarding group's mac defined in
the <ref column="vmac" table="Forwarding_Group"
db="OVN_Northbound"/>.
</p>
<p>
<var>A</var> is used as either the destination ip for load balancing
traffic to child ports or as nexthop to hosts behind the child ports.
</p>
<p>
These flows are required to respond to an ARP request if an ARP
request is sent for the IP <var>vip</var>.
</p>
</li>
<li>
One priority-0 fallback flow that matches all packets and advances to
the next table.
</li>
</ul>
<h3>Ingress Table 14: DHCP option processing</h3>
<p>
This table adds the DHCPv4 options to a DHCPv4 packet from the
logical ports configured with IPv4 address(es) and DHCPv4 options,
and similarly for DHCPv6 options. This table also adds flows for the
logical ports of type <code>external</code>.
</p>
<ul>
<li>
<p>
A priority-100 logical flow is added for these logical ports
which matches the IPv4 packet with <code>udp.src</code> = 68 and
<code>udp.dst</code> = 67 and applies the action
<code>put_dhcp_opts</code> and advances the packet to the next table.
</p>
<pre>
reg0[3] = put_dhcp_opts(offer_ip = <var>ip</var>, <var>options</var>...);
next;
</pre>
<p>
For DHCPDISCOVER and DHCPREQUEST, this transforms the packet into a
DHCP reply, adds the DHCP offer IP <var>ip</var> and options to the
packet, and stores 1 into reg0[3]. For other kinds of packets, it
just stores 0 into reg0[3]. Either way, it continues to the next
table.
</p>
</li>
<li>
<p>
A priority-100 logical flow is added for these logical ports
which matches the IPv6 packet with <code>udp.src</code> = 546 and
<code>udp.dst</code> = 547 and applies the action
<code>put_dhcpv6_opts</code> and advances the packet to the next
table.
</p>
<pre>
reg0[3] = put_dhcpv6_opts(ia_addr = <var>ip</var>, <var>options</var>...);
next;
</pre>
<p>
For DHCPv6 Solicit/Request/Confirm packets, this transforms the
packet into a DHCPv6 Advertise/Reply, adds the DHCPv6 offer IP
<var>ip</var> and options to the packet, and stores 1 into reg0[3].
For other kinds of packets, it just stores 0 into reg0[3]. Either
way, it continues to the next table.
</p>
</li>
<li>
A priority-0 flow that matches all packets to advances to table 15.
</li>
</ul>
<h3>Ingress Table 15: DHCP responses</h3>
<p>
This table implements DHCP responder for the DHCP replies generated by
the previous table.
</p>
<ul>
<li>
<p>
A priority 100 logical flow is added for the logical ports configured
with DHCPv4 options which matches IPv4 packets with <code>udp.src == 68
&& udp.dst == 67 && reg0[3] == 1</code> and
responds back to the <code>inport</code> after applying these
actions. If <code>reg0[3]</code> is set to 1, it means that the
action <code>put_dhcp_opts</code> was successful.
</p>
<pre>
eth.dst = eth.src;
eth.src = <var>E</var>;
ip4.src = <var>S</var>;
udp.src = 67;
udp.dst = 68;
outport = <var>P</var>;
flags.loopback = 1;
output;
</pre>
<p>
where <var>E</var> is the server MAC address and <var>S</var> is the
server IPv4 address defined in the DHCPv4 options. Note that
<code>ip4.dst</code> field is handled by <code>put_dhcp_opts</code>.
</p>
<p>
(This terminates ingress packet processing; the packet does not go
to the next ingress table.)
</p>
</li>
<li>
<p>
A priority 100 logical flow is added for the logical ports configured
with DHCPv6 options which matches IPv6 packets with <code>udp.src == 546
&& udp.dst == 547 && reg0[3] == 1</code> and
responds back to the <code>inport</code> after applying these
actions. If <code>reg0[3]</code> is set to 1, it means that the
action <code>put_dhcpv6_opts</code> was successful.
</p>
<pre>
eth.dst = eth.src;
eth.src = <var>E</var>;
ip6.dst = <var>A</var>;
ip6.src = <var>S</var>;
udp.src = 547;