Skip to content

Commit 87a2906

Browse files
committed
provider networks: Provide the option to tunnel traffic.
This patch adds a global config option - 'always_tunnel' and when set to true, any traffic destined to a VIF logical port of a provider logical switch (having localnet port(s)), is tunnelled to the destination chassis, instead of sending it out via the localnet port. This feature is useful for the following reasons: 1. CMS can add both provider logical switches and overlay logical swithes to a logical router. With this option set, E-W routing between these logical switches will be tunnelled all the time. The router port mac addresses are not leaked from multiple chassis to the upstream switches anymore. 2. NATting will work as expected either in the gateway chassis or on the source VIF chassis (if external_mac and logical_port set). 3. With this option set, there is no need to centralize routing for provider logical switches ('reside-on-redirect-chassis'). 4. With the commits [1] now merged, MTU issues arising due to tunnel overhead will be handled gracefully. [1] - 3faadc7 ("northd: Fix pmtud for non routed traffic.") 221476a ("ovn: Add tunnel PMTUD support.") Reported-at: https://issues.redhat.com/browse/FDP-209 Acked-by: Mark Michelson <mmichels@redhat.com> Signed-off-by: Numan Siddique <numans@ovn.org>
1 parent 07b6c97 commit 87a2906

File tree

9 files changed

+596
-1
lines changed

9 files changed

+596
-1
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ Post v24.03.0
3838
ability to disable "VXLAN mode" to extend available tunnel IDs space for
3939
datapaths from 4095 to 16711680. For more details see man ovn-nb(5) for
4040
mentioned option.
41+
- Added new global config option NB_Global:options:always_tunnel. If set to
42+
true, the traffic destined to a logical port of a provider logical switch
43+
(having a localnet port) will be tunnelled instead of sending it via the
44+
localnet port.
4145

4246
OVN v24.03.0 - 01 Mar 2024
4347
--------------------------

controller/ovn-controller.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3349,6 +3349,11 @@ non_vif_data_ovs_iface_handler(struct engine_node *node, void *data OVS_UNUSED)
33493349

33503350
struct ed_type_northd_options {
33513351
bool explicit_arp_ns_output;
3352+
bool always_tunnel; /* Indicates if the traffic to the
3353+
* logical port of a bridged logical
3354+
* switch (i.e with localnet port) should
3355+
* be tunnelled or sent via the localnet
3356+
* port. Default value is 'false'. */
33523357
};
33533358

33543359

@@ -3380,6 +3385,12 @@ en_northd_options_run(struct engine_node *node, void *data)
33803385
false)
33813386
: false;
33823387

3388+
n_opts->always_tunnel =
3389+
sb_global
3390+
? smap_get_bool(&sb_global->options, "always_tunnel",
3391+
false)
3392+
: false;
3393+
33833394
engine_set_node_state(node, EN_UPDATED);
33843395
}
33853396

@@ -3403,6 +3414,17 @@ en_northd_options_sb_sb_global_handler(struct engine_node *node, void *data)
34033414
engine_set_node_state(node, EN_UPDATED);
34043415
}
34053416

3417+
bool always_tunnel =
3418+
sb_global
3419+
? smap_get_bool(&sb_global->options, "always_tunnel",
3420+
false)
3421+
: false;
3422+
3423+
if (always_tunnel != n_opts->always_tunnel) {
3424+
n_opts->always_tunnel = always_tunnel;
3425+
engine_set_node_state(node, EN_UPDATED);
3426+
}
3427+
34063428
return true;
34073429
}
34083430

