ofproto: Disable STP when unregistering a port.
[openvswitch] / ofproto / ofproto-dpif.c
index 9356800c3bd57f1cdd83112b505a31c0d678635a..e89ae893fee1f319e677656851a06fd40219972f 100644 (file)
@@ -1035,7 +1035,7 @@ update_stp_port_state(struct ofport_dpif *ofport)
         ofport->stp_state = state;
         ofport->stp_state_entered = time_msec();
 
-        if (fwd_change) {
+        if (fwd_change && ofport->bundle) {
             bundle_update(ofport->bundle);
         }
 
@@ -1105,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;
 }
@@ -3638,7 +3639,7 @@ commit_vlan_action(struct action_xlate_ctx *ctx, ovs_be16 new_tci)
         struct ovs_action_push_vlan vlan;
 
         vlan.vlan_tpid = htons(ETH_TYPE_VLAN);
-        vlan.vlan_tci = new_tci & ~htons(VLAN_CFI);
+        vlan.vlan_tci = new_tci;
         nl_msg_put_unspec(ctx->odp_actions, OVS_ACTION_ATTR_PUSH_VLAN,
                           &vlan, sizeof vlan);
     }
@@ -4719,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 {