Merge ~fnordahl/ubuntu/+source/ovn:ubuntu/jammy into ~ubuntu-server-dev/ubuntu/+source/ovn:ubuntu/jammy
- Git
- lp:~fnordahl/ubuntu/+source/ovn
- ubuntu/jammy
- Merge into ubuntu/jammy
Proposed by
Frode Nordahl
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | 39a1886e1c2a9c0288be5c1d97775249541717fe | ||||
Proposed branch: | ~fnordahl/ubuntu/+source/ovn:ubuntu/jammy | ||||
Merge into: | ~ubuntu-server-dev/ubuntu/+source/ovn:ubuntu/jammy | ||||
Diff against target: |
7204 lines (+2849/-892) 44 files modified
.ci/ovn-kubernetes/Dockerfile (+1/-1) AUTHORS.rst (+1/-0) NEWS (+7/-1) configure.ac (+1/-1) controller-vtep/binding.c (+3/-5) controller/binding.c (+97/-2) controller/binding.h (+1/-0) controller/chassis.c (+7/-0) controller/lflow.c (+61/-10) controller/lflow.h (+3/-0) controller/ofctrl.c (+27/-6) controller/ovn-controller.c (+190/-12) controller/physical.c (+24/-26) controller/pinctrl.c (+4/-3) debian/changelog (+8/-0) debian/control (+1/-1) debian/ovn-common.install (+1/-0) include/ovn/actions.h (+12/-1) include/ovn/features.h (+2/-1) include/ovn/logical-fields.h (+3/-2) lib/actions.c (+122/-12) lib/expr.c (+18/-13) lib/inc-proc-eng.c (+4/-7) lib/logical-fields.c (+16/-1) lib/ovn-parallel-hmap.h (+5/-5) lib/ovn-util.c (+24/-3) lib/ovn-util.h (+4/-0) northd/en-lflow.c (+1/-0) northd/northd.c (+467/-190) northd/northd.h (+6/-0) northd/ovn-northd.8.xml (+44/-24) northd/ovn-northd.c (+9/-1) ovn-nb.xml (+2/-2) ovn-sb.xml (+59/-11) rhel/ovn-fedora.spec.in (+1/-1) tests/ovn-controller.at (+129/-0) tests/ovn-nbctl.at (+2/-0) tests/ovn-northd.at (+510/-303) tests/ovn-performance.at (+17/-0) tests/ovn.at (+630/-136) tests/system-ovn.at (+220/-101) tests/test-ovn.c (+1/-0) utilities/ovn-nbctl.c (+9/-6) utilities/ovn-trace.c (+95/-4) |
||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Page | Pending | ||
Review via email: mp+426342@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/.ci/ovn-kubernetes/Dockerfile b/.ci/ovn-kubernetes/Dockerfile |
2 | index bd220b1..1966288 100644 |
3 | --- a/.ci/ovn-kubernetes/Dockerfile |
4 | +++ b/.ci/ovn-kubernetes/Dockerfile |
5 | @@ -60,7 +60,7 @@ FROM fedora:35 |
6 | |
7 | # install needed dependencies |
8 | RUN INSTALL_PKGS=" \ |
9 | - iptables iproute iputils hostname unbound-libs kubernetes-client kmod" && \ |
10 | + iptables iproute iputils hostname unbound-libs kubernetes-client kmod socat" && \ |
11 | dnf install --best --refresh -y --setopt=tsflags=nodocs $INSTALL_PKGS && \ |
12 | dnf clean all && rm -rf /var/cache/dnf/* |
13 | |
14 | diff --git a/AUTHORS.rst b/AUTHORS.rst |
15 | index 8572c24..d3747f8 100644 |
16 | --- a/AUTHORS.rst |
17 | +++ b/AUTHORS.rst |
18 | @@ -147,6 +147,7 @@ Fabrizio D'Angelo fdangelo@redhat.com |
19 | Flavio Fernandes flavio@flaviof.com |
20 | Flavio Leitner fbl@redhat.com |
21 | Francesco Fusco ffusco@redhat.com |
22 | +François Rigault frigo@amadeus.com |
23 | Frank Wang wangpeihuixyz@126.com |
24 | Frédéric Tobias Christ fchrist@live.de |
25 | Frode Nordahl frode.nordahl@gmail.com |
26 | diff --git a/NEWS b/NEWS |
27 | index 9f3ce3c..1664707 100644 |
28 | --- a/NEWS |
29 | +++ b/NEWS |
30 | @@ -1,4 +1,10 @@ |
31 | -OVN v22.03.0 - XX XXX XXXX |
32 | +OVN v22.03.1 - 03 Jun 2022 |
33 | +-------------------------- |
34 | + - Bug fixes |
35 | + - Replaced the usage of masked ct_label by ct_mark in most cases to work |
36 | + better with hardware-offloading. |
37 | + |
38 | +OVN v22.03.0 - 11 Mar 2022 |
39 | -------------------------- |
40 | - Refactor CoPP commands introducing a unique name index in CoPP NB table. |
41 | Add following new CoPP commands to manage CoPP table: |
42 | diff --git a/configure.ac b/configure.ac |
43 | index 283381b..70f86e1 100644 |
44 | --- a/configure.ac |
45 | +++ b/configure.ac |
46 | @@ -13,7 +13,7 @@ |
47 | # limitations under the License. |
48 | |
49 | AC_PREREQ(2.63) |
50 | -AC_INIT(ovn, 22.03.0, bugs@openvswitch.org) |
51 | +AC_INIT(ovn, 22.03.1, bugs@openvswitch.org) |
52 | AC_CONFIG_MACRO_DIR([m4]) |
53 | AC_CONFIG_AUX_DIR([build-aux]) |
54 | AC_CONFIG_HEADERS([config.h]) |
55 | diff --git a/controller-vtep/binding.c b/controller-vtep/binding.c |
56 | index 01d5a16..1ee52b5 100644 |
57 | --- a/controller-vtep/binding.c |
58 | +++ b/controller-vtep/binding.c |
59 | @@ -109,12 +109,10 @@ update_pb_chassis(const struct sbrec_port_binding *port_binding_rec, |
60 | port_binding_rec->chassis->name, |
61 | chassis_rec->name); |
62 | } |
63 | - |
64 | sbrec_port_binding_set_chassis(port_binding_rec, chassis_rec); |
65 | - if (port_binding_rec->n_up) { |
66 | - bool up = true; |
67 | - sbrec_port_binding_set_up(port_binding_rec, &up, 1); |
68 | - } |
69 | + } else if (port_binding_rec->n_up) { |
70 | + bool up = true; |
71 | + sbrec_port_binding_set_up(port_binding_rec, &up, 1); |
72 | } |
73 | } |
74 | |
75 | diff --git a/controller/binding.c b/controller/binding.c |
76 | index 4d62b08..9eaaddb 100644 |
77 | --- a/controller/binding.c |
78 | +++ b/controller/binding.c |
79 | @@ -482,6 +482,16 @@ remove_related_lport(const struct sbrec_port_binding *pb, |
80 | } |
81 | |
82 | static void |
83 | +delete_active_pb_ras_pd(const struct sbrec_port_binding *pb, |
84 | + struct shash *ras_pd_map) |
85 | +{ |
86 | + struct pb_ld_binding *ras_pd = |
87 | + shash_find_and_delete(ras_pd_map, pb->logical_port); |
88 | + |
89 | + free(ras_pd); |
90 | +} |
91 | + |
92 | +static void |
93 | update_active_pb_ras_pd(const struct sbrec_port_binding *pb, |
94 | struct hmap *local_datapaths, |
95 | struct shash *map, const char *conf) |
96 | @@ -898,7 +908,9 @@ claimed_lport_set_up(const struct sbrec_port_binding *pb, |
97 | if (!notify_up) { |
98 | bool up = true; |
99 | if (!parent_pb || (parent_pb->n_up && parent_pb->up[0])) { |
100 | - sbrec_port_binding_set_up(pb, &up, 1); |
101 | + if (pb->n_up) { |
102 | + sbrec_port_binding_set_up(pb, &up, 1); |
103 | + } |
104 | } |
105 | return; |
106 | } |
107 | @@ -950,7 +962,8 @@ claim_lport(const struct sbrec_port_binding *pb, |
108 | /* Check if the port encap binding, if any, has changed */ |
109 | struct sbrec_encap *encap_rec = |
110 | sbrec_get_port_encap(chassis_rec, iface_rec); |
111 | - if (encap_rec && pb->encap != encap_rec) { |
112 | + if ((encap_rec && pb->encap != encap_rec) || |
113 | + (!encap_rec && pb->encap)) { |
114 | if (sb_readonly) { |
115 | return false; |
116 | } |
117 | @@ -1897,6 +1910,71 @@ is_iface_in_int_bridge(const struct ovsrec_interface *iface, |
118 | return false; |
119 | } |
120 | |
121 | +static bool |
122 | +is_ext_id_changed(const struct smap *a, const struct smap *b, const char *key) |
123 | +{ |
124 | + const char *value_a = smap_get(a, key); |
125 | + const char *value_b = smap_get(b, key); |
126 | + if ((value_a && !value_b) |
127 | + || (!value_a && value_b) |
128 | + || (value_a && value_b && strcmp(value_a, value_b))) { |
129 | + return true; |
130 | + } |
131 | + return false; |
132 | +} |
133 | + |
134 | +/* Check if the change in 'iface_rec' is something we are interested in from |
135 | + * port binding perspective. Return true if the change needs to be handled, |
136 | + * otherwise return false. |
137 | + * |
138 | + * The 'iface_rec' must be change tracked, i.e. iterator from |
139 | + * OVSREC_INTERFACE_TABLE_FOR_EACH_TRACKED. */ |
140 | +static bool |
141 | +ovs_interface_change_need_handle(const struct ovsrec_interface *iface_rec, |
142 | + struct shash *iface_table_external_ids_old) |
143 | +{ |
144 | + if (ovsrec_interface_is_updated(iface_rec, |
145 | + OVSREC_INTERFACE_COL_NAME)) { |
146 | + return true; |
147 | + } |
148 | + if (ovsrec_interface_is_updated(iface_rec, |
149 | + OVSREC_INTERFACE_COL_OFPORT)) { |
150 | + return true; |
151 | + } |
152 | + if (ovsrec_interface_is_updated(iface_rec, |
153 | + OVSREC_INTERFACE_COL_TYPE)) { |
154 | + return true; |
155 | + } |
156 | + if (ovsrec_interface_is_updated(iface_rec, |
157 | + OVSREC_INTERFACE_COL_EXTERNAL_IDS)) { |
158 | + /* Compare the external_ids that we are interested in with the old |
159 | + * values: |
160 | + * - iface-id |
161 | + * - iface-id-ver |
162 | + * - encap-ip |
163 | + * For any other changes, such as ovn-installed, ovn-installed-ts, etc, |
164 | + * we don't need to handle. */ |
165 | + struct smap *external_ids_old = |
166 | + shash_find_data(iface_table_external_ids_old, iface_rec->name); |
167 | + if (!external_ids_old) { |
168 | + return true; |
169 | + } |
170 | + if (is_ext_id_changed(&iface_rec->external_ids, external_ids_old, |
171 | + "iface-id")) { |
172 | + return true; |
173 | + } |
174 | + if (is_ext_id_changed(&iface_rec->external_ids, external_ids_old, |
175 | + "iface-id-ver")) { |
176 | + return true; |
177 | + } |
178 | + if (is_ext_id_changed(&iface_rec->external_ids, external_ids_old, |
179 | + "encap-ip")) { |
180 | + return true; |
181 | + } |
182 | + } |
183 | + return false; |
184 | +} |
185 | + |
186 | /* Returns true if the ovs interface changes were handled successfully, |
187 | * false otherwise. |
188 | */ |
189 | @@ -2008,6 +2086,11 @@ binding_handle_ovs_interface_changes(struct binding_ctx_in *b_ctx_in, |
190 | continue; |
191 | } |
192 | |
193 | + if (!ovs_interface_change_need_handle( |
194 | + iface_rec, b_ctx_in->iface_table_external_ids_old)) { |
195 | + continue; |
196 | + } |
197 | + |
198 | const char *iface_id = smap_get(&iface_rec->external_ids, "iface-id"); |
199 | int64_t ofport = iface_rec->n_ofport ? *iface_rec->ofport : 0; |
200 | if (iface_id && ofport > 0 && |
201 | @@ -2049,6 +2132,15 @@ handle_deleted_lport(const struct sbrec_port_binding *pb, |
202 | return; |
203 | } |
204 | |
205 | + /* |
206 | + * Remove localport that was part of local datapath that is not |
207 | + * considered to be local anymore. |
208 | + */ |
209 | + if (!ld && !strcmp(pb->type, "localport") && |
210 | + sset_find(&b_ctx_out->related_lports->lport_names, pb->logical_port)) { |
211 | + remove_related_lport(pb, b_ctx_out); |
212 | + } |
213 | + |
214 | /* If the binding is not local, if 'pb' is a L3 gateway port, we should |
215 | * remove its peer, if that one is local. |
216 | */ |
217 | @@ -2251,6 +2343,9 @@ binding_handle_port_binding_changes(struct binding_ctx_in *b_ctx_in, |
218 | continue; |
219 | } |
220 | |
221 | + delete_active_pb_ras_pd(pb, b_ctx_out->local_active_ports_ipv6_pd); |
222 | + delete_active_pb_ras_pd(pb, b_ctx_out->local_active_ports_ras); |
223 | + |
224 | enum en_lport_type lport_type = get_lport_type(pb); |
225 | |
226 | struct binding_lport *b_lport = |
227 | diff --git a/controller/binding.h b/controller/binding.h |
228 | index 430a8d9..e49e1eb 100644 |
229 | --- a/controller/binding.h |
230 | +++ b/controller/binding.h |
231 | @@ -55,6 +55,7 @@ struct binding_ctx_in { |
232 | const struct ovsrec_bridge_table *bridge_table; |
233 | const struct ovsrec_open_vswitch_table *ovs_table; |
234 | const struct ovsrec_interface_table *iface_table; |
235 | + struct shash *iface_table_external_ids_old; |
236 | }; |
237 | |
238 | /* Locally relevant port bindings, e.g., VIFs that might be bound locally, |
239 | diff --git a/controller/chassis.c b/controller/chassis.c |
240 | index 8a15596..92850fc 100644 |
241 | --- a/controller/chassis.c |
242 | +++ b/controller/chassis.c |
243 | @@ -350,6 +350,7 @@ chassis_build_other_config(const struct ovs_chassis_cfg *ovs_cfg, |
244 | smap_replace(config, "is-interconn", |
245 | ovs_cfg->is_interconn ? "true" : "false"); |
246 | smap_replace(config, OVN_FEATURE_PORT_UP_NOTIF, "true"); |
247 | + smap_replace(config, OVN_FEATURE_CT_NO_MASKED_LABEL, "true"); |
248 | } |
249 | |
250 | /* |
251 | @@ -455,6 +456,12 @@ chassis_other_config_changed(const struct ovs_chassis_cfg *ovs_cfg, |
252 | return true; |
253 | } |
254 | |
255 | + if (!smap_get_bool(&chassis_rec->other_config, |
256 | + OVN_FEATURE_CT_NO_MASKED_LABEL, |
257 | + false)) { |
258 | + return true; |
259 | + } |
260 | + |
261 | return false; |
262 | } |
263 | |
264 | diff --git a/controller/lflow.c b/controller/lflow.c |
265 | index e169ede..a988290 100644 |
266 | --- a/controller/lflow.c |
267 | +++ b/controller/lflow.c |
268 | @@ -1104,6 +1104,23 @@ lflow_parse_ctrl_meter(const struct sbrec_logical_flow *lflow, |
269 | } |
270 | } |
271 | |
272 | +static int |
273 | +get_common_nat_zone(const struct local_datapath *ldp) |
274 | +{ |
275 | + /* Normally, the common NAT zone defaults to the DNAT zone. However, |
276 | + * if the "snat-ct-zone" is set on the datapath, the user is |
277 | + * expecting an explicit CT zone to be used for SNAT. If we default |
278 | + * to the DNAT zone, then it means SNAT will not use the configured |
279 | + * value. The way we get around this is to use the SNAT zone as the |
280 | + * common zone if "snat-ct-zone" is set. |
281 | + */ |
282 | + if (smap_get(&ldp->datapath->external_ids, "snat-ct-zone")) { |
283 | + return MFF_LOG_SNAT_ZONE; |
284 | + } else { |
285 | + return MFF_LOG_DNAT_ZONE; |
286 | + } |
287 | +} |
288 | + |
289 | static void |
290 | add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, |
291 | const struct local_datapath *ldp, |
292 | @@ -1153,6 +1170,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow, |
293 | .fdb_ptable = OFTABLE_GET_FDB, |
294 | .fdb_lookup_ptable = OFTABLE_LOOKUP_FDB, |
295 | .ctrl_meter_id = ctrl_meter_id, |
296 | + .common_nat_ct_zone = get_common_nat_zone(ldp), |
297 | }; |
298 | ovnacts_encode(ovnacts->data, ovnacts->size, &ep, &ofpacts); |
299 | |
300 | @@ -1894,6 +1912,7 @@ add_lb_vip_hairpin_flows(struct ovn_controller_lb *lb, |
301 | struct ovn_lb_vip *lb_vip, |
302 | struct ovn_lb_backend *lb_backend, |
303 | uint8_t lb_proto, |
304 | + bool use_ct_mark, |
305 | struct ovn_desired_flow_table *flow_table) |
306 | { |
307 | uint64_t stub[1024 / 8]; |
308 | @@ -1984,15 +2003,30 @@ add_lb_vip_hairpin_flows(struct ovn_controller_lb *lb, |
309 | * - packets must have ip.src == ip.dst at this point. |
310 | * - the destination protocol and port must be of a valid backend that |
311 | * has the same IP as ip.dst. |
312 | + * |
313 | + * During upgrades logical flows might still use the old way of storing |
314 | + * ct.natted in ct_label. For backwards compatibility, only use ct_mark |
315 | + * if ovn-northd notified ovn-controller to do that. |
316 | */ |
317 | - ovs_u128 lb_ct_label = { |
318 | - .u64.lo = OVN_CT_NATTED, |
319 | - }; |
320 | - match_set_ct_label_masked(&hairpin_match, lb_ct_label, lb_ct_label); |
321 | + if (use_ct_mark) { |
322 | + uint32_t lb_ct_mark = OVN_CT_NATTED; |
323 | + match_set_ct_mark_masked(&hairpin_match, lb_ct_mark, lb_ct_mark); |
324 | + |
325 | + ofctrl_add_flow(flow_table, OFTABLE_CHK_LB_HAIRPIN, 100, |
326 | + lb->slb->header_.uuid.parts[0], &hairpin_match, |
327 | + &ofpacts, &lb->slb->header_.uuid); |
328 | + } else { |
329 | + match_set_ct_mark_masked(&hairpin_match, 0, 0); |
330 | + ovs_u128 lb_ct_label = { |
331 | + .u64.lo = OVN_CT_NATTED, |
332 | + }; |
333 | + match_set_ct_label_masked(&hairpin_match, lb_ct_label, lb_ct_label); |
334 | + |
335 | + ofctrl_add_flow(flow_table, OFTABLE_CHK_LB_HAIRPIN, 100, |
336 | + lb->slb->header_.uuid.parts[0], &hairpin_match, |
337 | + &ofpacts, &lb->slb->header_.uuid); |
338 | + } |
339 | |
340 | - ofctrl_add_flow(flow_table, OFTABLE_CHK_LB_HAIRPIN, 100, |
341 | - lb->slb->header_.uuid.parts[0], &hairpin_match, |
342 | - &ofpacts, &lb->slb->header_.uuid); |
343 | ofpbuf_uninit(&ofpacts); |
344 | } |
345 | |
346 | @@ -2265,6 +2299,7 @@ add_lb_ct_snat_hairpin_flows(struct ovn_controller_lb *lb, |
347 | static void |
348 | consider_lb_hairpin_flows(const struct sbrec_load_balancer *sbrec_lb, |
349 | const struct hmap *local_datapaths, |
350 | + bool use_ct_mark, |
351 | struct ovn_desired_flow_table *flow_table, |
352 | struct simap *ids) |
353 | { |
354 | @@ -2304,7 +2339,7 @@ consider_lb_hairpin_flows(const struct sbrec_load_balancer *sbrec_lb, |
355 | struct ovn_lb_backend *lb_backend = &lb_vip->backends[j]; |
356 | |
357 | add_lb_vip_hairpin_flows(lb, lb_vip, lb_backend, lb_proto, |
358 | - flow_table); |
359 | + use_ct_mark, flow_table); |
360 | } |
361 | } |
362 | |
363 | @@ -2317,7 +2352,7 @@ consider_lb_hairpin_flows(const struct sbrec_load_balancer *sbrec_lb, |
364 | * backends to handle the load balanced hairpin traffic. */ |
365 | static void |
366 | add_lb_hairpin_flows(const struct sbrec_load_balancer_table *lb_table, |
367 | - const struct hmap *local_datapaths, |
368 | + const struct hmap *local_datapaths, bool use_ct_mark, |
369 | struct ovn_desired_flow_table *flow_table, |
370 | struct simap *ids, |
371 | struct id_pool *pool) |
372 | @@ -2340,7 +2375,8 @@ add_lb_hairpin_flows(const struct sbrec_load_balancer_table *lb_table, |
373 | ovs_assert(id_pool_alloc_id(pool, &id)); |
374 | simap_put(ids, lb->name, id); |
375 | } |
376 | - consider_lb_hairpin_flows(lb, local_datapaths, flow_table, ids); |
377 | + consider_lb_hairpin_flows(lb, local_datapaths, use_ct_mark, |
378 | + flow_table, ids); |
379 | } |
380 | } |
381 | |
382 | @@ -2446,6 +2482,7 @@ lflow_run(struct lflow_ctx_in *l_ctx_in, struct lflow_ctx_out *l_ctx_out) |
383 | l_ctx_in->mac_binding_table, l_ctx_in->local_datapaths, |
384 | l_ctx_out->flow_table); |
385 | add_lb_hairpin_flows(l_ctx_in->lb_table, l_ctx_in->local_datapaths, |
386 | + l_ctx_in->lb_hairpin_use_ct_mark, |
387 | l_ctx_out->flow_table, |
388 | l_ctx_out->hairpin_lb_ids, |
389 | l_ctx_out->hairpin_id_pool); |
390 | @@ -2572,6 +2609,18 @@ lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *dp, |
391 | } |
392 | sbrec_fdb_index_destroy_row(fdb_index_row); |
393 | |
394 | + struct sbrec_mac_binding *mb_index_row = sbrec_mac_binding_index_init_row( |
395 | + l_ctx_in->sbrec_mac_binding_by_datapath); |
396 | + sbrec_mac_binding_index_set_datapath(mb_index_row, dp); |
397 | + const struct sbrec_mac_binding *mb; |
398 | + SBREC_MAC_BINDING_FOR_EACH_EQUAL ( |
399 | + mb, mb_index_row, l_ctx_in->sbrec_mac_binding_by_datapath) { |
400 | + consider_neighbor_flow(l_ctx_in->sbrec_port_binding_by_name, |
401 | + l_ctx_in->local_datapaths, |
402 | + mb, l_ctx_out->flow_table); |
403 | + } |
404 | + sbrec_mac_binding_index_destroy_row(mb_index_row); |
405 | + |
406 | dhcp_opts_destroy(&dhcp_opts); |
407 | dhcp_opts_destroy(&dhcpv6_opts); |
408 | nd_ra_opts_destroy(&nd_ra_opts); |
409 | @@ -2581,6 +2630,7 @@ lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *dp, |
410 | * associated. */ |
411 | for (size_t i = 0; i < n_dp_lbs; i++) { |
412 | consider_lb_hairpin_flows(dp_lbs[i], l_ctx_in->local_datapaths, |
413 | + l_ctx_in->lb_hairpin_use_ct_mark, |
414 | l_ctx_out->flow_table, |
415 | l_ctx_out->hairpin_lb_ids); |
416 | } |
417 | @@ -2694,6 +2744,7 @@ lflow_handle_changed_lbs(struct lflow_ctx_in *l_ctx_in, |
418 | VLOG_DBG("Add load balancer hairpin flows for "UUID_FMT, |
419 | UUID_ARGS(&lb->header_.uuid)); |
420 | consider_lb_hairpin_flows(lb, l_ctx_in->local_datapaths, |
421 | + l_ctx_in->lb_hairpin_use_ct_mark, |
422 | l_ctx_out->flow_table, |
423 | l_ctx_out->hairpin_lb_ids); |
424 | } |
425 | diff --git a/controller/lflow.h b/controller/lflow.h |
426 | index d61733b..48a3650 100644 |
427 | --- a/controller/lflow.h |
428 | +++ b/controller/lflow.h |
429 | @@ -136,6 +136,8 @@ struct lflow_ctx_in { |
430 | struct ovsdb_idl_index *sbrec_logical_flow_by_logical_dp_group; |
431 | struct ovsdb_idl_index *sbrec_port_binding_by_name; |
432 | struct ovsdb_idl_index *sbrec_fdb_by_dp_key; |
433 | + struct ovsdb_idl_index *sbrec_mac_binding_by_datapath; |
434 | + struct ovsdb_idl_index *sbrec_static_mac_binding_by_datapath; |
435 | const struct sbrec_port_binding_table *port_binding_table; |
436 | const struct sbrec_dhcp_options_table *dhcp_options_table; |
437 | const struct sbrec_dhcpv6_options_table *dhcpv6_options_table; |
438 | @@ -153,6 +155,7 @@ struct lflow_ctx_in { |
439 | const struct sset *active_tunnels; |
440 | const struct sset *related_lport_ids; |
441 | const struct hmap *chassis_tunnels; |
442 | + bool lb_hairpin_use_ct_mark; |
443 | }; |
444 | |
445 | struct lflow_ctx_out { |
446 | diff --git a/controller/ofctrl.c b/controller/ofctrl.c |
447 | index a7c2d20..3b9d717 100644 |
448 | --- a/controller/ofctrl.c |
449 | +++ b/controller/ofctrl.c |
450 | @@ -943,7 +943,12 @@ link_installed_to_desired(struct installed_flow *i, struct desired_flow *d) |
451 | break; |
452 | } |
453 | } |
454 | - ovs_list_insert(&f->installed_ref_list_node, &d->installed_ref_list_node); |
455 | + if (!f) { |
456 | + ovs_list_insert(&i->desired_refs, &d->installed_ref_list_node); |
457 | + } else { |
458 | + ovs_list_insert(&f->installed_ref_list_node, |
459 | + &d->installed_ref_list_node); |
460 | + } |
461 | d->installed_flow = i; |
462 | return installed_flow_get_active(i) == d; |
463 | } |
464 | @@ -2324,7 +2329,20 @@ deleted_flow_lookup(struct hmap *deleted_flows, struct ovn_flow *target) |
465 | && f->cookie == target->cookie |
466 | && ofpacts_equal(f->ofpacts, f->ofpacts_len, target->ofpacts, |
467 | target->ofpacts_len)) { |
468 | - return d; |
469 | + /* del_f must have been installed, otherwise it should have |
470 | + * been removed during track_flow_del. */ |
471 | + ovs_assert(d->installed_flow); |
472 | + |
473 | + /* Now we also need to make sure the desired flow being |
474 | + * added/updated has exact same action and cookie as the installed |
475 | + * flow of d. Otherwise, don't merge them, so that the |
476 | + * installed flow can be updated later. */ |
477 | + struct ovn_flow *f_i = &d->installed_flow->flow; |
478 | + if (f_i->cookie == target->cookie |
479 | + && ofpacts_equal(f_i->ofpacts, f_i->ofpacts_len, |
480 | + target->ofpacts, target->ofpacts_len)) { |
481 | + return d; |
482 | + } |
483 | } |
484 | } |
485 | return NULL; |
486 | @@ -2353,10 +2371,6 @@ merge_tracked_flows(struct ovn_desired_flow_table *flow_table) |
487 | continue; |
488 | } |
489 | |
490 | - /* del_f must have been installed, otherwise it should have been |
491 | - * removed during track_flow_add_or_modify. */ |
492 | - ovs_assert(del_f->installed_flow); |
493 | - |
494 | if (!f->installed_flow) { |
495 | /* f is not installed yet. */ |
496 | replace_installed_to_desired(del_f->installed_flow, del_f, f); |
497 | @@ -2665,6 +2679,13 @@ ofctrl_put(struct ovn_desired_flow_table *lflow_table, |
498 | EXTEND_TABLE_FOR_EACH_INSTALLED (m_installed, next_meter, meters) { |
499 | /* Delete the meter. */ |
500 | ofctrl_meter_bands_erase(m_installed, &msgs); |
501 | + if (!strncmp(m_installed->name, "__string: ", 10)) { |
502 | + struct ofputil_meter_mod mm = { |
503 | + .command = OFPMC13_DELETE, |
504 | + .meter = { .meter_id = m_installed->table_id }, |
505 | + }; |
506 | + add_meter_mod(&mm, &msgs); |
507 | + } |
508 | ovn_extend_table_remove_existing(meters, m_installed); |
509 | } |
510 | |
511 | diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c |
512 | index ea5e9df..6d10c03 100644 |
513 | --- a/controller/ovn-controller.c |
514 | +++ b/controller/ovn-controller.c |
515 | @@ -131,6 +131,9 @@ static const char *ssl_ca_cert_file; |
516 | #define DEFAULT_LFLOW_CACHE_WMARK_PERC 50 |
517 | #define DEFAULT_LFLOW_CACHE_TRIM_TO_MS 30000 |
518 | |
519 | +/* SB Global options defaults. */ |
520 | +#define DEFAULT_SB_GLOBAL_LB_HAIRPIN_USE_CT_MARK false |
521 | + |
522 | struct controller_engine_ctx { |
523 | struct lflow_cache *lflow_cache; |
524 | struct if_status_mgr *if_mgr; |
525 | @@ -819,13 +822,18 @@ restore_ct_zones(const struct ovsrec_bridge_table *bridge_table, |
526 | } |
527 | |
528 | const char *user = node->key + 8; |
529 | - int zone = atoi(node->value); |
530 | + if (!user[0]) { |
531 | + continue; |
532 | + } |
533 | |
534 | - if (user[0] && zone) { |
535 | - VLOG_DBG("restoring ct zone %"PRId32" for '%s'", zone, user); |
536 | - bitmap_set1(ct_zone_bitmap, zone); |
537 | - simap_put(ct_zones, user, zone); |
538 | + unsigned int zone; |
539 | + if (!str_to_uint(node->value, 10, &zone)) { |
540 | + continue; |
541 | } |
542 | + |
543 | + VLOG_DBG("restoring ct zone %"PRId32" for '%s'", zone, user); |
544 | + bitmap_set1(ct_zone_bitmap, zone); |
545 | + simap_put(ct_zones, user, zone); |
546 | } |
547 | } |
548 | |
549 | @@ -954,6 +962,7 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl) |
550 | } |
551 | |
552 | #define SB_NODES \ |
553 | + SB_NODE(sb_global, "sb_global") \ |
554 | SB_NODE(chassis, "chassis") \ |
555 | SB_NODE(encap, "encap") \ |
556 | SB_NODE(address_set, "address_set") \ |
557 | @@ -1034,6 +1043,91 @@ en_ofctrl_is_connected_run(struct engine_node *node, void *data) |
558 | engine_set_node_state(node, EN_UNCHANGED); |
559 | } |
560 | |
561 | +/* This engine node is to wrap the OVS_interface input and maintain a copy of |
562 | + * the old version of data for the column external_ids. |
563 | + * |
564 | + * There are some special considerations of this engine node: |
565 | + * 1. It has a single input OVS_interface, and it transparently passes the |
566 | + * input changes as its own output data to its dependants. So there is no |
567 | + * processing to OVS_interface changes but simply mark the node status as |
568 | + * UPDATED (and so the run() and the change handler is the same). |
569 | + * 2. The iface_table_external_ids_old is computed/updated in the member |
570 | + * clear_tracked_data(), because that is when the last round of processing |
571 | + * has completed but the new IDL data is yet to refresh, so we replace the |
572 | + * old data with the current data. */ |
573 | +struct ed_type_ovs_interface_shadow { |
574 | + struct ovsrec_interface_table *iface_table; |
575 | + struct shash iface_table_external_ids_old; |
576 | +}; |
577 | + |
578 | +static void * |
579 | +en_ovs_interface_shadow_init(struct engine_node *node OVS_UNUSED, |
580 | + struct engine_arg *arg OVS_UNUSED) |
581 | +{ |
582 | + struct ed_type_ovs_interface_shadow *data = xzalloc(sizeof *data); |
583 | + data->iface_table = NULL; |
584 | + shash_init(&data->iface_table_external_ids_old); |
585 | + |
586 | + return data; |
587 | +} |
588 | + |
589 | +static void |
590 | +iface_table_external_ids_old_destroy(struct shash *table_ext_ids) |
591 | +{ |
592 | + struct shash_node *node; |
593 | + SHASH_FOR_EACH (node, table_ext_ids) { |
594 | + struct smap *ext_ids = node->data; |
595 | + smap_destroy(ext_ids); |
596 | + } |
597 | + shash_destroy_free_data(table_ext_ids); |
598 | +} |
599 | + |
600 | +static void |
601 | +en_ovs_interface_shadow_cleanup(void *data_) |
602 | +{ |
603 | + struct ed_type_ovs_interface_shadow *data = data_; |
604 | + iface_table_external_ids_old_destroy(&data->iface_table_external_ids_old); |
605 | +} |
606 | + |
607 | +static void |
608 | +en_ovs_interface_shadow_clear_tracked_data(void *data_) |
609 | +{ |
610 | + struct ed_type_ovs_interface_shadow *data = data_; |
611 | + iface_table_external_ids_old_destroy(&data->iface_table_external_ids_old); |
612 | + shash_init(&data->iface_table_external_ids_old); |
613 | + |
614 | + if (!data->iface_table) { |
615 | + return; |
616 | + } |
617 | + |
618 | + const struct ovsrec_interface *iface_rec; |
619 | + OVSREC_INTERFACE_TABLE_FOR_EACH (iface_rec, data->iface_table) { |
620 | + struct smap *external_ids = xmalloc(sizeof *external_ids); |
621 | + smap_clone(external_ids, &iface_rec->external_ids); |
622 | + shash_add(&data->iface_table_external_ids_old, iface_rec->name, |
623 | + external_ids); |
624 | + } |
625 | +} |
626 | + |
627 | +static void |
628 | +en_ovs_interface_shadow_run(struct engine_node *node, void *data_) |
629 | +{ |
630 | + struct ed_type_ovs_interface_shadow *data = data_; |
631 | + struct ovsrec_interface_table *iface_table = |
632 | + (struct ovsrec_interface_table *)EN_OVSDB_GET( |
633 | + engine_get_input("OVS_interface", node)); |
634 | + data->iface_table = iface_table; |
635 | + engine_set_node_state(node, EN_UPDATED); |
636 | +} |
637 | + |
638 | +static bool |
639 | +ovs_interface_shadow_ovs_interface_handler(struct engine_node *node, |
640 | + void *data_) |
641 | +{ |
642 | + en_ovs_interface_shadow_run(node, data_); |
643 | + return true; |
644 | +} |
645 | + |
646 | struct ed_type_runtime_data { |
647 | /* Contains "struct local_datapath" nodes. */ |
648 | struct hmap local_datapaths; |
649 | @@ -1206,9 +1300,8 @@ init_binding_ctx(struct engine_node *node, |
650 | (struct ovsrec_port_table *)EN_OVSDB_GET( |
651 | engine_get_input("OVS_port", node)); |
652 | |
653 | - struct ovsrec_interface_table *iface_table = |
654 | - (struct ovsrec_interface_table *)EN_OVSDB_GET( |
655 | - engine_get_input("OVS_interface", node)); |
656 | + struct ed_type_ovs_interface_shadow *iface_shadow = |
657 | + engine_get_input_data("ovs_interface_shadow", node); |
658 | |
659 | struct ovsrec_qos_table *qos_table = |
660 | (struct ovsrec_qos_table *)EN_OVSDB_GET( |
661 | @@ -1241,7 +1334,9 @@ init_binding_ctx(struct engine_node *node, |
662 | b_ctx_in->sbrec_port_binding_by_datapath = sbrec_port_binding_by_datapath; |
663 | b_ctx_in->sbrec_port_binding_by_name = sbrec_port_binding_by_name; |
664 | b_ctx_in->port_table = port_table; |
665 | - b_ctx_in->iface_table = iface_table; |
666 | + b_ctx_in->iface_table = iface_shadow->iface_table; |
667 | + b_ctx_in->iface_table_external_ids_old = |
668 | + &iface_shadow->iface_table_external_ids_old; |
669 | b_ctx_in->qos_table = qos_table; |
670 | b_ctx_in->port_binding_table = pb_table; |
671 | b_ctx_in->br_int = br_int; |
672 | @@ -1323,7 +1418,7 @@ en_runtime_data_run(struct engine_node *node, void *data) |
673 | } |
674 | |
675 | static bool |
676 | -runtime_data_ovs_interface_handler(struct engine_node *node, void *data) |
677 | +runtime_data_ovs_interface_shadow_handler(struct engine_node *node, void *data) |
678 | { |
679 | struct ed_type_runtime_data *rt_data = data; |
680 | struct binding_ctx_in b_ctx_in; |
681 | @@ -2194,6 +2289,63 @@ non_vif_data_ovs_iface_handler(struct engine_node *node, void *data OVS_UNUSED) |
682 | return local_nonvif_data_handle_ovs_iface_changes(iface_table); |
683 | } |
684 | |
685 | +struct ed_type_northd_options { |
686 | + bool lb_hairpin_use_ct_mark; |
687 | +}; |
688 | + |
689 | + |
690 | +static void * |
691 | +en_northd_options_init(struct engine_node *node OVS_UNUSED, |
692 | + struct engine_arg *arg OVS_UNUSED) |
693 | +{ |
694 | + struct ed_type_northd_options *n_opts = xzalloc(sizeof *n_opts); |
695 | + return n_opts; |
696 | +} |
697 | + |
698 | +static void |
699 | +en_northd_options_cleanup(void *data OVS_UNUSED) |
700 | +{ |
701 | +} |
702 | + |
703 | +static void |
704 | +en_northd_options_run(struct engine_node *node, void *data) |
705 | +{ |
706 | + struct ed_type_northd_options *n_opts = data; |
707 | + const struct sbrec_sb_global_table *sb_global_table = |
708 | + EN_OVSDB_GET(engine_get_input("SB_sb_global", node)); |
709 | + const struct sbrec_sb_global *sb_global = |
710 | + sbrec_sb_global_table_first(sb_global_table); |
711 | + |
712 | + n_opts->lb_hairpin_use_ct_mark = |
713 | + sb_global |
714 | + ? smap_get_bool(&sb_global->options, "lb_hairpin_use_ct_mark", |
715 | + DEFAULT_SB_GLOBAL_LB_HAIRPIN_USE_CT_MARK) |
716 | + : DEFAULT_SB_GLOBAL_LB_HAIRPIN_USE_CT_MARK; |
717 | + engine_set_node_state(node, EN_UPDATED); |
718 | +} |
719 | + |
720 | +static bool |
721 | +en_northd_options_sb_sb_global_handler(struct engine_node *node, void *data) |
722 | +{ |
723 | + struct ed_type_northd_options *n_opts = data; |
724 | + const struct sbrec_sb_global_table *sb_global_table = |
725 | + EN_OVSDB_GET(engine_get_input("SB_sb_global", node)); |
726 | + const struct sbrec_sb_global *sb_global = |
727 | + sbrec_sb_global_table_first(sb_global_table); |
728 | + |
729 | + bool lb_hairpin_use_ct_mark = |
730 | + sb_global |
731 | + ? smap_get_bool(&sb_global->options, "lb_hairpin_use_ct_mark", |
732 | + DEFAULT_SB_GLOBAL_LB_HAIRPIN_USE_CT_MARK) |
733 | + : DEFAULT_SB_GLOBAL_LB_HAIRPIN_USE_CT_MARK; |
734 | + |
735 | + if (lb_hairpin_use_ct_mark != n_opts->lb_hairpin_use_ct_mark) { |
736 | + n_opts->lb_hairpin_use_ct_mark = lb_hairpin_use_ct_mark; |
737 | + engine_set_node_state(node, EN_UPDATED); |
738 | + } |
739 | + return true; |
740 | +} |
741 | + |
742 | struct lflow_output_persistent_data { |
743 | struct lflow_cache *lflow_cache; |
744 | }; |
745 | @@ -2259,6 +2411,11 @@ init_lflow_ctx(struct engine_node *node, |
746 | engine_get_input("SB_fdb", node), |
747 | "dp_key"); |
748 | |
749 | + struct ovsdb_idl_index *sbrec_mac_binding_by_datapath = |
750 | + engine_ovsdb_node_get_index( |
751 | + engine_get_input("SB_mac_binding", node), |
752 | + "datapath"); |
753 | + |
754 | struct sbrec_port_binding_table *port_binding_table = |
755 | (struct sbrec_port_binding_table *)EN_OVSDB_GET( |
756 | engine_get_input("SB_port_binding", node)); |
757 | @@ -2325,6 +2482,9 @@ init_lflow_ctx(struct engine_node *node, |
758 | engine_get_input_data("port_groups", node); |
759 | struct shash *port_groups = &pg_data->port_groups_cs_local; |
760 | |
761 | + struct ed_type_northd_options *n_opts = |
762 | + engine_get_input_data("northd_options", node); |
763 | + |
764 | l_ctx_in->sbrec_multicast_group_by_name_datapath = |
765 | sbrec_mc_group_by_name_dp; |
766 | l_ctx_in->sbrec_logical_flow_by_logical_datapath = |
767 | @@ -2333,6 +2493,7 @@ init_lflow_ctx(struct engine_node *node, |
768 | sbrec_logical_flow_by_dp_group; |
769 | l_ctx_in->sbrec_port_binding_by_name = sbrec_port_binding_by_name; |
770 | l_ctx_in->sbrec_fdb_by_dp_key = sbrec_fdb_by_dp_key; |
771 | + l_ctx_in->sbrec_mac_binding_by_datapath = sbrec_mac_binding_by_datapath; |
772 | l_ctx_in->port_binding_table = port_binding_table; |
773 | l_ctx_in->dhcp_options_table = dhcp_table; |
774 | l_ctx_in->dhcpv6_options_table = dhcpv6_table; |
775 | @@ -2349,6 +2510,7 @@ init_lflow_ctx(struct engine_node *node, |
776 | l_ctx_in->active_tunnels = &rt_data->active_tunnels; |
777 | l_ctx_in->related_lport_ids = &rt_data->related_lports.lport_ids; |
778 | l_ctx_in->chassis_tunnels = &non_vif_data->chassis_tunnels; |
779 | + l_ctx_in->lb_hairpin_use_ct_mark = n_opts->lb_hairpin_use_ct_mark; |
780 | |
781 | l_ctx_out->flow_table = &fo->flow_table; |
782 | l_ctx_out->group_table = &fo->group_table; |
783 | @@ -3173,6 +3335,9 @@ main(int argc, char *argv[]) |
784 | = ovsdb_idl_index_create2(ovnsb_idl_loop.idl, |
785 | &sbrec_fdb_col_mac, |
786 | &sbrec_fdb_col_dp_key); |
787 | + struct ovsdb_idl_index *sbrec_mac_binding_by_datapath |
788 | + = ovsdb_idl_index_create1(ovnsb_idl_loop.idl, |
789 | + &sbrec_mac_binding_col_datapath); |
790 | |
791 | ovsdb_idl_track_add_all(ovnsb_idl_loop.idl); |
792 | ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, |
793 | @@ -3234,6 +3399,8 @@ main(int argc, char *argv[]) |
794 | |
795 | /* Define inc-proc-engine nodes. */ |
796 | ENGINE_NODE_WITH_CLEAR_TRACK_DATA_IS_VALID(ct_zones, "ct_zones"); |
797 | + ENGINE_NODE_WITH_CLEAR_TRACK_DATA(ovs_interface_shadow, |
798 | + "ovs_interface_shadow"); |
799 | ENGINE_NODE_WITH_CLEAR_TRACK_DATA(runtime_data, "runtime_data"); |
800 | ENGINE_NODE(non_vif_data, "non_vif_data"); |
801 | ENGINE_NODE(mff_ovn_geneve, "mff_ovn_geneve"); |
802 | @@ -3243,6 +3410,7 @@ main(int argc, char *argv[]) |
803 | ENGINE_NODE(flow_output, "flow_output"); |
804 | ENGINE_NODE_WITH_CLEAR_TRACK_DATA(addr_sets, "addr_sets"); |
805 | ENGINE_NODE_WITH_CLEAR_TRACK_DATA(port_groups, "port_groups"); |
806 | + ENGINE_NODE(northd_options, "northd_options"); |
807 | |
808 | #define SB_NODE(NAME, NAME_STR) ENGINE_NODE_SB(NAME, NAME_STR); |
809 | SB_NODES |
810 | @@ -3291,6 +3459,11 @@ main(int argc, char *argv[]) |
811 | engine_add_input(&en_pflow_output, &en_ovs_open_vswitch, NULL); |
812 | engine_add_input(&en_pflow_output, &en_ovs_bridge, NULL); |
813 | |
814 | + engine_add_input(&en_northd_options, &en_sb_sb_global, |
815 | + en_northd_options_sb_sb_global_handler); |
816 | + |
817 | + engine_add_input(&en_lflow_output, &en_northd_options, NULL); |
818 | + |
819 | /* Keep en_addr_sets before en_runtime_data because |
820 | * lflow_output_runtime_data_handler may *partially* reprocess a lflow when |
821 | * the lflow is attached to a DP group and a new DP in that DP group is |
822 | @@ -3347,6 +3520,9 @@ main(int argc, char *argv[]) |
823 | engine_add_input(&en_ct_zones, &en_runtime_data, |
824 | ct_zones_runtime_data_handler); |
825 | |
826 | + engine_add_input(&en_ovs_interface_shadow, &en_ovs_interface, |
827 | + ovs_interface_shadow_ovs_interface_handler); |
828 | + |
829 | engine_add_input(&en_runtime_data, &en_ofctrl_is_connected, NULL); |
830 | |
831 | engine_add_input(&en_runtime_data, &en_ovs_open_vswitch, NULL); |
832 | @@ -3368,8 +3544,8 @@ main(int argc, char *argv[]) |
833 | */ |
834 | engine_add_input(&en_runtime_data, &en_ovs_port, |
835 | engine_noop_handler); |
836 | - engine_add_input(&en_runtime_data, &en_ovs_interface, |
837 | - runtime_data_ovs_interface_handler); |
838 | + engine_add_input(&en_runtime_data, &en_ovs_interface_shadow, |
839 | + runtime_data_ovs_interface_shadow_handler); |
840 | |
841 | engine_add_input(&en_flow_output, &en_lflow_output, |
842 | flow_output_lflow_output_handler); |
843 | @@ -3399,6 +3575,8 @@ main(int argc, char *argv[]) |
844 | sbrec_datapath_binding_by_key); |
845 | engine_ovsdb_node_add_index(&en_sb_fdb, "dp_key", |
846 | sbrec_fdb_by_dp_key); |
847 | + engine_ovsdb_node_add_index(&en_sb_mac_binding, "datapath", |
848 | + sbrec_mac_binding_by_datapath); |
849 | |
850 | struct ed_type_lflow_output *lflow_output_data = |
851 | engine_get_internal_data(&en_lflow_output); |
852 | diff --git a/controller/physical.c b/controller/physical.c |
853 | index 033828d..adf4632 100644 |
854 | --- a/controller/physical.c |
855 | +++ b/controller/physical.c |
856 | @@ -421,6 +421,12 @@ populate_remote_chassis_macs(const struct sbrec_chassis *my_chassis, |
857 | char *save_ptr2 = NULL; |
858 | char *chassis_mac_bridge = strtok_r(token, ":", &save_ptr2); |
859 | char *chassis_mac_str = strtok_r(NULL, "", &save_ptr2); |
860 | + if (!chassis_mac_str) { |
861 | + VLOG_WARN("Parsing of ovn-chassis-mac-mappings failed for: " |
862 | + "\"%s\", the correct format is \"br-name1:MAC1\".", |
863 | + token); |
864 | + continue; |
865 | + } |
866 | struct remote_chassis_mac *remote_chassis_mac = NULL; |
867 | remote_chassis_mac = xmalloc(sizeof *remote_chassis_mac); |
868 | hmap_insert(&remote_chassis_macs, &remote_chassis_mac->hmap_node, |
869 | @@ -1309,6 +1315,24 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name, |
870 | } |
871 | } |
872 | |
873 | + /* Table 37, priority 150. |
874 | + * ======================= |
875 | + * |
876 | + * Handles packets received from ports of type "localport". These |
877 | + * ports are present on every hypervisor. Traffic that originates at |
878 | + * one should never go over a tunnel to a remote hypervisor, |
879 | + * so resubmit them to table 38 for local delivery. */ |
880 | + if (!strcmp(binding->type, "localport")) { |
881 | + ofpbuf_clear(ofpacts_p); |
882 | + put_resubmit(OFTABLE_LOCAL_OUTPUT, ofpacts_p); |
883 | + match_init_catchall(&match); |
884 | + match_set_reg(&match, MFF_LOG_INPORT - MFF_REG0, |
885 | + binding->tunnel_key); |
886 | + match_set_metadata(&match, htonll(binding->datapath->tunnel_key)); |
887 | + ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, |
888 | + binding->header_.uuid.parts[0], &match, |
889 | + ofpacts_p, &binding->header_.uuid); |
890 | + } |
891 | } else if (!tun && !is_ha_remote) { |
892 | /* Remote port connected by localnet port */ |
893 | /* Table 38, priority 100. |
894 | @@ -1840,32 +1864,6 @@ physical_run(struct physical_ctx *p_ctx, |
895 | ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, 0, |
896 | &match, &ofpacts, hc_uuid); |
897 | |
898 | - /* Table 37, priority 150. |
899 | - * ======================= |
900 | - * |
901 | - * Handles packets received from ports of type "localport". These ports |
902 | - * are present on every hypervisor. Traffic that originates at one should |
903 | - * never go over a tunnel to a remote hypervisor, so resubmit them to table |
904 | - * 38 for local delivery. */ |
905 | - match_init_catchall(&match); |
906 | - ofpbuf_clear(&ofpacts); |
907 | - put_resubmit(OFTABLE_LOCAL_OUTPUT, &ofpacts); |
908 | - const char *localport; |
909 | - SSET_FOR_EACH (localport, p_ctx->local_lports) { |
910 | - /* Iterate over all local logical ports and insert a drop |
911 | - * rule with higher priority for every localport in this |
912 | - * datapath. */ |
913 | - const struct sbrec_port_binding *pb = lport_lookup_by_name( |
914 | - p_ctx->sbrec_port_binding_by_name, localport); |
915 | - if (pb && !strcmp(pb->type, "localport")) { |
916 | - match_set_reg(&match, MFF_LOG_INPORT - MFF_REG0, pb->tunnel_key); |
917 | - match_set_metadata(&match, htonll(pb->datapath->tunnel_key)); |
918 | - ofctrl_add_flow(flow_table, OFTABLE_REMOTE_OUTPUT, 150, |
919 | - pb->header_.uuid.parts[0], |
920 | - &match, &ofpacts, hc_uuid); |
921 | - } |
922 | - } |
923 | - |
924 | /* Table 37, Priority 0. |
925 | * ======================= |
926 | * |
927 | diff --git a/controller/pinctrl.c b/controller/pinctrl.c |
928 | index 25b37ee..2f718ac 100644 |
929 | --- a/controller/pinctrl.c |
930 | +++ b/controller/pinctrl.c |
931 | @@ -5523,7 +5523,7 @@ get_localnet_vifs_l3gwports( |
932 | } |
933 | const struct sbrec_port_binding *pb |
934 | = lport_lookup_by_name(sbrec_port_binding_by_name, iface_id); |
935 | - if (!pb) { |
936 | + if (!pb || pb->chassis != chassis) { |
937 | continue; |
938 | } |
939 | struct local_datapath *ld |
940 | @@ -5554,7 +5554,7 @@ get_localnet_vifs_l3gwports( |
941 | sbrec_port_binding_index_set_datapath(target, ld->datapath); |
942 | SBREC_PORT_BINDING_FOR_EACH_EQUAL (pb, target, |
943 | sbrec_port_binding_by_datapath) { |
944 | - if (!strcmp(pb->type, "l3gateway") |
945 | + if ((!strcmp(pb->type, "l3gateway") && pb->chassis == chassis) |
946 | || !strcmp(pb->type, "patch")) { |
947 | sset_add(local_l3gw_ports, pb->logical_port); |
948 | } |
949 | @@ -5781,7 +5781,8 @@ send_garp_rarp_prepare(struct ovsdb_idl_txn *ovnsb_idl_txn, |
950 | const struct sbrec_port_binding *pb = lport_lookup_by_name( |
951 | sbrec_port_binding_by_name, iface_id); |
952 | if (pb) { |
953 | - send_garp_rarp_update(ovnsb_idl_txn, sbrec_mac_binding_by_lport_ip, |
954 | + send_garp_rarp_update(ovnsb_idl_txn, |
955 | + sbrec_mac_binding_by_lport_ip, |
956 | local_datapaths, pb, &nat_addresses); |
957 | } |
958 | } |
959 | diff --git a/debian/changelog b/debian/changelog |
960 | index e1246f3..d294bfc 100644 |
961 | --- a/debian/changelog |
962 | +++ b/debian/changelog |
963 | @@ -1,3 +1,11 @@ |
964 | +ovn (22.03.1-0ubuntu1) UNRELEASED; urgency=medium |
965 | + |
966 | + * New upstream point release (LP: #1980809). |
967 | + * d/ovn-common.install: Add missing ovn_detrace.py binary (LP: #1971178). |
968 | + * d/control: Update openvswitch build requirement. |
969 | + |
970 | + -- Frode Nordahl <frode.nordahl@canonical.com> Wed, 06 Jul 2022 09:09:25 +0200 |
971 | + |
972 | ovn (22.03.0-0ubuntu1) jammy; urgency=medium |
973 | |
974 | [ Frode Nordahl ] |
975 | diff --git a/debian/control b/debian/control |
976 | index 503de8e..87f7265 100644 |
977 | --- a/debian/control |
978 | +++ b/debian/control |
979 | @@ -18,7 +18,7 @@ Build-Depends: |
980 | libudev-dev, |
981 | libunbound-dev, |
982 | openssl, |
983 | - openvswitch-source (>= 2.17.0~), |
984 | + openvswitch-source (>= 2.17.2~), |
985 | pkg-config, |
986 | procps, |
987 | python3-all-dev, |
988 | diff --git a/debian/ovn-common.install b/debian/ovn-common.install |
989 | index 8503c01..9bdbdca 100644 |
990 | --- a/debian/ovn-common.install |
991 | +++ b/debian/ovn-common.install |
992 | @@ -1,4 +1,5 @@ |
993 | usr/bin/ovn-appctl |
994 | +usr/bin/ovn_detrace.py |
995 | usr/bin/ovn-detrace |
996 | usr/bin/ovn-nbctl |
997 | usr/bin/ovn-sbctl |
998 | diff --git a/include/ovn/actions.h b/include/ovn/actions.h |
999 | index 0641b92..5477975 100644 |
1000 | --- a/include/ovn/actions.h |
1001 | +++ b/include/ovn/actions.h |
1002 | @@ -59,6 +59,8 @@ struct ovn_extend_table; |
1003 | OVNACT(NEXT, ovnact_next) \ |
1004 | OVNACT(LOAD, ovnact_load) \ |
1005 | OVNACT(MOVE, ovnact_move) \ |
1006 | + OVNACT(PUSH, ovnact_push_pop) \ |
1007 | + OVNACT(POP, ovnact_push_pop) \ |
1008 | OVNACT(EXCHANGE, ovnact_move) \ |
1009 | OVNACT(DEC_TTL, ovnact_null) \ |
1010 | OVNACT(CT_NEXT, ovnact_ct_next) \ |
1011 | @@ -69,6 +71,7 @@ struct ovn_extend_table; |
1012 | OVNACT(CT_DNAT_IN_CZONE, ovnact_ct_nat) \ |
1013 | OVNACT(CT_SNAT_IN_CZONE, ovnact_ct_nat) \ |
1014 | OVNACT(CT_LB, ovnact_ct_lb) \ |
1015 | + OVNACT(CT_LB_MARK, ovnact_ct_lb) \ |
1016 | OVNACT(SELECT, ovnact_select) \ |
1017 | OVNACT(CT_CLEAR, ovnact_null) \ |
1018 | OVNACT(CLONE, ovnact_nest) \ |
1019 | @@ -233,6 +236,12 @@ struct ovnact_move { |
1020 | struct expr_field rhs; |
1021 | }; |
1022 | |
1023 | +/* OVNACT_PUSH, OVNACT_POP. */ |
1024 | +struct ovnact_push_pop { |
1025 | + struct ovnact ovnact; |
1026 | + struct expr_field field; |
1027 | +}; |
1028 | + |
1029 | /* OVNACT_CT_NEXT. */ |
1030 | struct ovnact_ct_next { |
1031 | struct ovnact ovnact; |
1032 | @@ -273,7 +282,7 @@ struct ovnact_ct_lb_dst { |
1033 | uint16_t port; |
1034 | }; |
1035 | |
1036 | -/* OVNACT_CT_LB. */ |
1037 | +/* OVNACT_CT_LB/OVNACT_CT_LB_MARK. */ |
1038 | struct ovnact_ct_lb { |
1039 | struct ovnact ovnact; |
1040 | struct ovnact_ct_lb_dst *dsts; |
1041 | @@ -799,6 +808,8 @@ struct ovnact_encode_params { |
1042 | * 'lookup_fdb' to resubmit. */ |
1043 | uint32_t ctrl_meter_id; /* Meter to be used if the resulting flow |
1044 | sends packets to controller. */ |
1045 | + uint32_t common_nat_ct_zone; /* When performing NAT in a common CT zone, |
1046 | + this determines which CT zone to use */ |
1047 | }; |
1048 | |
1049 | void ovnacts_encode(const struct ovnact[], size_t ovnacts_len, |
1050 | diff --git a/include/ovn/features.h b/include/ovn/features.h |
1051 | index d12a8eb..8fbdbf1 100644 |
1052 | --- a/include/ovn/features.h |
1053 | +++ b/include/ovn/features.h |
1054 | @@ -21,7 +21,8 @@ |
1055 | #include "smap.h" |
1056 | |
1057 | /* ovn-controller supported feature names. */ |
1058 | -#define OVN_FEATURE_PORT_UP_NOTIF "port-up-notif" |
1059 | +#define OVN_FEATURE_PORT_UP_NOTIF "port-up-notif" |
1060 | +#define OVN_FEATURE_CT_NO_MASKED_LABEL "ct-no-masked-label" |
1061 | |
1062 | /* OVS datapath supported features. Based on availability OVN might generate |
1063 | * different types of openflows. |
1064 | diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h |
1065 | index 2118f79..1851663 100644 |
1066 | --- a/include/ovn/logical-fields.h |
1067 | +++ b/include/ovn/logical-fields.h |
1068 | @@ -36,8 +36,6 @@ enum ovn_controller_event { |
1069 | * (32 bits). */ |
1070 | #define MFF_LOG_SNAT_ZONE MFF_REG12 /* conntrack snat zone for gateway router |
1071 | * (32 bits). */ |
1072 | -#define MFF_LOG_NAT_ZONE MFF_LOG_DNAT_ZONE /* conntrack zone for both snat |
1073 | - * and dnat. */ |
1074 | #define MFF_LOG_CT_ZONE MFF_REG13 /* Logical conntrack zone for lports |
1075 | * (32 bits). */ |
1076 | #define MFF_LOG_INPORT MFF_REG14 /* Logical input port (32 bits). */ |
1077 | @@ -176,6 +174,9 @@ const struct ovn_field *ovn_field_from_name(const char *name); |
1078 | #define OVN_CT_BLOCKED 1 |
1079 | #define OVN_CT_NATTED 2 |
1080 | |
1081 | +#define OVN_CT_ECMP_ETH_1ST_BIT 32 |
1082 | +#define OVN_CT_ECMP_ETH_END_BIT 79 |
1083 | + |
1084 | #define OVN_CT_STR(LABEL_VALUE) OVS_STRINGIZE(LABEL_VALUE) |
1085 | #define OVN_CT_MASKED_STR(LABEL_VALUE) \ |
1086 | OVS_STRINGIZE(LABEL_VALUE) "/" OVS_STRINGIZE(LABEL_VALUE) |
1087 | diff --git a/lib/actions.c b/lib/actions.c |
1088 | index 5d3caaf..a9c2760 100644 |
1089 | --- a/lib/actions.c |
1090 | +++ b/lib/actions.c |
1091 | @@ -573,6 +573,75 @@ ovnact_move_free(struct ovnact_move *move OVS_UNUSED) |
1092 | { |
1093 | } |
1094 | |
1095 | |
1096 | + |
1097 | +static void |
1098 | +parse_push_pop(struct action_context *ctx, bool is_push) |
1099 | +{ |
1100 | + lexer_force_match(ctx->lexer, LEX_T_LPAREN); |
1101 | + |
1102 | + struct expr_field f; |
1103 | + if (!expr_field_parse(ctx->lexer, ctx->pp->symtab, &f, &ctx->prereqs)) { |
1104 | + return; |
1105 | + } |
1106 | + size_t ofs = ctx->ovnacts->size; |
1107 | + char *error = expr_type_check(&f, f.n_bits, !is_push, ctx->scope); |
1108 | + if (error) { |
1109 | + ctx->ovnacts->size = ofs; |
1110 | + lexer_error(ctx->lexer, "%s", error); |
1111 | + free(error); |
1112 | + return; |
1113 | + } |
1114 | + |
1115 | + lexer_force_match(ctx->lexer, LEX_T_RPAREN); |
1116 | + |
1117 | + struct ovnact_push_pop *p; |
1118 | + if (is_push) { |
1119 | + p = ovnact_put_PUSH(ctx->ovnacts); |
1120 | + } else { |
1121 | + p = ovnact_put_POP(ctx->ovnacts); |
1122 | + } |
1123 | + p->field = f; |
1124 | +} |
1125 | + |
1126 | +static void |
1127 | +format_PUSH(const struct ovnact_push_pop *push, struct ds *s) |
1128 | +{ |
1129 | + ds_put_cstr(s, "push("); |
1130 | + expr_field_format(&push->field, s); |
1131 | + ds_put_cstr(s, ");"); |
1132 | +} |
1133 | + |
1134 | +static void |
1135 | +encode_PUSH(const struct ovnact_push_pop *push, |
1136 | + const struct ovnact_encode_params *ep OVS_UNUSED, |
1137 | + struct ofpbuf *ofpacts) |
1138 | +{ |
1139 | + ofpact_put_STACK_PUSH(ofpacts)->subfield = |
1140 | + expr_resolve_field(&push->field); |
1141 | +} |
1142 | + |
1143 | +static void |
1144 | +format_POP(const struct ovnact_push_pop *pop, struct ds *s) |
1145 | +{ |
1146 | + ds_put_cstr(s, "pop("); |
1147 | + expr_field_format(&pop->field, s); |
1148 | + ds_put_cstr(s, ");"); |
1149 | +} |
1150 | + |
1151 | +static void |
1152 | +encode_POP(const struct ovnact_push_pop *pop, |
1153 | + const struct ovnact_encode_params *ep OVS_UNUSED, |
1154 | + struct ofpbuf *ofpacts) |
1155 | +{ |
1156 | + ofpact_put_STACK_POP(ofpacts)->subfield = |
1157 | + expr_resolve_field(&pop->field); |
1158 | +} |
1159 | + |
1160 | +static void |
1161 | +ovnact_push_pop_free(struct ovnact_push_pop *push OVS_UNUSED) |
1162 | +{ |
1163 | +} |
1164 | + |
1165 | |
1166 | static void |
1167 | parse_DEC_TTL(struct action_context *ctx) |
1168 | { |
1169 | @@ -1062,7 +1131,7 @@ encode_CT_DNAT_IN_CZONE(const struct ovnact_ct_nat *cn, |
1170 | const struct ovnact_encode_params *ep, |
1171 | struct ofpbuf *ofpacts) |
1172 | { |
1173 | - encode_ct_nat(cn, ep, false, MFF_LOG_NAT_ZONE, ofpacts); |
1174 | + encode_ct_nat(cn, ep, false, ep->common_nat_ct_zone, ofpacts); |
1175 | } |
1176 | |
1177 | static void |
1178 | @@ -1070,7 +1139,7 @@ encode_CT_SNAT_IN_CZONE(const struct ovnact_ct_nat *cn, |
1179 | const struct ovnact_encode_params *ep, |
1180 | struct ofpbuf *ofpacts) |
1181 | { |
1182 | - encode_ct_nat(cn, ep, true, MFF_LOG_NAT_ZONE, ofpacts); |
1183 | + encode_ct_nat(cn, ep, true, ep->common_nat_ct_zone, ofpacts); |
1184 | } |
1185 | |
1186 | static void |
1187 | @@ -1079,7 +1148,7 @@ ovnact_ct_nat_free(struct ovnact_ct_nat *ct_nat OVS_UNUSED) |
1188 | } |
1189 | |
1190 | |
1191 | static void |
1192 | -parse_ct_lb_action(struct action_context *ctx) |
1193 | +parse_ct_lb_action(struct action_context *ctx, bool ct_lb_mark) |
1194 | { |
1195 | if (ctx->pp->cur_ltable >= ctx->pp->n_tables) { |
1196 | lexer_error(ctx->lexer, "\"ct_lb\" action not allowed in last table."); |
1197 | @@ -1185,7 +1254,8 @@ parse_ct_lb_action(struct action_context *ctx) |
1198 | } |
1199 | } |
1200 | |
1201 | - struct ovnact_ct_lb *cl = ovnact_put_CT_LB(ctx->ovnacts); |
1202 | + struct ovnact_ct_lb *cl = ct_lb_mark ? ovnact_put_CT_LB_MARK(ctx->ovnacts) |
1203 | + : ovnact_put_CT_LB(ctx->ovnacts); |
1204 | cl->ltable = ctx->pp->cur_ltable + 1; |
1205 | cl->dsts = dsts; |
1206 | cl->n_dsts = n_dsts; |
1207 | @@ -1193,9 +1263,13 @@ parse_ct_lb_action(struct action_context *ctx) |
1208 | } |
1209 | |
1210 | static void |
1211 | -format_CT_LB(const struct ovnact_ct_lb *cl, struct ds *s) |
1212 | +format_ct_lb(const struct ovnact_ct_lb *cl, struct ds *s, bool ct_lb_mark) |
1213 | { |
1214 | - ds_put_cstr(s, "ct_lb"); |
1215 | + if (ct_lb_mark) { |
1216 | + ds_put_cstr(s, "ct_lb_mark"); |
1217 | + } else { |
1218 | + ds_put_cstr(s, "ct_lb"); |
1219 | + } |
1220 | if (cl->n_dsts) { |
1221 | ds_put_cstr(s, "(backends="); |
1222 | for (size_t i = 0; i < cl->n_dsts; i++) { |
1223 | @@ -1231,9 +1305,22 @@ format_CT_LB(const struct ovnact_ct_lb *cl, struct ds *s) |
1224 | } |
1225 | |
1226 | static void |
1227 | -encode_CT_LB(const struct ovnact_ct_lb *cl, |
1228 | +format_CT_LB(const struct ovnact_ct_lb *cl, struct ds *s) |
1229 | +{ |
1230 | + format_ct_lb(cl, s, false); |
1231 | +} |
1232 | + |
1233 | +static void |
1234 | +format_CT_LB_MARK(const struct ovnact_ct_lb *cl, struct ds *s) |
1235 | +{ |
1236 | + format_ct_lb(cl, s, true); |
1237 | +} |
1238 | + |
1239 | +static void |
1240 | +encode_ct_lb(const struct ovnact_ct_lb *cl, |
1241 | const struct ovnact_encode_params *ep, |
1242 | - struct ofpbuf *ofpacts) |
1243 | + struct ofpbuf *ofpacts, |
1244 | + bool ct_lb_mark) |
1245 | { |
1246 | uint8_t recirc_table = cl->ltable + first_ptable(ep, ep->pipeline); |
1247 | if (!cl->n_dsts) { |
1248 | @@ -1302,8 +1389,9 @@ encode_CT_LB(const struct ovnact_ct_lb *cl, |
1249 | ds_put_format(&ds, "),commit,table=%d,zone=NXM_NX_REG%d[0..15]," |
1250 | "exec(set_field:" |
1251 | OVN_CT_MASKED_STR(OVN_CT_NATTED) |
1252 | - "->ct_label))", |
1253 | - recirc_table, zone_reg); |
1254 | + "->%s))", |
1255 | + recirc_table, zone_reg, |
1256 | + ct_lb_mark ? "ct_mark" : "ct_label"); |
1257 | } |
1258 | |
1259 | table_id = ovn_extend_table_assign_id(ep->group_table, ds_cstr(&ds), |
1260 | @@ -1319,6 +1407,22 @@ encode_CT_LB(const struct ovnact_ct_lb *cl, |
1261 | } |
1262 | |
1263 | static void |
1264 | +encode_CT_LB(const struct ovnact_ct_lb *cl, |
1265 | + const struct ovnact_encode_params *ep, |
1266 | + struct ofpbuf *ofpacts) |
1267 | +{ |
1268 | + encode_ct_lb(cl, ep, ofpacts, false); |
1269 | +} |
1270 | + |
1271 | +static void |
1272 | +encode_CT_LB_MARK(const struct ovnact_ct_lb *cl, |
1273 | + const struct ovnact_encode_params *ep, |
1274 | + struct ofpbuf *ofpacts) |
1275 | +{ |
1276 | + encode_ct_lb(cl, ep, ofpacts, true); |
1277 | +} |
1278 | + |
1279 | +static void |
1280 | ovnact_ct_lb_free(struct ovnact_ct_lb *ct_lb) |
1281 | { |
1282 | free(ct_lb->dsts); |
1283 | @@ -2336,7 +2440,7 @@ validate_empty_lb_backends(struct action_context *ctx, |
1284 | |
1285 | switch (o->option->code) { |
1286 | case EMPTY_LB_VIP: |
1287 | - if (!inet_parse_active(c->string, 0, &ss, false)) { |
1288 | + if (!inet_parse_active(c->string, 0, &ss, false, NULL)) { |
1289 | lexer_error(ctx->lexer, "Invalid load balancer VIP '%s'", |
1290 | c->string); |
1291 | return; |
1292 | @@ -4202,6 +4306,10 @@ parse_action(struct action_context *ctx) |
1293 | parse_set_action(ctx); |
1294 | } else if (lexer_match_id(ctx->lexer, "next")) { |
1295 | parse_NEXT(ctx); |
1296 | + } else if (lexer_match_id(ctx->lexer, "push")) { |
1297 | + parse_push_pop(ctx, true); |
1298 | + } else if (lexer_match_id(ctx->lexer, "pop")) { |
1299 | + parse_push_pop(ctx, false); |
1300 | } else if (lexer_match_id(ctx->lexer, "output")) { |
1301 | ovnact_put_OUTPUT(ctx->ovnacts); |
1302 | } else if (lexer_match_id(ctx->lexer, "ip.ttl")) { |
1303 | @@ -4219,7 +4327,9 @@ parse_action(struct action_context *ctx) |
1304 | } else if (lexer_match_id(ctx->lexer, "ct_snat_in_czone")) { |
1305 | parse_CT_SNAT_IN_CZONE(ctx); |
1306 | } else if (lexer_match_id(ctx->lexer, "ct_lb")) { |
1307 | - parse_ct_lb_action(ctx); |
1308 | + parse_ct_lb_action(ctx, false); |
1309 | + } else if (lexer_match_id(ctx->lexer, "ct_lb_mark")) { |
1310 | + parse_ct_lb_action(ctx, true); |
1311 | } else if (lexer_match_id(ctx->lexer, "ct_clear")) { |
1312 | ovnact_put_CT_CLEAR(ctx->ovnacts); |
1313 | } else if (lexer_match_id(ctx->lexer, "clone")) { |
1314 | diff --git a/lib/expr.c b/lib/expr.c |
1315 | index 47ef610..058390a 100644 |
1316 | --- a/lib/expr.c |
1317 | +++ b/lib/expr.c |
1318 | @@ -211,16 +211,17 @@ expr_combine(enum expr_type type, struct expr *a, struct expr *b) |
1319 | } |
1320 | |
1321 | static void |
1322 | -expr_insert_andor(struct expr *andor, struct expr *before, struct expr *new) |
1323 | +expr_insert_andor(struct expr *andor, struct ovs_list *before, |
1324 | + struct expr *new) |
1325 | { |
1326 | if (new->type == andor->type) { |
1327 | if (andor->type == EXPR_T_AND) { |
1328 | /* Conjunction junction, what's your function? */ |
1329 | } |
1330 | - ovs_list_splice(&before->node, new->andor.next, &new->andor); |
1331 | + ovs_list_splice(before, new->andor.next, &new->andor); |
1332 | expr_destroy(new); |
1333 | } else { |
1334 | - ovs_list_insert(&before->node, &new->node); |
1335 | + ovs_list_insert(before, &new->node); |
1336 | } |
1337 | } |
1338 | |
1339 | @@ -2101,7 +2102,8 @@ expr_annotate__(struct expr *expr, const struct shash *symtab, |
1340 | expr_destroy(expr); |
1341 | return NULL; |
1342 | } |
1343 | - expr_insert_andor(expr, next, new_sub); |
1344 | + expr_insert_andor(expr, next ? &next->node : &expr->andor, |
1345 | + new_sub); |
1346 | } |
1347 | *errorp = NULL; |
1348 | return expr; |
1349 | @@ -2301,7 +2303,7 @@ expr_evaluate_condition(struct expr *expr, |
1350 | struct expr *e = expr_evaluate_condition(sub, is_chassis_resident, |
1351 | c_aux); |
1352 | e = expr_fix(e); |
1353 | - expr_insert_andor(expr, next, e); |
1354 | + expr_insert_andor(expr, next ? &next->node : &expr->andor, e); |
1355 | } |
1356 | return expr_fix(expr); |
1357 | |
1358 | @@ -2334,7 +2336,8 @@ expr_simplify(struct expr *expr) |
1359 | case EXPR_T_OR: |
1360 | LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) { |
1361 | ovs_list_remove(&sub->node); |
1362 | - expr_insert_andor(expr, next, expr_simplify(sub)); |
1363 | + expr_insert_andor(expr, next ? &next->node : &expr->andor, |
1364 | + expr_simplify(sub)); |
1365 | } |
1366 | return expr_fix(expr); |
1367 | |
1368 | @@ -2444,12 +2447,13 @@ crush_and_string(struct expr *expr, const struct expr_symbol *symbol) |
1369 | * EXPR_T_OR with EXPR_T_CMP subexpressions. */ |
1370 | struct expr *sub, *next = NULL; |
1371 | LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) { |
1372 | + struct ovs_list *next_list = next ? &next->node : &expr->andor; |
1373 | ovs_list_remove(&sub->node); |
1374 | struct expr *new = crush_cmps(sub, symbol); |
1375 | switch (new->type) { |
1376 | case EXPR_T_CMP: |
1377 | if (!singleton) { |
1378 | - ovs_list_insert(&next->node, &new->node); |
1379 | + ovs_list_insert(next_list, &new->node); |
1380 | singleton = new; |
1381 | } else { |
1382 | bool match = !strcmp(new->cmp.string, singleton->cmp.string); |
1383 | @@ -2463,7 +2467,7 @@ crush_and_string(struct expr *expr, const struct expr_symbol *symbol) |
1384 | case EXPR_T_AND: |
1385 | OVS_NOT_REACHED(); |
1386 | case EXPR_T_OR: |
1387 | - ovs_list_insert(&next->node, &new->node); |
1388 | + ovs_list_insert(next_list, &new->node); |
1389 | break; |
1390 | case EXPR_T_BOOLEAN: |
1391 | if (!new->boolean) { |
1392 | @@ -2559,7 +2563,7 @@ crush_and_numeric(struct expr *expr, const struct expr_symbol *symbol) |
1393 | case EXPR_T_AND: |
1394 | OVS_NOT_REACHED(); |
1395 | case EXPR_T_OR: |
1396 | - ovs_list_insert(&next->node, &new->node); |
1397 | + ovs_list_insert(next ? &next->node : &expr->andor, &new->node); |
1398 | break; |
1399 | case EXPR_T_BOOLEAN: |
1400 | if (!new->boolean) { |
1401 | @@ -2725,7 +2729,8 @@ crush_or(struct expr *expr, const struct expr_symbol *symbol) |
1402 | * is now a disjunction of cmps over the same symbol. */ |
1403 | LIST_FOR_EACH_SAFE (sub, next, node, &expr->andor) { |
1404 | ovs_list_remove(&sub->node); |
1405 | - expr_insert_andor(expr, next, crush_cmps(sub, symbol)); |
1406 | + expr_insert_andor(expr, next ? &next->node : &expr->andor, |
1407 | + crush_cmps(sub, symbol)); |
1408 | } |
1409 | expr = expr_fix(expr); |
1410 | if (expr->type != EXPR_T_OR) { |
1411 | @@ -2886,8 +2891,7 @@ expr_normalize_and(struct expr *expr) |
1412 | |
1413 | struct expr *a, *b; |
1414 | LIST_FOR_EACH_SAFE (a, b, node, &expr->andor) { |
1415 | - if (&b->node == &expr->andor |
1416 | - || a->type != EXPR_T_CMP || b->type != EXPR_T_CMP |
1417 | + if (!b || a->type != EXPR_T_CMP || b->type != EXPR_T_CMP |
1418 | || a->cmp.symbol != b->cmp.symbol) { |
1419 | continue; |
1420 | } else if (a->cmp.symbol->width |
1421 | @@ -2964,7 +2968,8 @@ expr_normalize_or(struct expr *expr) |
1422 | } |
1423 | expr_destroy(new); |
1424 | } else { |
1425 | - expr_insert_andor(expr, next, new); |
1426 | + expr_insert_andor(expr, next ? &next->node : &expr->andor, |
1427 | + new); |
1428 | } |
1429 | } else { |
1430 | ovs_assert(sub->type == EXPR_T_CMP || |
1431 | diff --git a/lib/inc-proc-eng.c b/lib/inc-proc-eng.c |
1432 | index 7b43917..575b774 100644 |
1433 | --- a/lib/inc-proc-eng.c |
1434 | +++ b/lib/inc-proc-eng.c |
1435 | @@ -354,14 +354,11 @@ engine_recompute(struct engine_node *node, bool allowed, |
1436 | const char *reason_fmt, ...) |
1437 | { |
1438 | char *reason = NULL; |
1439 | + va_list reason_args; |
1440 | |
1441 | - if (VLOG_IS_DBG_ENABLED()) { |
1442 | - va_list reason_args; |
1443 | - |
1444 | - va_start(reason_args, reason_fmt); |
1445 | - reason = xvasprintf(reason_fmt, reason_args); |
1446 | - va_end(reason_args); |
1447 | - } |
1448 | + va_start(reason_args, reason_fmt); |
1449 | + reason = xvasprintf(reason_fmt, reason_args); |
1450 | + va_end(reason_args); |
1451 | |
1452 | if (!allowed) { |
1453 | VLOG_DBG("node: %s, recompute (%s) aborted", node->name, reason); |
1454 | diff --git a/lib/logical-fields.c b/lib/logical-fields.c |
1455 | index 352a48c..ed3ec62 100644 |
1456 | --- a/lib/logical-fields.c |
1457 | +++ b/lib/logical-fields.c |
1458 | @@ -133,6 +133,18 @@ ovn_init_symtab(struct shash *symtab) |
1459 | /* Connection tracking state. */ |
1460 | expr_symtab_add_field_scoped(symtab, "ct_mark", MFF_CT_MARK, NULL, false, |
1461 | WR_CT_COMMIT); |
1462 | + expr_symtab_add_subfield_scoped(symtab, "ct_mark.blocked", NULL, |
1463 | + "ct_mark[" |
1464 | + OVN_CT_STR(OVN_CT_BLOCKED_BIT) |
1465 | + "]", |
1466 | + WR_CT_COMMIT); |
1467 | + expr_symtab_add_subfield_scoped(symtab, "ct_mark.natted", NULL, |
1468 | + "ct_mark[" |
1469 | + OVN_CT_STR(OVN_CT_NATTED_BIT) |
1470 | + "]", |
1471 | + WR_CT_COMMIT); |
1472 | + expr_symtab_add_subfield_scoped(symtab, "ct_mark.ecmp_reply_port", NULL, |
1473 | + "ct_mark[16..31]", WR_CT_COMMIT); |
1474 | |
1475 | expr_symtab_add_field_scoped(symtab, "ct_label", MFF_CT_LABEL, NULL, |
1476 | false, WR_CT_COMMIT); |
1477 | @@ -147,7 +159,10 @@ ovn_init_symtab(struct shash *symtab) |
1478 | "]", |
1479 | WR_CT_COMMIT); |
1480 | expr_symtab_add_subfield_scoped(symtab, "ct_label.ecmp_reply_eth", NULL, |
1481 | - "ct_label[32..79]", WR_CT_COMMIT); |
1482 | + "ct_label[" |
1483 | + OVN_CT_STR(OVN_CT_ECMP_ETH_1ST_BIT) ".." |
1484 | + OVN_CT_STR(OVN_CT_ECMP_ETH_END_BIT) "]", |
1485 | + WR_CT_COMMIT); |
1486 | expr_symtab_add_subfield_scoped(symtab, "ct_label.ecmp_reply_port", NULL, |
1487 | "ct_label[80..95]", WR_CT_COMMIT); |
1488 | expr_symtab_add_subfield_scoped(symtab, "ct_label.label", NULL, |
1489 | diff --git a/lib/ovn-parallel-hmap.h b/lib/ovn-parallel-hmap.h |
1490 | index 897208e..0f7d687 100644 |
1491 | --- a/lib/ovn-parallel-hmap.h |
1492 | +++ b/lib/ovn-parallel-hmap.h |
1493 | @@ -58,11 +58,11 @@ extern "C" { |
1494 | * ThreadID + step * i as the JOBID parameter. |
1495 | */ |
1496 | |
1497 | -#define HMAP_FOR_EACH_IN_PARALLEL(NODE, MEMBER, JOBID, HMAP) \ |
1498 | - for (INIT_CONTAINER(NODE, hmap_first_in_bucket_num(HMAP, JOBID), MEMBER); \ |
1499 | - (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER)) \ |
1500 | - || ((NODE = NULL), false); \ |
1501 | - ASSIGN_CONTAINER(NODE, hmap_next_in_bucket(&(NODE)->MEMBER), MEMBER)) |
1502 | +#define HMAP_FOR_EACH_IN_PARALLEL(NODE, MEMBER, JOBID, HMAP) \ |
1503 | + for (INIT_MULTIVAR(NODE, MEMBER, hmap_first_in_bucket_num(HMAP, JOBID), \ |
1504 | + struct hmap_node); \ |
1505 | + CONDITION_MULTIVAR(NODE, MEMBER, ITER_VAR(NODE) != NULL); \ |
1506 | + UPDATE_MULTIVAR(NODE, hmap_next_in_bucket(ITER_VAR(NODE)))) |
1507 | |
1508 | /* We do not have a SAFE version of the macro, because the hash size is not |
1509 | * atomic and hash removal operations would need to be wrapped with |
1510 | diff --git a/lib/ovn-util.c b/lib/ovn-util.c |
1511 | index a22ae84..81f18d6 100644 |
1512 | --- a/lib/ovn-util.c |
1513 | +++ b/lib/ovn-util.c |
1514 | @@ -735,7 +735,7 @@ ip_address_and_port_from_lb_key(const char *key, char **ip_address, |
1515 | uint16_t *port, int *addr_family) |
1516 | { |
1517 | struct sockaddr_storage ss; |
1518 | - if (!inet_parse_active(key, 0, &ss, false)) { |
1519 | + if (!inet_parse_active(key, 0, &ss, false, NULL)) { |
1520 | static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1); |
1521 | VLOG_WARN_RL(&rl, "bad ip address or port for load balancer key %s", |
1522 | key); |
1523 | @@ -754,8 +754,11 @@ ip_address_and_port_from_lb_key(const char *key, char **ip_address, |
1524 | } |
1525 | |
1526 | /* Increment this for any logical flow changes, if an existing OVN action is |
1527 | - * modified or a stage is added to a logical pipeline. */ |
1528 | -#define OVN_INTERNAL_MINOR_VER 3 |
1529 | + * modified or a stage is added to a logical pipeline. |
1530 | + * |
1531 | + * This value is also used to handle some backward compatibility during |
1532 | + * upgrading. It should never decrease or rewind. */ |
1533 | +#define OVN_INTERNAL_MINOR_VER 4 |
1534 | |
1535 | /* Returns the OVN version. The caller must free the returned value. */ |
1536 | char * |
1537 | @@ -766,6 +769,24 @@ ovn_get_internal_version(void) |
1538 | N_OVNACTS, OVN_INTERNAL_MINOR_VER); |
1539 | } |
1540 | |
1541 | +unsigned int |
1542 | +ovn_parse_internal_version_minor(const char *ver) |
1543 | +{ |
1544 | + const char *p = ver + strlen(ver); |
1545 | + for (int i = 0; i < strlen(ver); i++) { |
1546 | + if (*p == '.') { |
1547 | + break; |
1548 | + } |
1549 | + p--; |
1550 | + } |
1551 | + |
1552 | + unsigned int minor; |
1553 | + if (ovs_scan(p, ".%u", &minor)) { |
1554 | + return minor; |
1555 | + } |
1556 | + return 0; |
1557 | +} |
1558 | + |
1559 | #ifdef DDLOG |
1560 | /* Callbacks used by the ddlog northd code to print warnings and errors. */ |
1561 | void |
1562 | diff --git a/lib/ovn-util.h b/lib/ovn-util.h |
1563 | index 1fe91ba..024b86b 100644 |
1564 | --- a/lib/ovn-util.h |
1565 | +++ b/lib/ovn-util.h |
1566 | @@ -245,6 +245,10 @@ bool ip_address_and_port_from_lb_key(const char *key, char **ip_address, |
1567 | * value. */ |
1568 | char *ovn_get_internal_version(void); |
1569 | |
1570 | +/* Parse the provided internal version string and return the "minor" part which |
1571 | + * is expected to be an unsigned integer followed by the last "." in the |
1572 | + * string. Returns 0 if the string can't be parsed. */ |
1573 | +unsigned int ovn_parse_internal_version_minor(const char *ver); |
1574 | |
1575 | /* OVN Packet definitions. These may eventually find a home in OVS's |
1576 | * packets.h file. For the time being, they live here because OVN uses them |
1577 | diff --git a/northd/en-lflow.c b/northd/en-lflow.c |
1578 | index ffbdaf4..fa0dfcb 100644 |
1579 | --- a/northd/en-lflow.c |
1580 | +++ b/northd/en-lflow.c |
1581 | @@ -60,6 +60,7 @@ void en_lflow_run(struct engine_node *node, void *data OVS_UNUSED) |
1582 | lflow_input.meter_groups = &northd_data->meter_groups; |
1583 | lflow_input.lbs = &northd_data->lbs; |
1584 | lflow_input.bfd_connections = &northd_data->bfd_connections; |
1585 | + lflow_input.features = &northd_data->features; |
1586 | lflow_input.ovn_internal_version_changed = |
1587 | northd_data->ovn_internal_version_changed; |
1588 | |
1589 | diff --git a/northd/northd.c b/northd/northd.c |
1590 | index b22da67..d06f6a7 100644 |
1591 | --- a/northd/northd.c |
1592 | +++ b/northd/northd.c |
1593 | @@ -238,6 +238,17 @@ enum ovn_stage { |
1594 | /* Register used for setting a label for ACLs in a Logical Switch. */ |
1595 | #define REG_LABEL "reg3" |
1596 | |
1597 | +/* Register used for temporarily store ECMP eth.src to avoid masked ct_label |
1598 | + * access. It doesn't really occupy registers because the content of the |
1599 | + * register is saved to stack and then restored in the same flow. |
1600 | + * Note: the bits must match ct_label.ecmp_reply_eth defined in |
1601 | + * logical-fields.c */ |
1602 | +#define REG_ECMP_ETH_FULL "xxreg1" |
1603 | +#define REG_ECMP_ETH_FIELD REG_ECMP_ETH_FULL "[" \ |
1604 | + OVN_CT_STR(OVN_CT_ECMP_ETH_1ST_BIT) \ |
1605 | + ".." \ |
1606 | + OVN_CT_STR(OVN_CT_ECMP_ETH_END_BIT) "]" |
1607 | + |
1608 | #define FLAGBIT_NOT_VXLAN "flags[1] == 0" |
1609 | |
1610 | /* |
1611 | @@ -378,6 +389,23 @@ ovn_stage_to_datapath_type(enum ovn_stage stage) |
1612 | } |
1613 | } |
1614 | |
1615 | |
1616 | +static void |
1617 | +build_chassis_features(const struct northd_input *input_data, |
1618 | + struct chassis_features *chassis_features) |
1619 | +{ |
1620 | + const struct sbrec_chassis *chassis; |
1621 | + |
1622 | + SBREC_CHASSIS_TABLE_FOR_EACH (chassis, input_data->sbrec_chassis) { |
1623 | + if (!smap_get_bool(&chassis->other_config, |
1624 | + OVN_FEATURE_CT_NO_MASKED_LABEL, |
1625 | + false)) { |
1626 | + chassis_features->ct_no_masked_label = false; |
1627 | + return; |
1628 | + } |
1629 | + } |
1630 | + chassis_features->ct_no_masked_label = true; |
1631 | +} |
1632 | + |
1633 | |
1634 | struct ovn_chassis_qdisc_queues { |
1635 | struct hmap_node key_node; |
1636 | uint32_t queue_id; |
1637 | @@ -763,16 +791,6 @@ init_nat_entries(struct ovn_datapath *od) |
1638 | return; |
1639 | } |
1640 | |
1641 | - if (od->n_l3dgw_ports > 1) { |
1642 | - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); |
1643 | - VLOG_WARN_RL(&rl, "NAT is configured on logical router %s, which has %" |
1644 | - PRIuSIZE" distributed gateway ports. NAT is not supported" |
1645 | - " yet when there is more than one distributed gateway " |
1646 | - "port on the router.", |
1647 | - od->nbr->name, od->n_l3dgw_ports); |
1648 | - return; |
1649 | - } |
1650 | - |
1651 | od->nat_entries = xmalloc(od->nbr->n_nat * sizeof *od->nat_entries); |
1652 | |
1653 | for (size_t i = 0; i < od->nbr->n_nat; i++) { |
1654 | @@ -1795,6 +1813,38 @@ lsp_is_router(const struct nbrec_logical_switch_port *nbsp) |
1655 | } |
1656 | |
1657 | static bool |
1658 | +lsp_is_type_changed(const struct sbrec_port_binding *sb, |
1659 | + const struct nbrec_logical_switch_port *nbsp, |
1660 | + bool *is_old_container_lport) |
1661 | +{ |
1662 | + *is_old_container_lport = false; |
1663 | + if (!sb || !nbsp) { |
1664 | + return false; |
1665 | + } |
1666 | + |
1667 | + if (!sb->type[0] && !nbsp->type[0]) { |
1668 | + /* Two "VIF's" interface make sure both have parent_port |
1669 | + * set or both have parent_port unset, otherwisre they are |
1670 | + * different ports type. |
1671 | + */ |
1672 | + if ((!sb->parent_port && nbsp->parent_name) || |
1673 | + (sb->parent_port && !nbsp->parent_name)) { |
1674 | + *is_old_container_lport = true; |
1675 | + return true; |
1676 | + } else { |
1677 | + return false; |
1678 | + } |
1679 | + } |
1680 | + |
1681 | + /* Both lports are not "VIF's" it is safe to use strcmp. */ |
1682 | + if (sb->type[0] && nbsp->type[0]) { |
1683 | + return strcmp(sb->type, nbsp->type); |
1684 | + } |
1685 | + |
1686 | + return true; |
1687 | +} |
1688 | + |
1689 | +static bool |
1690 | lrport_is_enabled(const struct nbrec_logical_router_port *lrport) |
1691 | { |
1692 | return !lrport->enabled || *lrport->enabled; |
1693 | @@ -2474,22 +2524,56 @@ join_logical_ports(struct northd_input *input_data, |
1694 | VLOG_WARN_RL(&rl, "duplicate logical port %s", nbsp->name); |
1695 | continue; |
1696 | } else if (op && (!op->sb || op->sb->datapath == od->sb)) { |
1697 | - ovn_port_set_nb(op, nbsp, NULL); |
1698 | - ovs_list_remove(&op->list); |
1699 | - |
1700 | - uint32_t queue_id = smap_get_int(&op->sb->options, |
1701 | - "qdisc_queue_id", 0); |
1702 | - if (queue_id && op->sb->chassis) { |
1703 | - add_chassis_queue( |
1704 | - chassis_qdisc_queues, &op->sb->chassis->header_.uuid, |
1705 | - queue_id); |
1706 | - } |
1707 | + /* |
1708 | + * Handle cases where lport type was explicitly changed |
1709 | + * in the NBDB, in such cases: |
1710 | + * 1. remove the current sbrec of the affected lport from |
1711 | + * the port_binding table. |
1712 | + * |
1713 | + * 2. create a new sbrec with the same logical_port as the |
1714 | + * deleted lport and add it to the nb_only list which |
1715 | + * will make the northd handle this lport as a new |
1716 | + * created one and recompute everything that is needed |
1717 | + * for this lport. |
1718 | + * |
1719 | + * This change will affect container lport type changes |
1720 | + * only for now, this change is needed in container |
1721 | + * lport cases to avoid port type conflicts in the |
1722 | + * ovn-controller when the user clears the parent_port |
1723 | + * field in the container lport. |
1724 | + * |
1725 | + * This approach can be applied to all other lport types |
1726 | + * changes by removing the is_old_container_lport. |
1727 | + */ |
1728 | + bool is_old_container_lport = false; |
1729 | + if (op->sb && lsp_is_type_changed(op->sb, nbsp, |
1730 | + &is_old_container_lport) |
1731 | + && is_old_container_lport) { |
1732 | + ovs_list_remove(&op->list); |
1733 | + sbrec_port_binding_delete(op->sb); |
1734 | + ovn_port_destroy(ports, op); |
1735 | + op = ovn_port_create(ports, nbsp->name, nbsp, |
1736 | + NULL, NULL); |
1737 | + ovs_list_push_back(nb_only, &op->list); |
1738 | + } else { |
1739 | + ovn_port_set_nb(op, nbsp, NULL); |
1740 | + ovs_list_remove(&op->list); |
1741 | + |
1742 | + uint32_t queue_id = smap_get_int(&op->sb->options, |
1743 | + "qdisc_queue_id", 0); |
1744 | + if (queue_id && op->sb->chassis) { |
1745 | + add_chassis_queue( |
1746 | + chassis_qdisc_queues, |
1747 | + &op->sb->chassis->header_.uuid, |
1748 | + queue_id); |
1749 | + } |
1750 | |
1751 | - ovs_list_push_back(both, &op->list); |
1752 | + ovs_list_push_back(both, &op->list); |
1753 | |
1754 | - /* This port exists due to a SB binding, but should |
1755 | - * not have been initialized fully. */ |
1756 | - ovs_assert(!op->n_lsp_addrs && !op->n_ps_addrs); |
1757 | + /* This port exists due to a SB binding, but should |
1758 | + * not have been initialized fully. */ |
1759 | + ovs_assert(!op->n_lsp_addrs && !op->n_ps_addrs); |
1760 | + } |
1761 | } else { |
1762 | op = ovn_port_create(ports, nbsp->name, nbsp, NULL, NULL); |
1763 | ovs_list_push_back(nb_only, &op->list); |
1764 | @@ -3670,12 +3754,13 @@ static bool |
1765 | build_lb_vip_actions(struct ovn_lb_vip *lb_vip, |
1766 | struct ovn_northd_lb_vip *lb_vip_nb, |
1767 | struct ds *action, char *selection_fields, |
1768 | - bool ls_dp) |
1769 | + bool ls_dp, bool ct_lb_mark) |
1770 | { |
1771 | + const char *ct_lb_action = ct_lb_mark ? "ct_lb_mark" : "ct_lb"; |
1772 | bool skip_hash_fields = false, reject = false; |
1773 | |
1774 | if (lb_vip_nb->lb_health_check) { |
1775 | - ds_put_cstr(action, "ct_lb(backends="); |
1776 | + ds_put_format(action, "%s(backends=", ct_lb_action); |
1777 | |
1778 | size_t n_active_backends = 0; |
1779 | for (size_t i = 0; i < lb_vip->n_backends; i++) { |
1780 | @@ -3708,7 +3793,8 @@ build_lb_vip_actions(struct ovn_lb_vip *lb_vip, |
1781 | } else if (lb_vip->empty_backend_rej && !lb_vip->n_backends) { |
1782 | reject = true; |
1783 | } else { |
1784 | - ds_put_format(action, "ct_lb(backends=%s);", lb_vip_nb->backend_ips); |
1785 | + ds_put_format(action, "%s(backends=%s);", ct_lb_action, |
1786 | + lb_vip_nb->backend_ips); |
1787 | } |
1788 | |
1789 | if (reject) { |
1790 | @@ -5914,13 +6000,18 @@ build_pre_lb(struct ovn_datapath *od, struct hmap *lflows) |
1791 | } |
1792 | |
1793 | static void |
1794 | -build_pre_stateful(struct ovn_datapath *od, struct hmap *lflows) |
1795 | +build_pre_stateful(struct ovn_datapath *od, |
1796 | + const struct chassis_features *features, |
1797 | + struct hmap *lflows) |
1798 | { |
1799 | /* Ingress and Egress pre-stateful Table (Priority 0): Packets are |
1800 | * allowed by default. */ |
1801 | ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 0, "1", "next;"); |
1802 | ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_STATEFUL, 0, "1", "next;"); |
1803 | |
1804 | + const char *ct_lb_action = features->ct_no_masked_label |
1805 | + ? "ct_lb_mark" |
1806 | + : "ct_lb"; |
1807 | const char *lb_protocols[] = {"tcp", "udp", "sctp"}; |
1808 | struct ds actions = DS_EMPTY_INITIALIZER; |
1809 | struct ds match = DS_EMPTY_INITIALIZER; |
1810 | @@ -5931,8 +6022,8 @@ build_pre_stateful(struct ovn_datapath *od, struct hmap *lflows) |
1811 | ds_put_format(&match, REGBIT_CONNTRACK_NAT" == 1 && ip4 && %s", |
1812 | lb_protocols[i]); |
1813 | ds_put_format(&actions, REG_ORIG_DIP_IPV4 " = ip4.dst; " |
1814 | - REG_ORIG_TP_DPORT " = %s.dst; ct_lb;", |
1815 | - lb_protocols[i]); |
1816 | + REG_ORIG_TP_DPORT " = %s.dst; %s;", |
1817 | + lb_protocols[i], ct_lb_action); |
1818 | ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 120, |
1819 | ds_cstr(&match), ds_cstr(&actions)); |
1820 | |
1821 | @@ -5941,20 +6032,20 @@ build_pre_stateful(struct ovn_datapath *od, struct hmap *lflows) |
1822 | ds_put_format(&match, REGBIT_CONNTRACK_NAT" == 1 && ip6 && %s", |
1823 | lb_protocols[i]); |
1824 | ds_put_format(&actions, REG_ORIG_DIP_IPV6 " = ip6.dst; " |
1825 | - REG_ORIG_TP_DPORT " = %s.dst; ct_lb;", |
1826 | - lb_protocols[i]); |
1827 | + REG_ORIG_TP_DPORT " = %s.dst; %s;", |
1828 | + lb_protocols[i], ct_lb_action); |
1829 | ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 120, |
1830 | ds_cstr(&match), ds_cstr(&actions)); |
1831 | } |
1832 | |
1833 | - ds_destroy(&actions); |
1834 | - ds_destroy(&match); |
1835 | + ds_clear(&actions); |
1836 | + ds_put_format(&actions, "%s;", ct_lb_action); |
1837 | |
1838 | ovn_lflow_add(lflows, od, S_SWITCH_IN_PRE_STATEFUL, 110, |
1839 | - REGBIT_CONNTRACK_NAT" == 1", "ct_lb;"); |
1840 | + REGBIT_CONNTRACK_NAT" == 1", ds_cstr(&actions)); |
1841 | |
1842 | ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_STATEFUL, 110, |
1843 | - REGBIT_CONNTRACK_NAT" == 1", "ct_lb;"); |
1844 | + REGBIT_CONNTRACK_NAT" == 1", ds_cstr(&actions)); |
1845 | |
1846 | /* If REGBIT_CONNTRACK_DEFRAG is set as 1, then the packets should be |
1847 | * sent to conntrack for tracking and defragmentation. */ |
1848 | @@ -5963,10 +6054,15 @@ build_pre_stateful(struct ovn_datapath *od, struct hmap *lflows) |
1849 | |
1850 | ovn_lflow_add(lflows, od, S_SWITCH_OUT_PRE_STATEFUL, 100, |
1851 | REGBIT_CONNTRACK_DEFRAG" == 1", "ct_next;"); |
1852 | + |
1853 | + ds_destroy(&actions); |
1854 | + ds_destroy(&match); |
1855 | } |
1856 | |
1857 | static void |
1858 | -build_acl_hints(struct ovn_datapath *od, struct hmap *lflows) |
1859 | +build_acl_hints(struct ovn_datapath *od, |
1860 | + const struct chassis_features *features, |
1861 | + struct hmap *lflows) |
1862 | { |
1863 | /* This stage builds hints for the IN/OUT_ACL stage. Based on various |
1864 | * combinations of ct flags packets may hit only a subset of the logical |
1865 | @@ -5988,6 +6084,7 @@ build_acl_hints(struct ovn_datapath *od, struct hmap *lflows) |
1866 | |
1867 | for (size_t i = 0; i < ARRAY_SIZE(stages); i++) { |
1868 | enum ovn_stage stage = stages[i]; |
1869 | + const char *match; |
1870 | |
1871 | /* In any case, advance to the next stage. */ |
1872 | if (!od->has_acls && !od->has_lb_vip) { |
1873 | @@ -6017,8 +6114,10 @@ build_acl_hints(struct ovn_datapath *od, struct hmap *lflows) |
1874 | * REGBIT_ACL_HINT_ALLOW_NEW. |
1875 | * - drop ACLs. |
1876 | */ |
1877 | - ovn_lflow_add(lflows, od, stage, 6, |
1878 | - "!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1", |
1879 | + match = features->ct_no_masked_label |
1880 | + ? "!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1" |
1881 | + : "!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1"; |
1882 | + ovn_lflow_add(lflows, od, stage, 6, match, |
1883 | REGBIT_ACL_HINT_ALLOW_NEW " = 1; " |
1884 | REGBIT_ACL_HINT_DROP " = 1; " |
1885 | "next;"); |
1886 | @@ -6034,11 +6133,13 @@ build_acl_hints(struct ovn_datapath *od, struct hmap *lflows) |
1887 | * - allow ACLs in which case the traffic should be allowed so we set |
1888 | * REGBIT_ACL_HINT_ALLOW. |
1889 | * - drop ACLs in which case the traffic should be blocked and the |
1890 | - * connection must be committed with ct_label.blocked set so we set |
1891 | + * connection must be committed with ct_mark.blocked set so we set |
1892 | * REGBIT_ACL_HINT_BLOCK. |
1893 | */ |
1894 | - ovn_lflow_add(lflows, od, stage, 4, |
1895 | - "!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0", |
1896 | + match = features->ct_no_masked_label |
1897 | + ? "!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0" |
1898 | + : "!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0"; |
1899 | + ovn_lflow_add(lflows, od, stage, 4, match, |
1900 | REGBIT_ACL_HINT_ALLOW " = 1; " |
1901 | REGBIT_ACL_HINT_BLOCK " = 1; " |
1902 | "next;"); |
1903 | @@ -6049,15 +6150,21 @@ build_acl_hints(struct ovn_datapath *od, struct hmap *lflows) |
1904 | ovn_lflow_add(lflows, od, stage, 3, "!ct.est", |
1905 | REGBIT_ACL_HINT_DROP " = 1; " |
1906 | "next;"); |
1907 | - ovn_lflow_add(lflows, od, stage, 2, "ct.est && ct_label.blocked == 1", |
1908 | + match = features->ct_no_masked_label |
1909 | + ? "ct.est && ct_mark.blocked == 1" |
1910 | + : "ct.est && ct_label.blocked == 1"; |
1911 | + ovn_lflow_add(lflows, od, stage, 2, match, |
1912 | REGBIT_ACL_HINT_DROP " = 1; " |
1913 | "next;"); |
1914 | |
1915 | /* Established connections that were previously allowed might hit |
1916 | * drop ACLs in which case the connection must be committed with |
1917 | - * ct_label.blocked set. |
1918 | + * ct_mark.blocked set. |
1919 | */ |
1920 | - ovn_lflow_add(lflows, od, stage, 1, "ct.est && ct_label.blocked == 0", |
1921 | + match = features->ct_no_masked_label |
1922 | + ? "ct.est && ct_mark.blocked == 0" |
1923 | + : "ct.est && ct_label.blocked == 0"; |
1924 | + ovn_lflow_add(lflows, od, stage, 1, match, |
1925 | REGBIT_ACL_HINT_BLOCK " = 1; " |
1926 | "next;"); |
1927 | } |
1928 | @@ -6183,10 +6290,13 @@ build_reject_acl_rules(struct ovn_datapath *od, struct hmap *lflows, |
1929 | |
1930 | static void |
1931 | consider_acl(struct hmap *lflows, struct ovn_datapath *od, |
1932 | - struct nbrec_acl *acl, bool has_stateful, |
1933 | + struct nbrec_acl *acl, bool has_stateful, bool ct_masked_mark, |
1934 | const struct shash *meter_groups, struct ds *match, |
1935 | struct ds *actions) |
1936 | { |
1937 | + const char *ct_blocked_match = ct_masked_mark |
1938 | + ? "ct_mark.blocked" |
1939 | + : "ct_label.blocked"; |
1940 | bool ingress = !strcmp(acl->direction, "from-lport") ? true :false; |
1941 | enum ovn_stage stage; |
1942 | |
1943 | @@ -6230,7 +6340,7 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, |
1944 | * It's also possible that a known connection was marked for |
1945 | * deletion after a policy was deleted, but the policy was |
1946 | * re-added while that connection is still known. We catch |
1947 | - * that case here and un-set ct_label.blocked (which will be done |
1948 | + * that case here and un-set ct_mark.blocked (which will be done |
1949 | * by ct_commit in the "stateful" stage) to indicate that the |
1950 | * connection should be allowed to resume. |
1951 | */ |
1952 | @@ -6281,6 +6391,12 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, |
1953 | * the ACL, then we need to ensure that the related and reply |
1954 | * traffic is logged, so we install a slightly higher-priority |
1955 | * flow that matches the ACL, allows the traffic, and logs it. |
1956 | + * |
1957 | + * Note: Matching the ct_label.label may prevent OVS flow HW |
1958 | + * offloading to work for some NICs because masked-access of |
1959 | + * ct_label is not supported on those NICs due to HW |
1960 | + * limitations. In such case the user may choose to avoid using the |
1961 | + * "log-related" option. |
1962 | */ |
1963 | bool log_related = smap_get_bool(&acl->options, "log-related", |
1964 | false); |
1965 | @@ -6295,10 +6411,10 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, |
1966 | ds_clear(actions); |
1967 | |
1968 | ds_put_format(match, "ct.est && !ct.rel && !ct.new%s && " |
1969 | - "ct.rpl && ct_label.blocked == 0 && " |
1970 | + "ct.rpl && %s == 0 && " |
1971 | "ct_label.label == %" PRId64, |
1972 | use_ct_inv_match ? " && !ct.inv" : "", |
1973 | - acl->label); |
1974 | + ct_blocked_match, acl->label); |
1975 | build_acl_log(actions, acl, meter_groups); |
1976 | ds_put_cstr(actions, "next;"); |
1977 | ovn_lflow_add_with_hint(lflows, od, log_related_stage, |
1978 | @@ -6308,10 +6424,10 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, |
1979 | |
1980 | ds_clear(match); |
1981 | ds_put_format(match, "!ct.est && ct.rel && !ct.new%s && " |
1982 | - "ct_label.blocked == 0 && " |
1983 | + "%s == 0 && " |
1984 | "ct_label.label == %" PRId64, |
1985 | use_ct_inv_match ? " && !ct.inv" : "", |
1986 | - acl->label); |
1987 | + ct_blocked_match, acl->label); |
1988 | ovn_lflow_add_with_hint(lflows, od, log_related_stage, |
1989 | UINT16_MAX - 2, |
1990 | ds_cstr(match), ds_cstr(actions), |
1991 | @@ -6343,11 +6459,11 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, |
1992 | ds_cstr(match), ds_cstr(actions), |
1993 | &acl->header_); |
1994 | } |
1995 | - /* For an existing connection without ct_label set, we've |
1996 | + /* For an existing connection without ct_mark.blocked set, we've |
1997 | * encountered a policy change. ACLs previously allowed |
1998 | * this connection and we committed the connection tracking |
1999 | * entry. Current policy says that we should drop this |
2000 | - * connection. First, we set bit 0 of ct_label to indicate |
2001 | + * connection. First, we set ct_mark.blocked to indicate |
2002 | * that this connection is set for deletion. By not |
2003 | * specifying "next;", we implicitly drop the packet after |
2004 | * updating conntrack state. We would normally defer |
2005 | @@ -6357,7 +6473,8 @@ consider_acl(struct hmap *lflows, struct ovn_datapath *od, |
2006 | ds_clear(match); |
2007 | ds_clear(actions); |
2008 | ds_put_cstr(match, REGBIT_ACL_HINT_BLOCK " == 1"); |
2009 | - ds_put_cstr(actions, "ct_commit { ct_label.blocked = 1; }; "); |
2010 | + ds_put_format(actions, "ct_commit { %s = 1; }; ", |
2011 | + ct_blocked_match); |
2012 | if (!strcmp(acl->action, "reject")) { |
2013 | build_reject_acl_rules(od, lflows, stage, acl, match, |
2014 | actions, &acl->header_, meter_groups); |
2015 | @@ -6419,6 +6536,72 @@ ovn_port_group_destroy(struct hmap *pgs, struct ovn_port_group *pg) |
2016 | } |
2017 | |
2018 | static void |
2019 | +copy_ra_to_sb(struct ovn_port *op, const char *address_mode); |
2020 | + |
2021 | +static void |
2022 | +ovn_update_ipv6_options(struct hmap *ports) |
2023 | +{ |
2024 | + struct ovn_port *op; |
2025 | + HMAP_FOR_EACH (op, key_node, ports) { |
2026 | + if (!op->nbrp || op->nbrp->peer || !op->peer) { |
2027 | + continue; |
2028 | + } |
2029 | + |
2030 | + if (!op->lrp_networks.n_ipv6_addrs) { |
2031 | + continue; |
2032 | + } |
2033 | + |
2034 | + struct smap options; |
2035 | + smap_clone(&options, &op->sb->options); |
2036 | + |
2037 | + /* enable IPv6 prefix delegation */ |
2038 | + bool prefix_delegation = smap_get_bool(&op->nbrp->options, |
2039 | + "prefix_delegation", false); |
2040 | + if (!lrport_is_enabled(op->nbrp)) { |
2041 | + prefix_delegation = false; |
2042 | + } |
2043 | + if (smap_get_bool(&options, "ipv6_prefix_delegation", |
2044 | + false) != prefix_delegation) { |
2045 | + smap_add(&options, "ipv6_prefix_delegation", |
2046 | + prefix_delegation ? "true" : "false"); |
2047 | + } |
2048 | + |
2049 | + bool ipv6_prefix = smap_get_bool(&op->nbrp->options, |
2050 | + "prefix", false); |
2051 | + if (!lrport_is_enabled(op->nbrp)) { |
2052 | + ipv6_prefix = false; |
2053 | + } |
2054 | + if (smap_get_bool(&options, "ipv6_prefix", false) != ipv6_prefix) { |
2055 | + smap_add(&options, "ipv6_prefix", |
2056 | + ipv6_prefix ? "true" : "false"); |
2057 | + } |
2058 | + sbrec_port_binding_set_options(op->sb, &options); |
2059 | + |
2060 | + smap_destroy(&options); |
2061 | + |
2062 | + const char *address_mode = smap_get( |
2063 | + &op->nbrp->ipv6_ra_configs, "address_mode"); |
2064 | + |
2065 | + if (!address_mode) { |
2066 | + continue; |
2067 | + } |
2068 | + if (strcmp(address_mode, "slaac") && |
2069 | + strcmp(address_mode, "dhcpv6_stateful") && |
2070 | + strcmp(address_mode, "dhcpv6_stateless")) { |
2071 | + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); |
2072 | + VLOG_WARN_RL(&rl, "Invalid address mode [%s] defined", |
2073 | + address_mode); |
2074 | + continue; |
2075 | + } |
2076 | + |
2077 | + if (smap_get_bool(&op->nbrp->ipv6_ra_configs, "send_periodic", |
2078 | + false)) { |
2079 | + copy_ra_to_sb(op, address_mode); |
2080 | + } |
2081 | + } |
2082 | +} |
2083 | + |
2084 | +static void |
2085 | build_port_group_lswitches(struct northd_input *input_data, |
2086 | struct hmap *pgs, |
2087 | struct hmap *ports) |
2088 | @@ -6459,10 +6642,14 @@ build_port_group_lswitches(struct northd_input *input_data, |
2089 | } |
2090 | |
2091 | static void |
2092 | -build_acls(struct ovn_datapath *od, struct hmap *lflows, |
2093 | - const struct hmap *port_groups, const struct shash *meter_groups) |
2094 | +build_acls(struct ovn_datapath *od, const struct chassis_features *features, |
2095 | + struct hmap *lflows, const struct hmap *port_groups, |
2096 | + const struct shash *meter_groups) |
2097 | { |
2098 | bool has_stateful = od->has_stateful_acl || od->has_lb_vip; |
2099 | + const char *ct_blocked_match = features->ct_no_masked_label |
2100 | + ? "ct_mark.blocked" |
2101 | + : "ct_label.blocked"; |
2102 | struct ds match = DS_EMPTY_INITIALIZER; |
2103 | struct ds actions = DS_EMPTY_INITIALIZER; |
2104 | |
2105 | @@ -6498,30 +6685,34 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows, |
2106 | * subsequent packets will hit the flow at priority 0 that just |
2107 | * uses "next;" |
2108 | * |
2109 | - * We also check for established connections that have ct_label.blocked |
2110 | + * We also check for established connections that have ct_mark.blocked |
2111 | * set on them. That's a connection that was disallowed, but is |
2112 | * now allowed by policy again since it hit this default-allow flow. |
2113 | - * We need to set ct_label.blocked=0 to let the connection continue, |
2114 | + * We need to set ct_mark.blocked=0 to let the connection continue, |
2115 | * which will be done by ct_commit() in the "stateful" stage. |
2116 | * Subsequent packets will hit the flow at priority 0 that just |
2117 | * uses "next;". */ |
2118 | + ds_clear(&match); |
2119 | + ds_put_format(&match, "ip && (!ct.est || (ct.est && %s == 1))", |
2120 | + ct_blocked_match); |
2121 | ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL, 1, |
2122 | - "ip && (!ct.est || (ct.est && ct_label.blocked == 1))", |
2123 | - REGBIT_CONNTRACK_COMMIT" = 1; next;"); |
2124 | + ds_cstr(&match), |
2125 | + REGBIT_CONNTRACK_COMMIT" = 1; next;"); |
2126 | ovn_lflow_add(lflows, od, S_SWITCH_OUT_ACL, 1, |
2127 | - "ip && (!ct.est || (ct.est && ct_label.blocked == 1))", |
2128 | - REGBIT_CONNTRACK_COMMIT" = 1; next;"); |
2129 | + ds_cstr(&match), |
2130 | + REGBIT_CONNTRACK_COMMIT" = 1; next;"); |
2131 | |
2132 | /* Ingress and Egress ACL Table (Priority 65532). |
2133 | * |
2134 | * Always drop traffic that's in an invalid state. Also drop |
2135 | * reply direction packets for connections that have been marked |
2136 | - * for deletion (bit 0 of ct_label is set). |
2137 | + * for deletion (ct_mark.blocked is set). |
2138 | * |
2139 | * This is enforced at a higher priority than ACLs can be defined. */ |
2140 | ds_clear(&match); |
2141 | - ds_put_format(&match, "%s(ct.est && ct.rpl && ct_label.blocked == 1)", |
2142 | - use_ct_inv_match ? "ct.inv || " : ""); |
2143 | + ds_put_format(&match, "%s(ct.est && ct.rpl && %s == 1)", |
2144 | + use_ct_inv_match ? "ct.inv || " : "", |
2145 | + ct_blocked_match); |
2146 | ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL, UINT16_MAX - 3, |
2147 | ds_cstr(&match), "drop;"); |
2148 | ovn_lflow_add(lflows, od, S_SWITCH_OUT_ACL, UINT16_MAX - 3, |
2149 | @@ -6531,15 +6722,16 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows, |
2150 | * |
2151 | * Allow reply traffic that is part of an established |
2152 | * conntrack entry that has not been marked for deletion |
2153 | - * (bit 0 of ct_label). We only match traffic in the |
2154 | + * (ct_mark.blocked). We only match traffic in the |
2155 | * reply direction because we want traffic in the request |
2156 | * direction to hit the currently defined policy from ACLs. |
2157 | * |
2158 | * This is enforced at a higher priority than ACLs can be defined. */ |
2159 | ds_clear(&match); |
2160 | ds_put_format(&match, "ct.est && !ct.rel && !ct.new%s && " |
2161 | - "ct.rpl && ct_label.blocked == 0", |
2162 | - use_ct_inv_match ? " && !ct.inv" : ""); |
2163 | + "ct.rpl && %s == 0", |
2164 | + use_ct_inv_match ? " && !ct.inv" : "", |
2165 | + ct_blocked_match); |
2166 | ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL, UINT16_MAX - 3, |
2167 | ds_cstr(&match), REGBIT_ACL_HINT_DROP" = 0; " |
2168 | REGBIT_ACL_HINT_BLOCK" = 0; next;"); |
2169 | @@ -6549,7 +6741,7 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows, |
2170 | /* Ingress and Egress ACL Table (Priority 65535). |
2171 | * |
2172 | * Allow traffic that is related to an existing conntrack entry that |
2173 | - * has not been marked for deletion (bit 0 of ct_label). |
2174 | + * has not been marked for deletion (ct_mark.blocked). |
2175 | * |
2176 | * This is enforced at a higher priority than ACLs can be defined. |
2177 | * |
2178 | @@ -6558,9 +6750,9 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows, |
2179 | * related traffic such as an ICMP Port Unreachable through |
2180 | * that's generated from a non-listening UDP port. */ |
2181 | ds_clear(&match); |
2182 | - ds_put_format(&match, "!ct.est && ct.rel && !ct.new%s && " |
2183 | - "ct_label.blocked == 0", |
2184 | - use_ct_inv_match ? " && !ct.inv" : ""); |
2185 | + ds_put_format(&match, "!ct.est && ct.rel && !ct.new%s && %s == 0", |
2186 | + use_ct_inv_match ? " && !ct.inv" : "", |
2187 | + ct_blocked_match); |
2188 | ovn_lflow_add(lflows, od, S_SWITCH_IN_ACL, UINT16_MAX - 3, |
2189 | ds_cstr(&match), "next;"); |
2190 | ovn_lflow_add(lflows, od, S_SWITCH_OUT_ACL, UINT16_MAX - 3, |
2191 | @@ -6578,14 +6770,16 @@ build_acls(struct ovn_datapath *od, struct hmap *lflows, |
2192 | /* Ingress or Egress ACL Table (Various priorities). */ |
2193 | for (size_t i = 0; i < od->nbs->n_acls; i++) { |
2194 | struct nbrec_acl *acl = od->nbs->acls[i]; |
2195 | - consider_acl(lflows, od, acl, has_stateful, meter_groups, &match, |
2196 | - &actions); |
2197 | + consider_acl(lflows, od, acl, has_stateful, |
2198 | + features->ct_no_masked_label, |
2199 | + meter_groups, &match, &actions); |
2200 | } |
2201 | struct ovn_port_group *pg; |
2202 | HMAP_FOR_EACH (pg, key_node, port_groups) { |
2203 | if (ovn_port_group_ls_find(pg, &od->nbs->header_.uuid)) { |
2204 | for (size_t i = 0; i < pg->nb_pg->n_acls; i++) { |
2205 | consider_acl(lflows, od, pg->nb_pg->acls[i], has_stateful, |
2206 | + features->ct_no_masked_label, |
2207 | meter_groups, &match, &actions); |
2208 | } |
2209 | } |
2210 | @@ -6737,7 +6931,7 @@ build_qos(struct ovn_datapath *od, struct hmap *lflows) { |
2211 | } |
2212 | |
2213 | static void |
2214 | -build_lb_rules(struct hmap *lflows, struct ovn_northd_lb *lb, |
2215 | +build_lb_rules(struct hmap *lflows, struct ovn_northd_lb *lb, bool ct_lb_mark, |
2216 | struct ds *match, struct ds *action, |
2217 | const struct shash *meter_groups) |
2218 | { |
2219 | @@ -6787,7 +6981,8 @@ build_lb_rules(struct hmap *lflows, struct ovn_northd_lb *lb, |
2220 | /* New connections in Ingress table. */ |
2221 | const char *meter = NULL; |
2222 | bool reject = build_lb_vip_actions(lb_vip, lb_vip_nb, action, |
2223 | - lb->selection_fields, true); |
2224 | + lb->selection_fields, true, |
2225 | + ct_lb_mark); |
2226 | |
2227 | ds_put_format(match, "ct.new && %s.dst == %s", ip_match, |
2228 | lb_vip->vip_str); |
2229 | @@ -6809,21 +7004,29 @@ build_lb_rules(struct hmap *lflows, struct ovn_northd_lb *lb, |
2230 | if (reject) { |
2231 | meter = copp_meter_get(COPP_REJECT, od->nbs->copp, |
2232 | meter_groups); |
2233 | - } else if (ovn_dp_group_add_with_reference(lflow_ref, od)) { |
2234 | - continue; |
2235 | } |
2236 | - lflow_ref = ovn_lflow_add_at_with_hash(lflows, od, |
2237 | - S_SWITCH_IN_LB, priority, |
2238 | - ds_cstr(match), ds_cstr(action), |
2239 | - NULL, meter, &lb->nlb->header_, |
2240 | - OVS_SOURCE_LOCATOR, hash); |
2241 | + if (meter || !ovn_dp_group_add_with_reference(lflow_ref, od)) { |
2242 | + struct ovn_lflow *lflow = ovn_lflow_add_at_with_hash( |
2243 | + lflows, od, S_SWITCH_IN_LB, priority, |
2244 | + ds_cstr(match), ds_cstr(action), |
2245 | + NULL, meter, &lb->nlb->header_, |
2246 | + OVS_SOURCE_LOCATOR, hash); |
2247 | + lflow_ref = meter ? NULL : lflow; |
2248 | + } |
2249 | } |
2250 | } |
2251 | } |
2252 | |
2253 | static void |
2254 | -build_stateful(struct ovn_datapath *od, struct hmap *lflows) |
2255 | +build_stateful(struct ovn_datapath *od, |
2256 | + const struct chassis_features *features, |
2257 | + struct hmap *lflows) |
2258 | { |
2259 | + const char *ct_block_action = features->ct_no_masked_label |
2260 | + ? "ct_mark.blocked" |
2261 | + : "ct_label.blocked"; |
2262 | + struct ds actions = DS_EMPTY_INITIALIZER; |
2263 | + |
2264 | /* Ingress LB, Ingress and Egress stateful Table (Priority 0): Packets are |
2265 | * allowed by default. */ |
2266 | ovn_lflow_add(lflows, od, S_SWITCH_IN_LB, 0, "1", "next;"); |
2267 | @@ -6836,29 +7039,33 @@ build_stateful(struct ovn_datapath *od, struct hmap *lflows) |
2268 | * We always set ct_mark.blocked to 0 here as |
2269 | * any packet that makes it this far is part of a connection we |
2270 | * want to allow to continue. */ |
2271 | + ds_put_format(&actions, "ct_commit { %s = 0; " |
2272 | + "ct_label.label = " REG_LABEL "; }; next;", |
2273 | + ct_block_action); |
2274 | ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 100, |
2275 | REGBIT_CONNTRACK_COMMIT" == 1 && " |
2276 | REGBIT_ACL_LABEL" == 1", |
2277 | - "ct_commit { ct_label.blocked = 0; " |
2278 | - "ct_label.label = " REG_LABEL "; }; next;"); |
2279 | + ds_cstr(&actions)); |
2280 | ovn_lflow_add(lflows, od, S_SWITCH_OUT_STATEFUL, 100, |
2281 | REGBIT_CONNTRACK_COMMIT" == 1 && " |
2282 | REGBIT_ACL_LABEL" == 1", |
2283 | - "ct_commit { ct_label.blocked = 0; " |
2284 | - "ct_label.label = " REG_LABEL "; }; next;"); |
2285 | + ds_cstr(&actions)); |
2286 | |
2287 | /* If REGBIT_CONNTRACK_COMMIT is set as 1, then the packets should be |
2288 | - * committed to conntrack. We always set ct_label.blocked to 0 here as |
2289 | + * committed to conntrack. We always set ct_mark.blocked to 0 here as |
2290 | * any packet that makes it this far is part of a connection we |
2291 | * want to allow to continue. */ |
2292 | + ds_clear(&actions); |
2293 | + ds_put_format(&actions, "ct_commit { %s = 0; }; next;", ct_block_action); |
2294 | ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 100, |
2295 | REGBIT_CONNTRACK_COMMIT" == 1 && " |
2296 | REGBIT_ACL_LABEL" == 0", |
2297 | - "ct_commit { ct_label.blocked = 0; }; next;"); |
2298 | + ds_cstr(&actions)); |
2299 | ovn_lflow_add(lflows, od, S_SWITCH_OUT_STATEFUL, 100, |
2300 | REGBIT_CONNTRACK_COMMIT" == 1 && " |
2301 | REGBIT_ACL_LABEL" == 0", |
2302 | - "ct_commit { ct_label.blocked = 0; }; next;"); |
2303 | + ds_cstr(&actions)); |
2304 | + ds_destroy(&actions); |
2305 | } |
2306 | |
2307 | static void |
2308 | @@ -7596,6 +7803,7 @@ build_lswitch_flows(const struct hmap *datapaths, |
2309 | static void |
2310 | build_lswitch_lflows_pre_acl_and_acl(struct ovn_datapath *od, |
2311 | const struct hmap *port_groups, |
2312 | + const struct chassis_features *features, |
2313 | struct hmap *lflows, |
2314 | const struct shash *meter_groups) |
2315 | { |
2316 | @@ -7604,11 +7812,11 @@ build_lswitch_lflows_pre_acl_and_acl(struct ovn_datapath *od, |
2317 | |
2318 | build_pre_acls(od, port_groups, lflows); |
2319 | build_pre_lb(od, lflows); |
2320 | - build_pre_stateful(od, lflows); |
2321 | - build_acl_hints(od, lflows); |
2322 | - build_acls(od, lflows, port_groups, meter_groups); |
2323 | + build_pre_stateful(od, features, lflows); |
2324 | + build_acl_hints(od, features, lflows); |
2325 | + build_acls(od, features, lflows, port_groups, meter_groups); |
2326 | build_qos(od, lflows); |
2327 | - build_stateful(od, lflows); |
2328 | + build_stateful(od, features, lflows); |
2329 | build_lb_hairpin(od, lflows); |
2330 | } |
2331 | } |
2332 | @@ -9303,6 +9511,7 @@ find_static_route_outport(struct ovn_datapath *od, const struct hmap *ports, |
2333 | static void |
2334 | add_ecmp_symmetric_reply_flows(struct hmap *lflows, |
2335 | struct ovn_datapath *od, |
2336 | + bool ct_masked_mark, |
2337 | const char *port_ip, |
2338 | struct ovn_port *out_port, |
2339 | const struct parsed_route *route, |
2340 | @@ -9313,6 +9522,9 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows, |
2341 | struct ds actions = DS_EMPTY_INITIALIZER; |
2342 | struct ds ecmp_reply = DS_EMPTY_INITIALIZER; |
2343 | char *cidr = normalize_v46_prefix(&route->prefix, route->plen); |
2344 | + const char *ct_ecmp_reply_port_match = ct_masked_mark |
2345 | + ? "ct_mark.ecmp_reply_port" |
2346 | + : "ct_label.ecmp_reply_port"; |
2347 | |
2348 | /* If symmetric ECMP replies are enabled, then packets that arrive over |
2349 | * an ECMP route need to go through conntrack. |
2350 | @@ -9341,8 +9553,8 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows, |
2351 | ds_put_cstr(&match, " && (ct.new && !ct.est)"); |
2352 | |
2353 | ds_put_format(&actions, "ct_commit { ct_label.ecmp_reply_eth = eth.src;" |
2354 | - " ct_label.ecmp_reply_port = %" PRId64 ";}; next;", |
2355 | - out_port->sb->tunnel_key); |
2356 | + " %s = %" PRId64 ";}; next;", |
2357 | + ct_ecmp_reply_port_match, out_port->sb->tunnel_key); |
2358 | ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ECMP_STATEFUL, 100, |
2359 | ds_cstr(&match), ds_cstr(&actions), |
2360 | &st_route->header_); |
2361 | @@ -9350,8 +9562,8 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows, |
2362 | /* Bypass ECMP selection if we already have ct_label information |
2363 | * for where to route the packet. |
2364 | */ |
2365 | - ds_put_format(&ecmp_reply, "ct.rpl && ct_label.ecmp_reply_port == %" |
2366 | - PRId64, out_port->sb->tunnel_key); |
2367 | + ds_put_format(&ecmp_reply, "ct.rpl && %s == %"PRId64, |
2368 | + ct_ecmp_reply_port_match, out_port->sb->tunnel_key); |
2369 | ds_clear(&match); |
2370 | ds_put_format(&match, "%s && %s", ds_cstr(&ecmp_reply), |
2371 | ds_cstr(route_match)); |
2372 | @@ -9370,7 +9582,18 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows, |
2373 | ds_cstr(&ecmp_reply), "next;", |
2374 | &st_route->header_); |
2375 | |
2376 | - const char *action = "eth.dst = ct_label.ecmp_reply_eth; next;"; |
2377 | + /* Use REG_ECMP_ETH_FULL to pass the eth field from ct_label to eth.dst to |
2378 | + * avoid masked access to ct_label. Otherwise it may prevent OVS flow |
2379 | + * HW offloading to work for some NICs because masked-access of ct_label is |
2380 | + * not supported on those NICs due to HW limitations. |
2381 | + * |
2382 | + * Use push/pop to save the value of the register before using it and |
2383 | + * restore it immediately afterwards, so that the use of the register is |
2384 | + * temporary and doesn't interfere with other stages. */ |
2385 | + const char *action = "push(" REG_ECMP_ETH_FULL "); " |
2386 | + REG_ECMP_ETH_FULL " = ct_label;" |
2387 | + " eth.dst = " REG_ECMP_ETH_FIELD ";" |
2388 | + " pop(" REG_ECMP_ETH_FULL "); next;"; |
2389 | ovn_lflow_add_with_hint(lflows, od, S_ROUTER_IN_ARP_RESOLVE, |
2390 | 200, ds_cstr(&ecmp_reply), |
2391 | action, &st_route->header_); |
2392 | @@ -9382,7 +9605,8 @@ add_ecmp_symmetric_reply_flows(struct hmap *lflows, |
2393 | |
2394 | static void |
2395 | build_ecmp_route_flow(struct hmap *lflows, struct ovn_datapath *od, |
2396 | - const struct hmap *ports, struct ecmp_groups_node *eg) |
2397 | + bool ct_masked_mark, const struct hmap *ports, |
2398 | + struct ecmp_groups_node *eg) |
2399 | |
2400 | { |
2401 | bool is_ipv4 = IN6_IS_ADDR_V4MAPPED(&eg->prefix); |
2402 | @@ -9436,7 +9660,8 @@ build_ecmp_route_flow(struct hmap *lflows, struct ovn_datapath *od, |
2403 | if (smap_get(&od->nbr->options, "chassis") && |
2404 | route_->ecmp_symmetric_reply && sset_add(&visited_ports, |
2405 | out_port->key)) { |
2406 | - add_ecmp_symmetric_reply_flows(lflows, od, lrp_addr_s, out_port, |
2407 | + add_ecmp_symmetric_reply_flows(lflows, od, ct_masked_mark, |
2408 | + lrp_addr_s, out_port, |
2409 | route_, &route_match); |
2410 | } |
2411 | ds_clear(&match); |
2412 | @@ -9631,8 +9856,10 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip, |
2413 | struct ovn_northd_lb_vip *vips_nb, |
2414 | struct hmap *lflows, |
2415 | struct ds *match, struct ds *action, |
2416 | - const struct shash *meter_groups) |
2417 | + const struct shash *meter_groups, |
2418 | + bool ct_lb_mark) |
2419 | { |
2420 | + const char *ct_natted = ct_lb_mark ? "ct_mark.natted" : "ct_label.natted"; |
2421 | char *skip_snat_new_action = NULL; |
2422 | char *skip_snat_est_action = NULL; |
2423 | char *new_match; |
2424 | @@ -9642,12 +9869,13 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip, |
2425 | ds_clear(action); |
2426 | |
2427 | bool reject = build_lb_vip_actions(lb_vip, vips_nb, action, |
2428 | - lb->selection_fields, false); |
2429 | + lb->selection_fields, false, |
2430 | + ct_lb_mark); |
2431 | |
2432 | /* Higher priority rules are added for load-balancing in DNAT |
2433 | * table. For every match (on a VIP[:port]), we add two flows. |
2434 | * One flow is for specific matching on ct.new with an action |
2435 | - * of "ct_lb($targets);". The other flow is for ct.est with |
2436 | + * of "ct_lb_mark($targets);". The other flow is for ct.est with |
2437 | * an action of "next;". |
2438 | */ |
2439 | if (IN6_IS_ADDR_V4MAPPED(&lb_vip->vip)) { |
2440 | @@ -9674,13 +9902,13 @@ build_lrouter_nat_flows_for_lb(struct ovn_lb_vip *lb_vip, |
2441 | REG_ORIG_TP_DPORT_ROUTER" == %d", |
2442 | ds_cstr(match), lb->proto, lb_vip->vip_port); |
2443 | est_match = xasprintf("ct.est && %s && %s && " |
2444 | - REG_ORIG_TP_DPORT_ROUTER" == %d && " |
2445 | - "ct_label.natted == 1", |
2446 | - ds_cstr(match), lb->proto, lb_vip->vip_port); |
2447 | + REG_ORIG_TP_DPORT_ROUTER" == %d && %s == 1", |
2448 | + ds_cstr(match), lb->proto, lb_vip->vip_port, |
2449 | + ct_natted); |
2450 | } else { |
2451 | new_match = xasprintf("ct.new && %s", ds_cstr(match)); |
2452 | - est_match = xasprintf("ct.est && %s && ct_label.natted == 1", |
2453 | - ds_cstr(match)); |
2454 | + est_match = xasprintf("ct.est && %s && %s == 1", |
2455 | + ds_cstr(match), ct_natted); |
2456 | } |
2457 | |
2458 | const char *ip_match = NULL; |
2459 | @@ -9841,8 +10069,9 @@ next: |
2460 | |
2461 | static void |
2462 | build_lswitch_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows, |
2463 | - const struct shash *meter_groups, struct ds *match, |
2464 | - struct ds *action) |
2465 | + const struct shash *meter_groups, |
2466 | + const struct chassis_features *features, |
2467 | + struct ds *match, struct ds *action) |
2468 | { |
2469 | if (!lb->n_nb_ls) { |
2470 | return; |
2471 | @@ -9878,7 +10107,8 @@ build_lswitch_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows, |
2472 | * a higher priority rule for load balancing below also commits the |
2473 | * connection, so it is okay if we do not hit the above match on |
2474 | * REGBIT_CONNTRACK_COMMIT. */ |
2475 | - build_lb_rules(lflows, lb, match, action, meter_groups); |
2476 | + build_lb_rules(lflows, lb, features->ct_no_masked_label, |
2477 | + match, action, meter_groups); |
2478 | } |
2479 | |
2480 | /* If there are any load balancing rules, we should send the packet to |
2481 | @@ -9948,8 +10178,9 @@ build_lrouter_defrag_flows_for_lb(struct ovn_northd_lb *lb, |
2482 | |
2483 | static void |
2484 | build_lrouter_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows, |
2485 | - const struct shash *meter_groups, struct ds *match, |
2486 | - struct ds *action) |
2487 | + const struct shash *meter_groups, |
2488 | + const struct chassis_features *features, |
2489 | + struct ds *match, struct ds *action) |
2490 | { |
2491 | if (!lb->n_nb_lr) { |
2492 | return; |
2493 | @@ -9959,8 +10190,8 @@ build_lrouter_flows_for_lb(struct ovn_northd_lb *lb, struct hmap *lflows, |
2494 | struct ovn_lb_vip *lb_vip = &lb->vips[i]; |
2495 | |
2496 | build_lrouter_nat_flows_for_lb(lb_vip, lb, &lb->vips_nb[i], |
2497 | - lflows, match, action, |
2498 | - meter_groups); |
2499 | + lflows, match, action, meter_groups, |
2500 | + features->ct_no_masked_label); |
2501 | |
2502 | if (!build_empty_lb_event_flow(lb_vip, lb->nlb, match, action)) { |
2503 | continue; |
2504 | @@ -10100,7 +10331,7 @@ static inline void |
2505 | lrouter_nat_add_ext_ip_match(struct ovn_datapath *od, |
2506 | struct hmap *lflows, struct ds *match, |
2507 | const struct nbrec_nat *nat, |
2508 | - bool is_v6, bool is_src, ovs_be32 mask) |
2509 | + bool is_v6, bool is_src, int cidr_bits) |
2510 | { |
2511 | struct nbrec_address_set *allowed_ext_ips = nat->allowed_ext_ips; |
2512 | struct nbrec_address_set *exempted_ext_ips = nat->exempted_ext_ips; |
2513 | @@ -10136,7 +10367,7 @@ lrouter_nat_add_ext_ip_match(struct ovn_datapath *od, |
2514 | priority = 100 + 2; |
2515 | } else { |
2516 | /* S_ROUTER_OUT_SNAT uses priority (mask + 1 + 128 + 1) */ |
2517 | - priority = count_1bits(ntohl(mask)) + 3; |
2518 | + priority = cidr_bits + 3; |
2519 | |
2520 | if (!od->is_gw_router) { |
2521 | priority += 128; |
2522 | @@ -10576,6 +10807,28 @@ build_adm_ctrl_flows_for_lrouter( |
2523 | } |
2524 | } |
2525 | |
2526 | +static int |
2527 | +build_gateway_get_l2_hdr_size(struct ovn_port *op) |
2528 | +{ |
2529 | + struct ovn_port *peer = op->peer; |
2530 | + |
2531 | + if (peer && peer->od && peer->od->nbs) { |
2532 | + /* Check if vlans are enabled on a localnet port running the logical |
2533 | + * switch connected to this logical router. |
2534 | + */ |
2535 | + for (size_t i = 0; i < peer->od->n_localnet_ports; i++) { |
2536 | + struct ovn_port *localnet_port = peer->od->localnet_ports[i]; |
2537 | + const struct nbrec_logical_switch_port *nbsp = localnet_port->nbsp; |
2538 | + |
2539 | + if (nbsp && nbsp->n_tag_request > 0) { |
2540 | + return VLAN_ETH_HEADER_LEN; |
2541 | + } |
2542 | + } |
2543 | + } |
2544 | + |
2545 | + return ETH_HEADER_LEN; |
2546 | +} |
2547 | + |
2548 | /* All 'gateway_mtu' and 'gateway_mtu_bypass' flows should be built with this |
2549 | * function. |
2550 | */ |
2551 | @@ -10593,8 +10846,9 @@ build_gateway_mtu_flow(struct hmap *lflows, struct ovn_port *op, |
2552 | |
2553 | ds_clear(actions); |
2554 | if (gw_mtu > 0) { |
2555 | + int l2_hdr_size = build_gateway_get_l2_hdr_size(op); |
2556 | ds_put_format(actions, REGBIT_PKT_LARGER" = check_pkt_larger(%d); ", |
2557 | - gw_mtu + VLAN_ETH_HEADER_LEN); |
2558 | + gw_mtu + l2_hdr_size); |
2559 | } |
2560 | |
2561 | ds_put_format_valist(actions, extra_actions_fmt, extra_actions_args); |
2562 | @@ -10759,6 +11013,12 @@ build_neigh_learning_flows_for_lrouter( |
2563 | copp_meter_get(COPP_ARP, od->nbr->copp, |
2564 | meter_groups)); |
2565 | |
2566 | + ovn_lflow_metered(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 95, |
2567 | + "nd_na && nd.tll == 0", |
2568 | + "put_nd(inport, nd.target, eth.src); next;", |
2569 | + copp_meter_get(COPP_ND_NA, od->nbr->copp, |
2570 | + meter_groups)); |
2571 | + |
2572 | ovn_lflow_metered(lflows, od, S_ROUTER_IN_LEARN_NEIGHBOR, 90, |
2573 | "nd_na", "put_nd(inport, nd.target, nd.tll); next;", |
2574 | copp_meter_get(COPP_ND_NA, od->nbr->copp, |
2575 | @@ -10851,34 +11111,6 @@ build_ND_RA_flows_for_lrouter_port( |
2576 | return; |
2577 | } |
2578 | |
2579 | - struct smap options; |
2580 | - smap_clone(&options, &op->sb->options); |
2581 | - |
2582 | - /* enable IPv6 prefix delegation */ |
2583 | - bool prefix_delegation = smap_get_bool(&op->nbrp->options, |
2584 | - "prefix_delegation", false); |
2585 | - if (!lrport_is_enabled(op->nbrp)) { |
2586 | - prefix_delegation = false; |
2587 | - } |
2588 | - if (smap_get_bool(&options, "ipv6_prefix_delegation", |
2589 | - false) != prefix_delegation) { |
2590 | - smap_add(&options, "ipv6_prefix_delegation", |
2591 | - prefix_delegation ? "true" : "false"); |
2592 | - } |
2593 | - |
2594 | - bool ipv6_prefix = smap_get_bool(&op->nbrp->options, |
2595 | - "prefix", false); |
2596 | - if (!lrport_is_enabled(op->nbrp)) { |
2597 | - ipv6_prefix = false; |
2598 | - } |
2599 | - if (smap_get_bool(&options, "ipv6_prefix", false) != ipv6_prefix) { |
2600 | - smap_add(&options, "ipv6_prefix", |
2601 | - ipv6_prefix ? "true" : "false"); |
2602 | - } |
2603 | - sbrec_port_binding_set_options(op->sb, &options); |
2604 | - |
2605 | - smap_destroy(&options); |
2606 | - |
2607 | const char *address_mode = smap_get( |
2608 | &op->nbrp->ipv6_ra_configs, "address_mode"); |
2609 | |
2610 | @@ -10894,11 +11126,6 @@ build_ND_RA_flows_for_lrouter_port( |
2611 | return; |
2612 | } |
2613 | |
2614 | - if (smap_get_bool(&op->nbrp->ipv6_ra_configs, "send_periodic", |
2615 | - false)) { |
2616 | - copy_ra_to_sb(op, address_mode); |
2617 | - } |
2618 | - |
2619 | ds_clear(match); |
2620 | ds_put_format(match, "inport == %s && ip6.dst == ff02::2 && nd_rs", |
2621 | op->json_key); |
2622 | @@ -11072,8 +11299,9 @@ build_ip_routing_flows_for_lrouter_port( |
2623 | |
2624 | static void |
2625 | build_static_route_flows_for_lrouter( |
2626 | - struct ovn_datapath *od, struct hmap *lflows, |
2627 | - const struct hmap *ports, const struct hmap *bfd_connections) |
2628 | + struct ovn_datapath *od, const struct chassis_features *features, |
2629 | + struct hmap *lflows, const struct hmap *ports, |
2630 | + const struct hmap *bfd_connections) |
2631 | { |
2632 | if (od->nbr) { |
2633 | ovn_lflow_add(lflows, od, S_ROUTER_IN_IP_ROUTING_ECMP, 150, |
2634 | @@ -11116,7 +11344,8 @@ build_static_route_flows_for_lrouter( |
2635 | HMAP_FOR_EACH (group, hmap_node, &ecmp_groups) { |
2636 | /* add a flow in IP_ROUTING, and one flow for each member in |
2637 | * IP_ROUTING_ECMP. */ |
2638 | - build_ecmp_route_flow(lflows, od, ports, group); |
2639 | + build_ecmp_route_flow(lflows, od, features->ct_no_masked_label, |
2640 | + ports, group); |
2641 | } |
2642 | const struct unique_routes_node *ur; |
2643 | HMAP_FOR_EACH (ur, hmap_node, &unique_routes) { |
2644 | @@ -11815,6 +12044,23 @@ build_gateway_redirect_flows_for_lrouter( |
2645 | ds_cstr(match), ds_cstr(actions), |
2646 | stage_hint); |
2647 | } |
2648 | + |
2649 | + for (int i = 0; i < od->n_nat_entries; i++) { |
2650 | + const struct ovn_nat *nat = &od->nat_entries[i]; |
2651 | + |
2652 | + if (!lrouter_nat_is_stateless(nat->nb) || |
2653 | + strcmp(nat->nb->type, "dnat_and_snat")) { |
2654 | + continue; |
2655 | + } |
2656 | + |
2657 | + ds_clear(match); |
2658 | + ds_put_format(match, "ip && ip%s.dst == %s", |
2659 | + nat_entry_is_v6(nat) ? "6" : "4", |
2660 | + nat->nb->external_ip); |
2661 | + ovn_lflow_add(lflows, od, S_ROUTER_IN_GW_REDIRECT, 100, |
2662 | + ds_cstr(match), "drop;"); |
2663 | + } |
2664 | + |
2665 | /* Packets are allowed by default. */ |
2666 | ovn_lflow_add(lflows, od, S_ROUTER_IN_GW_REDIRECT, 0, "1", "next;"); |
2667 | } |
2668 | @@ -12553,8 +12799,7 @@ build_lrouter_in_unsnat_flow(struct hmap *lflows, struct ovn_datapath *od, |
2669 | ds_put_format(match, "ip && ip%s.dst == %s", |
2670 | is_v6 ? "6" : "4", nat->external_ip); |
2671 | if (!strcmp(nat->type, "dnat_and_snat") && stateless) { |
2672 | - ds_put_format(actions, "ip%s.dst=%s; next;", |
2673 | - is_v6 ? "6" : "4", nat->logical_ip); |
2674 | + ds_put_format(actions, "next;"); |
2675 | } else { |
2676 | ds_put_cstr(actions, "ct_snat;"); |
2677 | } |
2678 | @@ -12579,8 +12824,7 @@ build_lrouter_in_unsnat_flow(struct hmap *lflows, struct ovn_datapath *od, |
2679 | } |
2680 | |
2681 | if (!strcmp(nat->type, "dnat_and_snat") && stateless) { |
2682 | - ds_put_format(actions, "ip%s.dst=%s; next;", |
2683 | - is_v6 ? "6" : "4", nat->logical_ip); |
2684 | + ds_put_format(actions, "next;"); |
2685 | } else { |
2686 | ds_put_cstr(actions, "ct_snat_in_czone;"); |
2687 | } |
2688 | @@ -12614,7 +12858,7 @@ static void |
2689 | build_lrouter_in_dnat_flow(struct hmap *lflows, struct ovn_datapath *od, |
2690 | const struct nbrec_nat *nat, struct ds *match, |
2691 | struct ds *actions, bool distributed, |
2692 | - ovs_be32 mask, bool is_v6) |
2693 | + int cidr_bits, bool is_v6) |
2694 | { |
2695 | /* Ingress DNAT table: Packets enter the pipeline with destination |
2696 | * IP address that needs to be DNATted from a external IP address |
2697 | @@ -12632,7 +12876,7 @@ build_lrouter_in_dnat_flow(struct hmap *lflows, struct ovn_datapath *od, |
2698 | ds_clear(actions); |
2699 | if (nat->allowed_ext_ips || nat->exempted_ext_ips) { |
2700 | lrouter_nat_add_ext_ip_match(od, lflows, match, nat, |
2701 | - is_v6, true, mask); |
2702 | + is_v6, true, cidr_bits); |
2703 | } |
2704 | |
2705 | if (!lport_addresses_is_empty(&od->dnat_force_snat_addrs)) { |
2706 | @@ -12676,7 +12920,7 @@ build_lrouter_in_dnat_flow(struct hmap *lflows, struct ovn_datapath *od, |
2707 | ds_clear(actions); |
2708 | if (nat->allowed_ext_ips || nat->exempted_ext_ips) { |
2709 | lrouter_nat_add_ext_ip_match(od, lflows, match, nat, |
2710 | - is_v6, true, mask); |
2711 | + is_v6, true, cidr_bits); |
2712 | } |
2713 | |
2714 | if (!strcmp(nat->type, "dnat_and_snat") && stateless) { |
2715 | @@ -12733,8 +12977,7 @@ build_lrouter_out_undnat_flow(struct hmap *lflows, struct ovn_datapath *od, |
2716 | |
2717 | if (!strcmp(nat->type, "dnat_and_snat") && |
2718 | lrouter_nat_is_stateless(nat)) { |
2719 | - ds_put_format(actions, "ip%s.src=%s; next;", |
2720 | - is_v6 ? "6" : "4", nat->external_ip); |
2721 | + ds_put_format(actions, "next;"); |
2722 | } else { |
2723 | ds_put_format(actions, |
2724 | od->is_gw_router ? "ct_dnat;" : "ct_dnat_in_czone;"); |
2725 | @@ -12779,8 +13022,7 @@ static void |
2726 | build_lrouter_out_snat_flow(struct hmap *lflows, struct ovn_datapath *od, |
2727 | const struct nbrec_nat *nat, struct ds *match, |
2728 | struct ds *actions, bool distributed, |
2729 | - struct eth_addr mac, ovs_be32 mask, |
2730 | - int cidr_bits, bool is_v6) |
2731 | + struct eth_addr mac, int cidr_bits, bool is_v6) |
2732 | { |
2733 | /* Egress SNAT table: Packets enter the egress pipeline with |
2734 | * source ip address that needs to be SNATted to a external ip |
2735 | @@ -12798,13 +13040,14 @@ build_lrouter_out_snat_flow(struct hmap *lflows, struct ovn_datapath *od, |
2736 | |
2737 | if (nat->allowed_ext_ips || nat->exempted_ext_ips) { |
2738 | lrouter_nat_add_ext_ip_match(od, lflows, match, nat, |
2739 | - is_v6, false, mask); |
2740 | + is_v6, false, cidr_bits); |
2741 | } |
2742 | |
2743 | if (!strcmp(nat->type, "dnat_and_snat") && stateless) { |
2744 | ds_put_format(actions, "ip%s.src=%s; next;", |
2745 | is_v6 ? "6" : "4", nat->external_ip); |
2746 | } else { |
2747 | + ds_put_format(match, " && (!ct.trk || !ct.rpl)"); |
2748 | ds_put_format(actions, "ct_snat(%s", nat->external_ip); |
2749 | |
2750 | if (nat->external_port_range[0]) { |
2751 | @@ -12846,7 +13089,7 @@ build_lrouter_out_snat_flow(struct hmap *lflows, struct ovn_datapath *od, |
2752 | |
2753 | if (nat->allowed_ext_ips || nat->exempted_ext_ips) { |
2754 | lrouter_nat_add_ext_ip_match(od, lflows, match, nat, |
2755 | - is_v6, false, mask); |
2756 | + is_v6, false, cidr_bits); |
2757 | } |
2758 | |
2759 | if (distributed) { |
2760 | @@ -13155,6 +13398,18 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows, |
2761 | return; |
2762 | } |
2763 | |
2764 | + /* NAT rules are not currently supported on logical routers with multiple |
2765 | + * distributed gateway ports. */ |
2766 | + if (od->n_l3dgw_ports > 1) { |
2767 | + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); |
2768 | + VLOG_WARN_RL(&rl, "NAT is configured on logical router %s, which has %" |
2769 | + PRIuSIZE" distributed gateway ports. NAT is not supported" |
2770 | + " yet when there is more than one distributed gateway " |
2771 | + "port on the router.", |
2772 | + od->nbr->name, od->n_l3dgw_ports); |
2773 | + return; |
2774 | + } |
2775 | + |
2776 | struct sset nat_entries = SSET_INITIALIZER(&nat_entries); |
2777 | |
2778 | bool dnat_force_snat_ip = |
2779 | @@ -13179,7 +13434,7 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows, |
2780 | is_v6); |
2781 | /* S_ROUTER_IN_DNAT */ |
2782 | build_lrouter_in_dnat_flow(lflows, od, nat, match, actions, distributed, |
2783 | - mask, is_v6); |
2784 | + cidr_bits, is_v6); |
2785 | |
2786 | /* ARP resolve for NAT IPs. */ |
2787 | if (od->is_gw_router) { |
2788 | @@ -13218,7 +13473,7 @@ build_lrouter_nat_defrag_and_lb(struct ovn_datapath *od, struct hmap *lflows, |
2789 | mac, is_v6); |
2790 | /* S_ROUTER_OUT_SNAT */ |
2791 | build_lrouter_out_snat_flow(lflows, od, nat, match, actions, distributed, |
2792 | - mac, mask, cidr_bits, is_v6); |
2793 | + mac, cidr_bits, is_v6); |
2794 | |
2795 | /* S_ROUTER_IN_ADMISSION - S_ROUTER_IN_IP_INPUT */ |
2796 | build_lrouter_ingress_flow(lflows, od, nat, match, actions, |
2797 | @@ -13341,6 +13596,7 @@ struct lswitch_flow_build_info { |
2798 | const struct shash *meter_groups; |
2799 | const struct hmap *lbs; |
2800 | const struct hmap *bfd_connections; |
2801 | + const struct chassis_features *features; |
2802 | char *svc_check_match; |
2803 | struct ds match; |
2804 | struct ds actions; |
2805 | @@ -13359,7 +13615,9 @@ build_lswitch_and_lrouter_iterate_by_od(struct ovn_datapath *od, |
2806 | struct lswitch_flow_build_info *lsi) |
2807 | { |
2808 | /* Build Logical Switch Flows. */ |
2809 | - build_lswitch_lflows_pre_acl_and_acl(od, lsi->port_groups, lsi->lflows, |
2810 | + build_lswitch_lflows_pre_acl_and_acl(od, lsi->port_groups, |
2811 | + lsi->features, |
2812 | + lsi->lflows, |
2813 | lsi->meter_groups); |
2814 | |
2815 | build_fwd_group_lflows(od, lsi->lflows); |
2816 | @@ -13379,7 +13637,8 @@ build_lswitch_and_lrouter_iterate_by_od(struct ovn_datapath *od, |
2817 | &lsi->actions, lsi->meter_groups); |
2818 | build_ND_RA_flows_for_lrouter(od, lsi->lflows); |
2819 | build_ip_routing_pre_flows_for_lrouter(od, lsi->lflows); |
2820 | - build_static_route_flows_for_lrouter(od, lsi->lflows, lsi->ports, |
2821 | + build_static_route_flows_for_lrouter(od, lsi->features, |
2822 | + lsi->lflows, lsi->ports, |
2823 | lsi->bfd_connections); |
2824 | build_mcast_lookup_flows_for_lrouter(od, lsi->lflows, &lsi->match, |
2825 | &lsi->actions); |
2826 | @@ -13509,10 +13768,12 @@ build_lflows_thread(void *arg) |
2827 | build_lrouter_defrag_flows_for_lb(lb, lsi->lflows, |
2828 | &lsi->match); |
2829 | build_lrouter_flows_for_lb(lb, lsi->lflows, |
2830 | - lsi->meter_groups, &lsi->match, |
2831 | - &lsi->actions); |
2832 | + lsi->meter_groups, |
2833 | + lsi->features, |
2834 | + &lsi->match, &lsi->actions); |
2835 | build_lswitch_flows_for_lb(lb, lsi->lflows, |
2836 | lsi->meter_groups, |
2837 | + lsi->features, |
2838 | &lsi->match, &lsi->actions); |
2839 | } |
2840 | } |
2841 | @@ -13604,7 +13865,8 @@ build_lswitch_and_lrouter_flows(const struct hmap *datapaths, |
2842 | struct hmap *igmp_groups, |
2843 | const struct shash *meter_groups, |
2844 | const struct hmap *lbs, |
2845 | - const struct hmap *bfd_connections) |
2846 | + const struct hmap *bfd_connections, |
2847 | + const struct chassis_features *features) |
2848 | { |
2849 | |
2850 | char *svc_check_match = xasprintf("eth.dst == %s", svc_monitor_mac); |
2851 | @@ -13648,6 +13910,7 @@ build_lswitch_and_lrouter_flows(const struct hmap *datapaths, |
2852 | lsiv[index].meter_groups = meter_groups; |
2853 | lsiv[index].lbs = lbs; |
2854 | lsiv[index].bfd_connections = bfd_connections; |
2855 | + lsiv[index].features = features; |
2856 | lsiv[index].svc_check_match = svc_check_match; |
2857 | lsiv[index].thread_lflow_counter = 0; |
2858 | ds_init(&lsiv[index].match); |
2859 | @@ -13686,6 +13949,7 @@ build_lswitch_and_lrouter_flows(const struct hmap *datapaths, |
2860 | .meter_groups = meter_groups, |
2861 | .lbs = lbs, |
2862 | .bfd_connections = bfd_connections, |
2863 | + .features = features, |
2864 | .svc_check_match = svc_check_match, |
2865 | .match = DS_EMPTY_INITIALIZER, |
2866 | .actions = DS_EMPTY_INITIALIZER, |
2867 | @@ -13711,9 +13975,9 @@ build_lswitch_and_lrouter_flows(const struct hmap *datapaths, |
2868 | &lsi.match); |
2869 | build_lrouter_defrag_flows_for_lb(lb, lsi.lflows, &lsi.match); |
2870 | build_lrouter_flows_for_lb(lb, lsi.lflows, lsi.meter_groups, |
2871 | - &lsi.match, &lsi.actions); |
2872 | + lsi.features, &lsi.match, &lsi.actions); |
2873 | build_lswitch_flows_for_lb(lb, lsi.lflows, lsi.meter_groups, |
2874 | - &lsi.match, &lsi.actions); |
2875 | + lsi.features, &lsi.match, &lsi.actions); |
2876 | } |
2877 | stopwatch_stop(LFLOWS_LBS_STOPWATCH_NAME, time_msec()); |
2878 | stopwatch_start(LFLOWS_IGMP_STOPWATCH_NAME, time_msec()); |
2879 | @@ -13845,7 +14109,8 @@ void build_lflows(struct lflow_input *input_data, |
2880 | input_data->port_groups, &lflows, |
2881 | &mcast_groups, &igmp_groups, |
2882 | input_data->meter_groups, input_data->lbs, |
2883 | - input_data->bfd_connections); |
2884 | + input_data->bfd_connections, |
2885 | + input_data->features); |
2886 | |
2887 | /* Parallel build may result in a suboptimal hash. Resize the |
2888 | * hash to a correct size before doing lookups */ |
2889 | @@ -14901,6 +15166,7 @@ northd_init(struct northd_data *data) |
2890 | hmap_init(&data->lbs); |
2891 | hmap_init(&data->bfd_connections); |
2892 | ovs_list_init(&data->lr_list); |
2893 | + memset(&data->features, 0, sizeof data->features); |
2894 | data->ovn_internal_version_changed = false; |
2895 | } |
2896 | |
2897 | @@ -14961,15 +15227,6 @@ ovnnb_db_run(struct northd_input *input_data, |
2898 | if (!nb) { |
2899 | nb = nbrec_nb_global_insert(ovnnb_txn); |
2900 | } |
2901 | - const struct sbrec_sb_global *sb = sbrec_sb_global_table_first( |
2902 | - input_data->sbrec_sb_global_table); |
2903 | - if (!sb) { |
2904 | - sb = sbrec_sb_global_insert(ovnsb_txn); |
2905 | - } |
2906 | - if (nb->ipsec != sb->ipsec) { |
2907 | - sbrec_sb_global_set_ipsec(sb, nb->ipsec); |
2908 | - } |
2909 | - sbrec_sb_global_set_options(sb, &nb->options); |
2910 | |
2911 | const char *mac_addr_prefix = set_mac_prefix(smap_get(&nb->options, |
2912 | "mac_prefix")); |
2913 | @@ -15015,8 +15272,6 @@ ovnnb_db_run(struct northd_input *input_data, |
2914 | nbrec_nb_global_set_options(nb, &options); |
2915 | } |
2916 | |
2917 | - smap_destroy(&options); |
2918 | - |
2919 | use_parallel_build = |
2920 | (smap_get_bool(&nb->options, "use_parallel_build", false) && |
2921 | can_parallelize_hashes(false)); |
2922 | @@ -15032,6 +15287,7 @@ ovnnb_db_run(struct northd_input *input_data, |
2923 | check_lsp_is_up = !smap_get_bool(&nb->options, |
2924 | "ignore_lsp_down", true); |
2925 | |
2926 | + build_chassis_features(input_data, &data->features); |
2927 | build_datapaths(input_data, ovnsb_txn, &data->datapaths, &data->lr_list); |
2928 | build_ovn_lbs(input_data, ovnsb_txn, &data->datapaths, &data->lbs); |
2929 | build_lrouter_lbs(&data->datapaths, &data->lbs); |
2930 | @@ -15048,6 +15304,7 @@ ovnnb_db_run(struct northd_input *input_data, |
2931 | build_meter_groups(input_data, &data->meter_groups); |
2932 | stopwatch_stop(BUILD_LFLOWS_CTX_STOPWATCH_NAME, time_msec()); |
2933 | stopwatch_start(CLEAR_LFLOWS_CTX_STOPWATCH_NAME, time_msec()); |
2934 | + ovn_update_ipv6_options(&data->ports); |
2935 | ovn_update_ipv6_prefix(&data->ports); |
2936 | |
2937 | sync_address_sets(input_data, ovnsb_txn, &data->datapaths); |
2938 | @@ -15056,6 +15313,26 @@ ovnnb_db_run(struct northd_input *input_data, |
2939 | sync_dns_entries(input_data, ovnsb_txn, &data->datapaths); |
2940 | cleanup_stale_fdp_entries(input_data, &data->datapaths); |
2941 | stopwatch_stop(CLEAR_LFLOWS_CTX_STOPWATCH_NAME, time_msec()); |
2942 | + |
2943 | + /* Set up SB_Global (depends on chassis features). */ |
2944 | + const struct sbrec_sb_global *sb = sbrec_sb_global_table_first( |
2945 | + input_data->sbrec_sb_global_table); |
2946 | + if (!sb) { |
2947 | + sb = sbrec_sb_global_insert(ovnsb_txn); |
2948 | + } |
2949 | + if (nb->ipsec != sb->ipsec) { |
2950 | + sbrec_sb_global_set_ipsec(sb, nb->ipsec); |
2951 | + } |
2952 | + |
2953 | + /* Inform ovn-controllers whether LB flows will use ct_mark |
2954 | + * (i.e., only if all chassis support it). |
2955 | + */ |
2956 | + smap_replace(&options, "lb_hairpin_use_ct_mark", |
2957 | + data->features.ct_no_masked_label ? "true" : "false"); |
2958 | + if (!smap_equal(&sb->options, &options)) { |
2959 | + sbrec_sb_global_set_options(sb, &options); |
2960 | + } |
2961 | + smap_destroy(&options); |
2962 | } |
2963 | |
2964 | /* Stores the list of chassis which references an ha_chassis_group. |
2965 | diff --git a/northd/northd.h b/northd/northd.h |
2966 | index ebcb40d..0d9c7b8 100644 |
2967 | --- a/northd/northd.h |
2968 | +++ b/northd/northd.h |
2969 | @@ -53,6 +53,10 @@ struct northd_input { |
2970 | struct ovsdb_idl_index *sbrec_ip_mcast_by_dp; |
2971 | }; |
2972 | |
2973 | +struct chassis_features { |
2974 | + bool ct_no_masked_label; |
2975 | +}; |
2976 | + |
2977 | struct northd_data { |
2978 | /* Global state for 'en-northd'. */ |
2979 | struct hmap datapaths; |
2980 | @@ -63,6 +67,7 @@ struct northd_data { |
2981 | struct hmap bfd_connections; |
2982 | struct ovs_list lr_list; |
2983 | bool ovn_internal_version_changed; |
2984 | + struct chassis_features features; |
2985 | }; |
2986 | |
2987 | struct lflow_input { |
2988 | @@ -84,6 +89,7 @@ struct lflow_input { |
2989 | const struct shash *meter_groups; |
2990 | const struct hmap *lbs; |
2991 | const struct hmap *bfd_connections; |
2992 | + const struct chassis_features *features; |
2993 | bool ovn_internal_version_changed; |
2994 | }; |
2995 | |
2996 | diff --git a/northd/ovn-northd.8.xml b/northd/ovn-northd.8.xml |
2997 | index 1c9d408..199d419 100644 |
2998 | --- a/northd/ovn-northd.8.xml |
2999 | +++ b/northd/ovn-northd.8.xml |
3000 | @@ -599,7 +599,7 @@ |
3001 | <ul> |
3002 | <li> |
3003 | Priority-120 flows that send the packets to connection tracker using |
3004 | - <code>ct_lb;</code> as the action so that the already established |
3005 | + <code>ct_lb_mark;</code> as the action so that the already established |
3006 | traffic destined to the load balancer VIP gets DNATted based on a hint |
3007 | provided by the previous tables (with a match |
3008 | for <code>reg0[2] == 1</code> and on supported load balancer protocols |
3009 | @@ -614,7 +614,7 @@ |
3010 | A priority-110 flow sends the packets to connection tracker based |
3011 | on a hint provided by the previous tables |
3012 | (with a match for <code>reg0[2] == 1</code>) by using the |
3013 | - <code>ct_lb;</code> action. This flow is added to handle |
3014 | + <code>ct_lb_mark;</code> action. This flow is added to handle |
3015 | the traffic for load balancer VIPs whose protocol is not defined |
3016 | (mainly for ICMP traffic). |
3017 | </li> |
3018 | @@ -790,12 +790,12 @@ |
3019 | A priority-65532 flow that allows any traffic in the reply |
3020 | direction for a connection that has been committed to the |
3021 | connection tracker (i.e., established flows), as long as |
3022 | - the committed flow does not have <code>ct_label.blocked</code> set. |
3023 | + the committed flow does not have <code>ct_mark.blocked</code> set. |
3024 | We only handle traffic in the reply direction here because |
3025 | we want all packets going in the request direction to still |
3026 | go through the flows that implement the currently defined |
3027 | policy based on ACLs. If a connection is no longer allowed by |
3028 | - policy, <code>ct_label.blocked</code> will get set and packets in the |
3029 | + policy, <code>ct_mark.blocked</code> will get set and packets in the |
3030 | reply direction will no longer be allowed, either. This flow also |
3031 | clears the register bits <code>reg0[9]</code> and |
3032 | <code>reg0[10]</code>. If ACL logging and logging of related packets |
3033 | @@ -807,7 +807,7 @@ |
3034 | A priority-65532 flow that allows any traffic that is considered |
3035 | related to a committed flow in the connection tracker (e.g., an |
3036 | ICMP Port Unreachable from a non-listening UDP port), as long |
3037 | - as the committed flow does not have <code>ct_label.blocked</code> set. |
3038 | + as the committed flow does not have <code>ct_mark.blocked</code> set. |
3039 | If ACL logging and logging of related packets is enabled, then a |
3040 | companion priority-65533 flow will be installed that accomplishes the |
3041 | same thing but also logs the traffic. |
3042 | @@ -820,7 +820,7 @@ |
3043 | |
3044 | <li> |
3045 | A priority-65532 flow that drops all traffic in the reply direction |
3046 | - with <code>ct_label.blocked</code> set meaning that the connection |
3047 | + with <code>ct_mark.blocked</code> set meaning that the connection |
3048 | should no longer be allowed due to a policy change. Packets |
3049 | in the request direction are skipped here to let a newly created |
3050 | ACL re-allow this connection. |
3051 | @@ -908,7 +908,7 @@ |
3052 | <var>P</var>.dst == <var>PORT</var></code>. For IPv6 <var>VIPs</var>, |
3053 | the flow matches <code>ct.new && ip && ip6.dst == <var> |
3054 | VIP </var>&& <var>P</var> && <var>P</var>.dst == <var> |
3055 | - PORT</var></code>. The flow's action is <code>ct_lb(<var>args</var>) |
3056 | + PORT</var></code>. The flow's action is <code>ct_lb_mark(<var>args</var>) |
3057 | </code>, where <var>args</var> contains comma separated IP addresses |
3058 | (and optional port numbers) to load balance to. The address family of |
3059 | the IP addresses of <var>args</var> is the same as the address family |
3060 | @@ -929,7 +929,7 @@ |
3061 | ip4.dst == <var>VIP</var></code>. For IPv6 <var>VIPs</var>, |
3062 | the flow matches <code>ct.new && ip && ip6.dst == <var> |
3063 | VIP</var></code>. The action on this flow is <code> |
3064 | - ct_lb(<var>args</var>)</code>, where <var>args</var> contains comma |
3065 | + ct_lb_mark(<var>args</var>)</code>, where <var>args</var> contains comma |
3066 | separated IP addresses of the same address family as <var>VIP</var>. |
3067 | For IPv4 traffic the flow also loads the original destination |
3068 | IP and transport port in registers <code>reg1</code> and |
3069 | @@ -1929,11 +1929,11 @@ output; |
3070 | <ul> |
3071 | <li> |
3072 | A Priority-120 flow that send the packets to connection tracker using |
3073 | - <code>ct_lb;</code> as the action so that the already established |
3074 | + <code>ct_lb_mark;</code> as the action so that the already established |
3075 | traffic gets unDNATted from the backend IP to the load balancer VIP |
3076 | based on a hint provided by the previous tables with a match |
3077 | for <code>reg0[2] == 1</code>. If the packet was not DNATted earlier, |
3078 | - then <code>ct_lb</code> functions like <code>ct_next</code>. |
3079 | + then <code>ct_lb_mark</code> functions like <code>ct_next</code>. |
3080 | </li> |
3081 | |
3082 | <li> |
3083 | @@ -2302,6 +2302,12 @@ next; |
3084 | </li> |
3085 | |
3086 | <li> |
3087 | + A priority-95 flow with the match <code>nd_na && |
3088 | + nd.tll == 0</code> and applies the action |
3089 | + <code>put_nd(inport, nd.target, eth.src); next;</code> |
3090 | + </li> |
3091 | + |
3092 | + <li> |
3093 | A priority-90 flow with the match <code>nd_na</code> and |
3094 | applies the action |
3095 | <code>put_nd(inport, nd.target, nd.tll); next;</code> |
3096 | @@ -3149,14 +3155,14 @@ icmp6 { |
3097 | && <var>P</var> && reg9[16..31] == </code> |
3098 | <code><var>PORT</var></code> (<code>xxreg0 == <var>VIP</var></code> |
3099 | in the IPv6 case) with an action of |
3100 | - <code>ct_lb(<var>args</var>)</code>, where <var>args</var> contains |
3101 | + <code>ct_lb_mark(<var>args</var>)</code>, where <var>args</var> contains |
3102 | comma separated IPv4 or IPv6 addresses (and optional port numbers) to |
3103 | load balance to. If the router is configured to force SNAT any |
3104 | load-balanced packets, the above action will be replaced by |
3105 | - <code>flags.force_snat_for_lb = 1; ct_lb(<var>args</var>);</code>. |
3106 | + <code>flags.force_snat_for_lb = 1; ct_lb_mark(<var>args</var>);</code>. |
3107 | If the load balancing rule is configured with <code>skip_snat</code> |
3108 | set to true, the above action will be replaced by |
3109 | - <code>flags.skip_snat_for_lb = 1; ct_lb(<var>args</var>);</code>. |
3110 | + <code>flags.skip_snat_for_lb = 1; ct_lb_mark(<var>args</var>);</code>. |
3111 | If health check is enabled, then |
3112 | <var>args</var> will only contain those endpoints whose service |
3113 | monitor status entry in <code>OVN_Southbound</code> db is |
3114 | @@ -3205,14 +3211,14 @@ icmp6 { |
3115 | <code>ct.new && ip4 && reg0 == |
3116 | <var>VIP</var></code> (<code>ip6</code> and <code>xxreg0 == |
3117 | <var>VIP</var></code> in the IPv6 case) with an action of |
3118 | - <code>ct_lb(<var>args</var>)</code>, where <var>args</var> contains |
3119 | + <code>ct_lb_mark(<var>args</var>)</code>, where <var>args</var> contains |
3120 | comma separated IPv4 or IPv6 addresses. If the router is configured |
3121 | to force SNAT any load-balanced packets, the above action will be |
3122 | replaced by <code>flags.force_snat_for_lb = 1; |
3123 | - ct_lb(<var>args</var>);</code>. |
3124 | + ct_lb_mark(<var>args</var>);</code>. |
3125 | If the load balancing rule is configured with <code>skip_snat</code> |
3126 | set to true, the above action will be replaced by |
3127 | - <code>flags.skip_snat_for_lb = 1; ct_lb(<var>args</var>);</code>. |
3128 | + <code>flags.skip_snat_for_lb = 1; ct_lb_mark(<var>args</var>);</code>. |
3129 | </p> |
3130 | |
3131 | <p> |
3132 | @@ -3365,7 +3371,7 @@ icmp6 { |
3133 | route with a destination routing policy will instead match if the |
3134 | source IP address matches the static route's prefix. The flow uses |
3135 | the action <code>ct_commit { ct_label.ecmp_reply_eth = eth.src;" |
3136 | - " ct_label.ecmp_reply_port = <var>K</var>;}; next; </code> to commit |
3137 | + " ct_mark.ecmp_reply_port = <var>K</var>;}; next; </code> to commit |
3138 | the connection and storing <code>eth.src</code> and the ECMP |
3139 | reply port binding tunnel key <var>K</var> in the |
3140 | <code>ct_label</code>. |
3141 | @@ -3502,12 +3508,15 @@ output; |
3142 | <code>reg8[16..31]</code>. This step is skipped with a priority-10300 |
3143 | rule if the traffic going out the ECMP route is reply traffic, and the |
3144 | ECMP route was configured to use symmetric replies. Instead, the stored |
3145 | - <code>ct_label</code> value is used to choose the destination. The least |
3146 | - significant 48 bits of the <code>ct_label</code> tell the destination MAC |
3147 | - address to which the packet should be sent. The next 16 bits tell the |
3148 | - logical router port on which the packet should be sent. These values in |
3149 | - the <code>ct_label</code> are set when the initial ingress traffic is |
3150 | - received over the ECMP route. |
3151 | + values in conntrack is used to choose the destination. The |
3152 | + <code>ct_label.ecmp_reply_eth</code> tells the destination MAC address to |
3153 | + which the packet should be sent. The <code>ct_mark.ecmp_reply_port</code> |
3154 | + tells the logical router port on which the packet should be sent. These |
3155 | + values saved to the conntrack fields when the initial ingress traffic is |
3156 | + received over the ECMP route and committed to conntrack. The |
3157 | + priority-10300 flows in this stage set the <code>outport</code>, |
3158 | + while the <code>eth.dst</code> is set by flows at the ARP/ND Resolution |
3159 | + stage. |
3160 | </p> |
3161 | |
3162 | <p> |
3163 | @@ -3847,6 +3856,16 @@ outport = <var>P</var> |
3164 | |
3165 | <li> |
3166 | <p> |
3167 | + Priority-200 flows that match ECMP reply traffic for the routes |
3168 | + configured to use symmetric replies, with actions |
3169 | + <code>push(xxreg1); xxreg1 = ct_label; eth.dst = xxreg1[32..79]; pop(xxreg1); next;</code>. |
3170 | + <code>xxreg1</code> is used here to avoid masked access to ct_label, |
3171 | + to make the flow HW-offloading friendly. |
3172 | + </p> |
3173 | + </li> |
3174 | + |
3175 | + <li> |
3176 | + <p> |
3177 | Static MAC bindings. MAC bindings can be known statically based on |
3178 | data in the <code>OVN_Northbound</code> database. For router ports |
3179 | connected to logical switches, MAC bindings can be known statically |
3180 | @@ -4452,7 +4471,8 @@ nd_ns { |
3181 | to change the source IP address of a packet from an IP address of |
3182 | <var>A</var> or to change the source IP address of a packet that |
3183 | belongs to network <var>A</var> to <var>B</var>, a flow matches |
3184 | - <code>ip && ip4.src == <var>A</var></code> with an action |
3185 | + <code>ip && ip4.src == <var>A</var> && |
3186 | + (!ct.trk || !ct.rpl)</code> with an action |
3187 | <code>ct_snat(<var>B</var>);</code>. The priority of the flow |
3188 | is calculated based on the mask of <var>A</var>, with matches |
3189 | having larger masks getting higher priorities. If the NAT rule is |
3190 | diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c |
3191 | index 95b3959..9d191ce 100644 |
3192 | --- a/northd/ovn-northd.c |
3193 | +++ b/northd/ovn-northd.c |
3194 | @@ -723,10 +723,18 @@ main(int argc, char *argv[]) |
3195 | unixctl_command_register("nb-connection-status", "", 0, 0, |
3196 | ovn_conn_show, ovnnb_idl_loop.idl); |
3197 | |
3198 | - /* We want to detect all changes to the ovn-sb db. */ |
3199 | + /* We want to detect all changes to the ovn-sb db so enable change |
3200 | + * tracking but, for performance reasons, and because northd |
3201 | + * reconciles all database changes, also configure the IDL to only |
3202 | + * write columns that actually change value. |
3203 | + */ |
3204 | struct ovsdb_idl_loop ovnsb_idl_loop = OVSDB_IDL_LOOP_INITIALIZER( |
3205 | ovsdb_idl_create(ovnsb_db, &sbrec_idl_class, true, true)); |
3206 | ovsdb_idl_track_add_all(ovnsb_idl_loop.idl); |
3207 | + ovsdb_idl_set_write_changed_only_all(ovnsb_idl_loop.idl, true); |
3208 | + |
3209 | + /* Disable alerting for pure write-only columns. */ |
3210 | + ovsdb_idl_omit_alert(ovnsb_idl_loop.idl, &sbrec_sb_global_col_nb_cfg); |
3211 | |
3212 | unixctl_command_register("sb-connection-status", "", 0, 0, |
3213 | ovn_conn_show, ovnsb_idl_loop.idl); |
3214 | diff --git a/ovn-nb.xml b/ovn-nb.xml |
3215 | index 4d7a23c..0535f11 100644 |
3216 | --- a/ovn-nb.xml |
3217 | +++ b/ovn-nb.xml |
3218 | @@ -2357,9 +2357,9 @@ |
3219 | <ref column="match"/> with the highest-<ref column="priority"/> |
3220 | will have QoS applied to it. If the <ref column="action"/> column is |
3221 | specified, then matching packets will have DSCP marking applied. |
3222 | - If the <ref column="bandwdith"/> column is specified, then matching |
3223 | + If the <ref column="bandwidth"/> column is specified, then matching |
3224 | packets will have metering applied. <ref column="action"/> and |
3225 | - <ref column="bandwdith"/> are not exclusive, so both marking and |
3226 | + <ref column="bandwidth"/> are not exclusive, so both marking and |
3227 | metering by defined for the same QoS entry. If no row matches, |
3228 | packets will not have any QoS applied. |
3229 | </p> |
3230 | diff --git a/ovn-sb.xml b/ovn-sb.xml |
3231 | index f7c41cc..3edefff 100644 |
3232 | --- a/ovn-sb.xml |
3233 | +++ b/ovn-sb.xml |
3234 | @@ -199,6 +199,22 @@ |
3235 | tunnel interfaces. |
3236 | </column> |
3237 | </group> |
3238 | + |
3239 | + <group title="Options for configuring Load Balancers"> |
3240 | + <p> |
3241 | + These options apply when <code>ovn-controller</code> configures |
3242 | + load balancer related flows. |
3243 | + </p> |
3244 | + |
3245 | + <column name="options" key="lb_hairpin_use_ct_mark"> |
3246 | + This value is automatically set to <code>true</code> by |
3247 | + <code>ovn-northd</code> when action <code>ct_lb_mark</code> is used |
3248 | + for new load balancer sessions. <code>ovn-controller</code> then |
3249 | + knows that it should check <code>ct_mark.natted</code> to detect |
3250 | + load balanced traffic. |
3251 | + </column> |
3252 | + </group> |
3253 | + |
3254 | </group> |
3255 | |
3256 | <group title="Connection Options"> |
3257 | @@ -1271,6 +1287,21 @@ |
3258 | </p> |
3259 | </dd> |
3260 | |
3261 | + <dt><code>push(<var>field</var>);</code></dt> |
3262 | + <dd> |
3263 | + <p> |
3264 | + Push the value of <var>field</var> to the stack top. |
3265 | + </p> |
3266 | + </dd> |
3267 | + |
3268 | + <dt><code>pop(<var>field</var>);</code></dt> |
3269 | + <dd> |
3270 | + <p> |
3271 | + Pop the stack top and store the value to <var>field</var>, |
3272 | + which must be modifiable. |
3273 | + </p> |
3274 | + </dd> |
3275 | + |
3276 | <dt><code>ip.ttl--;</code></dt> |
3277 | <dd> |
3278 | <p> |
3279 | @@ -1955,21 +1986,19 @@ |
3280 | </dd> |
3281 | |
3282 | <dt><code>ct_lb;</code></dt> |
3283 | - <dt><code>ct_lb(</code><var>ip</var>[<code>:</code><var>port</var>]...<code>);</code></dt> |
3284 | + <dt><code>ct_lb(backends=<var>ip</var>[:<var>port</var>][,...][; hash_fields=<var>field1</var>,<var>field2</var>,...]);</code></dt> |
3285 | <dd> |
3286 | <p> |
3287 | - With one or more arguments, <code>ct_lb</code> commits the packet |
3288 | + With arguments, <code>ct_lb</code> commits the packet |
3289 | to the connection tracking table and DNATs the packet's destination |
3290 | IP address (and port) to the IP address or addresses (and optional |
3291 | - ports) specified in the string. If multiple comma-separated IP |
3292 | - addresses are specified, each is given equal weight for picking the |
3293 | - DNAT address. Processing automatically moves on to the next table, |
3294 | - as if <code>next;</code> were specified, and later tables act on |
3295 | - the packet as modified by the connection tracker. Connection |
3296 | - tracking state is scoped by the logical port when the action is |
3297 | - used in a flow for a logical switch, so overlapping |
3298 | - addresses may be used. Connection tracking state is scoped by the |
3299 | - logical topology when the action is used in a flow for a router. |
3300 | + ports) specified in the <code>backends</code>. If multiple |
3301 | + comma-separated IP addresses are specified, each is given equal |
3302 | + weight for picking the DNAT address. By default, |
3303 | + <code>dp_hash</code> is used as the OpenFlow group selection |
3304 | + method, but if <code>hash_fields</code> is specified, |
3305 | + <code>hash</code> is used as the selection method, and the fields |
3306 | + listed are used as the hash fields. |
3307 | </p> |
3308 | <p> |
3309 | Without arguments, <code>ct_lb</code> sends the packet to the |
3310 | @@ -1979,6 +2008,25 @@ |
3311 | will automatically get DNATed to the same IP address as the first |
3312 | packet in that connection. |
3313 | </p> |
3314 | + <p> |
3315 | + Processing automatically moves on to the next table, |
3316 | + as if <code>next;</code> were specified, and later tables act on |
3317 | + the packet as modified by the connection tracker. Connection |
3318 | + tracking state is scoped by the logical port when the action is |
3319 | + used in a flow for a logical switch, so overlapping |
3320 | + addresses may be used. Connection tracking state is scoped by the |
3321 | + logical topology when the action is used in a flow for a router. |
3322 | + </p> |
3323 | + </dd> |
3324 | + |
3325 | + <dt><code>ct_lb_mark;</code></dt> |
3326 | + <dt><code>ct_lb_mark(backends=<var>ip</var>[:<var>port</var>][,...][; hash_fields=<var>field1</var>,<var>field2</var>,...]);</code></dt> |
3327 | + <dd> |
3328 | + <p> |
3329 | + Same as <code>ct_lb</code>, except that it internally uses ct_mark |
3330 | + to store the NAT flag, while <code>ct_lb</code> uses ct_label for |
3331 | + the same purpose. |
3332 | + </p> |
3333 | </dd> |
3334 | |
3335 | <dt> |
3336 | diff --git a/rhel/ovn-fedora.spec.in b/rhel/ovn-fedora.spec.in |
3337 | index 3fb854a..821eb03 100644 |
3338 | --- a/rhel/ovn-fedora.spec.in |
3339 | +++ b/rhel/ovn-fedora.spec.in |
3340 | @@ -323,7 +323,7 @@ ln -sf ovn_detrace.py %{_bindir}/ovn-detrace |
3341 | %if %{with libcapng} |
3342 | if [ $1 -eq 1 ]; then |
3343 | sed -i 's:^#OVN_USER_ID=:OVN_USER_ID=:' %{_sysconfdir}/sysconfig/ovn |
3344 | - sed -i 's:\(.*su\).*:\1 ovn ovn:' %{_sysconfdir}/logrotate.d/ovn |
3345 | + sed -i 's:\(.*su\).*:\1 openvswitch openvswitch:' %{_sysconfdir}/logrotate.d/ovn |
3346 | fi |
3347 | %endif |
3348 | |
3349 | diff --git a/tests/ovn-controller.at b/tests/ovn-controller.at |
3350 | index 6e4c24f..5d53712 100644 |
3351 | --- a/tests/ovn-controller.at |
3352 | +++ b/tests/ovn-controller.at |
3353 | @@ -2057,3 +2057,132 @@ AT_CHECK([echo $(($reprocess_count_new - $reprocess_count_old))], [0], [2 |
3354 | |
3355 | OVN_CLEANUP([hv1]) |
3356 | AT_CLEANUP |
3357 | + |
3358 | +AT_SETUP([ovn-controller - I-P handle lb_hairpin_use_ct_mark change]) |
3359 | + |
3360 | +ovn_start --backup-northd=none |
3361 | + |
3362 | +net_add n1 |
3363 | +sim_add hv1 |
3364 | +as hv1 |
3365 | +check ovs-vsctl add-br br-phys |
3366 | +ovn_attach n1 br-phys 192.168.0.1 |
3367 | +check ovs-vsctl -- add-port br-int hv1-vif1 -- \ |
3368 | + set interface hv1-vif1 external-ids:iface-id=ls1-lp1 |
3369 | + |
3370 | +check ovn-nbctl ls-add ls1 |
3371 | + |
3372 | +check ovn-nbctl lsp-add ls1 ls1-lp1 \ |
3373 | +-- lsp-set-addresses ls1-lp1 "f0:00:00:00:00:01" |
3374 | + |
3375 | +wait_for_ports_up |
3376 | +ovn-appctl -t ovn-controller vlog/set file:dbg |
3377 | + |
3378 | +read_counter() { |
3379 | + ovn-appctl -t ovn-controller coverage/read-counter $1 |
3380 | +} |
3381 | + |
3382 | +# nb_cfg update in sb_global shouldn't trigger lflow_run. |
3383 | +lflow_run_old=$(read_counter lflow_run) |
3384 | +check ovn-nbctl --wait=hv sync |
3385 | +lflow_run_new=$(read_counter lflow_run) |
3386 | +AT_CHECK([echo $(($lflow_run_new - $lflow_run_old))], [0], [0 |
3387 | +]) |
3388 | + |
3389 | +# lb_hairpin_use_ct_mark update in sb_global:options should trigger lflow_run. |
3390 | +# The below steps should cause lb_hairpin_use_ct_mark change twice. One by |
3391 | +# ovn-sbctl, and the other by ovn-northd to change it back. |
3392 | + |
3393 | +lflow_run_old=$(read_counter lflow_run) |
3394 | +check ovn-sbctl set SB_Global . options:lb_hairpin_use_ct_mark=false |
3395 | +check ovn-nbctl --wait=hv sync |
3396 | +lflow_run_new=$(read_counter lflow_run) |
3397 | +AT_CHECK([echo $(($lflow_run_new - $lflow_run_old))], [0], [2 |
3398 | +]) |
3399 | + |
3400 | +OVN_CLEANUP([hv1]) |
3401 | +AT_CLEANUP |
3402 | + |
3403 | + |
3404 | +AT_SETUP([ovn-controller - check ovn-chassis-mac-mappings]) |
3405 | + |
3406 | +ovn_start |
3407 | + |
3408 | +net_add n1 |
3409 | +sim_add hv1 |
3410 | +as hv1 |
3411 | +ovs-vsctl add-br br-phys |
3412 | +ovn_attach n1 br-phys 192.168.0.1 |
3413 | + |
3414 | +pid=$(cat hv1/ovn-controller.pid) |
3415 | + |
3416 | +# Add chassis with some ovn-chassis-mac-mappings |
3417 | +AT_CHECK([ovn-sbctl chassis-add foo geneve 127.0.0.2]) |
3418 | +AT_CHECK([ovn-sbctl set chassis foo other_config:ovn-chassis-mac-mappings="invalid1,invalid2,br1:00:00:00:00:00:00"]) |
3419 | +AT_CHECK([ovn-nbctl --wait=hv sync]) |
3420 | + |
3421 | +# Check if ovn-controller is still alive |
3422 | +AT_CHECK([ps $pid], [0], [ignore]) |
3423 | +# Check if we got warnings for invalid |
3424 | +AT_CHECK([grep "Parsing of ovn-chassis-mac-mappings failed" hv1/ovn-controller.log | grep -q invalid1]) |
3425 | +AT_CHECK([grep "Parsing of ovn-chassis-mac-mappings failed" hv1/ovn-controller.log | grep -q invalid2]) |
3426 | +AT_CHECK([grep "Parsing of ovn-chassis-mac-mappings failed" hv1/ovn-controller.log | grep -q br1], [1]) |
3427 | + |
3428 | +OVN_CLEANUP([hv1]) |
3429 | +AT_CLEANUP |
3430 | + |
3431 | +AT_SETUP([ovn-controller - localport can be recreated]) |
3432 | + |
3433 | +ovn_start |
3434 | + |
3435 | +net_add n1 |
3436 | +sim_add hv1 |
3437 | +as hv1 |
3438 | +ovs-vsctl add-br br-phys |
3439 | +ovn_attach n1 br-phys 192.168.0.1 |
3440 | + |
3441 | +port_binding_cookie() { |
3442 | + name=$1 |
3443 | + ovn-sbctl --bare --columns _uuid find port_binding logical_port=$name |\ |
3444 | + cut -d '-' -f 1 | tr -d '\n' | sed 's/^0\{0,8\}//' |
3445 | +} |
3446 | + |
3447 | +create_localport() { |
3448 | + AT_CHECK([ovn-nbctl lsp-add ls0 metadata]) |
3449 | + AT_CHECK([ovn-nbctl lsp-set-type metadata localport]) |
3450 | + AT_CHECK([ovn-nbctl lsp-set-addresses metadata "00:00:00:00:10:25 192.168.10.25"]) |
3451 | +} |
3452 | + |
3453 | +bind_ports() { |
3454 | + AT_CHECK([ovs-vsctl add-port br-int vm0 -- set interface vm0 type=internal external_ids:iface-id=vm0]) |
3455 | + AT_CHECK([ovs-vsctl add-port br-int metadata -- set interface metadata type=internal external_ids:iface-id=metadata]) |
3456 | +} |
3457 | + |
3458 | +# Create one VIF and localport and bind it to chassis |
3459 | +AT_CHECK([ovn-nbctl ls-add ls0]) |
3460 | +AT_CHECK([ovn-nbctl lsp-add ls0 vm0]) |
3461 | +AT_CHECK([ovn-nbctl lsp-set-addresses vm0 "00:00:00:00:10:10 192.168.10.10"]) |
3462 | +create_localport |
3463 | +bind_ports |
3464 | + |
3465 | +# Check that localport has all physical flows defined |
3466 | +OVS_WAIT_UNTIL([test 6 = $(as hv1 ovs-ofctl dump-flows br-int | grep -c $(port_binding_cookie metadata))]) |
3467 | + |
3468 | +# Remove ls0 from local datapaths |
3469 | +AT_CHECK([ovs-vsctl del-port br-int vm0]) |
3470 | +AT_CHECK([ovn-appctl inc-engine/recompute]) |
3471 | + |
3472 | +# Check that localports physical flows are removed |
3473 | +OVS_WAIT_UNTIL([test 0 = $(as hv1 ovs-ofctl dump-flows br-int | grep -c $(port_binding_cookie metadata))]) |
3474 | + |
3475 | +# The order is impotant, if the port is removed first, the bug wouldn't be triggered |
3476 | +AT_CHECK([ovn-nbctl lsp-del metadata]) |
3477 | +AT_CHECK([ovs-vsctl del-port br-int metadata]) |
3478 | +create_localport |
3479 | +bind_ports |
3480 | + |
3481 | +# Check that localport has all physical flows re-defined |
3482 | +OVS_WAIT_UNTIL([test 6 = $(as hv1 ovs-ofctl dump-flows br-int | grep -c $(port_binding_cookie metadata))]) |
3483 | + |
3484 | +OVN_CLEANUP([hv1]) |
3485 | +AT_CLEANUP |
3486 | diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at |
3487 | index 539a121..efc1b60 100644 |
3488 | --- a/tests/ovn-nbctl.at |
3489 | +++ b/tests/ovn-nbctl.at |
3490 | @@ -597,6 +597,8 @@ AT_CHECK([ovn-nbctl --stateless lr-nat-add lr0 dnat_and_snat 40.0.0.3 192.168.1. |
3491 | [ovn-nbctl: 40.0.0.3, 192.168.1.7: External ip cannot be shared across stateless and stateful NATs |
3492 | ]) |
3493 | |
3494 | +AT_CHECK([ovn-nbctl --stateless --may-exist lr-nat-add lr0 dnat_and_snat 40.0.0.3 192.168.1.7]) |
3495 | + |
3496 | dnl Deletes the NATs |
3497 | AT_CHECK([ovn-nbctl lr-nat-del lr0 dnat_and_snat 30.0.0.3], [1], [], |
3498 | [ovn-nbctl: no matching NAT with the type (dnat_and_snat) and external_ip (30.0.0.3) |
3499 | diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at |
3500 | index 3865003..47d0d77 100644 |
3501 | --- a/tests/ovn-northd.at |
3502 | +++ b/tests/ovn-northd.at |
3503 | @@ -895,7 +895,7 @@ ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 |
3504 | echo |
3505 | echo "IPv4: stateless" |
3506 | ovn-nbctl --wait=sb --stateless lr-nat-add R1 dnat_and_snat 172.16.1.1 50.0.0.11 |
3507 | -check_flow_match_sets 2 0 0 2 2 0 0 |
3508 | +check_flow_match_sets 2 0 0 1 1 0 0 |
3509 | ovn-nbctl lr-nat-del R1 dnat_and_snat 172.16.1.1 |
3510 | |
3511 | echo |
3512 | @@ -907,7 +907,7 @@ ovn-nbctl lr-nat-del R1 dnat_and_snat fd01::1 |
3513 | echo |
3514 | echo "IPv6: stateless" |
3515 | ovn-nbctl --wait=sb --stateless lr-nat-add R1 dnat_and_snat fd01::1 fd11::2 |
3516 | -check_flow_match_sets 2 0 0 0 0 2 2 |
3517 | +check_flow_match_sets 2 0 0 0 0 1 1 |
3518 | |
3519 | AT_CLEANUP |
3520 | ]) |
3521 | @@ -1030,7 +1030,7 @@ AT_CHECK([grep -e "lr_out_snat" drflows | sed 's/table=../table=??/' | sort], [0 |
3522 | AT_CHECK([grep -e "lr_out_snat" crflows | sed 's/table=../table=??/' | sort], [0], [dnl |
3523 | table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) |
3524 | table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) |
3525 | - table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range), action=(ct_snat(172.16.1.1);) |
3526 | + table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);) |
3527 | ]) |
3528 | |
3529 | |
3530 | @@ -1062,7 +1062,7 @@ AT_CHECK([grep -e "lr_out_snat" drflows2 | sed 's/table=../table=??/' | sort], [ |
3531 | AT_CHECK([grep -e "lr_out_snat" crflows2 | sed 's/table=../table=??/' | sort], [0], [dnl |
3532 | table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) |
3533 | table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) |
3534 | - table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11), action=(ct_snat(172.16.1.1);) |
3535 | + table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.1);) |
3536 | table=??(lr_out_snat ), priority=35 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;) |
3537 | ]) |
3538 | |
3539 | @@ -1091,7 +1091,7 @@ AT_CHECK([grep -e "lr_out_snat" drflows3 | sed 's/table=../table=??/' | sort], [ |
3540 | AT_CHECK([grep -e "lr_out_snat" crflows3 | sed 's/table=../table=??/' | sort], [0], [dnl |
3541 | table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) |
3542 | table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) |
3543 | - table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range), action=(ct_snat(172.16.1.2);) |
3544 | + table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $allowed_range && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);) |
3545 | ]) |
3546 | |
3547 | # Stateful FIP with DISALLOWED_IPs |
3548 | @@ -1120,7 +1120,7 @@ AT_CHECK([grep -e "lr_out_snat" drflows4 | sed 's/table=../table=??/' | sort], [ |
3549 | AT_CHECK([grep -e "lr_out_snat" crflows4 | sed 's/table=../table=??/' | sort], [0], [dnl |
3550 | table=??(lr_out_snat ), priority=0 , match=(1), action=(next;) |
3551 | table=??(lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) |
3552 | - table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11), action=(ct_snat(172.16.1.2);) |
3553 | + table=??(lr_out_snat ), priority=33 , match=(ip && ip4.src == 50.0.0.11 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.16.1.2);) |
3554 | table=??(lr_out_snat ), priority=35 , match=(ip && ip4.src == 50.0.0.11 && ip4.dst == $disallowed_range), action=(next;) |
3555 | ]) |
3556 | |
3557 | @@ -1226,7 +1226,7 @@ check ovn-nbctl --wait=sb ls-lb-add sw0 lb1 |
3558 | AT_CAPTURE_FILE([sbflows]) |
3559 | OVS_WAIT_FOR_OUTPUT( |
3560 | [ovn-sbctl dump-flows sw0 | tee sbflows | grep 'priority=120.*backends' | sed 's/table=..//'], 0, [dnl |
3561 | - (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.3:80,20.0.0.3:80);) |
3562 | + (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);) |
3563 | ]) |
3564 | |
3565 | AS_BOX([Delete the Load_Balancer_Health_Check]) |
3566 | @@ -1236,7 +1236,7 @@ wait_row_count Service_Monitor 0 |
3567 | AT_CAPTURE_FILE([sbflows2]) |
3568 | OVS_WAIT_FOR_OUTPUT( |
3569 | [ovn-sbctl dump-flows sw0 | tee sbflows2 | grep 'priority=120.*backends' | sed 's/table=..//'], [0], |
3570 | -[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.3:80,20.0.0.3:80);) |
3571 | +[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);) |
3572 | ]) |
3573 | |
3574 | AS_BOX([Create the Load_Balancer_Health_Check again.]) |
3575 | @@ -1248,7 +1248,7 @@ check ovn-nbctl --wait=sb sync |
3576 | |
3577 | ovn-sbctl dump-flows sw0 | grep backends | grep priority=120 > lflows.txt |
3578 | AT_CHECK([cat lflows.txt | sed 's/table=..//'], [0], [dnl |
3579 | - (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.3:80,20.0.0.3:80);) |
3580 | + (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);) |
3581 | ]) |
3582 | |
3583 | AS_BOX([Get the uuid of both the service_monitor]) |
3584 | @@ -1258,7 +1258,7 @@ sm_sw1_p1=$(fetch_column Service_Monitor _uuid logical_port=sw1-p1) |
3585 | AT_CAPTURE_FILE([sbflows3]) |
3586 | OVS_WAIT_FOR_OUTPUT( |
3587 | [ovn-sbctl dump-flows sw0 | tee sbflows 3 | grep 'priority=120.*backends' | sed 's/table=..//'], [0], |
3588 | -[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.3:80,20.0.0.3:80);) |
3589 | +[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);) |
3590 | ]) |
3591 | |
3592 | AS_BOX([Set the service monitor for sw1-p1 to offline]) |
3593 | @@ -1269,7 +1269,7 @@ check ovn-nbctl --wait=sb sync |
3594 | AT_CAPTURE_FILE([sbflows4]) |
3595 | OVS_WAIT_FOR_OUTPUT( |
3596 | [ovn-sbctl dump-flows sw0 | tee sbflows4 | grep 'priority=120.*backends' | sed 's/table=..//'], [0], |
3597 | -[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.3:80);) |
3598 | +[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80);) |
3599 | ]) |
3600 | |
3601 | AS_BOX([Set the service monitor for sw0-p1 to offline]) |
3602 | @@ -1298,7 +1298,7 @@ check ovn-nbctl --wait=sb sync |
3603 | AT_CAPTURE_FILE([sbflows7]) |
3604 | OVS_WAIT_FOR_OUTPUT( |
3605 | [ovn-sbctl dump-flows sw0 | tee sbflows7 | grep backends | grep priority=120 | sed 's/table=..//'], 0, |
3606 | -[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.3:80,20.0.0.3:80);) |
3607 | +[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);) |
3608 | ]) |
3609 | |
3610 | AS_BOX([Set the service monitor for sw1-p1 to error]) |
3611 | @@ -1309,7 +1309,7 @@ check ovn-nbctl --wait=sb sync |
3612 | ovn-sbctl dump-flows sw0 | grep "ip4.dst == 10.0.0.10 && tcp.dst == 80" \ |
3613 | | grep priority=120 > lflows.txt |
3614 | AT_CHECK([cat lflows.txt | sed 's/table=..//'], [0], [dnl |
3615 | - (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.3:80);) |
3616 | + (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80);) |
3617 | ]) |
3618 | |
3619 | AS_BOX([Add one more vip to lb1]) |
3620 | @@ -1335,8 +1335,8 @@ AT_CAPTURE_FILE([sbflows9]) |
3621 | OVS_WAIT_FOR_OUTPUT( |
3622 | [ovn-sbctl dump-flows sw0 | tee sbflows9 | grep backends | grep priority=120 | sed 's/table=..//' | sort], |
3623 | 0, |
3624 | -[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.3:80);) |
3625 | - (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(reg0[[1]] = 0; reg1 = 10.0.0.40; reg2[[0..15]] = 1000; ct_lb(backends=10.0.0.3:1000);) |
3626 | +[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80);) |
3627 | + (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(reg0[[1]] = 0; reg1 = 10.0.0.40; reg2[[0..15]] = 1000; ct_lb_mark(backends=10.0.0.3:1000);) |
3628 | ]) |
3629 | |
3630 | AS_BOX([Set the service monitor for sw1-p1 to online]) |
3631 | @@ -1349,8 +1349,8 @@ AT_CAPTURE_FILE([sbflows10]) |
3632 | OVS_WAIT_FOR_OUTPUT( |
3633 | [ovn-sbctl dump-flows sw0 | tee sbflows10 | grep backends | grep priority=120 | sed 's/table=..//' | sort], |
3634 | 0, |
3635 | -[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.3:80,20.0.0.3:80);) |
3636 | - (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(reg0[[1]] = 0; reg1 = 10.0.0.40; reg2[[0..15]] = 1000; ct_lb(backends=10.0.0.3:1000,20.0.0.3:80);) |
3637 | +[ (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);) |
3638 | + (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(reg0[[1]] = 0; reg1 = 10.0.0.40; reg2[[0..15]] = 1000; ct_lb_mark(backends=10.0.0.3:1000,20.0.0.3:80);) |
3639 | ]) |
3640 | |
3641 | AS_BOX([Associate lb1 to sw1]) |
3642 | @@ -1359,8 +1359,8 @@ AT_CAPTURE_FILE([sbflows11]) |
3643 | OVS_WAIT_FOR_OUTPUT( |
3644 | [ovn-sbctl dump-flows sw1 | tee sbflows11 | grep backends | grep priority=120 | sed 's/table=..//' | sort], |
3645 | 0, [dnl |
3646 | - (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.3:80,20.0.0.3:80);) |
3647 | - (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(reg0[[1]] = 0; reg1 = 10.0.0.40; reg2[[0..15]] = 1000; ct_lb(backends=10.0.0.3:1000,20.0.0.3:80);) |
3648 | + (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.3:80,20.0.0.3:80);) |
3649 | + (ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.40 && tcp.dst == 1000), action=(reg0[[1]] = 0; reg1 = 10.0.0.40; reg2[[0..15]] = 1000; ct_lb_mark(backends=10.0.0.3:1000,20.0.0.3:80);) |
3650 | ]) |
3651 | |
3652 | AS_BOX([Now create lb2 same as lb1 but udp protocol.]) |
3653 | @@ -2071,15 +2071,15 @@ AT_CAPTURE_FILE([sw1flows3]) |
3654 | AT_CHECK([grep "ls_out_acl" sw0flows3 sw1flows3 | grep pg0 | sort], [0], [dnl |
3655 | sw0flows3: table=4 (ls_out_acl ), priority=2001 , match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;) |
3656 | sw0flows3: table=4 (ls_out_acl ), priority=2001 , match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;) |
3657 | -sw0flows3: table=4 (ls_out_acl ), priority=2002 , match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3658 | +sw0flows3: table=4 (ls_out_acl ), priority=2002 , match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit { ct_mark.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3659 | sw0flows3: table=4 (ls_out_acl ), priority=2002 , match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3660 | -sw0flows3: table=4 (ls_out_acl ), priority=2003 , match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3661 | +sw0flows3: table=4 (ls_out_acl ), priority=2003 , match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit { ct_mark.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3662 | sw0flows3: table=4 (ls_out_acl ), priority=2003 , match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3663 | sw1flows3: table=4 (ls_out_acl ), priority=2001 , match=(reg0[[7]] == 1 && (outport == @pg0 && ip)), action=(reg0[[1]] = 1; next;) |
3664 | sw1flows3: table=4 (ls_out_acl ), priority=2001 , match=(reg0[[8]] == 1 && (outport == @pg0 && ip)), action=(next;) |
3665 | -sw1flows3: table=4 (ls_out_acl ), priority=2002 , match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3666 | +sw1flows3: table=4 (ls_out_acl ), priority=2002 , match=((reg0[[10]] == 1) && outport == @pg0 && ip4 && udp), action=(ct_commit { ct_mark.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3667 | sw1flows3: table=4 (ls_out_acl ), priority=2002 , match=((reg0[[9]] == 1) && outport == @pg0 && ip4 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3668 | -sw1flows3: table=4 (ls_out_acl ), priority=2003 , match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit { ct_label.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3669 | +sw1flows3: table=4 (ls_out_acl ), priority=2003 , match=((reg0[[10]] == 1) && outport == @pg0 && ip6 && udp), action=(ct_commit { ct_mark.blocked = 1; }; reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3670 | sw1flows3: table=4 (ls_out_acl ), priority=2003 , match=((reg0[[9]] == 1) && outport == @pg0 && ip6 && udp), action=(reg0 = 0; reject { /* eth.dst <-> eth.src; ip.dst <-> ip.src; is implicit. */ outport <-> inport; next(pipeline=ingress,table=24); };) |
3671 | ]) |
3672 | AT_CLEANUP |
3673 | @@ -2220,28 +2220,28 @@ check ovn-nbctl --wait=sb \ |
3674 | -- acl-add ls from-lport 2 "udp" allow-related \ |
3675 | -- acl-add ls to-lport 2 "udp" allow-related |
3676 | AT_CHECK([ovn-sbctl lflow-list ls | grep -e ls_in_acl_hint -e ls_out_acl_hint -e ls_in_acl -e ls_out_acl | grep 'ct\.' | sort], [0], [dnl |
3677 | - table=3 (ls_out_acl_hint ), priority=1 , match=(ct.est && ct_label.blocked == 0), action=(reg0[[10]] = 1; next;) |
3678 | - table=3 (ls_out_acl_hint ), priority=2 , match=(ct.est && ct_label.blocked == 1), action=(reg0[[9]] = 1; next;) |
3679 | + table=3 (ls_out_acl_hint ), priority=1 , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;) |
3680 | + table=3 (ls_out_acl_hint ), priority=2 , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;) |
3681 | table=3 (ls_out_acl_hint ), priority=3 , match=(!ct.est), action=(reg0[[9]] = 1; next;) |
3682 | - table=3 (ls_out_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
3683 | + table=3 (ls_out_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
3684 | table=3 (ls_out_acl_hint ), priority=5 , match=(!ct.trk), action=(reg0[[8]] = 1; reg0[[9]] = 1; next;) |
3685 | - table=3 (ls_out_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3686 | + table=3 (ls_out_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3687 | table=3 (ls_out_acl_hint ), priority=7 , match=(ct.new && !ct.est), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3688 | - table=4 (ls_out_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;) |
3689 | - table=4 (ls_out_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
3690 | - table=4 (ls_out_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(next;) |
3691 | - table=4 (ls_out_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
3692 | - table=8 (ls_in_acl_hint ), priority=1 , match=(ct.est && ct_label.blocked == 0), action=(reg0[[10]] = 1; next;) |
3693 | - table=8 (ls_in_acl_hint ), priority=2 , match=(ct.est && ct_label.blocked == 1), action=(reg0[[9]] = 1; next;) |
3694 | + table=4 (ls_out_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_mark.blocked == 1))), action=(reg0[[1]] = 1; next;) |
3695 | + table=4 (ls_out_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
3696 | + table=4 (ls_out_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(next;) |
3697 | + table=4 (ls_out_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
3698 | + table=8 (ls_in_acl_hint ), priority=1 , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;) |
3699 | + table=8 (ls_in_acl_hint ), priority=2 , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;) |
3700 | table=8 (ls_in_acl_hint ), priority=3 , match=(!ct.est), action=(reg0[[9]] = 1; next;) |
3701 | - table=8 (ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
3702 | + table=8 (ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
3703 | table=8 (ls_in_acl_hint ), priority=5 , match=(!ct.trk), action=(reg0[[8]] = 1; reg0[[9]] = 1; next;) |
3704 | - table=8 (ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3705 | + table=8 (ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3706 | table=8 (ls_in_acl_hint ), priority=7 , match=(ct.new && !ct.est), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3707 | - table=9 (ls_in_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;) |
3708 | - table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
3709 | - table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
3710 | - table=9 (ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
3711 | + table=9 (ls_in_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_mark.blocked == 1))), action=(reg0[[1]] = 1; next;) |
3712 | + table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
3713 | + table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
3714 | + table=9 (ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
3715 | ]) |
3716 | |
3717 | AS_BOX([Check match ct_state with load balancer]) |
3718 | @@ -2254,38 +2254,38 @@ check ovn-nbctl --wait=sb \ |
3719 | AT_CHECK([ovn-sbctl lflow-list ls | grep -e ls_in_acl_hint -e ls_out_acl_hint -e ls_in_acl -e ls_out_acl | sort], [0], [dnl |
3720 | table=13(ls_in_acl_after_lb ), priority=0 , match=(1), action=(next;) |
3721 | table=3 (ls_out_acl_hint ), priority=0 , match=(1), action=(next;) |
3722 | - table=3 (ls_out_acl_hint ), priority=1 , match=(ct.est && ct_label.blocked == 0), action=(reg0[[10]] = 1; next;) |
3723 | - table=3 (ls_out_acl_hint ), priority=2 , match=(ct.est && ct_label.blocked == 1), action=(reg0[[9]] = 1; next;) |
3724 | + table=3 (ls_out_acl_hint ), priority=1 , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;) |
3725 | + table=3 (ls_out_acl_hint ), priority=2 , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;) |
3726 | table=3 (ls_out_acl_hint ), priority=3 , match=(!ct.est), action=(reg0[[9]] = 1; next;) |
3727 | - table=3 (ls_out_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
3728 | + table=3 (ls_out_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
3729 | table=3 (ls_out_acl_hint ), priority=5 , match=(!ct.trk), action=(reg0[[8]] = 1; reg0[[9]] = 1; next;) |
3730 | - table=3 (ls_out_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3731 | + table=3 (ls_out_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3732 | table=3 (ls_out_acl_hint ), priority=7 , match=(ct.new && !ct.est), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3733 | table=4 (ls_out_acl ), priority=0 , match=(1), action=(next;) |
3734 | - table=4 (ls_out_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;) |
3735 | + table=4 (ls_out_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_mark.blocked == 1))), action=(reg0[[1]] = 1; next;) |
3736 | table=4 (ls_out_acl ), priority=1001 , match=(reg0[[7]] == 1 && (ip)), action=(reg0[[1]] = 1; next;) |
3737 | table=4 (ls_out_acl ), priority=1001 , match=(reg0[[8]] == 1 && (ip)), action=(next;) |
3738 | table=4 (ls_out_acl ), priority=34000, match=(eth.src == $svc_monitor_mac), action=(next;) |
3739 | - table=4 (ls_out_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
3740 | - table=4 (ls_out_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(next;) |
3741 | - table=4 (ls_out_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
3742 | + table=4 (ls_out_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
3743 | + table=4 (ls_out_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(next;) |
3744 | + table=4 (ls_out_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
3745 | table=4 (ls_out_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
3746 | table=8 (ls_in_acl_hint ), priority=0 , match=(1), action=(next;) |
3747 | - table=8 (ls_in_acl_hint ), priority=1 , match=(ct.est && ct_label.blocked == 0), action=(reg0[[10]] = 1; next;) |
3748 | - table=8 (ls_in_acl_hint ), priority=2 , match=(ct.est && ct_label.blocked == 1), action=(reg0[[9]] = 1; next;) |
3749 | + table=8 (ls_in_acl_hint ), priority=1 , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;) |
3750 | + table=8 (ls_in_acl_hint ), priority=2 , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;) |
3751 | table=8 (ls_in_acl_hint ), priority=3 , match=(!ct.est), action=(reg0[[9]] = 1; next;) |
3752 | - table=8 (ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
3753 | + table=8 (ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
3754 | table=8 (ls_in_acl_hint ), priority=5 , match=(!ct.trk), action=(reg0[[8]] = 1; reg0[[9]] = 1; next;) |
3755 | - table=8 (ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3756 | + table=8 (ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3757 | table=8 (ls_in_acl_hint ), priority=7 , match=(ct.new && !ct.est), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
3758 | table=9 (ls_in_acl ), priority=0 , match=(1), action=(next;) |
3759 | - table=9 (ls_in_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;) |
3760 | + table=9 (ls_in_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_mark.blocked == 1))), action=(reg0[[1]] = 1; next;) |
3761 | table=9 (ls_in_acl ), priority=1001 , match=(reg0[[7]] == 1 && (ip)), action=(reg0[[1]] = 1; next;) |
3762 | table=9 (ls_in_acl ), priority=1001 , match=(reg0[[8]] == 1 && (ip)), action=(next;) |
3763 | table=9 (ls_in_acl ), priority=34000, match=(eth.dst == $svc_monitor_mac), action=(next;) |
3764 | - table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
3765 | - table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
3766 | - table=9 (ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
3767 | + table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
3768 | + table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
3769 | + table=9 (ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
3770 | table=9 (ls_in_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
3771 | ]) |
3772 | |
3773 | @@ -2928,12 +2928,12 @@ ovn-nbctl --wait=sb sync |
3774 | flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}" |
3775 | AT_CHECK_UNQUOTED([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl |
3776 | # tcp,reg14=0x${lsp1_inport},vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0 |
3777 | -ct_lb { |
3778 | - ct_lb { |
3779 | +ct_lb_mark { |
3780 | + ct_lb_mark { |
3781 | reg0[[6]] = 0; |
3782 | *** chk_lb_hairpin_reply action not implemented; |
3783 | reg0[[12]] = 0; |
3784 | - ct_lb /* default (use --ct to customize) */ { |
3785 | + ct_lb_mark /* default (use --ct to customize) */ { |
3786 | output("lsp2"); |
3787 | }; |
3788 | }; |
3789 | @@ -2944,12 +2944,12 @@ ct_lb { |
3790 | flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}" |
3791 | AT_CHECK_UNQUOTED([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl |
3792 | # udp,reg14=0x${lsp1_inport},vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80 |
3793 | -ct_lb { |
3794 | - ct_lb { |
3795 | +ct_lb_mark { |
3796 | + ct_lb_mark { |
3797 | reg0[[6]] = 0; |
3798 | *** chk_lb_hairpin_reply action not implemented; |
3799 | reg0[[12]] = 0; |
3800 | - ct_lb /* default (use --ct to customize) */ { |
3801 | + ct_lb_mark /* default (use --ct to customize) */ { |
3802 | output("lsp2"); |
3803 | }; |
3804 | }; |
3805 | @@ -2966,12 +2966,12 @@ ovn-nbctl --wait=sb sync |
3806 | flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}" |
3807 | AT_CHECK_UNQUOTED([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl |
3808 | # tcp,reg14=0x${lsp1_inport},vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0 |
3809 | -ct_lb { |
3810 | - ct_lb { |
3811 | +ct_lb_mark { |
3812 | + ct_lb_mark { |
3813 | reg0[[6]] = 0; |
3814 | *** chk_lb_hairpin_reply action not implemented; |
3815 | reg0[[12]] = 0; |
3816 | - ct_lb /* default (use --ct to customize) */ { |
3817 | + ct_lb_mark /* default (use --ct to customize) */ { |
3818 | output("lsp2"); |
3819 | }; |
3820 | }; |
3821 | @@ -2982,12 +2982,12 @@ ct_lb { |
3822 | flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}" |
3823 | AT_CHECK_UNQUOTED([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl |
3824 | # udp,reg14=0x${lsp1_inport},vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80 |
3825 | -ct_lb { |
3826 | - ct_lb { |
3827 | +ct_lb_mark { |
3828 | + ct_lb_mark { |
3829 | reg0[[6]] = 0; |
3830 | *** chk_lb_hairpin_reply action not implemented; |
3831 | reg0[[12]] = 0; |
3832 | - ct_lb /* default (use --ct to customize) */ { |
3833 | + ct_lb_mark /* default (use --ct to customize) */ { |
3834 | output("lsp2"); |
3835 | }; |
3836 | }; |
3837 | @@ -3084,12 +3084,12 @@ ovn-nbctl --wait=sb sync |
3838 | flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}" |
3839 | AT_CHECK_UNQUOTED([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl |
3840 | # tcp,reg14=0x${lsp1_inport},vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0 |
3841 | -ct_lb { |
3842 | - ct_lb { |
3843 | +ct_lb_mark { |
3844 | + ct_lb_mark { |
3845 | reg0[[6]] = 0; |
3846 | *** chk_lb_hairpin_reply action not implemented; |
3847 | reg0[[12]] = 0; |
3848 | - ct_lb /* default (use --ct to customize) */ { |
3849 | + ct_lb_mark /* default (use --ct to customize) */ { |
3850 | output("lsp2"); |
3851 | }; |
3852 | }; |
3853 | @@ -3100,12 +3100,12 @@ ct_lb { |
3854 | flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}" |
3855 | AT_CHECK_UNQUOTED([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl |
3856 | # udp,reg14=0x${lsp1_inport},vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80 |
3857 | -ct_lb { |
3858 | - ct_lb { |
3859 | +ct_lb_mark { |
3860 | + ct_lb_mark { |
3861 | reg0[[6]] = 0; |
3862 | *** chk_lb_hairpin_reply action not implemented; |
3863 | reg0[[12]] = 0; |
3864 | - ct_lb /* default (use --ct to customize) */ { |
3865 | + ct_lb_mark /* default (use --ct to customize) */ { |
3866 | output("lsp2"); |
3867 | }; |
3868 | }; |
3869 | @@ -3122,12 +3122,12 @@ ovn-nbctl --wait=sb sync |
3870 | flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_tcp}" |
3871 | AT_CHECK_UNQUOTED([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl |
3872 | # tcp,reg14=0x${lsp1_inport},vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80,tcp_flags=0 |
3873 | -ct_lb { |
3874 | - ct_lb { |
3875 | +ct_lb_mark { |
3876 | + ct_lb_mark { |
3877 | reg0[[6]] = 0; |
3878 | *** chk_lb_hairpin_reply action not implemented; |
3879 | reg0[[12]] = 0; |
3880 | - ct_lb /* default (use --ct to customize) */ { |
3881 | + ct_lb_mark /* default (use --ct to customize) */ { |
3882 | output("lsp2"); |
3883 | }; |
3884 | }; |
3885 | @@ -3138,12 +3138,12 @@ ct_lb { |
3886 | flow="inport == \"lsp1\" && ${flow_eth} && ${flow_ip} && ${flow_udp}" |
3887 | AT_CHECK_UNQUOTED([ovn-trace --ct new --ct new --minimal ls "${flow}"], [0], [dnl |
3888 | # udp,reg14=0x${lsp1_inport},vlan_tci=0x0000,dl_src=00:00:00:00:00:01,dl_dst=00:00:00:00:00:02,nw_src=42.42.42.1,nw_dst=66.66.66.66,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=80 |
3889 | -ct_lb { |
3890 | - ct_lb { |
3891 | +ct_lb_mark { |
3892 | + ct_lb_mark { |
3893 | reg0[[6]] = 0; |
3894 | *** chk_lb_hairpin_reply action not implemented; |
3895 | reg0[[12]] = 0; |
3896 | - ct_lb /* default (use --ct to customize) */ { |
3897 | + ct_lb_mark /* default (use --ct to customize) */ { |
3898 | output("lsp2"); |
3899 | }; |
3900 | }; |
3901 | @@ -3447,7 +3447,7 @@ ls_copp_uuid=$(fetch_column nb:Logical_Switch copp) |
3902 | AT_CHECK([test "$ls_copp_uuid" = "$copp_uuid"]) |
3903 | |
3904 | check ovn-nbctl --wait=hv copp-add $copp_uuid igmp meter0 |
3905 | -AT_CHECK([ovn-nbctl copp-list copp0], [0], [dnl |
3906 | +AT_CHECK([ovn-nbctl copp-list copp0 | sort], [0], [dnl |
3907 | arp: meter0 |
3908 | igmp: meter0 |
3909 | ]) |
3910 | @@ -3589,10 +3589,10 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
3911 | |
3912 | AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl |
3913 | table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) |
3914 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(next;) |
3915 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(next;) |
3916 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(ct_lb(backends=10.0.0.4:8080);) |
3917 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(ct_lb(backends=10.0.0.40:8080);) |
3918 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(next;) |
3919 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(next;) |
3920 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(ct_lb_mark(backends=10.0.0.4:8080);) |
3921 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(ct_lb_mark(backends=10.0.0.40:8080);) |
3922 | ]) |
3923 | |
3924 | AT_CHECK([grep "lr_out_undnat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
3925 | @@ -3625,10 +3625,10 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
3926 | |
3927 | AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl |
3928 | table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) |
3929 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3930 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3931 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.4:8080);) |
3932 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.40:8080);) |
3933 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3934 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3935 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) |
3936 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080);) |
3937 | ]) |
3938 | |
3939 | AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
3940 | @@ -3671,10 +3671,10 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
3941 | |
3942 | AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl |
3943 | table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) |
3944 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3945 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3946 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.4:8080);) |
3947 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.40:8080);) |
3948 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3949 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3950 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) |
3951 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080);) |
3952 | ]) |
3953 | |
3954 | AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
3955 | @@ -3731,10 +3731,10 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
3956 | |
3957 | AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl |
3958 | table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) |
3959 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3960 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3961 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.4:8080);) |
3962 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.40:8080);) |
3963 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3964 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
3965 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) |
3966 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.100 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080);) |
3967 | ]) |
3968 | |
3969 | AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
3970 | @@ -3777,8 +3777,8 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
3971 | ]) |
3972 | |
3973 | AT_CHECK([grep "lr_in_dnat" lr0flows | grep skip_snat_for_lb | sort], [0], [dnl |
3974 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.20 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(flags.skip_snat_for_lb = 1; next;) |
3975 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.20 && tcp && reg9[[16..31]] == 80), action=(flags.skip_snat_for_lb = 1; ct_lb(backends=10.0.0.40:8080);) |
3976 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.20 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.skip_snat_for_lb = 1; next;) |
3977 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.20 && tcp && reg9[[16..31]] == 80), action=(flags.skip_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.40:8080);) |
3978 | ]) |
3979 | |
3980 | AT_CHECK([grep "lr_out_snat" lr0flows | grep skip_snat_for_lb | sed 's/table=./table=?/' | sort], [0], [dnl |
3981 | @@ -3941,25 +3941,25 @@ check_stateful_flows() { |
3982 | AT_CHECK([grep "ls_in_pre_stateful" sw0flows | sort], [0], [dnl |
3983 | table=7 (ls_in_pre_stateful ), priority=0 , match=(1), action=(next;) |
3984 | table=7 (ls_in_pre_stateful ), priority=100 , match=(reg0[[0]] == 1), action=(ct_next;) |
3985 | - table=7 (ls_in_pre_stateful ), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb;) |
3986 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && sctp), action=(reg1 = ip4.dst; reg2[[0..15]] = sctp.dst; ct_lb;) |
3987 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && tcp), action=(reg1 = ip4.dst; reg2[[0..15]] = tcp.dst; ct_lb;) |
3988 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && udp), action=(reg1 = ip4.dst; reg2[[0..15]] = udp.dst; ct_lb;) |
3989 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = sctp.dst; ct_lb;) |
3990 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = tcp.dst; ct_lb;) |
3991 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && udp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = udp.dst; ct_lb;) |
3992 | + table=7 (ls_in_pre_stateful ), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb_mark;) |
3993 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && sctp), action=(reg1 = ip4.dst; reg2[[0..15]] = sctp.dst; ct_lb_mark;) |
3994 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && tcp), action=(reg1 = ip4.dst; reg2[[0..15]] = tcp.dst; ct_lb_mark;) |
3995 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && udp), action=(reg1 = ip4.dst; reg2[[0..15]] = udp.dst; ct_lb_mark;) |
3996 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = sctp.dst; ct_lb_mark;) |
3997 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = tcp.dst; ct_lb_mark;) |
3998 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && udp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = udp.dst; ct_lb_mark;) |
3999 | ]) |
4000 | |
4001 | AT_CHECK([grep "ls_in_lb" sw0flows | sort], [0], [dnl |
4002 | table=12(ls_in_lb ), priority=0 , match=(1), action=(next;) |
4003 | - table=12(ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.4:8080);) |
4004 | - table=12(ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.20 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.20; reg2[[0..15]] = 80; ct_lb(backends=10.0.0.40:8080);) |
4005 | + table=12(ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.10 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.10; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.4:8080);) |
4006 | + table=12(ls_in_lb ), priority=120 , match=(ct.new && ip4.dst == 10.0.0.20 && tcp.dst == 80), action=(reg0[[1]] = 0; reg1 = 10.0.0.20; reg2[[0..15]] = 80; ct_lb_mark(backends=10.0.0.40:8080);) |
4007 | ]) |
4008 | |
4009 | AT_CHECK([grep "ls_in_stateful" sw0flows | sort], [0], [dnl |
4010 | table=14(ls_in_stateful ), priority=0 , match=(1), action=(next;) |
4011 | - table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4012 | - table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4013 | + table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4014 | + table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4015 | ]) |
4016 | |
4017 | AT_CHECK([grep "ls_out_pre_lb" sw0flows | sort], [0], [dnl |
4018 | @@ -3974,15 +3974,15 @@ check_stateful_flows() { |
4019 | AT_CHECK([grep "ls_out_pre_stateful" sw0flows | sort], [0], [dnl |
4020 | table=2 (ls_out_pre_stateful), priority=0 , match=(1), action=(next;) |
4021 | table=2 (ls_out_pre_stateful), priority=100 , match=(reg0[[0]] == 1), action=(ct_next;) |
4022 | - table=2 (ls_out_pre_stateful), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb;) |
4023 | + table=2 (ls_out_pre_stateful), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb_mark;) |
4024 | ]) |
4025 | |
4026 | AT_CHECK([grep "ls_out_lb" sw0flows | sort], [0], []) |
4027 | |
4028 | AT_CHECK([grep "ls_out_stateful" sw0flows | sort], [0], [dnl |
4029 | table=7 (ls_out_stateful ), priority=0 , match=(1), action=(next;) |
4030 | - table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4031 | - table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4032 | + table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4033 | + table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4034 | ]) |
4035 | } |
4036 | |
4037 | @@ -4013,13 +4013,13 @@ AT_CHECK([grep "ls_in_pre_lb" sw0flows | sort], [0], [dnl |
4038 | AT_CHECK([grep "ls_in_pre_stateful" sw0flows | sort], [0], [dnl |
4039 | table=7 (ls_in_pre_stateful ), priority=0 , match=(1), action=(next;) |
4040 | table=7 (ls_in_pre_stateful ), priority=100 , match=(reg0[[0]] == 1), action=(ct_next;) |
4041 | - table=7 (ls_in_pre_stateful ), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb;) |
4042 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && sctp), action=(reg1 = ip4.dst; reg2[[0..15]] = sctp.dst; ct_lb;) |
4043 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && tcp), action=(reg1 = ip4.dst; reg2[[0..15]] = tcp.dst; ct_lb;) |
4044 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && udp), action=(reg1 = ip4.dst; reg2[[0..15]] = udp.dst; ct_lb;) |
4045 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = sctp.dst; ct_lb;) |
4046 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = tcp.dst; ct_lb;) |
4047 | - table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && udp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = udp.dst; ct_lb;) |
4048 | + table=7 (ls_in_pre_stateful ), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb_mark;) |
4049 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && sctp), action=(reg1 = ip4.dst; reg2[[0..15]] = sctp.dst; ct_lb_mark;) |
4050 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && tcp), action=(reg1 = ip4.dst; reg2[[0..15]] = tcp.dst; ct_lb_mark;) |
4051 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && udp), action=(reg1 = ip4.dst; reg2[[0..15]] = udp.dst; ct_lb_mark;) |
4052 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = sctp.dst; ct_lb_mark;) |
4053 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = tcp.dst; ct_lb_mark;) |
4054 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && udp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = udp.dst; ct_lb_mark;) |
4055 | ]) |
4056 | |
4057 | AT_CHECK([grep "ls_in_lb" sw0flows | sort], [0], [dnl |
4058 | @@ -4028,8 +4028,8 @@ AT_CHECK([grep "ls_in_lb" sw0flows | sort], [0], [dnl |
4059 | |
4060 | AT_CHECK([grep "ls_in_stateful" sw0flows | sort], [0], [dnl |
4061 | table=14(ls_in_stateful ), priority=0 , match=(1), action=(next;) |
4062 | - table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4063 | - table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4064 | + table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4065 | + table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4066 | ]) |
4067 | |
4068 | AT_CHECK([grep "ls_out_pre_lb" sw0flows | sort], [0], [dnl |
4069 | @@ -4043,13 +4043,13 @@ AT_CHECK([grep "ls_out_pre_lb" sw0flows | sort], [0], [dnl |
4070 | AT_CHECK([grep "ls_out_pre_stateful" sw0flows | sort], [0], [dnl |
4071 | table=2 (ls_out_pre_stateful), priority=0 , match=(1), action=(next;) |
4072 | table=2 (ls_out_pre_stateful), priority=100 , match=(reg0[[0]] == 1), action=(ct_next;) |
4073 | - table=2 (ls_out_pre_stateful), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb;) |
4074 | + table=2 (ls_out_pre_stateful), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb_mark;) |
4075 | ]) |
4076 | |
4077 | AT_CHECK([grep "ls_out_stateful" sw0flows | sort], [0], [dnl |
4078 | table=7 (ls_out_stateful ), priority=0 , match=(1), action=(next;) |
4079 | - table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4080 | - table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4081 | + table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4082 | + table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4083 | ]) |
4084 | |
4085 | AT_CLEANUP |
4086 | @@ -4074,8 +4074,8 @@ AT_CHECK([grep -w "ls_in_acl" sw0flows | grep 2002 | sort], [0], [dnl |
4087 | ]) |
4088 | AT_CHECK([grep "ls_in_stateful" sw0flows | sort], [0], [dnl |
4089 | table=14(ls_in_stateful ), priority=0 , match=(1), action=(next;) |
4090 | - table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4091 | - table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4092 | + table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4093 | + table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4094 | ]) |
4095 | |
4096 | AT_CHECK([grep -w "ls_out_acl" sw0flows | grep 2002 | sort], [0], [dnl |
4097 | @@ -4084,8 +4084,8 @@ AT_CHECK([grep -w "ls_out_acl" sw0flows | grep 2002 | sort], [0], [dnl |
4098 | ]) |
4099 | AT_CHECK([grep "ls_out_stateful" sw0flows | sort], [0], [dnl |
4100 | table=7 (ls_out_stateful ), priority=0 , match=(1), action=(next;) |
4101 | - table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4102 | - table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4103 | + table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4104 | + table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4105 | ]) |
4106 | |
4107 | # Add new ACL without label |
4108 | @@ -4103,8 +4103,8 @@ AT_CHECK([grep -w "ls_in_acl" sw0flows | grep 2002 | sort], [0], [dnl |
4109 | ]) |
4110 | AT_CHECK([grep "ls_in_stateful" sw0flows | sort], [0], [dnl |
4111 | table=14(ls_in_stateful ), priority=0 , match=(1), action=(next;) |
4112 | - table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4113 | - table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4114 | + table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4115 | + table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4116 | ]) |
4117 | |
4118 | AT_CHECK([grep -w "ls_out_acl" sw0flows | grep 2002 | sort], [0], [dnl |
4119 | @@ -4115,8 +4115,8 @@ AT_CHECK([grep -w "ls_out_acl" sw0flows | grep 2002 | sort], [0], [dnl |
4120 | ]) |
4121 | AT_CHECK([grep "ls_out_stateful" sw0flows | sort], [0], [dnl |
4122 | table=7 (ls_out_stateful ), priority=0 , match=(1), action=(next;) |
4123 | - table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4124 | - table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4125 | + table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4126 | + table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4127 | ]) |
4128 | |
4129 | # Delete new ACL with label |
4130 | @@ -4132,8 +4132,8 @@ AT_CHECK([grep -w "ls_in_acl" sw0flows | grep 2002 | sort], [0], [dnl |
4131 | ]) |
4132 | AT_CHECK([grep "ls_in_stateful" sw0flows | sort], [0], [dnl |
4133 | table=14(ls_in_stateful ), priority=0 , match=(1), action=(next;) |
4134 | - table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4135 | - table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4136 | + table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4137 | + table=14(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4138 | ]) |
4139 | |
4140 | AT_CHECK([grep -w "ls_out_acl" sw0flows | grep 2002 | sort], [0], [dnl |
4141 | @@ -4142,8 +4142,8 @@ AT_CHECK([grep -w "ls_out_acl" sw0flows | grep 2002 | sort], [0], [dnl |
4142 | ]) |
4143 | AT_CHECK([grep "ls_out_stateful" sw0flows | sort], [0], [dnl |
4144 | table=7 (ls_out_stateful ), priority=0 , match=(1), action=(next;) |
4145 | - table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4146 | - table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4147 | + table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4148 | + table=7 (ls_out_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4149 | ]) |
4150 | AT_CLEANUP |
4151 | ]) |
4152 | @@ -4161,16 +4161,16 @@ ovn-sbctl dump-flows sw0 > sw0flows |
4153 | AT_CAPTURE_FILE([sw0flows]) |
4154 | |
4155 | AT_CHECK([grep -w "ls_in_acl" sw0flows | grep 6553 | sort], [0], [dnl |
4156 | - table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
4157 | - table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4158 | - table=9 (ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
4159 | + table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
4160 | + table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4161 | + table=9 (ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
4162 | table=9 (ls_in_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
4163 | ]) |
4164 | |
4165 | AT_CHECK([grep -w "ls_out_acl" sw0flows | grep 6553 | sort], [0], [dnl |
4166 | - table=4 (ls_out_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
4167 | - table=4 (ls_out_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(next;) |
4168 | - table=4 (ls_out_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
4169 | + table=4 (ls_out_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
4170 | + table=4 (ls_out_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(next;) |
4171 | + table=4 (ls_out_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
4172 | table=4 (ls_out_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
4173 | ]) |
4174 | |
4175 | @@ -4181,16 +4181,16 @@ ovn-sbctl dump-flows sw0 > sw0flows |
4176 | AT_CAPTURE_FILE([sw0flows]) |
4177 | |
4178 | AT_CHECK([grep -w "ls_in_acl" sw0flows | grep 6553 | sort], [0], [dnl |
4179 | - table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && ct_label.blocked == 0), action=(next;) |
4180 | - table=9 (ls_in_acl ), priority=65532, match=((ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
4181 | - table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && ct.rpl && ct_label.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4182 | + table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && ct_mark.blocked == 0), action=(next;) |
4183 | + table=9 (ls_in_acl ), priority=65532, match=((ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
4184 | + table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4185 | table=9 (ls_in_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
4186 | ]) |
4187 | |
4188 | AT_CHECK([grep -w "ls_out_acl" sw0flows | grep 6553 | sort], [0], [dnl |
4189 | - table=4 (ls_out_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && ct_label.blocked == 0), action=(next;) |
4190 | - table=4 (ls_out_acl ), priority=65532, match=((ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
4191 | - table=4 (ls_out_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && ct.rpl && ct_label.blocked == 0), action=(next;) |
4192 | + table=4 (ls_out_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && ct_mark.blocked == 0), action=(next;) |
4193 | + table=4 (ls_out_acl ), priority=65532, match=((ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
4194 | + table=4 (ls_out_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && ct.rpl && ct_mark.blocked == 0), action=(next;) |
4195 | table=4 (ls_out_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
4196 | ]) |
4197 | |
4198 | @@ -4205,16 +4205,16 @@ ovn-sbctl dump-flows sw0 > sw0flows |
4199 | AT_CAPTURE_FILE([sw0flows]) |
4200 | |
4201 | AT_CHECK([grep -w "ls_in_acl" sw0flows | grep 6553 | sort], [0], [dnl |
4202 | - table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
4203 | - table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4204 | - table=9 (ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
4205 | + table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
4206 | + table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4207 | + table=9 (ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
4208 | table=9 (ls_in_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
4209 | ]) |
4210 | |
4211 | AT_CHECK([grep -w "ls_out_acl" sw0flows | grep 6553 | sort], [0], [dnl |
4212 | - table=4 (ls_out_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
4213 | - table=4 (ls_out_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(next;) |
4214 | - table=4 (ls_out_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
4215 | + table=4 (ls_out_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
4216 | + table=4 (ls_out_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(next;) |
4217 | + table=4 (ls_out_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
4218 | table=4 (ls_out_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
4219 | ]) |
4220 | |
4221 | @@ -4946,7 +4946,8 @@ AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [ |
4222 | table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) |
4223 | ]) |
4224 | |
4225 | -ovn-sbctl chassis-add gw1 geneve 127.0.0.1 |
4226 | +check ovn-sbctl chassis-add gw1 geneve 127.0.0.1 \ |
4227 | + -- set chassis gw1 other_config:ct-no-masked-label="true" |
4228 | |
4229 | # Create a distributed gw port on lr0 |
4230 | check ovn-nbctl ls-add public |
4231 | @@ -5045,14 +5046,14 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
4232 | AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl |
4233 | table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) |
4234 | table=6 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(ct_dnat_in_czone(10.0.0.3);) |
4235 | - table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_label.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;) |
4236 | - table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200 && is_chassis_resident("cr-lr0-public")), action=(ct_lb(backends=10.0.0.80,10.0.0.81);) |
4237 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;) |
4238 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_label.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;) |
4239 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_label.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;) |
4240 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && is_chassis_resident("cr-lr0-public")), action=(ct_lb(backends=10.0.0.4:8080);) |
4241 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && is_chassis_resident("cr-lr0-public")), action=(ct_lb(backends=10.0.0.50:82,10.0.0.60:82);) |
4242 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && is_chassis_resident("cr-lr0-public")), action=(ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4243 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;) |
4244 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);) |
4245 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;) |
4246 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_mark.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;) |
4247 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_mark.natted == 1 && is_chassis_resident("cr-lr0-public")), action=(next;) |
4248 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.4:8080);) |
4249 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) |
4250 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && is_chassis_resident("cr-lr0-public")), action=(ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4251 | ]) |
4252 | |
4253 | AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
4254 | @@ -5113,14 +5114,14 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
4255 | AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl |
4256 | table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) |
4257 | table=6 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) |
4258 | - table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_label.natted == 1), action=(next;) |
4259 | - table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200), action=(ct_lb(backends=10.0.0.80,10.0.0.81);) |
4260 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(next;) |
4261 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_label.natted == 1), action=(next;) |
4262 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_label.natted == 1), action=(next;) |
4263 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(ct_lb(backends=10.0.0.4:8080);) |
4264 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(ct_lb(backends=10.0.0.50:82,10.0.0.60:82);) |
4265 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4266 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1), action=(next;) |
4267 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200), action=(ct_lb_mark(backends=10.0.0.80,10.0.0.81);) |
4268 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(next;) |
4269 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_mark.natted == 1), action=(next;) |
4270 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(next;) |
4271 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(ct_lb_mark(backends=10.0.0.4:8080);) |
4272 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) |
4273 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4274 | ]) |
4275 | |
4276 | AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
4277 | @@ -5140,11 +5141,12 @@ AT_CHECK([grep "lr_out_post_undnat" lr0flows | sed 's/table=./table=?/' | sort], |
4278 | AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
4279 | table=? (lr_out_snat ), priority=0 , match=(1), action=(next;) |
4280 | table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) |
4281 | - table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) |
4282 | - table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) |
4283 | - table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) |
4284 | + table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);) |
4285 | + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);) |
4286 | + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);) |
4287 | ]) |
4288 | |
4289 | + |
4290 | # Set lb force snat logical router. |
4291 | check ovn-nbctl --wait=sb set logical_router lr0 options:lb_force_snat_ip="router_ip" |
4292 | check ovn-nbctl --wait=sb sync |
4293 | @@ -5172,14 +5174,14 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
4294 | AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl |
4295 | table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) |
4296 | table=6 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) |
4297 | - table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4298 | - table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.80,10.0.0.81);) |
4299 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4300 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4301 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4302 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.4:8080);) |
4303 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:82,10.0.0.60:82);) |
4304 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4305 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4306 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81);) |
4307 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4308 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4309 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4310 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) |
4311 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) |
4312 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4313 | ]) |
4314 | |
4315 | AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
4316 | @@ -5201,9 +5203,9 @@ AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [ |
4317 | table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) |
4318 | table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) |
4319 | table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) |
4320 | - table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) |
4321 | - table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) |
4322 | - table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) |
4323 | + table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);) |
4324 | + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);) |
4325 | + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);) |
4326 | ]) |
4327 | |
4328 | # Add a LB VIP same as router ip. |
4329 | @@ -5235,16 +5237,16 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
4330 | AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl |
4331 | table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) |
4332 | table=6 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) |
4333 | - table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4334 | - table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.80,10.0.0.81);) |
4335 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4336 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4337 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4338 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4339 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.4:8080);) |
4340 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:82,10.0.0.60:82);) |
4341 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:82,10.0.0.60:82);) |
4342 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4343 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4344 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81);) |
4345 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4346 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4347 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4348 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4349 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) |
4350 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) |
4351 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) |
4352 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4353 | ]) |
4354 | |
4355 | AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
4356 | @@ -5266,9 +5268,9 @@ AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [ |
4357 | table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-public"), action=(ct_snat(172.168.0.10);) |
4358 | table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip4 && outport == "lr0-sw0"), action=(ct_snat(10.0.0.1);) |
4359 | table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) |
4360 | - table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) |
4361 | - table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) |
4362 | - table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) |
4363 | + table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);) |
4364 | + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);) |
4365 | + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);) |
4366 | ]) |
4367 | |
4368 | # Add IPv6 router port and LB. |
4369 | @@ -5311,18 +5313,18 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
4370 | AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl |
4371 | table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) |
4372 | table=6 (lr_in_dnat ), priority=100 , match=(ip && ip4.dst == 172.168.0.20), action=(flags.loopback = 1; ct_dnat(10.0.0.3);) |
4373 | - table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4374 | - table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.80,10.0.0.81);) |
4375 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4376 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4377 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4378 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4379 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip6 && xxreg0 == def0::2 && tcp && reg9[[16..31]] == 8000 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4380 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.4:8080);) |
4381 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:82,10.0.0.60:82);) |
4382 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:82,10.0.0.60:82);) |
4383 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4384 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip6 && xxreg0 == def0::2 && tcp && reg9[[16..31]] == 8000), action=(flags.force_snat_for_lb = 1; ct_lb(backends=[[aef0::2]]:80,[[aef0::3]]:80);) |
4385 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 172.168.0.200 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4386 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 172.168.0.200), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.80,10.0.0.81);) |
4387 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4388 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4389 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4390 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4391 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip6 && xxreg0 == def0::2 && tcp && reg9[[16..31]] == 8000 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4392 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 10.0.0.10 && tcp && reg9[[16..31]] == 80), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.4:8080);) |
4393 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.10 && tcp && reg9[[16..31]] == 9082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) |
4394 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.100 && tcp && reg9[[16..31]] == 8082), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:82,10.0.0.60:82);) |
4395 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4396 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip6 && xxreg0 == def0::2 && tcp && reg9[[16..31]] == 8000), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=[[aef0::2]]:80,[[aef0::3]]:80);) |
4397 | ]) |
4398 | |
4399 | AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
4400 | @@ -5346,9 +5348,9 @@ AT_CHECK([grep "lr_out_snat" lr0flows | sed 's/table=./table=?/' | sort], [0], [ |
4401 | table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-public"), action=(ct_snat(def0::10);) |
4402 | table=? (lr_out_snat ), priority=110 , match=(flags.force_snat_for_lb == 1 && ip6 && outport == "lr0-sw0"), action=(ct_snat(aef0::1);) |
4403 | table=? (lr_out_snat ), priority=120 , match=(nd_ns), action=(next;) |
4404 | - table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24), action=(ct_snat(172.168.0.10);) |
4405 | - table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10), action=(ct_snat(172.168.0.30);) |
4406 | - table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3), action=(ct_snat(172.168.0.20);) |
4407 | + table=? (lr_out_snat ), priority=25 , match=(ip && ip4.src == 10.0.0.0/24 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.10);) |
4408 | + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.10 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.30);) |
4409 | + table=? (lr_out_snat ), priority=33 , match=(ip && ip4.src == 10.0.0.3 && (!ct.trk || !ct.rpl)), action=(ct_snat(172.168.0.20);) |
4410 | ]) |
4411 | |
4412 | check ovn-nbctl lrp-del lr0-sw0 |
4413 | @@ -5377,10 +5379,10 @@ AT_CHECK([grep "lr_in_defrag" lr0flows | sort], [0], [dnl |
4414 | |
4415 | AT_CHECK([grep "lr_in_dnat" lr0flows | sort], [0], [dnl |
4416 | table=6 (lr_in_dnat ), priority=0 , match=(1), action=(next;) |
4417 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && tcp && reg9[[16..31]] == 60 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4418 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_label.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4419 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && tcp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4420 | - table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4421 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && tcp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4422 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.est && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60 && ct_mark.natted == 1), action=(flags.force_snat_for_lb = 1; next;) |
4423 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && tcp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4424 | + table=6 (lr_in_dnat ), priority=120 , match=(ct.new && ip4 && reg0 == 172.168.0.210 && udp && reg9[[16..31]] == 60), action=(flags.force_snat_for_lb = 1; ct_lb_mark(backends=10.0.0.50:6062,10.0.0.60:6062);) |
4425 | ]) |
4426 | |
4427 | AT_CHECK([grep "lr_out_chk_dnat_local" lr0flows | sed 's/table=./table=?/' | sort], [0], [dnl |
4428 | @@ -5490,7 +5492,7 @@ AT_CAPTURE_FILE([lr0flows]) |
4429 | |
4430 | AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl |
4431 | table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) |
4432 | - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) |
4433 | + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); next;) |
4434 | table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) |
4435 | table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) |
4436 | table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) |
4437 | @@ -5499,8 +5501,8 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=. |
4438 | ]) |
4439 | |
4440 | AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl |
4441 | - table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4442 | - table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4443 | + table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public" && is_chassis_resident("cr-lr0-public")), action=(reg9[[1]] = check_pkt_larger(1514); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4444 | + table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4445 | ]) |
4446 | |
4447 | AT_CHECK([grep -E "lr_in_ip_input.*icmp4_error" lr0flows | sort], [0], [dnl |
4448 | @@ -5521,7 +5523,7 @@ AT_CAPTURE_FILE([lr0flows]) |
4449 | |
4450 | AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl |
4451 | table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) |
4452 | - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) |
4453 | + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); next;) |
4454 | table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) |
4455 | table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) |
4456 | table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff01; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1500; next(pipeline=ingress, table=0); };) |
4457 | @@ -5530,8 +5532,8 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=. |
4458 | ]) |
4459 | |
4460 | AT_CHECK([grep -E "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl |
4461 | - table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4462 | - table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4463 | + table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4464 | + table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4465 | ]) |
4466 | |
4467 | AT_CHECK([grep -E "lr_in_ip_input.*icmp4_error" lr0flows | sort], [0], [dnl |
4468 | @@ -5549,7 +5551,7 @@ AT_CAPTURE_FILE([lr0flows]) |
4469 | |
4470 | AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl |
4471 | table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) |
4472 | - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) |
4473 | + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); next;) |
4474 | table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == "lr0-public" && (tcp)), action=(next;) |
4475 | table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) |
4476 | table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw0" && outport == "lr0-public" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:01; ip4.dst = ip4.src; ip4.src = 10.0.0.1; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1500; next(pipeline=ingress, table=0); };) |
4477 | @@ -5559,8 +5561,8 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=. |
4478 | ]) |
4479 | |
4480 | AT_CHECK([grep "lr_in_admission" lr0flows | grep -e "check_pkt_larger" -e "tcp" | sort], [0], [dnl |
4481 | - table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4482 | - table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4483 | + table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4484 | + table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4485 | table=0 (lr_in_admission ), priority=55 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public" && (tcp)), action=(xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4486 | table=0 (lr_in_admission ), priority=55 , match=(eth.mcast && inport == "lr0-public" && (tcp)), action=(xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4487 | ]) |
4488 | @@ -5573,8 +5575,8 @@ AT_CAPTURE_FILE([lr0flows]) |
4489 | |
4490 | AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl |
4491 | table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) |
4492 | - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) |
4493 | - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) |
4494 | + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); next;) |
4495 | + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); next;) |
4496 | table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == "lr0-public" && (tcp)), action=(next;) |
4497 | table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) |
4498 | table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) |
4499 | @@ -5588,10 +5590,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=. |
4500 | ]) |
4501 | |
4502 | AT_CHECK([grep "lr_in_admission.*check_pkt_larger" lr0flows | sort], [0], [dnl |
4503 | - table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:00:00:ff:01 && inport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); xreg0[[0..47]] = 00:00:00:00:ff:01; next;) |
4504 | - table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4505 | - table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4506 | - table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); xreg0[[0..47]] = 00:00:00:00:ff:01; next;) |
4507 | + table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:00:00:ff:01 && inport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); xreg0[[0..47]] = 00:00:00:00:ff:01; next;) |
4508 | + table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4509 | + table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4510 | + table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); xreg0[[0..47]] = 00:00:00:00:ff:01; next;) |
4511 | ]) |
4512 | |
4513 | AT_CHECK([grep -E "lr_in_ip_input.*icmp4_error" lr0flows | sort], [0], [dnl |
4514 | @@ -5611,8 +5613,8 @@ AT_CAPTURE_FILE([lr0flows]) |
4515 | |
4516 | AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl |
4517 | table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) |
4518 | - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); next;) |
4519 | - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) |
4520 | + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); next;) |
4521 | + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); next;) |
4522 | table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == "lr0-public" && (tcp)), action=(next;) |
4523 | table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == "lr0-sw0" && (tcp)), action=(next;) |
4524 | table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) |
4525 | @@ -5627,10 +5629,10 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=. |
4526 | ]) |
4527 | |
4528 | AT_CHECK([grep "lr_in_admission" lr0flows | grep -e "check_pkt_larger" -e "tcp" | sort], [0], [dnl |
4529 | - table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:00:00:ff:01 && inport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); xreg0[[0..47]] = 00:00:00:00:ff:01; next;) |
4530 | - table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4531 | - table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4532 | - table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); xreg0[[0..47]] = 00:00:00:00:ff:01; next;) |
4533 | + table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:00:00:ff:01 && inport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); xreg0[[0..47]] = 00:00:00:00:ff:01; next;) |
4534 | + table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4535 | + table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1514); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4536 | + table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); xreg0[[0..47]] = 00:00:00:00:ff:01; next;) |
4537 | table=0 (lr_in_admission ), priority=55 , match=(eth.dst == 00:00:00:00:ff:01 && inport == "lr0-sw0" && (tcp)), action=(xreg0[[0..47]] = 00:00:00:00:ff:01; next;) |
4538 | table=0 (lr_in_admission ), priority=55 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public" && (tcp)), action=(xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4539 | table=0 (lr_in_admission ), priority=55 , match=(eth.mcast && inport == "lr0-public" && (tcp)), action=(xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4540 | @@ -5644,7 +5646,7 @@ AT_CAPTURE_FILE([lr0flows]) |
4541 | |
4542 | AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=../table=??/' | sort], [0], [dnl |
4543 | table=??(lr_in_chk_pkt_len ), priority=0 , match=(1), action=(next;) |
4544 | - table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1418); next;) |
4545 | + table=??(lr_in_chk_pkt_len ), priority=50 , match=(outport == "lr0-sw0"), action=(reg9[[1]] = check_pkt_larger(1414); next;) |
4546 | table=??(lr_in_chk_pkt_len ), priority=55 , match=(outport == "lr0-sw0" && (tcp)), action=(next;) |
4547 | table=??(lr_in_larger_pkts ), priority=0 , match=(1), action=(next;) |
4548 | table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-public" && outport == "lr0-sw0" && ip4 && reg9[[1]] && reg9[[0]] == 0), action=(icmp4_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:20:20:12:13; ip4.dst = ip4.src; ip4.src = 172.168.0.100; ip.ttl = 255; icmp4.type = 3; /* Destination Unreachable. */ icmp4.code = 4; /* Frag Needed and DF was Set. */ icmp4.frag_mtu = 1400; next(pipeline=ingress, table=0); };) |
4549 | @@ -5653,6 +5655,19 @@ AT_CHECK([grep -e "chk_pkt_len" -e "lr_in_larger_pkts" lr0flows | sed 's/table=. |
4550 | table=??(lr_in_larger_pkts ), priority=150 , match=(inport == "lr0-sw1" && outport == "lr0-sw0" && ip6 && reg9[[1]] && reg9[[0]] == 0), action=(icmp6_error {reg9[[0]] = 1; reg9[[1]] = 0; eth.dst = 00:00:00:00:ff:02; ip6.dst = ip6.src; ip6.src = fe80::200:ff:fe00:ff02; ip.ttl = 255; icmp6.type = 2; /* Packet Too Big. */ icmp6.code = 0; icmp6.frag_mtu = 1400; next(pipeline=ingress, table=0); };) |
4551 | ]) |
4552 | |
4553 | +check ovn-nbctl --wait=sb clear logical_router_port lr0-sw0 options |
4554 | +check ovn-nbctl --wait=sb set logical_router_port lr0-public options:gateway_mtu=1500 |
4555 | +check ovn-nbctl lsp-add public ext-port |
4556 | +check ovn-nbctl lsp-set-addresses ext-port unknown |
4557 | +check ovn-nbctl lsp-set-type ext-port localnet |
4558 | +check ovn-nbctl --wait=sb set Logical_Switch_Port ext-port tag_request=2 |
4559 | +ovn-sbctl dump-flows lr0 > lr0flows |
4560 | + |
4561 | +AT_CHECK([grep "lr_in_admission" lr0flows | grep -e "check_pkt_larger" | sort], [0], [dnl |
4562 | + table=0 (lr_in_admission ), priority=50 , match=(eth.dst == 00:00:20:20:12:13 && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4563 | + table=0 (lr_in_admission ), priority=50 , match=(eth.mcast && inport == "lr0-public"), action=(reg9[[1]] = check_pkt_larger(1518); xreg0[[0..47]] = 00:00:20:20:12:13; next;) |
4564 | +]) |
4565 | + |
4566 | AT_CLEANUP |
4567 | ]) |
4568 | |
4569 | @@ -5664,6 +5679,7 @@ ovn_start |
4570 | check ovn-sbctl chassis-add ch1 geneve 127.0.0.1 |
4571 | |
4572 | check ovn-nbctl lr-add lr0 |
4573 | +check ovn-nbctl set logical_router lr0 options:chassis=ch1 |
4574 | check ovn-nbctl ls-add public |
4575 | check ovn-nbctl lrp-add lr0 lr0-public 00:00:20:20:12:13 192.168.0.1/24 |
4576 | check ovn-nbctl lsp-add public public-lr0 |
4577 | @@ -5693,6 +5709,22 @@ AT_CHECK([grep -e "lr_in_ip_routing_ecmp" lr0flows | sed 's/192\.168\.0\..0/192. |
4578 | table=??(lr_in_ip_routing_ecmp), priority=150 , match=(reg8[[0..15]] == 0), action=(next;) |
4579 | ]) |
4580 | |
4581 | +dnl The chassis was created with other_config:ct-no-masked-label=false, the flows |
4582 | +dnl should be using ct_label.ecmp_reply_port. |
4583 | +AT_CHECK([grep -e "lr_in_arp_resolve.*ecmp" lr0flows | sed 's/table=../table=??/'], [0], [dnl |
4584 | + table=??(lr_in_arp_resolve ), priority=200 , match=(ct.rpl && ct_label.ecmp_reply_port == 1), action=(push(xxreg1); xxreg1 = ct_label; eth.dst = xxreg1[[32..79]]; pop(xxreg1); next;) |
4585 | +]) |
4586 | + |
4587 | +dnl Simulate an ovn-controller upgrade to a version that supports |
4588 | +dnl ct-no-masked-label. ovn-northd should start using ct_mark.ecmp_reply_port. |
4589 | + |
4590 | +check ovn-sbctl set chassis ch1 other_config:ct-no-masked-label=true |
4591 | +check ovn-nbctl --wait=sb sync |
4592 | +ovn-sbctl dump-flows lr0 > lr0flows |
4593 | +AT_CHECK([grep -e "lr_in_arp_resolve.*ecmp" lr0flows | sed 's/table=../table=??/'], [0], [dnl |
4594 | + table=??(lr_in_arp_resolve ), priority=200 , match=(ct.rpl && ct_mark.ecmp_reply_port == 1), action=(push(xxreg1); xxreg1 = ct_label; eth.dst = xxreg1[[32..79]]; pop(xxreg1); next;) |
4595 | +]) |
4596 | + |
4597 | # add ecmp route with wrong nexthop |
4598 | check ovn-nbctl --wait=sb --ecmp-symmetric-reply lr-route-add lr0 1.0.0.1 192.168.1.20 |
4599 | |
4600 | @@ -5804,6 +5836,12 @@ AT_CHECK([grep lr_in_gw_redirect lrflows | grep cr-DR | sed 's/table=../table=?? |
4601 | table=??(lr_in_gw_redirect ), priority=50 , match=(outport == "DR-S3"), action=(outport = "cr-DR-S3"; next;) |
4602 | ]) |
4603 | |
4604 | +# Check that ovn-northd logs a warning when trying to configure NAT |
4605 | +# on the router with multiple distributed gw ports. Such configurations are |
4606 | +# not supported yet. |
4607 | +check ovn-nbctl lr-nat-add DR dnat_and_snat 42.42.42.1 20.0.0.2 |
4608 | +AT_CHECK([grep -q 'NAT is configured on logical router DR, which has 2 distributed gateway ports. NAT is not supported yet when there is more than one distributed gateway port on the router.' northd/ovn-northd.log], [0]) |
4609 | + |
4610 | AT_CLEANUP |
4611 | ]) |
4612 | |
4613 | @@ -5888,7 +5926,7 @@ flow="eth.dst == 00:00:00:00:01:00 && inport == \"rtr-ls\" && ip4.src == 42.42.4 |
4614 | AT_CHECK_UNQUOTED([ovn-trace --ct new --minimal "${flow}" --lb-dst 42.42.42.42:4242], [0], [dnl |
4615 | # tcp,reg14=0x1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:01:00,nw_src=42.42.42.42,nw_dst=43.43.43.43,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=0,tp_dst=4343,tcp_flags=0 |
4616 | ct_dnat /* assuming no un-dnat entry, so no change */ { |
4617 | - ct_lb /* default (use --ct to customize) */ { |
4618 | + ct_lb_mark /* default (use --ct to customize) */ { |
4619 | ip.ttl--; |
4620 | eth.src = 00:00:00:00:01:00; |
4621 | eth.dst = 00:00:00:00:00:00; |
4622 | @@ -6078,10 +6116,10 @@ check_log_flows_count 0 in |
4623 | |
4624 | # Now ensure the flows are what we expect them to be for the ACLs we created |
4625 | AT_CHECK([cat log_flows], [0], [dnl |
4626 | - table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4627 | - table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4628 | - table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4629 | - table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4630 | + table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4631 | + table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4632 | + table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4633 | + table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4634 | ]) |
4635 | |
4636 | rm log_flows |
4637 | @@ -6099,10 +6137,10 @@ check_log_flows_count 0 in |
4638 | |
4639 | # And the log flows will remain the same since the stateless ACL will not be represented. |
4640 | AT_CHECK([cat log_flows], [0], [dnl |
4641 | - table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4642 | - table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4643 | - table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4644 | - table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4645 | + table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4646 | + table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4647 | + table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4648 | + table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4649 | ]) |
4650 | |
4651 | rm log_flows |
4652 | @@ -6121,8 +6159,8 @@ check_log_flows_count 0 in |
4653 | |
4654 | # And make sure only the allow ACL has the log flows installed |
4655 | AT_CHECK([cat log_flows], [0], [dnl |
4656 | - table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4657 | - table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4658 | + table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4659 | + table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4660 | ]) |
4661 | |
4662 | rm log_flows |
4663 | @@ -6138,8 +6176,8 @@ check_log_flows_count 0 in |
4664 | |
4665 | # And make sure only the allow ACL has the log flows installed |
4666 | AT_CHECK([cat log_flows], [0], [dnl |
4667 | - table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4668 | - table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4669 | + table=??(ls_out_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4670 | + table=??(ls_out_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4671 | ]) |
4672 | |
4673 | rm log_flows |
4674 | @@ -6183,10 +6221,10 @@ check_log_flows_count 0 out |
4675 | |
4676 | # Now ensure the flows are what we expect them to be for the ACLs we created |
4677 | AT_CHECK([cat log_flows], [0], [dnl |
4678 | - table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4679 | - table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4680 | - table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4681 | - table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4682 | + table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4683 | + table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4684 | + table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4685 | + table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4686 | ]) |
4687 | |
4688 | rm log_flows |
4689 | @@ -6204,10 +6242,10 @@ check_log_flows_count 0 out |
4690 | |
4691 | # And the log flows will remain the same since the stateless ACL will not be represented. |
4692 | AT_CHECK([cat log_flows], [0], [dnl |
4693 | - table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4694 | - table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4695 | - table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4696 | - table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4697 | + table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4698 | + table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4699 | + table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4700 | + table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 2), action=(log(name="allow_related_acl", severity=info, verdict=allow); next;) |
4701 | ]) |
4702 | |
4703 | rm log_flows |
4704 | @@ -6226,8 +6264,8 @@ check_log_flows_count 0 out |
4705 | |
4706 | # And make sure only the allow ACL has the log flows installed |
4707 | AT_CHECK([cat log_flows], [0], [dnl |
4708 | - table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4709 | - table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4710 | + table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4711 | + table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4712 | ]) |
4713 | |
4714 | rm log_flows |
4715 | @@ -6243,8 +6281,8 @@ check_log_flows_count 0 out |
4716 | |
4717 | # And make sure only the allow ACL has the log flows installed |
4718 | AT_CHECK([cat log_flows], [0], [dnl |
4719 | - table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4720 | - table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4721 | + table=??(ls_in_acl ), priority=65533, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4722 | + table=??(ls_in_acl ), priority=65533, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0 && ct_label.label == 1), action=(log(name="allow_acl", severity=info, verdict=allow); next;) |
4723 | ]) |
4724 | |
4725 | rm log_flows |
4726 | @@ -6284,40 +6322,40 @@ AT_CAPTURE_FILE([lsflows]) |
4727 | |
4728 | AT_CHECK([grep -e "ls_in_acl" lsflows | sed 's/table=../table=??/' | sort], [0], [dnl |
4729 | table=??(ls_in_acl ), priority=0 , match=(1), action=(next;) |
4730 | - table=??(ls_in_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;) |
4731 | - table=??(ls_in_acl ), priority=2001 , match=(reg0[[10]] == 1 && (ip4)), action=(ct_commit { ct_label.blocked = 1; }; /* drop */) |
4732 | + table=??(ls_in_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_mark.blocked == 1))), action=(reg0[[1]] = 1; next;) |
4733 | + table=??(ls_in_acl ), priority=2001 , match=(reg0[[10]] == 1 && (ip4)), action=(ct_commit { ct_mark.blocked = 1; }; /* drop */) |
4734 | table=??(ls_in_acl ), priority=2001 , match=(reg0[[9]] == 1 && (ip4)), action=(/* drop */) |
4735 | table=??(ls_in_acl ), priority=2002 , match=(reg0[[7]] == 1 && (ip4 && tcp)), action=(reg0[[1]] = 1; next;) |
4736 | table=??(ls_in_acl ), priority=2002 , match=(reg0[[8]] == 1 && (ip4 && tcp)), action=(next;) |
4737 | table=??(ls_in_acl ), priority=2003 , match=(reg0[[7]] == 1 && (ip4 && icmp)), action=(reg0[[1]] = 1; next;) |
4738 | table=??(ls_in_acl ), priority=2003 , match=(reg0[[8]] == 1 && (ip4 && icmp)), action=(next;) |
4739 | - table=??(ls_in_acl ), priority=2004 , match=(reg0[[10]] == 1 && (ip4 && ip4.dst == 10.0.0.2)), action=(ct_commit { ct_label.blocked = 1; }; /* drop */) |
4740 | + table=??(ls_in_acl ), priority=2004 , match=(reg0[[10]] == 1 && (ip4 && ip4.dst == 10.0.0.2)), action=(ct_commit { ct_mark.blocked = 1; }; /* drop */) |
4741 | table=??(ls_in_acl ), priority=2004 , match=(reg0[[9]] == 1 && (ip4 && ip4.dst == 10.0.0.2)), action=(/* drop */) |
4742 | table=??(ls_in_acl ), priority=34000, match=(eth.dst == $svc_monitor_mac), action=(next;) |
4743 | - table=??(ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
4744 | - table=??(ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4745 | - table=??(ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
4746 | + table=??(ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
4747 | + table=??(ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4748 | + table=??(ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
4749 | table=??(ls_in_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
4750 | table=??(ls_in_acl_after_lb ), priority=0 , match=(1), action=(next;) |
4751 | table=??(ls_in_acl_hint ), priority=0 , match=(1), action=(next;) |
4752 | - table=??(ls_in_acl_hint ), priority=1 , match=(ct.est && ct_label.blocked == 0), action=(reg0[[10]] = 1; next;) |
4753 | - table=??(ls_in_acl_hint ), priority=2 , match=(ct.est && ct_label.blocked == 1), action=(reg0[[9]] = 1; next;) |
4754 | + table=??(ls_in_acl_hint ), priority=1 , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;) |
4755 | + table=??(ls_in_acl_hint ), priority=2 , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;) |
4756 | table=??(ls_in_acl_hint ), priority=3 , match=(!ct.est), action=(reg0[[9]] = 1; next;) |
4757 | - table=??(ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
4758 | + table=??(ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
4759 | table=??(ls_in_acl_hint ), priority=5 , match=(!ct.trk), action=(reg0[[8]] = 1; reg0[[9]] = 1; next;) |
4760 | - table=??(ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
4761 | + table=??(ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
4762 | table=??(ls_in_acl_hint ), priority=7 , match=(ct.new && !ct.est), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
4763 | ]) |
4764 | |
4765 | AT_CHECK([grep -e "ls_in_lb" lsflows | sed 's/table=../table=??/' | sort], [0], [dnl |
4766 | table=??(ls_in_lb ), priority=0 , match=(1), action=(next;) |
4767 | - table=??(ls_in_lb ), priority=110 , match=(ct.new && ip4.dst == 10.0.0.2), action=(reg0[[1]] = 0; reg1 = 10.0.0.2; ct_lb(backends=10.0.0.10);) |
4768 | + table=??(ls_in_lb ), priority=110 , match=(ct.new && ip4.dst == 10.0.0.2), action=(reg0[[1]] = 0; reg1 = 10.0.0.2; ct_lb_mark(backends=10.0.0.10);) |
4769 | ]) |
4770 | |
4771 | AT_CHECK([grep -e "ls_in_stateful" lsflows | sed 's/table=../table=??/' | sort], [0], [dnl |
4772 | table=??(ls_in_stateful ), priority=0 , match=(1), action=(next;) |
4773 | - table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4774 | - table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4775 | + table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4776 | + table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4777 | ]) |
4778 | |
4779 | AS_BOX([Remove and add the ACLs back with the apply-after-lb option]) |
4780 | @@ -6336,40 +6374,40 @@ AT_CAPTURE_FILE([lsflows]) |
4781 | |
4782 | AT_CHECK([grep -e "ls_in_acl" lsflows | sed 's/table=../table=??/' | sort], [0], [dnl |
4783 | table=??(ls_in_acl ), priority=0 , match=(1), action=(next;) |
4784 | - table=??(ls_in_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;) |
4785 | + table=??(ls_in_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_mark.blocked == 1))), action=(reg0[[1]] = 1; next;) |
4786 | table=??(ls_in_acl ), priority=34000, match=(eth.dst == $svc_monitor_mac), action=(next;) |
4787 | - table=??(ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
4788 | - table=??(ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4789 | - table=??(ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
4790 | + table=??(ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
4791 | + table=??(ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4792 | + table=??(ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
4793 | table=??(ls_in_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
4794 | table=??(ls_in_acl_after_lb ), priority=0 , match=(1), action=(next;) |
4795 | - table=??(ls_in_acl_after_lb ), priority=2001 , match=(reg0[[10]] == 1 && (ip4)), action=(ct_commit { ct_label.blocked = 1; }; /* drop */) |
4796 | + table=??(ls_in_acl_after_lb ), priority=2001 , match=(reg0[[10]] == 1 && (ip4)), action=(ct_commit { ct_mark.blocked = 1; }; /* drop */) |
4797 | table=??(ls_in_acl_after_lb ), priority=2001 , match=(reg0[[9]] == 1 && (ip4)), action=(/* drop */) |
4798 | table=??(ls_in_acl_after_lb ), priority=2002 , match=(reg0[[7]] == 1 && (ip4 && tcp)), action=(reg0[[1]] = 1; next;) |
4799 | table=??(ls_in_acl_after_lb ), priority=2002 , match=(reg0[[8]] == 1 && (ip4 && tcp)), action=(next;) |
4800 | table=??(ls_in_acl_after_lb ), priority=2003 , match=(reg0[[7]] == 1 && (ip4 && icmp)), action=(reg0[[1]] = 1; next;) |
4801 | table=??(ls_in_acl_after_lb ), priority=2003 , match=(reg0[[8]] == 1 && (ip4 && icmp)), action=(next;) |
4802 | - table=??(ls_in_acl_after_lb ), priority=2004 , match=(reg0[[10]] == 1 && (ip4 && ip4.dst == 10.0.0.2)), action=(ct_commit { ct_label.blocked = 1; }; /* drop */) |
4803 | + table=??(ls_in_acl_after_lb ), priority=2004 , match=(reg0[[10]] == 1 && (ip4 && ip4.dst == 10.0.0.2)), action=(ct_commit { ct_mark.blocked = 1; }; /* drop */) |
4804 | table=??(ls_in_acl_after_lb ), priority=2004 , match=(reg0[[9]] == 1 && (ip4 && ip4.dst == 10.0.0.2)), action=(/* drop */) |
4805 | table=??(ls_in_acl_hint ), priority=0 , match=(1), action=(next;) |
4806 | - table=??(ls_in_acl_hint ), priority=1 , match=(ct.est && ct_label.blocked == 0), action=(reg0[[10]] = 1; next;) |
4807 | - table=??(ls_in_acl_hint ), priority=2 , match=(ct.est && ct_label.blocked == 1), action=(reg0[[9]] = 1; next;) |
4808 | + table=??(ls_in_acl_hint ), priority=1 , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;) |
4809 | + table=??(ls_in_acl_hint ), priority=2 , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;) |
4810 | table=??(ls_in_acl_hint ), priority=3 , match=(!ct.est), action=(reg0[[9]] = 1; next;) |
4811 | - table=??(ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
4812 | + table=??(ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
4813 | table=??(ls_in_acl_hint ), priority=5 , match=(!ct.trk), action=(reg0[[8]] = 1; reg0[[9]] = 1; next;) |
4814 | - table=??(ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
4815 | + table=??(ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
4816 | table=??(ls_in_acl_hint ), priority=7 , match=(ct.new && !ct.est), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
4817 | ]) |
4818 | |
4819 | AT_CHECK([grep -e "ls_in_lb" lsflows | sed 's/table=../table=??/' | sort], [0], [dnl |
4820 | table=??(ls_in_lb ), priority=0 , match=(1), action=(next;) |
4821 | - table=??(ls_in_lb ), priority=110 , match=(ct.new && ip4.dst == 10.0.0.2), action=(reg0[[1]] = 0; reg1 = 10.0.0.2; ct_lb(backends=10.0.0.10);) |
4822 | + table=??(ls_in_lb ), priority=110 , match=(ct.new && ip4.dst == 10.0.0.2), action=(reg0[[1]] = 0; reg1 = 10.0.0.2; ct_lb_mark(backends=10.0.0.10);) |
4823 | ]) |
4824 | |
4825 | AT_CHECK([grep -e "ls_in_stateful" lsflows | sed 's/table=../table=??/' | sort], [0], [dnl |
4826 | table=??(ls_in_stateful ), priority=0 , match=(1), action=(next;) |
4827 | - table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4828 | - table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4829 | + table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4830 | + table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4831 | ]) |
4832 | |
4833 | AS_BOX([Remove and add the ACLs back with a few ACLs with apply-after-lb option]) |
4834 | @@ -6388,40 +6426,209 @@ AT_CAPTURE_FILE([lsflows]) |
4835 | |
4836 | AT_CHECK([grep -e "ls_in_acl" lsflows | sed 's/table=../table=??/' | sort], [0], [dnl |
4837 | table=??(ls_in_acl ), priority=0 , match=(1), action=(next;) |
4838 | - table=??(ls_in_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_label.blocked == 1))), action=(reg0[[1]] = 1; next;) |
4839 | + table=??(ls_in_acl ), priority=1 , match=(ip && (!ct.est || (ct.est && ct_mark.blocked == 1))), action=(reg0[[1]] = 1; next;) |
4840 | table=??(ls_in_acl ), priority=2002 , match=(reg0[[7]] == 1 && (ip4 && tcp)), action=(reg0[[1]] = 1; next;) |
4841 | table=??(ls_in_acl ), priority=2002 , match=(reg0[[8]] == 1 && (ip4 && tcp)), action=(next;) |
4842 | table=??(ls_in_acl ), priority=2003 , match=(reg0[[7]] == 1 && (ip4 && icmp)), action=(reg0[[1]] = 1; next;) |
4843 | table=??(ls_in_acl ), priority=2003 , match=(reg0[[8]] == 1 && (ip4 && icmp)), action=(next;) |
4844 | table=??(ls_in_acl ), priority=34000, match=(eth.dst == $svc_monitor_mac), action=(next;) |
4845 | - table=??(ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_label.blocked == 0), action=(next;) |
4846 | - table=??(ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_label.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4847 | - table=??(ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_label.blocked == 1)), action=(drop;) |
4848 | + table=??(ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
4849 | + table=??(ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
4850 | + table=??(ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
4851 | table=??(ls_in_acl ), priority=65532, match=(nd || nd_ra || nd_rs || mldv1 || mldv2), action=(next;) |
4852 | table=??(ls_in_acl_after_lb ), priority=0 , match=(1), action=(next;) |
4853 | - table=??(ls_in_acl_after_lb ), priority=2001 , match=(reg0[[10]] == 1 && (ip4)), action=(ct_commit { ct_label.blocked = 1; }; /* drop */) |
4854 | + table=??(ls_in_acl_after_lb ), priority=2001 , match=(reg0[[10]] == 1 && (ip4)), action=(ct_commit { ct_mark.blocked = 1; }; /* drop */) |
4855 | table=??(ls_in_acl_after_lb ), priority=2001 , match=(reg0[[9]] == 1 && (ip4)), action=(/* drop */) |
4856 | - table=??(ls_in_acl_after_lb ), priority=2004 , match=(reg0[[10]] == 1 && (ip4 && ip4.dst == 10.0.0.2)), action=(ct_commit { ct_label.blocked = 1; }; /* drop */) |
4857 | + table=??(ls_in_acl_after_lb ), priority=2004 , match=(reg0[[10]] == 1 && (ip4 && ip4.dst == 10.0.0.2)), action=(ct_commit { ct_mark.blocked = 1; }; /* drop */) |
4858 | table=??(ls_in_acl_after_lb ), priority=2004 , match=(reg0[[9]] == 1 && (ip4 && ip4.dst == 10.0.0.2)), action=(/* drop */) |
4859 | table=??(ls_in_acl_hint ), priority=0 , match=(1), action=(next;) |
4860 | - table=??(ls_in_acl_hint ), priority=1 , match=(ct.est && ct_label.blocked == 0), action=(reg0[[10]] = 1; next;) |
4861 | - table=??(ls_in_acl_hint ), priority=2 , match=(ct.est && ct_label.blocked == 1), action=(reg0[[9]] = 1; next;) |
4862 | + table=??(ls_in_acl_hint ), priority=1 , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;) |
4863 | + table=??(ls_in_acl_hint ), priority=2 , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;) |
4864 | table=??(ls_in_acl_hint ), priority=3 , match=(!ct.est), action=(reg0[[9]] = 1; next;) |
4865 | - table=??(ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
4866 | + table=??(ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
4867 | table=??(ls_in_acl_hint ), priority=5 , match=(!ct.trk), action=(reg0[[8]] = 1; reg0[[9]] = 1; next;) |
4868 | - table=??(ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_label.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
4869 | + table=??(ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
4870 | table=??(ls_in_acl_hint ), priority=7 , match=(ct.new && !ct.est), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
4871 | ]) |
4872 | |
4873 | AT_CHECK([grep -e "ls_in_lb" lsflows | sed 's/table=../table=??/' | sort], [0], [dnl |
4874 | table=??(ls_in_lb ), priority=0 , match=(1), action=(next;) |
4875 | - table=??(ls_in_lb ), priority=110 , match=(ct.new && ip4.dst == 10.0.0.2), action=(reg0[[1]] = 0; reg1 = 10.0.0.2; ct_lb(backends=10.0.0.10);) |
4876 | + table=??(ls_in_lb ), priority=110 , match=(ct.new && ip4.dst == 10.0.0.2), action=(reg0[[1]] = 0; reg1 = 10.0.0.2; ct_lb_mark(backends=10.0.0.10);) |
4877 | ]) |
4878 | |
4879 | AT_CHECK([grep -e "ls_in_stateful" lsflows | sed 's/table=../table=??/' | sort], [0], [dnl |
4880 | table=??(ls_in_stateful ), priority=0 , match=(1), action=(next;) |
4881 | - table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_label.blocked = 0; }; next;) |
4882 | - table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_label.blocked = 0; ct_label.label = reg3; }; next;) |
4883 | + table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 0), action=(ct_commit { ct_mark.blocked = 0; }; next;) |
4884 | + table=??(ls_in_stateful ), priority=100 , match=(reg0[[1]] == 1 && reg0[[13]] == 1), action=(ct_commit { ct_mark.blocked = 0; ct_label.label = reg3; }; next;) |
4885 | +]) |
4886 | + |
4887 | +AT_CLEANUP |
4888 | +]) |
4889 | + |
4890 | +OVN_FOR_EACH_NORTHD([ |
4891 | +AT_SETUP([LR neighbor lookup and learning flows]) |
4892 | +ovn_start |
4893 | + |
4894 | +# Create logical routers |
4895 | +ovn-nbctl --wait=sb lr-add lr0 |
4896 | + |
4897 | +ovn-sbctl dump-flows lr0 > lrflows |
4898 | +AT_CAPTURE_FILE([lrflows]) |
4899 | + |
4900 | +AT_CHECK([cat lrflows | grep -e lr_in_lookup_neighbor -e lr_in_learn_neighbor | sort], [0], [dnl |
4901 | + table=1 (lr_in_lookup_neighbor), priority=0 , match=(1), action=(reg9[[2]] = 1; next;) |
4902 | + table=1 (lr_in_lookup_neighbor), priority=100 , match=(arp.op == 2), action=(reg9[[2]] = lookup_arp(inport, arp.spa, arp.sha); next;) |
4903 | + table=1 (lr_in_lookup_neighbor), priority=100 , match=(nd_na), action=(reg9[[2]] = lookup_nd(inport, nd.target, nd.tll); next;) |
4904 | + table=1 (lr_in_lookup_neighbor), priority=100 , match=(nd_ns), action=(reg9[[2]] = lookup_nd(inport, ip6.src, nd.sll); next;) |
4905 | + table=2 (lr_in_learn_neighbor), priority=100 , match=(reg9[[2]] == 1), action=(next;) |
4906 | + table=2 (lr_in_learn_neighbor), priority=90 , match=(arp), action=(put_arp(inport, arp.spa, arp.sha); next;) |
4907 | + table=2 (lr_in_learn_neighbor), priority=90 , match=(nd_na), action=(put_nd(inport, nd.target, nd.tll); next;) |
4908 | + table=2 (lr_in_learn_neighbor), priority=90 , match=(nd_ns), action=(put_nd(inport, ip6.src, nd.sll); next;) |
4909 | + table=2 (lr_in_learn_neighbor), priority=95 , match=(nd_na && nd.tll == 0), action=(put_nd(inport, nd.target, eth.src); next;) |
4910 | +]) |
4911 | + |
4912 | +AT_CLEANUP |
4913 | +]) |
4914 | + |
4915 | +OVN_FOR_EACH_NORTHD([ |
4916 | +AT_SETUP([Load balancer ct_lb_mark backwards compatibility]) |
4917 | +AT_KEYWORDS([lb]) |
4918 | +ovn_start |
4919 | + |
4920 | +check ovn-nbctl \ |
4921 | + -- ls-add ls \ |
4922 | + -- lr-add lr -- set logical_router lr options:chassis=local \ |
4923 | + -- lb-add lb-test 66.66.66.66 42.42.42.2 \ |
4924 | + -- ls-lb-add ls lb-test \ |
4925 | + -- lr-lb-add lr lb-test |
4926 | + |
4927 | +AS_BOX([No chassis registered - use ct_lb_mark and ct_mark.natted]) |
4928 | +check ovn-nbctl --wait=sb sync |
4929 | +AT_CHECK([ovn-sbctl lflow-list | grep -e natted -e ct_lb], [0], [dnl |
4930 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 66.66.66.66 && ct_mark.natted == 1), action=(next;) |
4931 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 66.66.66.66), action=(ct_lb_mark(backends=42.42.42.2);) |
4932 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && sctp), action=(reg1 = ip4.dst; reg2[[0..15]] = sctp.dst; ct_lb_mark;) |
4933 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && tcp), action=(reg1 = ip4.dst; reg2[[0..15]] = tcp.dst; ct_lb_mark;) |
4934 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && udp), action=(reg1 = ip4.dst; reg2[[0..15]] = udp.dst; ct_lb_mark;) |
4935 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = sctp.dst; ct_lb_mark;) |
4936 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = tcp.dst; ct_lb_mark;) |
4937 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && udp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = udp.dst; ct_lb_mark;) |
4938 | + table=7 (ls_in_pre_stateful ), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb_mark;) |
4939 | + table=12(ls_in_lb ), priority=110 , match=(ct.new && ip4.dst == 66.66.66.66), action=(reg0[[1]] = 0; reg1 = 66.66.66.66; ct_lb_mark(backends=42.42.42.2);) |
4940 | + table=2 (ls_out_pre_stateful), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb_mark;) |
4941 | +]) |
4942 | + |
4943 | +AS_BOX([Chassis registered that doesn't support ct_lb_mark - use ct_lb and ct_label.natted]) |
4944 | +check ovn-sbctl chassis-add hv geneve 127.0.0.1 |
4945 | +check ovn-nbctl --wait=sb sync |
4946 | +AT_CHECK([ovn-sbctl lflow-list | grep -e natted -e ct_lb], [0], [dnl |
4947 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 66.66.66.66 && ct_label.natted == 1), action=(next;) |
4948 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 66.66.66.66), action=(ct_lb(backends=42.42.42.2);) |
4949 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && sctp), action=(reg1 = ip4.dst; reg2[[0..15]] = sctp.dst; ct_lb;) |
4950 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && tcp), action=(reg1 = ip4.dst; reg2[[0..15]] = tcp.dst; ct_lb;) |
4951 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && udp), action=(reg1 = ip4.dst; reg2[[0..15]] = udp.dst; ct_lb;) |
4952 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = sctp.dst; ct_lb;) |
4953 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = tcp.dst; ct_lb;) |
4954 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && udp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = udp.dst; ct_lb;) |
4955 | + table=7 (ls_in_pre_stateful ), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb;) |
4956 | + table=12(ls_in_lb ), priority=110 , match=(ct.new && ip4.dst == 66.66.66.66), action=(reg0[[1]] = 0; reg1 = 66.66.66.66; ct_lb(backends=42.42.42.2);) |
4957 | + table=2 (ls_out_pre_stateful), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb;) |
4958 | +]) |
4959 | + |
4960 | +AS_BOX([Chassis upgrades and supports ct_lb_mark - use ct_lb_mark and ct_mark.natted]) |
4961 | +check ovn-sbctl set chassis hv other_config:ct-no-masked-label=true |
4962 | +check ovn-nbctl --wait=sb sync |
4963 | +AT_CHECK([ovn-sbctl lflow-list | grep -e natted -e ct_lb], [0], [dnl |
4964 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.est && ip4 && reg0 == 66.66.66.66 && ct_mark.natted == 1), action=(next;) |
4965 | + table=6 (lr_in_dnat ), priority=110 , match=(ct.new && ip4 && reg0 == 66.66.66.66), action=(ct_lb_mark(backends=42.42.42.2);) |
4966 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && sctp), action=(reg1 = ip4.dst; reg2[[0..15]] = sctp.dst; ct_lb_mark;) |
4967 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && tcp), action=(reg1 = ip4.dst; reg2[[0..15]] = tcp.dst; ct_lb_mark;) |
4968 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip4 && udp), action=(reg1 = ip4.dst; reg2[[0..15]] = udp.dst; ct_lb_mark;) |
4969 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && sctp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = sctp.dst; ct_lb_mark;) |
4970 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && tcp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = tcp.dst; ct_lb_mark;) |
4971 | + table=7 (ls_in_pre_stateful ), priority=120 , match=(reg0[[2]] == 1 && ip6 && udp), action=(xxreg1 = ip6.dst; reg2[[0..15]] = udp.dst; ct_lb_mark;) |
4972 | + table=7 (ls_in_pre_stateful ), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb_mark;) |
4973 | + table=12(ls_in_lb ), priority=110 , match=(ct.new && ip4.dst == 66.66.66.66), action=(reg0[[1]] = 0; reg1 = 66.66.66.66; ct_lb_mark(backends=42.42.42.2);) |
4974 | + table=2 (ls_out_pre_stateful), priority=110 , match=(reg0[[2]] == 1), action=(ct_lb_mark;) |
4975 | +]) |
4976 | + |
4977 | +AT_CLEANUP |
4978 | +]) |
4979 | + |
4980 | +OVN_FOR_EACH_NORTHD([ |
4981 | +AT_SETUP([ACL ct_mark.blocked backwards compatibility]) |
4982 | +AT_KEYWORDS([acl]) |
4983 | +ovn_start |
4984 | + |
4985 | +check ovn-nbctl \ |
4986 | + -- ls-add ls \ |
4987 | + -- acl-add ls from-lport 1 1 allow-related \ |
4988 | + -- --apply-after-lb acl-add ls from-lport 1 1 allow-related \ |
4989 | + -- acl-add ls to-lport 1 1 allow-related |
4990 | + |
4991 | +AS_BOX([No chassis registered - use ct_mark.blocked]) |
4992 | +check ovn-nbctl --wait=sb sync |
4993 | +AT_CHECK([ovn-sbctl lflow-list | grep 'ls.*acl.*blocked' ], [0], [dnl |
4994 | + table=8 (ls_in_acl_hint ), priority=6 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 1), action=(reg0[[7]] = 1; reg0[[9]] = 1; next;) |
4995 | + table=8 (ls_in_acl_hint ), priority=4 , match=(!ct.new && ct.est && !ct.rpl && ct_mark.blocked == 0), action=(reg0[[8]] = 1; reg0[[10]] = 1; next;) |
4996 | + table=8 (ls_in_acl_hint ), priority=2 , match=(ct.est && ct_mark.blocked == 1), action=(reg0[[9]] = 1; next;) |
4997 | + table=8 (ls_in_acl_hint ), priority=1 , match=(ct.est && ct_mark.blocked == 0), action=(reg0[[10]] = 1; next;) |
4998 | + table=9 (ls_in_acl ), priority=65532, match=(!ct.est && ct.rel && !ct.new && !ct.inv && ct_mark.blocked == 0), action=(next;) |
4999 | + table=9 (ls_in_acl ), priority=65532, match=(ct.est && !ct.rel && !ct.new && !ct.inv && ct.rpl && ct_mark.blocked == 0), action=(reg0[[9]] = 0; reg0[[10]] = 0; next;) |
5000 | + table=9 (ls_in_acl ), priority=65532, match=(ct.inv || (ct.est && ct.rpl && ct_mark.blocked == 1)), action=(drop;) |
The diff has been truncated for viewing.