netdev: Fix carrier status for down interfaces.
[sliver-openvswitch.git] / ofproto / ofproto.c
index 5e99fca..2ec7c8c 100644 (file)
@@ -1277,6 +1277,15 @@ ofproto_port_del(struct ofproto *ofproto, uint16_t odp_port)
     return error;
 }
 
+/* Checks if 'ofproto' thinks 'odp_port' should be included in floods.  Returns
+ * true if 'odp_port' exists and should be included, false otherwise. */
+bool
+ofproto_port_is_floodable(struct ofproto *ofproto, uint16_t odp_port)
+{
+    struct ofport *ofport = get_port(ofproto, odp_port);
+    return ofport && !(ofport->opp.config & OFPPC_NO_FLOOD);
+}
+
 int
 ofproto_send_packet(struct ofproto *p, const struct flow *flow,
                     const union ofp_action *actions, size_t n_actions,
@@ -1363,6 +1372,8 @@ reinit_ports(struct ofproto *p)
     size_t n_odp_ports;
     size_t i;
 
+    COVERAGE_INC(ofproto_reinit_ports);
+
     svec_init(&devnames);
     HMAP_FOR_EACH (ofport, hmap_node, &p->ports) {
         svec_add (&devnames, (char *) ofport->opp.name);
@@ -1387,7 +1398,6 @@ make_ofport(const struct odp_port *odp_port)
     enum netdev_flags flags;
     struct ofport *ofport;
     struct netdev *netdev;
-    bool carrier;
     int error;
 
     memset(&netdev_options, 0, sizeof netdev_options);
@@ -1415,8 +1425,7 @@ make_ofport(const struct odp_port *odp_port)
     netdev_get_flags(netdev, &flags);
     ofport->opp.config = flags & NETDEV_UP ? 0 : OFPPC_PORT_DOWN;
 
-    netdev_get_carrier(netdev, &carrier);
-    ofport->opp.state = carrier ? 0 : OFPPS_LINK_DOWN;
+    ofport->opp.state = netdev_get_carrier(netdev) ? 0 : OFPPS_LINK_DOWN;
 
     netdev_get_features(netdev,
                         &ofport->opp.curr, &ofport->opp.advertised,
@@ -2759,16 +2768,15 @@ do_xlate_actions(const union ofp_action *in, size_t n_in,
 
         case OFPAT_SET_VLAN_VID:
             oa = odp_actions_add(ctx->out, ODPAT_SET_DL_TCI);
-            oa->dl_tci.tci = ia->vlan_vid.vlan_vid & htons(VLAN_VID_MASK);
-            oa->dl_tci.mask = htons(VLAN_VID_MASK);
+            oa->dl_tci.tci = ia->vlan_vid.vlan_vid;
+            oa->dl_tci.tci |= htons(ctx->flow.dl_vlan_pcp << VLAN_PCP_SHIFT);
             ctx->flow.dl_vlan = ia->vlan_vid.vlan_vid;
             break;
 
         case OFPAT_SET_VLAN_PCP:
             oa = odp_actions_add(ctx->out, ODPAT_SET_DL_TCI);
-            oa->dl_tci.tci = htons((ia->vlan_pcp.vlan_pcp << VLAN_PCP_SHIFT)
-                                   & VLAN_PCP_MASK);
-            oa->dl_tci.mask = htons(VLAN_PCP_MASK);
+            oa->dl_tci.tci = htons(ia->vlan_pcp.vlan_pcp << VLAN_PCP_SHIFT);
+            oa->dl_tci.tci |= ctx->flow.dl_vlan;
             ctx->flow.dl_vlan_pcp = ia->vlan_pcp.vlan_pcp;
             break;
 
@@ -3338,6 +3346,8 @@ flow_stats_ds_cb(struct cls_rule *rule_, void *cbdata_)
     ofp_print_match(results, &match, true);
     if (act_len > 0) {
         ofp_print_actions(results, &rule->actions->header, act_len);
+    } else {
+        ds_put_cstr(results, "drop");
     }
     ds_put_cstr(results, "\n");
 }