ovn/controller/ofctrl.c
char *
ofctrl_inject_pkt(const struct ovsrec_bridge *br_int, const char *flow_s,
                  const struct shash *addr_sets)
{
    int version = rconn_get_version(swconn);
    if (version < 0) {
        return xstrdup("OpenFlow channel not ready.");
    }

    struct flow uflow;
    char *error = expr_parse_microflow(flow_s, &symtab, addr_sets,
                                       ofctrl_lookup_port, br_int, &uflow);
    if (error) {
        return error;
    }

    /* The physical OpenFlow port was stored in the logical ingress
     * port, so put it in the correct location for a flow structure. */
    uflow.in_port.ofp_port = u16_to_ofp(uflow.regs[MFF_LOG_INPORT - MFF_REG0]);
    uflow.regs[MFF_LOG_INPORT - MFF_REG0] = 0;

    if (!uflow.in_port.ofp_port) {
        return xstrdup("ingress port not found on hypervisor.");
    }

    uint64_t packet_stub[128 / 8];
    struct dp_packet packet;
    dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
    flow_compose(&packet, &uflow, 0);

    uint64_t ofpacts_stub[1024 / 8];
    struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
    struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
    resubmit->in_port = OFPP_IN_PORT;
    resubmit->table_id = 0;

    struct ofputil_packet_out po = {
        .packet = dp_packet_data(&packet),
        .packet_len = dp_packet_size(&packet),
        .buffer_id = UINT32_MAX,
        .ofpacts = ofpacts.data,
        .ofpacts_len = ofpacts.size,
    };
    match_set_in_port(&po.flow_metadata, uflow.in_port.ofp_port);
    enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
    queue_msg(ofputil_encode_packet_out(&po, proto));
    dp_packet_uninit(&packet);
    ofpbuf_uninit(&ofpacts);

    return NULL;
}
/* Generates a packet described by 'flow_s' in the syntax of an OVN
 * logical expression and injects it into 'br_int'.  The flow
 * description must contain an ingress logical port that is present on
 * 'br_int'.
 *
 * Returns NULL if successful, otherwise an error message that the caller
 * must free(). */
Generates a packet described by 'flow_s' in the syntax of an OVN
logical expression and injects it into 'br_int'.  The flow
description must contain an ingress logical port that is present on
'br_int'.

Returns NULL if successful, otherwise an error message that the caller
must free().
Generates a packet described by ' flow_s ' in the syntax of an OVN logical expression and injects it into ' br_int ' . The flow description must contain an ingress logical port that is present on ' br_int ' . Returns NULL if successful otherwise an error message that the caller must free () .
char *
ofctrl_inject_pkt(const struct ovsrec_bridge *br_int, const char *flow_s,
                  const struct shash *addr_sets)
{
    int version = rconn_get_version(swconn);
    if (version < 0) {
        return xstrdup("OpenFlow channel not ready.");
    }
    struct flow uflow;
    char *error = expr_parse_microflow(flow_s, &symtab, addr_sets,
                                       ofctrl_lookup_port, br_int, &uflow);
    if (error) {
        return error;
    }
    uflow.in_port.ofp_port = u16_to_ofp(uflow.regs[MFF_LOG_INPORT - MFF_REG0]);
    uflow.regs[MFF_LOG_INPORT - MFF_REG0] = 0;
    if (!uflow.in_port.ofp_port) {
        return xstrdup("ingress port not found on hypervisor.");
    }
    uint64_t packet_stub[128 / 8];
    struct dp_packet packet;
    dp_packet_use_stub(&packet, packet_stub, sizeof packet_stub);
    flow_compose(&packet, &uflow, 0);
    uint64_t ofpacts_stub[1024 / 8];
    struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
    struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
    resubmit->in_port = OFPP_IN_PORT;
    resubmit->table_id = 0;
    struct ofputil_packet_out po = {
        .packet = dp_packet_data(&packet),
        .packet_len = dp_packet_size(&packet),
        .buffer_id = UINT32_MAX,
        .ofpacts = ofpacts.data,
        .ofpacts_len = ofpacts.size,
    };
    match_set_in_port(&po.flow_metadata, uflow.in_port.ofp_port);
    enum ofputil_protocol proto = ofputil_protocol_from_ofp_version(version);
    queue_msg(ofputil_encode_packet_out(&po, proto));
    dp_packet_uninit(&packet);
    ofpbuf_uninit(&ofpacts);
    return NULL;
}
char * ofctrl_inject_pkt ( const struct ovsrec_bridge * br_int , const char * flow_s , const struct shash * addr_sets ) { int version = rconn_get_version ( swconn ) ; if ( version < 0 ) { return xstrdup ( " " ) ; } struct flow uflow ; char * error = expr_parse_microflow ( flow_s , & symtab , addr_sets , ofctrl_lookup_port , br_int , & uflow ) ; if ( error ) { return error ; } uflow . in_port . ofp_port = u16_to_ofp ( uflow . regs [ MFF_LOG_INPORT - MFF_REG0 ] ) ; uflow . regs [ MFF_LOG_INPORT - MFF_REG0 ] = 0 ; if ( ! uflow . in_port . ofp_port ) { return xstrdup ( " " ) ; } uint64_t packet_stub [ 128 / 8 ] ; struct dp_packet packet ; dp_packet_use_stub ( & packet , packet_stub , sizeof packet_stub ) ; flow_compose ( & packet , & uflow , 0 ) ; uint64_t ofpacts_stub [ 1024 / 8 ] ; struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER ( ofpacts_stub ) ; struct ofpact_resubmit * resubmit = ofpact_put_RESUBMIT ( & ofpacts ) ; resubmit -> in_port = OFPP_IN_PORT ; resubmit -> table_id = 0 ; struct ofputil_packet_out po = { . packet = dp_packet_data ( & packet ) , . packet_len = dp_packet_size ( & packet ) , . buffer_id = UINT32_MAX , . ofpacts = ofpacts . data , . ofpacts_len = ofpacts . size , } ; match_set_in_port ( & po . flow_metadata , uflow . in_port . ofp_port ) ; enum ofputil_protocol proto = ofputil_protocol_from_ofp_version ( version ) ; queue_msg ( ofputil_encode_packet_out ( & po , proto ) ) ; dp_packet_uninit ( & packet ) ; ofpbuf_uninit ( & ofpacts ) ; return NULL ; }
Generates a packet described by 'flow_s' in the syntax of an OVN
 logical expression and injects it into 'br_int'.
Generates a packet described by ' flow_s ' in the syntax of an OVN logical expression and injects it into ' br_int ' .
/* The physical OpenFlow port was stored in the logical ingress
     * port, so put it in the correct location for a flow structure. */