Hi Numan, I found one tiny nit in this patch. See below

On Mon, Nov 3, 2025 at 9:20 PM <[email protected]> wrote:
>
> From: Numan Siddique <[email protected]>
>
> Signed-off-by: Numan Siddique <[email protected]>
> ---
>  br-controller/automake.mk             |   2 +
>  br-controller/en-lflow.h              |   7 +-
>  br-controller/en-pflow.c              | 192 ++++++++++++++++++++++++++
>  br-controller/en-pflow.h              |  16 +++
>  br-controller/ovn-br-controller.8.xml |  28 ++++
>  br-controller/ovn-br-controller.c     |   6 +
>  6 files changed, 249 insertions(+), 2 deletions(-)
>  create mode 100644 br-controller/en-pflow.c
>  create mode 100644 br-controller/en-pflow.h
>
> diff --git a/br-controller/automake.mk b/br-controller/automake.mk
> index ea515a85e4..4baea4f6fe 100644
> --- a/br-controller/automake.mk
> +++ b/br-controller/automake.mk
> @@ -6,6 +6,8 @@ br_controller_ovn_br_controller_SOURCES = \
>         br-controller/en-bridge-data.h \
>         br-controller/en-lflow.c \
>         br-controller/en-lflow.h \
> +       br-controller/en-pflow.c \
> +       br-controller/en-pflow.h \
>         br-controller/ovn-br-controller.c
>
>  br_controller_ovn_br_controller_LDADD = lib/libovn.la 
> $(OVS_LIBDIR)/libopenvswitch.la
> diff --git a/br-controller/en-lflow.h b/br-controller/en-lflow.h
> index 39daa30174..0b9f1deb1a 100644
> --- a/br-controller/en-lflow.h
> +++ b/br-controller/en-lflow.h
> @@ -9,8 +9,11 @@
>
>  #include "lib/inc-proc-eng.h"
>
> -#define BR_OFTABLE_LOG_INGRESS_PIPELINE      8
> -#define BR_OFTABLE_SAVE_INPORT               64
> +/* OpenFlow table numbers. */
> +#define BR_OFTABLE_PHY_TO_LOG             0
> +#define BR_OFTABLE_LOG_INGRESS_PIPELINE   8
> +#define BR_OFTABLE_SAVE_INPORT            120
> +#define BR_OFTABLE_LOG_TO_PHY             121
>
>  enum engine_node_state en_lflow_output_run(struct engine_node *, void *data);
>  void *en_lflow_output_init(struct engine_node *node, struct engine_arg *arg);
> diff --git a/br-controller/en-pflow.c b/br-controller/en-pflow.c
> new file mode 100644
> index 0000000000..5f4c5b914f
> --- /dev/null
> +++ b/br-controller/en-pflow.c
> @@ -0,0 +1,192 @@
> +/*
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at:
> + *
> + *     http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include <config.h>
> +
> +#include <getopt.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +/* OVS includes. */
> +#include "lib/coverage.h"
> +#include "lib/flow.h"
> +#include "lib/simap.h"
> +#include "lib/vswitch-idl.h"
> +#include "openvswitch/match.h"
> +#include "openvswitch/ofp-actions.h"
> +#include "openvswitch/ofpbuf.h"
> +#include "openvswitch/ofp-parse.h"
> +
> +#include "openvswitch/vlog.h"
> +#include "openvswitch/uuid.h"
> +
> +/* OVN includes. */
> +#include "br-flow-mgr.h"
> +#include "en-lflow.h"
> +#include "en-pflow.h"
> +#include "en-bridge-data.h"
> +#include "include/ovn/logical-fields.h"
> +#include "lib/ovn-br-idl.h"
> +
> +VLOG_DEFINE_THIS_MODULE(en_pflow);
> +
> +
> +static void pflow_run(const struct shash *ovn_bridges);
> +static void physical_flows_add(const struct ovn_bridge *);
> +
> +static void put_load(uint64_t value, enum mf_field_id dst, int ofs, int 
> n_bits,
> +                     struct ofpbuf *);
> +static void put_resubmit(uint8_t table_id, struct ofpbuf *);
> +
> +static void add_interface_flows(const char *bridge,
> +                                const struct ovsrec_interface *iface_rec,
> +                                int64_t, struct ofpbuf *);
> +
> +/* Public functions. */
> +void *en_pflow_output_init(struct engine_node *node OVS_UNUSED,
> +                           struct engine_arg *arg OVS_UNUSED)
> +{
> +    return NULL;
> +}
> +
> +void en_pflow_output_cleanup(void *data_ OVS_UNUSED)
> +{
> +}
> +
> +enum engine_node_state
> +en_pflow_output_run(struct engine_node *node, void *data_  OVS_UNUSED)
> +{
> +    struct ed_type_bridge_data *br_data =
> +        engine_get_input_data("bridge_data", node);
> +
> +    pflow_run(&br_data->bridges);
> +
> +    return EN_UPDATED;
> +}
> +
> +/* Static functions. */
> +static void
> +pflow_run(const struct shash *ovn_bridges)
> +{
> +    br_flow_switch_physical_oflow_tables();
> +    struct shash_node *shash_node;
> +    SHASH_FOR_EACH (shash_node, ovn_bridges) {
> +        physical_flows_add(shash_node->data);
> +    }
> +}
> +
> +static void
> +physical_flows_add(const struct ovn_bridge *br)
> +{
> +    if (!br->ovs_br) {
> +        return;
> +    }
> +
> +    struct ofpbuf ofpacts;
> +    ofpbuf_init(&ofpacts, 0);
> +
> +    struct match match = MATCH_CATCHALL_INITIALIZER;
> +
> +    /* Table 0 and 65, priority 0, actions=NORMAL

This appears to have been copied from controller/physical.c. The
tables here are actually 0 and 121.

> +     * ===================================
> +     *
> +     */
> +    ofpact_put_OUTPUT(&ofpacts)->port = OFPP_NORMAL;
> +    br_flow_add_physical_oflow(br->db_br->name, BR_OFTABLE_PHY_TO_LOG, 0,
> +                               br->ovs_br->header_.uuid.parts[0],
> +                               &match, &ofpacts, &br->ovs_br->header_.uuid);
> +    br_flow_add_physical_oflow(br->db_br->name, BR_OFTABLE_LOG_TO_PHY, 0,
> +                               br->ovs_br->header_.uuid.parts[0],
> +                               &match, &ofpacts, &br->ovs_br->header_.uuid);
> +
> +    ofpbuf_clear(&ofpacts);
> +    put_resubmit(BR_OFTABLE_LOG_TO_PHY, &ofpacts);
> +    br_flow_add_physical_oflow(br->db_br->name, BR_OFTABLE_SAVE_INPORT, 0,
> +                               br->ovs_br->header_.uuid.parts[0],
> +                               &match, &ofpacts, &br->ovs_br->header_.uuid);
> +
> +    for (size_t i = 0; i < br->ovs_br->n_ports; i++) {
> +        const struct ovsrec_port *port_rec = br->ovs_br->ports[i];
> +
> +        for (size_t j = 0; j < port_rec->n_interfaces; j++) {
> +            const struct ovsrec_interface *iface_rec;
> +
> +            iface_rec = port_rec->interfaces[j];
> +            int64_t ofport = iface_rec->n_ofport ? *iface_rec->ofport : 0;
> +            if (ofport > 0 && ofport != ofp_to_u16(OFPP_LOCAL) &&
> +                smap_get_bool(&iface_rec->external_ids,
> +                              "ovnbr-managed", true)) {
> +                add_interface_flows(br->db_br->name, iface_rec,
> +                                    ofport, &ofpacts);
> +            }
> +        }
> +    }
> +
> +    ofpbuf_uninit(&ofpacts);
> +}
> +
> +static void
> +put_load(uint64_t value, enum mf_field_id dst, int ofs, int n_bits,
> +         struct ofpbuf *ofpacts)
> +{
> +    struct ofpact_set_field *sf = ofpact_put_set_field(ofpacts,
> +                                                       mf_from_id(dst), NULL,
> +                                                       NULL);
> +    ovs_be64 n_value = htonll(value);
> +    bitwise_copy(&n_value, 8, 0, sf->value, sf->field->n_bytes, ofs, n_bits);
> +    bitwise_one(ofpact_set_field_mask(sf), sf->field->n_bytes, ofs, n_bits);
> +}
> +
> +static void
> +put_resubmit(uint8_t table_id, struct ofpbuf *ofpacts)
> +{
> +    struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(ofpacts);
> +    resubmit->in_port = OFPP_IN_PORT;
> +    resubmit->table_id = table_id;
> +}
> +
> +static void
> +add_interface_flows(const char *bridge,
> +                    const struct ovsrec_interface *iface_rec,
> +                    int64_t ofport, struct ofpbuf *ofpacts_p)
> +{
> +    struct match match = MATCH_CATCHALL_INITIALIZER;
> +    match_set_in_port(&match, u16_to_ofp(ofport));
> +
> +    ofpbuf_clear(ofpacts_p);
> +    put_load(ofport, MFF_LOG_INPORT, 0, 32, ofpacts_p);
> +
> +    uint32_t iface_metadata =
> +        smap_get_uint(&iface_rec->external_ids, "ovn-iface-metadata", 0);
> +    if (iface_metadata) {
> +        put_load(iface_metadata, MFF_METADATA, 0, 32, ofpacts_p);
> +    }
> +
> +    put_resubmit(BR_OFTABLE_LOG_INGRESS_PIPELINE, ofpacts_p);
> +    br_flow_add_physical_oflow(bridge, BR_OFTABLE_PHY_TO_LOG, 100,
> +                               iface_rec->header_.uuid.parts[0],
> +                               &match, ofpacts_p,
> +                               &iface_rec->header_.uuid);
> +
> +
> +    match_init_catchall(&match);
> +    match_set_reg(&match, MFF_LOG_OUTPORT - MFF_REG0, ofport);
> +
> +    ofpbuf_clear(ofpacts_p);
> +    ofpact_put_OUTPUT(ofpacts_p)->port = u16_to_ofp(ofport);
> +    br_flow_add_physical_oflow(bridge, BR_OFTABLE_LOG_TO_PHY, 100,
> +                               iface_rec->header_.uuid.parts[0],
> +                               &match, ofpacts_p,
> +                               &iface_rec->header_.uuid);
> +}
> diff --git a/br-controller/en-pflow.h b/br-controller/en-pflow.h
> new file mode 100644
> index 0000000000..85edf53c17
> --- /dev/null
> +++ b/br-controller/en-pflow.h
> @@ -0,0 +1,16 @@
> +#ifndef EN_PFLOW_H
> +#define EN_PFLOW_H 1
> +
> +#include <config.h>
> +
> +#include <getopt.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +
> +#include "lib/inc-proc-eng.h"
> +
> +enum engine_node_state en_pflow_output_run(struct engine_node *, void *data);
> +void *en_pflow_output_init(struct engine_node *node, struct engine_arg *arg);
> +void en_pflow_output_cleanup(void *data);
> +
> +#endif /* EN_PFLOW_H */
> diff --git a/br-controller/ovn-br-controller.8.xml 
> b/br-controller/ovn-br-controller.8.xml
> index cfc88a8aae..6816ece8f7 100644
> --- a/br-controller/ovn-br-controller.8.xml
> +++ b/br-controller/ovn-br-controller.8.xml
> @@ -48,4 +48,32 @@
>          </p>
>        </dd>
>      </dl>
> +
> +    <p>
> +      <code>ovn-br-controller</code> reads the following values from the
> +      <code>Open_vSwitch</code> database of the local OVS instance:
> +    </p>
> +
> +    <dl>
> +      <dt>
> +        <code>external_ids:ovnbr-managed</code> from
> +        <ref table="Interface" db="Open_vSwitch"/> table
> +      </dt>
> +      <dd>
> +        <p>
> +          If the value is <code>true</code>, then this interface is managed 
> by
> +          <code>ovn-br-controller</code> if this interface is connected to
> +          the OVS bridge managed by <code>ovn-br-controller</code>.
> +        </p>
> +
> +        <p>
> +          Default value is true if this option is not defined.
> +        </p>
> +
> +        <p>
> +          CMS should set the value of this option to <code>false</code>
> +          if it doesn't want <code>ovn-br-controller</code> to manage it.
> +        </p>
> +      </dd>
> +    </dl>
>  </manpage>
> diff --git a/br-controller/ovn-br-controller.c 
> b/br-controller/ovn-br-controller.c
> index 7cfe6ac23d..ae0e192429 100644
> --- a/br-controller/ovn-br-controller.c
> +++ b/br-controller/ovn-br-controller.c
> @@ -37,6 +37,7 @@
>  /* OVN includes. */
>  #include "en-bridge-data.h"
>  #include "en-lflow.h"
> +#include "en-pflow.h"
>  #include "lib/ovn-br-idl.h"
>  #include "lib/inc-proc-eng.h"
>  #include "lib/ovn-util.h"
> @@ -171,6 +172,7 @@ main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
>      /* Define inc-proc-engine nodes. */
>      ENGINE_NODE(bridge_data);
>      ENGINE_NODE(lflow_output);
> +    ENGINE_NODE(pflow_output);
>      ENGINE_NODE(br_controller_output);
>
>  #define BRCTL_NODE(NAME) ENGINE_NODE_BR(NAME);
> @@ -191,7 +193,11 @@ main(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
>
>      engine_add_input(&en_lflow_output, &en_bridge_data, NULL);
>      engine_add_input(&en_lflow_output, &en_ovnbr_logical_flow, NULL);
> +
> +    engine_add_input(&en_pflow_output, &en_bridge_data, NULL);
> +
>      engine_add_input(&en_br_controller_output, &en_lflow_output, NULL);
> +    engine_add_input(&en_br_controller_output, &en_pflow_output, NULL);
>
>      struct engine_arg engine_arg = {
>          .ovs_idl = ovs_idl_loop.idl,
> --
> 2.51.0
>
> _______________________________________________
> dev mailing list
> [email protected]
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
>

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to