@@ -4315,6 +4337,9 @@ static void init_physical_ctx(struct engine_node *node,
43154337
engine_get_input_data("ct_zones", node);
43164338
struct simap *ct_zones = &ct_zones_data->ctx.current;
43174339

4340+
struct ed_type_northd_options *n_opts =
4341+
engine_get_input_data("northd_options", node);
4342+
43184343
parse_encap_ips(ovs_table, &p_ctx->n_encap_ips, &p_ctx->encap_ips);
43194344
p_ctx->sbrec_port_binding_by_name = sbrec_port_binding_by_name;
43204345
p_ctx->sbrec_port_binding_by_datapath = sbrec_port_binding_by_datapath;
@@ -4332,6 +4357,7 @@ static void init_physical_ctx(struct engine_node *node,
43324357
p_ctx->local_bindings = &rt_data->lbinding_data.bindings;
43334358
p_ctx->patch_ofports = &non_vif_data->patch_ofports;
43344359
p_ctx->chassis_tunnels = &non_vif_data->chassis_tunnels;
4360+
p_ctx->always_tunnel = n_opts->always_tunnel;
43354361

43364362
struct controller_engine_ctx *ctrl_ctx = engine_get_context()->client_ctx;
43374363
p_ctx->if_mgr = ctrl_ctx->if_mgr;
@@ -5032,6 +5058,7 @@ main(int argc, char *argv[])
50325058
*/
50335059
engine_add_input(&en_pflow_output, &en_non_vif_data,
50345060
NULL);
5061+
engine_add_input(&en_pflow_output, &en_northd_options, NULL);
50355062
engine_add_input(&en_pflow_output, &en_ct_zones,
50365063
pflow_output_ct_zones_handler);
50375064
engine_add_input(&en_pflow_output, &en_sb_chassis,

controller/physical.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1489,6 +1489,7 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
14891489
const struct if_status_mgr *if_mgr,
14901490
size_t n_encap_ips,
14911491
const char **encap_ips,
1492+
bool always_tunnel,
14921493
struct ovn_desired_flow_table *flow_table,
14931494
struct ofpbuf *ofpacts_p)
14941495
{
@@ -1922,14 +1923,19 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name,
19221923
binding->header_.uuid.parts[0], &match,
19231924
ofpacts_p, &binding->header_.uuid);
19241925
}
1925-
} else if (access_type == PORT_LOCALNET) {
1926+
} else if (access_type == PORT_LOCALNET && !always_tunnel) {
19261927
/* Remote port connected by localnet port */
19271928
/* Table 40, priority 100.
19281929
* =======================
19291930
*
19301931
* Implements switching to localnet port. Each flow matches a
19311932
* logical output port on remote hypervisor, switch the output port
19321933
* to connected localnet port and resubmits to same table.
1934+
*
1935+
* Note: If 'always_tunnel' is true, then
1936+
* put_remote_port_redirect_overlay() called from below takes care
1937+
* of adding the flow in OFTABLE_REMOTE_OUTPUT table to tunnel to
1938+
* the destination chassis.
19331939
*/
19341940

19351941
ofpbuf_clear(ofpacts_p);
@@ -2355,6 +2361,7 @@ physical_eval_port_binding(struct physical_ctx *p_ctx,
23552361
p_ctx->if_mgr,
23562362
p_ctx->n_encap_ips,
23572363
p_ctx->encap_ips,
2364+
p_ctx->always_tunnel,
23582365
flow_table, &ofpacts);
23592366
ofpbuf_uninit(&ofpacts);
23602367
}
@@ -2482,6 +2489,7 @@ physical_run(struct physical_ctx *p_ctx,
24822489
p_ctx->if_mgr,
24832490
p_ctx->n_encap_ips,
24842491
p_ctx->encap_ips,
2492+
p_ctx->always_tunnel,
24852493
flow_table, &ofpacts);
24862494
}
24872495

controller/physical.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ struct physical_ctx {
6969
size_t n_encap_ips;
7070
const char **encap_ips;
7171
struct physical_debug debug;
72+
bool always_tunnel;
7273
};
7374

7475
void physical_register_ovs_idl(struct ovsdb_idl *);

northd/en-global-config.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,11 @@ check_nb_options_out_of_sync(const struct nbrec_nb_global *nb,
521521
return true;
522522
}
523523

524+
if (config_out_of_sync(&nb->options, &config_data->nb_options,
525+
"always_tunnel", false)) {
526+
return true;
527+
}
528+
524529
return false;
525530
}
526531

ovn-nb.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,22 @@
391391
non-<code>VXLAN mode</code> tunnel IDs allocation logic.
392392
</column>
393393

394+
<column name="options" key="always_tunnel"
395+
type='{"type": "boolean"}'>
396+
<p>
397+
If set to true, then the traffic destined to a VIF of a provider
398+
logical switch (having a localnet port) will be tunnelled instead
399+
of sending it via the localnet port. This option will be useful
400+
if CMS wants to connect overlay logical switches (without
401+
localnet port) and provider logical switches to a router. Without
402+
this option set, the traffic path will be a mix of tunnelling and
403+
localnet ports (since routing is distributed) resulting in the
404+
leakage of the router port mac address to the upstream switches
405+
and undefined behavior if NATting is involed. This option is
406+
disabled by default.
407+
</p>
408+
</column>
409+
394410
<group title="Options for configuring interconnection route advertisement">
395411
<p>
396412
These options control how routes are advertised between OVN

tests/multinode-macros.at

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,25 @@ m4_define([M_NS_CHECK_EXEC],
2222
[ AT_CHECK([M_NS_EXEC([$1], [$2], [$3])], m4_shift(m4_shift(m4_shift($@)))) ]
2323
)
2424

25+
# M_DAEMONIZE([fake_node],[command],[pidfile])
26+
m4_define([M_DAEMONIZE],
27+
[podman exec $1 $2 & echo $! > $3
28+
echo "kill \`cat $3\`" >> cleanup
29+
]
30+
)
31+
32+
# M_START_TCPDUMP([fake_node], [params], [name])
33+
#
34+
# Helper to properly start tcpdump and wait for the startup.
35+
# The tcpdump output is available in <name>.tcpdump file.
36+
m4_define([M_START_TCPDUMP],
37+
[
38+
podman exec $1 tcpdump -l $2 >$3.tcpdump 2>$3.stderr &
39+
OVS_WAIT_UNTIL([grep -q "listening" $3.stderr])
40+
]
41+
)
42+
43+
2544
OVS_START_SHELL_HELPERS
2645

2746
m_as() {

0 commit comments

Comments
 (0)