@@ -815,7 +815,7 @@ ipam_insert_lsp_addresses(struct ovn_datapath *od, struct ovn_port *op,
char *address)
{
if (!od || !op || !address || !strcmp(address, "unknown")
- || is_dynamic_lsp_address(address)) {
+ || !strcmp(address, "router") || is_dynamic_lsp_address(address)) {
return;
}
@@ -1205,7 +1205,8 @@ join_logical_ports(struct northd_context *ctx,
op->lsp_addrs
= xmalloc(sizeof *op->lsp_addrs * nbsp->n_addresses);
for (size_t j = 0; j < nbsp->n_addresses; j++) {
- if (!strcmp(nbsp->addresses[j], "unknown")) {
+ if (!strcmp(nbsp->addresses[j], "unknown")
+ || !strcmp(nbsp->addresses[j], "router")) {
continue;
}
if (is_dynamic_lsp_address(nbsp->addresses[j])) {
@@ -1323,6 +1324,18 @@ join_logical_ports(struct northd_context *ctx,
op->od->router_ports,
sizeof *op->od->router_ports * (op->od->n_router_ports + 1));
op->od->router_ports[op->od->n_router_ports++] = op;
+
+ /* Fill op->lsp_addrs for op->nbsp->addresses[] with
+ * contents "router", which was skipped in the loop above. */
+ for (size_t j = 0; j < op->nbsp->n_addresses; j++) {
+ if (!strcmp(op->nbsp->addresses[j], "router")) {
+ if (extract_lrp_networks(peer->nbrp,
+ &op->lsp_addrs[op->n_lsp_addrs])) {
+ op->n_lsp_addrs++;
+ }
+ break;
+ }
+ }
} else if (op->nbrp && op->nbrp->peer) {
struct ovn_port *peer = ovn_port_find(ports, op->nbrp->peer);
if (peer) {
@@ -3123,6 +3136,20 @@ build_lswitch_flows(struct hmap *datapaths, struct hmap *ports,
ds_put_format(&actions, "outport = %s; output;", op->json_key);
ovn_lflow_add(lflows, op->od, S_SWITCH_IN_L2_LKUP, 50,
ds_cstr(&match), ds_cstr(&actions));
+ } else if (!strcmp(op->nbsp->addresses[i], "router")) {
+ if (!op->peer || !op->peer->nbrp
+ || !ovs_scan(op->peer->nbrp->mac,
+ ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(mac))) {
+ continue;
+ }
+ ds_clear(&match);
+ ds_put_format(&match, "eth.dst == "ETH_ADDR_FMT,
+ ETH_ADDR_ARGS(mac));
+
+ ds_clear(&actions);
+ ds_put_format(&actions, "outport = %s; output;", op->json_key);
+ ovn_lflow_add(lflows, op->od, S_SWITCH_IN_L2_LKUP, 50,
+ ds_cstr(&match), ds_cstr(&actions));
} else {
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
@@ -519,6 +519,28 @@
</dl>
</dd>
+ <dt><code>router</code></dt>
+ <dd>
+ <p>
+ Accepted only when <ref column="type"/> is <code>router</code>.
+ This indicates that the Ethernet, IPv4, and IPv6 addresses for
+ this logical switch port should be obtained from the connected
+ logical router port, as specified by <code>router-port</code> in
+ <ref column="options"/>.
+ </p>
+
+ <p>
+ The resulting addresses are used to populate the logical
+ switch's destination lookup, and also for the logical switch
+ to generate ARP and ND replies.
+ </p>
+
+ <p>
+ Supported only in OVN 2.7 and later. Earlier versions required
+ router addresses to be manually synchronized.
+ </p>
+ </dd>
+
</dl>
</column>
@@ -197,6 +197,15 @@
the logical port's subnet and store them in the port's
<code>dynamic_addresses</code> column.
</dd>
+
+ <dt><code>router</code></dt>
+ <dd>
+ Accepted only when the <code>type</code> of the logical switch
+ port is <code>router</code>. This indicates that the Ethernet,
+ IPv4, and IPv6 addresses for this logical switch port should be
+ obtained from the connected logical router port, as specified by
+ <code>router-port</code> in <code>lsp-set-options</code>.
+ </dd>
</dl>
<p>
@@ -987,6 +987,7 @@ nbctl_lsp_set_addresses(struct ctl_context *ctx)
struct eth_addr ea;
if (strcmp(ctx->argv[i], "unknown") && strcmp(ctx->argv[i], "dynamic")
+ && strcmp(ctx->argv[i], "router")
&& !ovs_scan(ctx->argv[i], ETH_ADDR_SCAN_FMT,
ETH_ADDR_SCAN_ARGS(ea))) {
ctl_fatal("%s: Invalid address format. See ovn-nb(5). "
@@ -4804,7 +4804,8 @@ ovn-nbctl ls-add alice -- add Logical_Switch alice other_config subnet=192.168.2
# Connect foo to R1
ovn-nbctl lrp-add R1 foo 00:00:00:01:02:03 192.168.1.1/24
ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo type=router \
- options:router-port=foo addresses=\"00:00:00:01:02:03\"
+ options:router-port=foo \
+ -- lsp-set-addresses rp-foo router
# Connect alice to R1
ovn-nbctl lrp-add R1 alice 00:00:00:01:02:04 192.168.2.1/24