From 40345aa35d03c93cde877ccfa8111346291ebc7c Mon Sep 17 00:00:00 2001 From: zhangzujian Date: Mon, 11 Nov 2024 06:52:19 +0000 Subject: [PATCH] support dedicated bfd lrp Signed-off-by: zhangzujian --- controller/physical.c | 31 ++++++++++++++++++++++++++ controller/pinctrl.c | 13 ++++++----- northd/northd.c | 52 +++++++++++++++++++++++++++++++++++++++---- 3 files changed, 87 insertions(+), 9 deletions(-) diff --git a/controller/physical.c b/controller/physical.c index 0073151f89..6fbf275080 100644 --- a/controller/physical.c +++ b/controller/physical.c @@ -38,6 +38,7 @@ #include "ovn-controller.h" #include "lib/chassis-index.h" #include "lib/mcast-group-index.h" +#include "lib/ovn-l7.h" #include "lib/ovn-sb-idl.h" #include "lib/ovn-util.h" #include "ovn/actions.h" @@ -1603,6 +1604,36 @@ consider_port_binding(struct ovsdb_idl_index *sbrec_port_binding_by_name, binding->header_.uuid.parts[0], &match, ofpacts_p, &binding->header_.uuid); + if (smap_get_bool(&binding->options, "bfd-only", false)) { + match_set_nw_proto(&match, IPPROTO_UDP); + match_set_tp_dst(&match, htons(BFD_DEST_PORT)); + ofpbuf_clear(ofpacts_p); + encode_controller_op(ACTION_OPCODE_BFD_MSG, 0, ofpacts_p); + + for (size_t i = 0; i < binding->n_mac; i++) { + struct lport_addresses laddrs; + if (!extract_lsp_addresses(binding->mac[i], &laddrs)) { + continue; + } + + for (size_t j = 0; j < laddrs.n_ipv4_addrs; j++) { + match_set_nw_dst(&match, laddrs.ipv4_addrs[j].addr); + ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 110, + binding->header_.uuid.parts[0], + &match, ofpacts_p, &binding->header_.uuid); + } + match_set_nw_dst(&match, 0); + + for (size_t j = 0; j < laddrs.n_ipv6_addrs; j++) { + match_set_ipv6_dst(&match, &laddrs.ipv6_addrs[j].addr); + ofctrl_add_flow(flow_table, OFTABLE_LOCAL_OUTPUT, 110, + binding->header_.uuid.parts[0], + &match, ofpacts_p, &binding->header_.uuid); + } + + destroy_lport_addresses(&laddrs); + } + } return; } diff --git a/controller/pinctrl.c b/controller/pinctrl.c index 10ae63e2ec..006120b9eb 100644 --- a/controller/pinctrl.c +++ b/controller/pinctrl.c @@ -7572,15 +7572,18 @@ bfd_monitor_run(struct ovsdb_idl_txn *ovnsb_idl_txn, continue; } + bool bfd_only = smap_get_bool(&pb->options, "bfd-only", false); const char *peer_s = smap_get(&pb->options, "peer"); - if (!peer_s) { + if (!peer_s && !bfd_only) { continue; } - const struct sbrec_port_binding *peer - = lport_lookup_by_name(sbrec_port_binding_by_name, peer_s); - if (!peer) { - continue; + if (peer_s && !bfd_only) { + const struct sbrec_port_binding *peer + = lport_lookup_by_name(sbrec_port_binding_by_name, peer_s); + if (!peer) { + continue; + } } char *redirect_name = xasprintf("cr-%s", pb->logical_port); diff --git a/northd/northd.c b/northd/northd.c index a12fbed98f..3d5dac8ac1 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -3906,6 +3906,11 @@ sync_pb_for_lrp(struct ovn_port *op, smap_add(&new, "ipv6_ra_pd_list", ipv6_pd_list); } + const bool bfd_only = smap_get_bool(&op->nbrp->options, "bfd-only", false); + if (bfd_only) { + smap_add(&new, "bfd-only", "true"); + } + sbrec_port_binding_set_options(op->sb, &new); smap_destroy(&new); } @@ -10312,6 +10317,7 @@ static struct ovs_mutex bfd_lock = OVS_MUTEX_INITIALIZER; static bool check_bfd_state( const struct nbrec_logical_router_policy *rule, + const struct hmap *lr_ports, const struct hmap *bfd_connections, struct ovn_port *out_port, const char *nexthop) @@ -10337,7 +10343,11 @@ static bool check_bfd_state( } if (strcmp(nb_bt->logical_port, out_port->key)) { - continue; + struct ovn_port *op = ovn_port_find(lr_ports, nb_bt->logical_port); + if (!op || !op->nbrp || + !smap_get_bool(&op->nbrp->options, "bfd-only", false)) { + continue; + } } struct bfd_entry *bfd_e = bfd_port_lookup(bfd_connections, @@ -10391,7 +10401,8 @@ build_routing_policy_flow(struct lflow_table *lflows, struct ovn_datapath *od, return; } - if (!check_bfd_state(rule, bfd_connections, out_port, nexthop)) { + if (!check_bfd_state(rule, lr_ports, bfd_connections, + out_port, nexthop)) { return; } @@ -10488,8 +10499,8 @@ build_ecmp_routing_policy_flows(struct lflow_table *lflows, goto cleanup; } - if (!check_bfd_state(rule, bfd_connections, out_port, - rule->nexthops[i])) { + if (!check_bfd_state(rule, lr_ports, bfd_connections, + out_port, rule->nexthops[i])) { continue; } @@ -12448,6 +12459,9 @@ build_lrouter_bfd_flows(struct lflow_table *lflows, struct ovn_port *op, struct ds ip_list = DS_EMPTY_INITIALIZER; struct ds match = DS_EMPTY_INITIALIZER; + char *redirect_name = ovn_chassis_redirect_name(op->nbrp->name); + char *actions = xasprintf("outport = \"%s\"; output;", redirect_name); + bool bfd_only = smap_get_bool(&op->nbrp->options, "bfd-only", false); if (op->lrp_networks.n_ipv4_addrs) { op_put_v4_networks(&ip_list, op, false); @@ -12466,6 +12480,20 @@ build_lrouter_bfd_flows(struct lflow_table *lflows, struct ovn_port *op, meter_groups), &op->nbrp->header_, lflow_ref); + if ((op->nbrp->ha_chassis_group || op->nbrp->n_gateway_chassis) && + bfd_only) { + ds_clear(&match); + ds_put_format(&match, "ip4.dst == %s && udp.dst == 3784 && " + "!is_chassis_resident(\"%s\")", + ds_cstr(&ip_list), redirect_name); + ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT, + 115, ds_cstr(&match), actions, NULL, + copp_meter_get(COPP_BFD, + op->od->nbr->copp, + meter_groups), + &op->nbrp->header_, + lflow_ref); + } } if (op->lrp_networks.n_ipv6_addrs) { ds_clear(&ip_list); @@ -12487,10 +12515,26 @@ build_lrouter_bfd_flows(struct lflow_table *lflows, struct ovn_port *op, meter_groups), &op->nbrp->header_, lflow_ref); + if ((op->nbrp->ha_chassis_group || op->nbrp->n_gateway_chassis) && + bfd_only) { + ds_clear(&match); + ds_put_format(&match, "ip6.dst == %s && udp.dst == 3784 && " + "!is_chassis_resident(\"%s\")", + ds_cstr(&ip_list), redirect_name); + ovn_lflow_add_with_hint__(lflows, op->od, S_ROUTER_IN_IP_INPUT, + 115, ds_cstr(&match), actions, NULL, + copp_meter_get(COPP_BFD, + op->od->nbr->copp, + meter_groups), + &op->nbrp->header_, + lflow_ref); + } } ds_destroy(&ip_list); ds_destroy(&match); + free(redirect_name); + free(actions); } /* Logical router ingress Table 0: L2 Admission Control