add support for routing-protocol-redirects in combination with active-active routing.
Signed-off-by: Felix Huettner <[email protected]> --- northd/northd.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++-- ovn-nb.xml | 4 ++++ tests/ovn.at | 40 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 2 deletions(-) diff --git a/northd/northd.c b/northd/northd.c index 5ed2720d8..ff665d187 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -2309,6 +2309,7 @@ join_logical_ports_lrp(struct hmap *ports, struct active_active_port { const struct nbrec_logical_switch_port *nbsp; + const struct nbrec_logical_switch_port *routing_protocol_redirect; const struct nbrec_logical_router_port *nbrp; struct ovn_datapath *switch_dp; struct ovn_datapath *router_dp; @@ -2376,6 +2377,7 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, ovs_list_init(both); struct shash active_active_ports = SHASH_INITIALIZER(&active_active_ports); + struct shash aa_redirect_targets = SHASH_INITIALIZER(&aa_redirect_targets); const struct sbrec_port_binding *sb; SBREC_PORT_BINDING_TABLE_FOR_EACH (sb, sbrec_pb_table) { @@ -2404,6 +2406,12 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, aap->nbrp = nbrp; aap->router_dp = od; shash_add(&active_active_ports, nbrp->name, aap); + + const char *redirect_port_name = smap_get(&nbrp->options, + "routing-protocol-redirect"); + if (redirect_port_name) { + shash_add(&aa_redirect_targets, redirect_port_name, aap); + } continue; } @@ -2434,6 +2442,12 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, aap->switch_dp = od; continue; } + struct active_active_port *aap = + shash_find_data(&aa_redirect_targets, nbsp->name); + if (aap) { + aap->routing_protocol_redirect = nbsp; + continue; + } join_logical_ports_lsp(ports, nb_only, both, od, nbsp, nbsp->name, queue_id_bitmap, tag_alloc_table); @@ -2517,6 +2531,8 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, SHASH_FOR_EACH (aa_snode, &active_active_ports) { const struct active_active_port *aap = aa_snode->data; const struct nbrec_logical_switch_port *nbsp = aap->nbsp; + const struct nbrec_logical_switch_port *nbsp_rpr = + aap->routing_protocol_redirect; const struct nbrec_logical_router_port *nbrp = aap->nbrp; ovs_assert(nbrp); ovs_assert(aap->router_dp); @@ -2609,6 +2625,18 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, lsp->aa_chassis_name = xstrdup(chassis->name); lrp->aa_chassis_index = j; lsp->aa_chassis_index = j; + + if (nbsp_rpr) { + char *lsp_rpr_name = xasprintf("%s-%s-%"PRIuSIZE, + nbsp_rpr->name, + chassis->name, j); + join_logical_ports_lsp(ports, nb_only, both, + aap->switch_dp, nbsp_rpr, + lsp_rpr_name, queue_id_bitmap, + tag_alloc_table); + free(lsp_rpr_name); + } + } free(networks.network_name); free(networks.addresses); @@ -2672,6 +2700,7 @@ join_logical_ports(const struct sbrec_port_binding_table *sbrec_pb_table, ipam_add_port_addresses(op->od, op); } + shash_destroy(&aa_redirect_targets); shash_destroy_free_data(&active_active_ports); } @@ -14332,6 +14361,20 @@ build_arp_resolve_flows_for_lrp(struct ovn_port *op, } } +static char* +ovn_port_get_redirect_port_name(struct ovn_port *op) { + const char *rpr = smap_get(&op->nbrp->options, + "routing-protocol-redirect"); + if (!rpr) { + return NULL; + } + if (op->is_active_active) { + return xasprintf("%s-%s-%"PRIuSIZE, rpr, + op->aa_chassis_name, op->aa_chassis_index); + } + return xstrdup(rpr); +} + static void build_routing_protocols_redirect_rule__( const char *s_addr, const char *redirect_port_name, int protocol_port, @@ -14465,8 +14508,7 @@ build_lrouter_routing_protocol_redirect( /* Proceed only for LRPs that have 'routing-protocol-redirect' option set. * Value of this option is the name of LSP to which the routing protocol * traffic will be redirected. */ - const char *redirect_port_name = smap_get(&op->nbrp->options, - "routing-protocol-redirect"); + char *redirect_port_name = ovn_port_get_redirect_port_name(op); if (!redirect_port_name) { return; } @@ -14482,6 +14524,7 @@ build_lrouter_routing_protocol_redirect( "Switch Port. Routing protocol redirecting won't be " "configured.", op->key); + free(redirect_port_name); return; } if (lsp_in_peer->od != op->peer->od) { @@ -14492,6 +14535,7 @@ build_lrouter_routing_protocol_redirect( "option. Routing protocol redirecting won't be " "configured.", op->key, redirect_port_name); + free(redirect_port_name); return; } @@ -14503,6 +14547,7 @@ build_lrouter_routing_protocol_redirect( "were set via 'routing-protocols' options. This " "configuration has no effect.", op->key); + free(redirect_port_name); return; } @@ -14550,6 +14595,7 @@ build_lrouter_routing_protocol_redirect( ds_cstr(match), REGBIT_PORT_SEC_DROP " = 1; next;", lflow_ref); + free(redirect_port_name); } /* This function adds ARP resolve flows related to a LSP. */ diff --git a/ovn-nb.xml b/ovn-nb.xml index da8cdbe08..ed425f45e 100644 --- a/ovn-nb.xml +++ b/ovn-nb.xml @@ -3790,6 +3790,10 @@ or The MAC and IP configuration of this LRP in the northbound database is ignored. + + In case the option <ref column="options" + key="routing-protocol-redirect"/> is set the target LSP will also be + duplicated per LRP/LSP combination. </p> <p> The LRP must be connected via its LSP to an external network. diff --git a/tests/ovn.at b/tests/ovn.at index eb38189d5..ecdb50816 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -39636,6 +39636,27 @@ check ovn-nbctl lsp-add phys phys1 \ -- lsp-set-type phys1 localnet \ -- lsp-set-options phys1 network_name=phys +# routing-protocol redirection +check ovn-nbctl set logical_router_port internet-phys \ + options:routing-protocol-redirect=bgp-redirect \ + options:routing-protocols=BGP,BFD +check ovn-nbctl lsp-add phys bgp-redirect + +as hv1 ovs-vsctl add-port br-int bgp-redirect-0 -- \ + set Interface bgp-redirect-0 external-ids:iface-id=bgp-redirect-hv1-0 \ + options:tx_pcap=hv1/bgp-redirect-0-tx.pcap \ + options:rxq_pcap=hv1/bgp-redirect-0-rx.pcap +as hv1 ovs-vsctl add-port br-int bgp-redirect-1 -- \ + set Interface bgp-redirect-1 external-ids:iface-id=bgp-redirect-hv1-1 \ + options:tx_pcap=hv1/bgp-redirect-1-tx.pcap \ + options:rxq_pcap=hv1/bgp-redirect-1-rx.pcap +as hv2 ovs-vsctl add-port br-int bgp-redirect-0 -- \ + set Interface bgp-redirect-0 external-ids:iface-id=bgp-redirect-hv2-0 \ + options:tx_pcap=hv2/bgp-redirect-0-tx.pcap \ + options:rxq_pcap=hv2/bgp-redirect-0-rx.pcap + +# now all setup is done + check ovn-nbctl --wait=hv sync wait_for_ports_up OVN_POPULATE_ARP @@ -39719,6 +39740,25 @@ packet=$(fmt_pkt "Ether(dst='00:cc:cc:cc:cc:20', src='00:02:01:00:00:01')/ \ cut -c 1-68) OVN_CHECK_PACKETS_CONTAIN_PARTS([hv2/br-phys_hv2-1-tx.pcap], ["$packet"]) +# bgp packet to the active-active router ports are forwarded to the respective +# bgp redirect LSP +outside_to_bgp() { + local hv=$1 if=$2 redirindex=$3 mac=$4 ip=$5 + packet=$(fmt_pkt "Ether(dst='$mac', src='00:aa:bb:cc:dd:ee')/ \ + IP(dst='$ip', src='1.1.1.1')/ \ + TCP(dport=179)") + as hv$hv ovs-appctl netdev-dummy/receive $if $packet + local filename="hv$hv-bgp-redirect-$redirindex-tx.expected" + rm -f $filename + echo $packet > $filename + OVN_CHECK_PACKETS_REMOVE_BROADCAST([hv$hv/bgp-redirect-$redirindex-tx.pcap], + [$filename]) +} + +outside_to_bgp 1 br-phys_hv1-1 0 00:01:01:00:00:01 192.168.10.10 +outside_to_bgp 1 br-phys2_hv1-2 1 00:01:02:00:00:01 192.168.11.10 +outside_to_bgp 2 br-phys_hv2-1 0 00:02:01:00:00:01 192.168.20.10 + OVN_CLEANUP([hv1],[hv2 /Couldn't parse MAC binding/d]) AT_CLEANUP -- 2.47.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
