ovn/controller/ofctrl.c
enum mf_field_id
ofctrl_run(const struct ovsrec_bridge *br_int, struct shash *pending_ct_zones)
{
    char *target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name);
    if (strcmp(target, rconn_get_target(swconn))) {
        VLOG_INFO("%s: connecting to switch", target);
        rconn_connect(swconn, target, target);
    }
    free(target);

    rconn_run(swconn);

    if (!rconn_is_connected(swconn)) {
        return 0;
    }
    if (seqno != rconn_get_connection_seqno(swconn)) {
        seqno = rconn_get_connection_seqno(swconn);
        state = S_NEW;

        /* Reset the state of any outstanding ct flushes to resend them. */
        struct shash_node *iter;
        SHASH_FOR_EACH(iter, pending_ct_zones) {
            struct ct_zone_pending_entry *ctzpe = iter->data;
            if (ctzpe->state == CT_ZONE_OF_SENT) {
                ctzpe->state = CT_ZONE_OF_QUEUED;
            }
        }
    }

    bool progress = true;
    for (int i = 0; progress && i < 50; i++) {
        /* Allow the state machine to run. */
        enum ofctrl_state old_state = state;
        switch (state) {
#define STATE(NAME) case NAME: run_##NAME(); break;
            STATES
#undef STATE
        default:
            OVS_NOT_REACHED();
        }

        /* Try to process a received packet. */
        struct ofpbuf *msg = rconn_recv(swconn);
        if (msg) {
            const struct ofp_header *oh = msg->data;
            enum ofptype type;
            enum ofperr error;

            error = ofptype_decode(&type, oh);
            if (!error) {
                switch (state) {
#define STATE(NAME) case NAME: recv_##NAME(oh, type, pending_ct_zones); break;
                    STATES
#undef STATE
                default:
                    OVS_NOT_REACHED();
                }
            } else {
                char *s = ofp_to_string(oh, ntohs(oh->length), NULL, 1);
                VLOG_WARN("could not decode OpenFlow message (%s): %s",
                          ofperr_to_string(error), s);
                free(s);
            }

            ofpbuf_delete(msg);
        }

        /* If we did some work, plan to go around again. */
        progress = old_state != state || msg;
    }
    if (progress) {
        /* We bailed out to limit the amount of work we do in one go, to allow
         * other code a chance to run.  We were still making progress at that
         * point, so ensure that we come back again without waiting. */
        poll_immediate_wake();
    }

    return (state == S_CLEAR_FLOWS || state == S_UPDATE_FLOWS
            ? mff_ovn_geneve : 0);
}
/* Runs the OpenFlow state machine against 'br_int', which is local to the
 * hypervisor on which we are running.  Attempts to negotiate a Geneve option
 * field for class OVN_GENEVE_CLASS, type OVN_GENEVE_TYPE.  If successful,
 * returns the MFF_* field ID for the option, otherwise returns 0. */
