xenserver: Set fail_mode on internal bridges.
[openvswitch] / vswitchd / bridge.c
index 72eb7346cade7a4265809ff6f4d39a38b8a91574..9c614fb343d39e40b8a1ef96a8e27e6fbab5f64a 100644 (file)
@@ -76,6 +76,8 @@ VLOG_DEFINE_THIS_MODULE(bridge);
 
 COVERAGE_DEFINE(bridge_flush);
 COVERAGE_DEFINE(bridge_process_flow);
+COVERAGE_DEFINE(bridge_process_cfm);
+COVERAGE_DEFINE(bridge_process_lacp);
 COVERAGE_DEFINE(bridge_reconfigure);
 COVERAGE_DEFINE(bridge_lacp_update);
 
@@ -3005,26 +3007,38 @@ bridge_normal_ofhook_cb(const struct flow *flow, const struct ofpbuf *packet,
                         struct ofpbuf *actions, tag_type *tags,
                         uint16_t *nf_output_iface, void *br_)
 {
-    struct iface *iface;
     struct bridge *br = br_;
 
     COVERAGE_INC(bridge_process_flow);
+    return process_flow(br, flow, packet, actions, tags, nf_output_iface);
+}
+
+static bool
+bridge_special_ofhook_cb(const struct flow *flow,
+                         const struct ofpbuf *packet, void *br_)
+{
+    struct iface *iface;
+    struct bridge *br = br_;
 
     iface = iface_from_dp_ifidx(br, flow->in_port);
 
     if (cfm_should_process_flow(flow)) {
-        if (packet && iface->cfm) {
+
+        if (iface && packet && iface->cfm) {
+            COVERAGE_INC(bridge_process_cfm);
             cfm_process_heartbeat(iface->cfm, packet);
         }
         return false;
     } else if (flow->dl_type == htons(ETH_TYPE_LACP)) {
-        if (packet) {
+
+        if (iface && packet) {
+            COVERAGE_INC(bridge_process_lacp);
             lacp_process_packet(packet, iface);
         }
         return false;
     }
 
-    return process_flow(br, flow, packet, actions, tags, nf_output_iface);
+    return true;
 }
 
 static void
@@ -3094,6 +3108,7 @@ bridge_account_checkpoint_ofhook_cb(void *br_)
 
 static struct ofhooks bridge_ofhooks = {
     bridge_normal_ofhook_cb,
+    bridge_special_ofhook_cb,
     bridge_account_flow_ofhook_cb,
     bridge_account_checkpoint_ofhook_cb,
 };
@@ -3114,7 +3129,8 @@ lacp_process_packet(const struct ofpbuf *packet, struct iface *iface)
         return;
     }
 
-    iface->lacp_status = LACP_CURRENT;
+    iface->lacp_status |= LACP_CURRENT;
+    iface->lacp_status &= ~(LACP_EXPIRED | LACP_DEFAULTED);
     iface->lacp_rx = time_msec() + LACP_SLOW_TIME_RX;
 
     iface->lacp_actor.state = iface_get_lacp_state(iface);
@@ -4687,7 +4703,8 @@ iface_set_lacp_defaulted(struct iface *iface)
 {
     memset(&iface->lacp_partner, 0, sizeof iface->lacp_partner);
 
-    iface->lacp_status = LACP_DEFAULTED;
+    iface->lacp_status |= LACP_DEFAULTED;
+    iface->lacp_status &= ~(LACP_CURRENT | LACP_EXPIRED);
     iface->lacp_tx = 0;
     iface->port->lacp_need_update = true;
 }