OVS PI Ofpt_port_status Process

Source: Internet
Author: User


According to the OpenFlow contract [ofp1.0-38], when the physical port OvS DataPath added, changed or deleted. Will run the detailed action first. The controller is then informed by Ofp_port_status asynchronous messages, such as when we run a command such as Ovs-vsctl Add-port br0 eth0, the OVSDB database is updated. The global variable reconfiguring becomes true at one polling time, and this OvS is configured again.


if (reconfiguring) {///CFG entries can be traced to a configuration change in Ovsdb        if (cfg) {            if (!reconf_txn) {                Reconf_txn = Ovsdb_idl_txn_ Create (IDL);            } Configure each CFG again, core Ingress            if (bridge_reconfigure_continue (cfg)) {                ovsrec_open_vswitch_set_cur_cfg (cfg, cfg-> NEXT_CFG);            }        } else {            bridge_reconfigure_continue (&null_cfg);        }    }

Next, run the configuration in detail:

static boolbridge_reconfigure_continue (const struct Ovsrec_open_vswitch *ovs_cfg) {struct sockaddr_in *managers;    int sflow_bridge_number;    size_t N_managers;    struct Bridge *br;    BOOL done;    ASSERT (reconfiguring);//Reconfigure First thing to do is to delete the old port, and then build a new port based on the configuration done = BRIDGE_RECONFIGURE_OFP (); /* Complete the configuration.    */sflow_bridge_number = 0;    Collect_in_band_managers (Ovs_cfg, &managers, &n_managers);        Hmap_for_each (BR, node, &all_bridges) {struct Port *port; /* We need the DataPath ID early to allow LACP ports to use it as the * default system ID.        */bridge_configure_datapath_id (BR);            Hmap_for_each (port, Hmap_node, &br->ports) {struct iface *iface;            Port_configure (port);                List_for_each (Iface, Port_elem, &port->ifaces) {iface_configure_cfm (iface);                Iface_configure_qos (Iface, Port->cfg->qos); Iface_set_mac (Iface);           }} bridge_configure_mirrors (BR);        Bridge_configure_flow_eviction_threshold (BR);        BRIDGE_CONFIGURE_FORWARD_BPDU (BR);        Bridge_configure_mac_idle_time (BR);        Bridge_configure_remotes (BR, managers, n_managers);        Bridge_configure_netflow (BR);        Bridge_configure_sflow (BR, &sflow_bridge_number);        BRIDGE_CONFIGURE_STP (BR);    Bridge_configure_tables (BR);    } free (managers); if (done) {/* Ovs-vswitchd have completed initialization, so allow the process that * forked us to exit suc Cessfully.        */Daemonize_complete ();        reconfiguring = false;    Vlog_info ("%s (Open vSwitch)%s", program_name, VERSION); } return done;}


Delete all the ports first, then add:

Static BOOLBRIDGE_RECONFIGURE_OFP (void) {long long int deadline;    struct Bridge *br;    Time_refresh ();    Deadline = Time_msec () + Ofp_port_action_window; /* The kernel would reject any attempt to add a given port to a datapath if * This port already belongs to a different DataPath, so we must does all * ports deletions before any port additions.        */Hmap_for_each (BR, node, &all_bridges) {struct ofpp_garbage *garbage, *next; List_for_each_safe (Garbage, Next, List_node, &br->ofpp_garbage) {/* It ' s a bit dangerous to call BRIDG  E_run_fast () Here as Ofproto's * internal datastructures may is not consistent. Eventually, when * port additions and deletions is cheaper, these calls should be * removed.            */Bridge_run_fast ();            Ofproto_port_del (Br->ofproto, Garbage->ofp_port);            List_remove (&garbage->list_node);            Free (garbage); Time_refresh ();            if (Time_msec () >= deadline) {return false;        } bridge_run_fast ();        }} hmap_for_each (BR, node, &all_bridges) {struct if_cfg *if_cfg, *next; Hmap_for_each_safe (If_cfg, Next, Hmap_node, &br->if_cfg_todo) {//Here is the core, add an interface on our OvS bridge Iface_crea            Te (BR, If_cfg,-1);            Time_refresh ();            if (Time_msec () >= deadline) {return false; }}} return true;

add a interface to the BR according to the configuration if_cfg, assuming that the specified openflowport number is negative. Indicates that you are actively assigning:

Static booliface_create (struct bridge *br, struct if_cfg *if_cfg, int ofp_port) {const struct Ovsrec_interface *iface_c    FG = if_cfg->cfg;    const struct Ovsrec_port *port_cfg = if_cfg->parent;    struct Netdev *netdev;    struct Iface *iface;    struct Port *port;    int error;  /* Get rid of ' if_cfg ' itself. We already copied out the interesting * bits.    */Hmap_remove (&br->if_cfg_todo, &if_cfg->hmap_node);    Free (IF_CFG);     /* Do the bits, the can fail up front. * * It's a bit dangerous to call Bridge_run_fast () here as Ofproto's * internal datastructures may is not consiste  Nt. Eventually, when Port * additions and deletions is cheaper, these calls should be removed.    */Bridge_run_fast ();    ASSERT (!iface_lookup (BR, iface_cfg->name));    Error = Iface_do_create (BR, Iface_cfg, Port_cfg, &ofp_port, &netdev);    Bridge_run_fast ();        if (Error) {Iface_clear_db_record (iface_cfg);    return false; }/* Get or create the port structure.    */port = port_lookup (BR, port_cfg->name);    if (!port) {port = Port_create (BR, port_cfg); }/* Create the IFACE structure.    */iface = xzalloc (sizeof *iface);    List_push_back (&port->ifaces, &iface->port_elem);    Hmap_insert (&br->iface_by_name, &iface->name_node, hash_string (iface_cfg->name, 0));    Iface->port = port;    Iface->name = Xstrdup (iface_cfg->name);    Iface->ofp_port =-1;    Iface->netdev = Netdev;    Iface->type = Iface_get_type (iface_cfg, br->cfg);    Iface->cfg = iface_cfg;    Iface_set_ofp_port (Iface, Ofp_port); /* Populate initial status in database.    */Iface_refresh_stats (iface);    Iface_refresh_status (Iface); /* ADD bond fake iface if necessary.        */if (Port_is_bond_fake_iface (port)) {struct Ofproto_port ofproto_port;                                    if (Ofproto_port_query_by_name (Br->ofproto, Port->name,   &ofproto_port) {struct Netdev *netdev;            int error;            Error = Netdev_open (port->name, "internal", &netdev);                if (!error) {//Add this network device to our OpenFlow switch Ofproto_port_add (Br->ofproto, Netdev, NULL);            Netdev_close (Netdev); } else {Vlog_warn ("Could not open network device%s (%s)", Port->name, Strerro            R (Error));        }} else {/* already exists, nothing to do. */Ofproto_port_destroy (&ofproto_port); }} return true;

Call Ofproto (OpenFlow SW Interface) to implement the Port_add method in detail:

Intofproto_port_add (struct Ofproto *ofproto, struct Netdev *netdev,                 uint16_t *ofp_portp) {    uint16_t ofp_port;    int error;    Error = Ofproto->ofproto_class->port_add (Ofproto, Netdev, &ofp_port);//See Dpif_linux_class's Detailed implementation    if (! Error) {//update our openflow switch (i.e. Ofproto)        Update_port (Ofproto, Netdev_get_name (Netdev));    }    if (OFP_PORTP) {        *OFP_PORTP = error? Ofpp_none:ofp_port;    }    return error;}


Static Voidupdate_port (struct Ofproto *ofproto, const char *name) {struct Ofproto_port ofproto_port;    struct Ofputil_phy_port pp;    struct Netdev *netdev;    struct Ofport *port;    Coverage_inc (Ofproto_update_port); /* Fetch ' name ' s location and properties from the DataPath. */Netdev = (!ofproto_port_query_by_name (ofproto, name, &ofproto_port)? Ofport_open (Ofproto, &OFP    Roto_port, &PP): NULL);        if (netdev) {port = Ofproto_get_port (Ofproto, Ofproto_port.ofp_port); if (Port &&!strcmp (Netdev_get_name (Port->netdev), name)) {struct Netdev *old_netdev = port->net            Dev  /* ' name ' hasn ' t changed location. Any properties changed?            */if (!ofport_equal (&PORT->PP, &pp)) {ofport_modified (port, &PP);            } update_mtu (Ofproto, Port);             /* Install The newly opened Netdev in case it has changed. * Don ' t close the old Netdev Yet in case port_modified have to * remove a retained reference to it.*/Port->netdev = n            Etdev;            Port->change_seq = Netdev_change_seq (Netdev); if (port->ofproto->ofproto_class->port_modified) {Port->ofproto->ofproto_class->port_mod            Ified (port);        } netdev_close (Old_netdev);  } else {/* If ' port ' is nonnull then its name differs from ' name ' and thus * we should delete it. If we think there ' s a port named ' name ' * then its port number must is wrong now so delete it too.            */if (port) {ofport_remove (port);        } ofport_remove_with_name (Ofproto, name);//See here Ofport_install (Ofproto, Netdev, &pp);    }} else {/* Any port named ' name ' was gone now. */Ofport_remove_with_name (Ofproto, name); } Ofproto_port_destroy (&ofproto_port);}

Static Voidofport_install (struct Ofproto *p, struct netdev *netdev, const struct Ofputil_phy_port *pp) {C    Onst char *netdev_name = netdev_get_name (Netdev);    struct Ofport *ofport;    int error; /* Create Ofport.    */Ofport = P->ofproto_class->port_alloc ();        if (!ofport) {error = Enomem;    Goto error;    } Ofport->ofproto = P;    Ofport->netdev = Netdev;    Ofport->change_seq = Netdev_change_seq (Netdev);    OFPORT->PP = *pp;    Ofport->ofp_port = pp->port_no; /* ADD port to ' P '.    */Hmap_insert (&p->ports, &ofport->hmap_node, Hash_int (ofport->ofp_port, 0));    Shash_add (&p->port_by_name, Netdev_name, Ofport);    UPDATE_MTU (P, ofport); /* Let the Ofproto_class initialize its private data.    */error = p->ofproto_class->port_construct (Ofport);    if (Error) {goto error; After the}//update operation is complete.    Send notification message to Controller connmgr_send_port_status (P->connmgr, pp, ofppr_add);   Return;error: VLOG_WARN_RL (&RL, "%s:could not add port%s (%s)", P->name, Netdev_name, strerror (Error));    if (ofport) {ofport_destroy__ (ofport);    } else {netdev_close (Netdev); }}

send Port_status and Port change Reasons to SDN Controller:

Voidconnmgr_send_port_status (struct connmgr *mgr,                         const struct Ofputil_phy_port *pp, uint8_t reason) {/    * XXX Should limit the number of queued port status change messages. */    struct ofputil_port_status PS;    struct Ofconn *ofconn;    Ps.reason = reason;    Ps.desc = *pp;    List_for_each (Ofconn, node, &mgr->all_conns) {        if (ofconn_receives_async_msg (Ofconn, Oam_port_status, Reason) {            struct ofpbuf *msg;            msg = Ofputil_encode_port_status (&ps, ofconn->protocol);            Ofconn_send (Ofconn, MSG, NULL);}}}    



Copyright notice: This article Bo Master original article. Blog, not reproduced without consent.

OVS PI Ofpt_port_status Process

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.