Runs the OpenFlow state machine against 'br_int', which is local to the
hypervisor on which we are running.  Attempts to negotiate a Geneve option
field for class OVN_GENEVE_CLASS, type OVN_GENEVE_TYPE.  If successful,
returns the MFF_* field ID for the option, otherwise returns 0.
Runs the OpenFlow state machine against ' br_int ' which is local to the hypervisor on which we are running . Attempts to negotiate a Geneve option field for class OVN_GENEVE_CLASS type OVN_GENEVE_TYPE . If successful returns the MFF_ * field ID for the option otherwise returns 0 .
enum mf_field_id
ofctrl_run(const struct ovsrec_bridge *br_int, struct shash *pending_ct_zones)
{
    char *target = xasprintf("unix:%s/%s.mgmt", ovs_rundir(), br_int->name);
    if (strcmp(target, rconn_get_target(swconn))) {
        VLOG_INFO("%s: connecting to switch", target);
        rconn_connect(swconn, target, target);
    }
    free(target);
    rconn_run(swconn);
    if (!rconn_is_connected(swconn)) {
        return 0;
    }
    if (seqno != rconn_get_connection_seqno(swconn)) {
        seqno = rconn_get_connection_seqno(swconn);
        state = S_NEW;
        struct shash_node *iter;
        SHASH_FOR_EACH(iter, pending_ct_zones) {
            struct ct_zone_pending_entry *ctzpe = iter->data;
            if (ctzpe->state == CT_ZONE_OF_SENT) {
                ctzpe->state = CT_ZONE_OF_QUEUED;
            }
        }
    }
    bool progress = true;
    for (int i = 0; progress && i < 50; i++) {
        enum ofctrl_state old_state = state;
        switch (state) {
#define STATE(NAME) case NAME: run_##NAME(); break;
            STATES
#undef STATE
        default:
            OVS_NOT_REACHED();
        }
        struct ofpbuf *msg = rconn_recv(swconn);
        if (msg) {
            const struct ofp_header *oh = msg->data;
            enum ofptype type;
            enum ofperr error;
            error = ofptype_decode(&type, oh);
            if (!error) {
                switch (state) {
#define STATE(NAME) case NAME: recv_##NAME(oh, type, pending_ct_zones); break;
                    STATES
#undef STATE
                default:
                    OVS_NOT_REACHED();
                }
            } else {
                char *s = ofp_to_string(oh, ntohs(oh->length), NULL, 1);
                VLOG_WARN("could not decode OpenFlow message (%s): %s",
                          ofperr_to_string(error), s);
                free(s);
            }
            ofpbuf_delete(msg);
        }
        progress = old_state != state || msg;
    }
    if (progress) {
        poll_immediate_wake();
    }
    return (state == S_CLEAR_FLOWS || state == S_UPDATE_FLOWS
            ? mff_ovn_geneve : 0);
}
enum mf_field_id ofctrl_run ( const struct ovsrec_bridge * br_int , struct shash * pending_ct_zones ) { char * target = xasprintf ( " " , ovs_rundir ( ) , br_int -> name ) ; if ( strcmp ( target , rconn_get_target ( swconn ) ) ) { VLOG_INFO ( " " , target ) ; rconn_connect ( swconn , target , target ) ; } free ( target ) ; rconn_run ( swconn ) ; if ( ! rconn_is_connected ( swconn ) ) { return 0 ; } if ( seqno != rconn_get_connection_seqno ( swconn ) ) { seqno = rconn_get_connection_seqno ( swconn ) ; state = S_NEW ; struct shash_node * iter ; SHASH_FOR_EACH ( iter , pending_ct_zones ) { struct ct_zone_pending_entry * ctzpe = iter -> data ; if ( ctzpe -> state == CT_ZONE_OF_SENT ) { ctzpe -> state = CT_ZONE_OF_QUEUED ; } } } bool progress = true ; for ( int i = 0 ; progress && i < 50 ; i ++ ) { enum ofctrl_state old_state = state ; switch ( state ) { #define STATE ( NAME )  case NAME: run_##NAME(); break; STATES #undef  STATE default : OVS_NOT_REACHED ( ) ; } struct ofpbuf * msg = rconn_recv ( swconn ) ; if ( msg ) { const struct ofp_header * oh = msg -> data ; enum ofptype type ; enum ofperr error ; error = ofptype_decode ( & type , oh ) ; if ( ! error ) { switch ( state ) { #define STATE ( NAME )  case NAME: recv_##NAME(oh, type, pending_ct_zones); break; STATES #undef  STATE default : OVS_NOT_REACHED ( ) ; } } else { char * s = ofp_to_string ( oh , ntohs ( oh -> length ) , NULL , 1 ) ; VLOG_WARN ( " " , ofperr_to_string ( error ) , s ) ; free ( s ) ; } ofpbuf_delete ( msg ) ; } progress = old_state != state || msg ; } if ( progress ) { poll_immediate_wake ( ) ; } return ( state == S_CLEAR_FLOWS || state == S_UPDATE_FLOWS ? mff_ovn_geneve : 0 ) ; }
Runs the OpenFlow state machine against 'br_int', which is local to the
 hypervisor on which we are running.
Runs the OpenFlow state machine against ' br_int ' which is local to the hypervisor on which we are running .
/* Reset the state of any outstanding ct flushes to resend them. */ /* Allow the state machine to run. */ /* Try to process a received packet. */ /* If we did some work, plan to go around again. */ /* We bailed out to limit the amount of work we do in one go, to allow
         * other code a chance to run.  We were still making progress at that
         * point, so ensure that we come back again without waiting. */