X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=ofproto%2Fofproto-dpif.c;h=4cc720667d143dff167fd4ae42bdcb8c95fbe46b;hb=80740385d2700b1a03d28a02338d02509fd0b697;hp=9fdc489daf9f0d696cec342f777804cf55453947;hpb=ea131871e4c8793ff90f60cfb5f45947d6a2c10b;p=openvswitch diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 9fdc489d..4cc72066 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1065,6 +1065,7 @@ set_stp_port(struct ofport *ofport_, if (sp) { ofport->stp_port = NULL; stp_port_disable(sp); + update_stp_port_state(ofport); } return 0; } else if (sp && stp_port_no(sp) != s->port_num @@ -1104,6 +1105,7 @@ get_stp_port_status(struct ofport *ofport_, s->state = stp_port_get_state(sp); s->sec_in_state = (time_msec() - ofport->stp_state_entered) / 1000; s->role = stp_port_get_role(sp); + stp_port_get_counts(sp, &s->tx_count, &s->rx_count, &s->error_count); return 0; } @@ -2884,10 +2886,10 @@ facet_account(struct ofproto_dpif *ofproto, struct facet *facet) * hash bucket.) */ vlan_tci = facet->flow.vlan_tci; NL_ATTR_FOR_EACH_UNSAFE (a, left, facet->actions, facet->actions_len) { + const struct ovs_action_push_vlan *vlan; struct ofport_dpif *port; switch (nl_attr_type(a)) { - const struct nlattr *nested; case OVS_ACTION_ATTR_OUTPUT: port = get_odp_port(ofproto, nl_attr_get_u32(a)); if (port && port->bundle && port->bundle->bond) { @@ -2896,20 +2898,13 @@ facet_account(struct ofproto_dpif *ofproto, struct facet *facet) } break; - case OVS_ACTION_ATTR_POP: - if (nl_attr_get_u16(a) == OVS_KEY_ATTR_8021Q) { - vlan_tci = htons(0); - } + case OVS_ACTION_ATTR_POP_VLAN: + vlan_tci = htons(0); break; - case OVS_ACTION_ATTR_PUSH: - nested = nl_attr_get(a); - if (nl_attr_type(nested) == OVS_KEY_ATTR_8021Q) { - const struct ovs_key_8021q *q_key; - - q_key = nl_attr_get_unspec(nested, sizeof(*q_key)); - vlan_tci = q_key->q_tci; - } + case OVS_ACTION_ATTR_PUSH_VLAN: + vlan = nl_attr_get(a); + vlan_tci = vlan->vlan_tci; break; } } @@ -3247,7 +3242,7 @@ rule_dpif_lookup(struct ofproto_dpif *ofproto, const struct flow *flow, } cls = &ofproto->up.tables[table_id]; - if (flow->tos_frag & FLOW_FRAG_ANY + if (flow->nw_frag & FLOW_NW_FRAG_ANY && ofproto->up.frag_handling == OFPC_FRAG_NORMAL) { /* For OFPC_NORMAL frag_handling, we must pretend that transport ports * are unavailable. */ @@ -3585,13 +3580,10 @@ fix_sflow_action(struct action_xlate_ctx *ctx) } static void -commit_action__(struct ofpbuf *odp_actions, - enum ovs_action_attr act_type, - enum ovs_key_attr key_type, - const void *key, size_t key_size) +commit_set_action(struct ofpbuf *odp_actions, enum ovs_key_attr key_type, + const void *key, size_t key_size) { - size_t offset = nl_msg_start_nested(odp_actions, act_type); - + size_t offset = nl_msg_start_nested(odp_actions, OVS_ACTION_ATTR_SET); nl_msg_put_unspec(odp_actions, key_type, key, key_size); nl_msg_end_nested(odp_actions, offset); } @@ -3605,8 +3597,8 @@ commit_set_tun_id_action(const struct flow *flow, struct flow *base, } base->tun_id = flow->tun_id; - commit_action__(odp_actions, OVS_ACTION_ATTR_SET, - OVS_KEY_ATTR_TUN_ID, &base->tun_id, sizeof(base->tun_id)); + commit_set_action(odp_actions, OVS_KEY_ATTR_TUN_ID, + &base->tun_id, sizeof(base->tun_id)); } static void @@ -3626,8 +3618,8 @@ commit_set_ether_addr_action(const struct flow *flow, struct flow *base, memcpy(eth_key.eth_src, base->dl_src, ETH_ADDR_LEN); memcpy(eth_key.eth_dst, base->dl_dst, ETH_ADDR_LEN); - commit_action__(odp_actions, OVS_ACTION_ATTR_SET, - OVS_KEY_ATTR_ETHERNET, ð_key, sizeof(eth_key)); + commit_set_action(odp_actions, OVS_KEY_ATTR_ETHERNET, + ð_key, sizeof(eth_key)); } static void @@ -3640,18 +3632,16 @@ commit_vlan_action(struct action_xlate_ctx *ctx, ovs_be16 new_tci) } if (base->vlan_tci & htons(VLAN_CFI)) { - nl_msg_put_u16(ctx->odp_actions, OVS_ACTION_ATTR_POP, - OVS_KEY_ATTR_8021Q); + nl_msg_put_flag(ctx->odp_actions, OVS_ACTION_ATTR_POP_VLAN); } if (new_tci & htons(VLAN_CFI)) { - struct ovs_key_8021q q_key; - - q_key.q_tpid = htons(ETH_TYPE_VLAN); - q_key.q_tci = new_tci & ~htons(VLAN_CFI); + struct ovs_action_push_vlan vlan; - commit_action__(ctx->odp_actions, OVS_ACTION_ATTR_PUSH, - OVS_KEY_ATTR_8021Q, &q_key, sizeof(q_key)); + vlan.vlan_tpid = htons(ETH_TYPE_VLAN); + vlan.vlan_tci = new_tci; + nl_msg_put_unspec(ctx->odp_actions, OVS_ACTION_ATTR_PUSH_VLAN, + &vlan, sizeof vlan); } base->vlan_tci = new_tci; } @@ -3660,7 +3650,6 @@ static void commit_set_nw_action(const struct flow *flow, struct flow *base, struct ofpbuf *odp_actions) { - int frag = base->tos_frag & FLOW_FRAG_MASK; struct ovs_key_ipv4 ipv4_key; if (base->dl_type != htons(ETH_TYPE_IP) || @@ -3670,22 +3659,23 @@ commit_set_nw_action(const struct flow *flow, struct flow *base, if (base->nw_src == flow->nw_src && base->nw_dst == flow->nw_dst && - base->tos_frag == flow->tos_frag) { + base->nw_tos == flow->nw_tos && + base->nw_ttl == flow->nw_ttl && + base->nw_frag == flow->nw_frag) { return; } - - memset(&ipv4_key, 0, sizeof(ipv4_key)); ipv4_key.ipv4_src = base->nw_src = flow->nw_src; ipv4_key.ipv4_dst = base->nw_dst = flow->nw_dst; ipv4_key.ipv4_proto = base->nw_proto; - ipv4_key.ipv4_tos = flow->tos_frag & IP_DSCP_MASK; - ipv4_key.ipv4_frag = (frag == 0 ? OVS_FRAG_TYPE_NONE - : frag == FLOW_FRAG_ANY ? OVS_FRAG_TYPE_FIRST - : OVS_FRAG_TYPE_LATER); + ipv4_key.ipv4_tos = flow->nw_tos; + ipv4_key.ipv4_ttl = flow->nw_ttl; + ipv4_key.ipv4_frag = (base->nw_frag == 0 ? OVS_FRAG_TYPE_NONE + : base->nw_frag == FLOW_NW_FRAG_ANY + ? OVS_FRAG_TYPE_FIRST : OVS_FRAG_TYPE_LATER); - commit_action__(odp_actions, OVS_ACTION_ATTR_SET, - OVS_KEY_ATTR_IPV4, &ipv4_key, sizeof(ipv4_key)); + commit_set_action(odp_actions, OVS_KEY_ATTR_IPV4, + &ipv4_key, sizeof(ipv4_key)); } static void @@ -3707,8 +3697,8 @@ commit_set_port_action(const struct flow *flow, struct flow *base, port_key.tcp_src = base->tp_src = flow->tp_src; port_key.tcp_dst = base->tp_dst = flow->tp_dst; - commit_action__(odp_actions, OVS_ACTION_ATTR_SET, - OVS_KEY_ATTR_TCP, &port_key, sizeof(port_key)); + commit_set_action(odp_actions, OVS_KEY_ATTR_TCP, + &port_key, sizeof(port_key)); } else if (flow->nw_proto == IPPROTO_UDP) { struct ovs_key_udp port_key; @@ -3716,8 +3706,8 @@ commit_set_port_action(const struct flow *flow, struct flow *base, port_key.udp_src = base->tp_src = flow->tp_src; port_key.udp_dst = base->tp_dst = flow->tp_dst; - commit_action__(odp_actions, OVS_ACTION_ATTR_SET, - OVS_KEY_ATTR_UDP, &port_key, sizeof(port_key)); + commit_set_action(odp_actions, OVS_KEY_ATTR_UDP, + &port_key, sizeof(port_key)); } } @@ -3730,9 +3720,8 @@ commit_set_priority_action(const struct flow *flow, struct flow *base, } base->priority = flow->priority; - commit_action__(odp_actions, OVS_ACTION_ATTR_SET, - OVS_KEY_ATTR_PRIORITY, &base->priority, - sizeof(base->priority)); + commit_set_action(odp_actions, OVS_KEY_ATTR_PRIORITY, + &base->priority, sizeof(base->priority)); } static void @@ -4166,8 +4155,8 @@ do_xlate_actions(const union ofp_action *in, size_t n_in, break; case OFPUTIL_OFPAT_SET_NW_TOS: - ctx->flow.tos_frag &= ~IP_DSCP_MASK; - ctx->flow.tos_frag |= ia->nw_tos.nw_tos & IP_DSCP_MASK; + ctx->flow.nw_tos &= ~IP_DSCP_MASK; + ctx->flow.nw_tos |= ia->nw_tos.nw_tos & IP_DSCP_MASK; break; case OFPUTIL_OFPAT_SET_TP_SRC: @@ -4308,7 +4297,7 @@ xlate_actions(struct action_xlate_ctx *ctx, ctx->table_id = 0; ctx->exit = false; - if (ctx->flow.tos_frag & FLOW_FRAG_ANY) { + if (ctx->flow.nw_frag & FLOW_NW_FRAG_ANY) { switch (ctx->ofproto->up.frag_handling) { case OFPC_FRAG_NORMAL: /* We must pretend that transport ports are unavailable. */ @@ -4731,6 +4720,14 @@ flow_get_vlan(struct ofproto_dpif *ofproto, const struct flow *flow, return -1; } } else { + if (flow->dl_type == htons(ETH_TYPE_VLAN) && + !(flow->vlan_tci & htons(VLAN_CFI))) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + VLOG_WARN_RL(&rl, "bridge %s: dropping packet with partial " + "VLAN tag received on port %s", + ofproto->up.name, in_bundle->name); + return -1; + } if (in_bundle->vlan_mode != PORT_VLAN_TRUNK) { return in_bundle->vlan; } else {