X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto-dpif.c;h=36e7213a99a85953f71f44cc068aa722c06a962d;hb=b2fda3effc787f265b5ad5dfa967ac00627bd075;hp=ca99bec12c7aff862d9a3dc5371ad66199f4fdc0;hpb=6c1491fbd75754d2e4d5028650554f9d5d3a4958;p=sliver-openvswitch.git diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index ca99bec12..36e7213a9 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -171,11 +171,6 @@ struct action_xlate_ctx { * calling action_xlate_ctx_init(). */ void (*resubmit_hook)(struct action_xlate_ctx *, struct rule_dpif *); - /* If true, the speciality of 'flow' should be checked before executing - * its actions. If special_cb returns false on 'flow' rendered - * uninstallable and no actions will be executed. */ - bool check_special; - /* xlate_actions() initializes and uses these members. The client might want * to look at them after it returns. */ @@ -289,6 +284,7 @@ struct ofport_dpif { struct list bundle_node; /* In struct ofbundle's "ports" list. */ struct cfm *cfm; /* Connectivity Fault Management, if any. */ tag_type tag; /* Tag associated with this port. */ + uint32_t bond_stable_id; /* stable_id to use as bond slave, or 0. */ }; static struct ofport_dpif * @@ -355,8 +351,7 @@ static void handle_upcall(struct ofproto_dpif *, struct dpif_upcall *); static int expire(struct ofproto_dpif *); /* Utilities. */ -static int send_packet(struct ofproto_dpif *, - uint32_t odp_port, uint16_t vlan_tci, +static int send_packet(struct ofproto_dpif *, uint32_t odp_port, const struct ofpbuf *packet); /* Global variables. */ @@ -834,6 +829,8 @@ bundle_del_port(struct ofport_dpif *port) { struct ofbundle *bundle = port->bundle; + bundle->ofproto->need_revalidate = true; + list_remove(&port->bundle_node); port->bundle = NULL; @@ -854,7 +851,8 @@ bundle_del_port(struct ofport_dpif *port) static bool bundle_add_port(struct ofbundle *bundle, uint32_t ofp_port, - struct lacp_slave_settings *lacp) + struct lacp_slave_settings *lacp, + uint32_t bond_stable_id) { struct ofport_dpif *port; @@ -864,6 +862,7 @@ bundle_add_port(struct ofbundle *bundle, uint32_t ofp_port, } if (port->bundle != bundle) { + bundle->ofproto->need_revalidate = true; if (port->bundle) { bundle_del_port(port); } @@ -878,6 +877,8 @@ bundle_add_port(struct ofbundle *bundle, uint32_t ofp_port, lacp_slave_register(bundle->lacp, port, lacp); } + port->bond_stable_id = bond_stable_id; + return true; } @@ -981,7 +982,8 @@ bundle_set(struct ofproto *ofproto_, void *aux, ok = true; for (i = 0; i < s->n_slaves; i++) { if (!bundle_add_port(bundle, s->slaves[i], - s->lacp ? &s->lacp_slaves[i] : NULL)) { + s->lacp ? &s->lacp_slaves[i] : NULL, + s->bond_stable_ids ? s->bond_stable_ids[i] : 0)) { ok = false; } } @@ -990,7 +992,7 @@ bundle_set(struct ofproto *ofproto_, void *aux, LIST_FOR_EACH_SAFE (port, next_port, bundle_node, &bundle->ports) { for (i = 0; i < s->n_slaves; i++) { - if (s->slaves[i] == odp_port_to_ofp_port(port->odp_port)) { + if (s->slaves[i] == port->up.ofp_port) { goto found; } } @@ -1029,13 +1031,11 @@ bundle_set(struct ofproto *ofproto_, void *aux, } } else { bundle->bond = bond_create(s->bond); + ofproto->need_revalidate = true; } LIST_FOR_EACH (port, bundle_node, &bundle->ports) { - uint16_t stable_id = (bundle->lacp - ? lacp_slave_get_port_id(bundle->lacp, port) - : port->odp_port); - bond_slave_register(bundle->bond, port, stable_id, + bond_slave_register(bundle->bond, port, port->bond_stable_id, port->up.netdev); } } else { @@ -1356,7 +1356,8 @@ is_mirror_output_bundle(struct ofproto *ofproto_, void *aux) static struct ofport_dpif * get_ofp_port(struct ofproto_dpif *ofproto, uint16_t ofp_port) { - return ofport_dpif_cast(ofproto_get_port(&ofproto->up, ofp_port)); + struct ofport *ofport = ofproto_get_port(&ofproto->up, ofp_port); + return ofport ? ofport_dpif_cast(ofport) : NULL; } static struct ofport_dpif * @@ -1389,7 +1390,7 @@ port_run(struct ofport_dpif *ofport) ETH_TYPE_CFM, sizeof *ccm); cfm_compose_ccm(ofport->cfm, ccm); send_packet(ofproto_dpif_cast(ofport->up.ofproto), - ofport->odp_port, 0, &packet); + ofport->odp_port, &packet); ofpbuf_uninit(&packet); } } @@ -1589,7 +1590,7 @@ handle_miss_upcall(struct ofproto_dpif *ofproto, struct dpif_upcall *upcall) /* Check with in-band control to see if this packet should be sent * to the local port regardless of the flow table. */ if (connmgr_msg_in_hook(ofproto->up.connmgr, &flow, upcall->packet)) { - send_packet(ofproto, OFPP_LOCAL, 0, upcall->packet); + send_packet(ofproto, OFPP_LOCAL, upcall->packet); } facet = facet_lookup_valid(ofproto, &flow); @@ -2615,23 +2616,16 @@ rule_modify_actions(struct rule *rule_, return error; } -/* Sends 'packet' out of port 'odp_port' within 'ofproto'. If 'vlan_tci' is - * zero the packet will not have any 802.1Q hader; if it is nonzero, then the - * packet will be sent with the VLAN TCI specified by 'vlan_tci & ~VLAN_CFI'. - * +/* Sends 'packet' out of port 'odp_port' within 'p'. * Returns 0 if successful, otherwise a positive errno value. */ static int -send_packet(struct ofproto_dpif *ofproto, uint32_t odp_port, uint16_t vlan_tci, +send_packet(struct ofproto_dpif *ofproto, uint32_t odp_port, const struct ofpbuf *packet) { struct ofpbuf odp_actions; int error; ofpbuf_init(&odp_actions, 32); - if (vlan_tci != 0) { - nl_msg_put_u32(&odp_actions, ODP_ACTION_ATTR_SET_DL_TCI, - ntohs(vlan_tci & ~VLAN_CFI)); - } nl_msg_put_u32(&odp_actions, ODP_ACTION_ATTR_OUTPUT, odp_port); error = dpif_execute(ofproto->dpif, odp_actions.data, odp_actions.size, packet); @@ -3114,7 +3108,6 @@ action_xlate_ctx_init(struct action_xlate_ctx *ctx, ctx->flow = *flow; ctx->packet = packet; ctx->resubmit_hook = NULL; - ctx->check_special = true; } static struct ofpbuf * @@ -3130,8 +3123,7 @@ xlate_actions(struct action_xlate_ctx *ctx, ctx->recurse = 0; ctx->last_pop_priority = -1; - if (ctx->check_special - && process_special(ctx->ofproto, &ctx->flow, ctx->packet)) { + if (process_special(ctx->ofproto, &ctx->flow, ctx->packet)) { ctx->may_set_up_flow = false; } else { do_xlate_actions(in, n_in, ctx); @@ -3530,7 +3522,7 @@ is_admissible(struct ofproto_dpif *ofproto, const struct flow *flow, /* Find the port and bundle for the received packet. */ in_port = get_ofp_port(ofproto, flow->in_port); - *in_bundlep = in_bundle = in_port->bundle; + *in_bundlep = in_bundle = in_port ? in_port->bundle : NULL; if (!in_port || !in_bundle) { /* No interface? Something fishy... */ if (have_packet) {