dpif-linux: Fix flow_dump_next annotation.
[sliver-openvswitch.git] / lib / dpif-linux.c
index 54d7f2a..933c872 100644 (file)
@@ -73,6 +73,7 @@ struct dpif_linux_dp {
     /* Attributes. */
     const char *name;                  /* OVS_DP_ATTR_NAME. */
     const uint32_t *upcall_pid;        /* OVS_DP_ATTR_UPCALL_PID. */
+    uint32_t user_features;            /* OVS_DP_ATTR_USER_FEATURES */
     struct ovs_dp_stats stats;         /* OVS_DP_ATTR_STATS. */
     struct ovs_dp_megaflow_stats megaflow_stats;
                                        /* OVS_DP_ATTR_MEGAFLOW_STATS.*/
@@ -231,9 +232,11 @@ dpif_linux_open(const struct dpif_class *class OVS_UNUSED, const char *name,
         upcall_pid = 0;
         dp_request.upcall_pid = &upcall_pid;
     } else {
-        dp_request.cmd = OVS_DP_CMD_GET;
+        /* Use OVS_DP_CMD_SET to report user features */
+        dp_request.cmd = OVS_DP_CMD_SET;
     }
     dp_request.name = name;
+    dp_request.user_features |= OVS_DP_F_UNALIGNED;
     error = dpif_linux_dp_transact(&dp_request, &dp, &buf);
     if (error) {
         return error;
@@ -670,12 +673,6 @@ dpif_linux_port_query_by_name(const struct dpif *dpif, const char *devname,
     return dpif_linux_port_query__(dpif, 0, devname, dpif_port);
 }
 
-static uint32_t
-dpif_linux_get_max_ports(const struct dpif *dpif OVS_UNUSED)
-{
-    return MAX_PORTS;
-}
-
 static uint32_t
 dpif_linux_port_get_pid(const struct dpif *dpif_, odp_port_t port_no)
 {
@@ -688,7 +685,8 @@ dpif_linux_port_get_pid(const struct dpif *dpif_, odp_port_t port_no)
         /* The ODPP_NONE "reserved" port number uses the "ovs-system"'s
          * channel, since it is not heavily loaded. */
         uint32_t idx = port_idx >= dpif->uc_array_size ? 0 : port_idx;
-        pid = nl_sock_pid(dpif->channels[idx].sock);
+        const struct nl_sock *sock = dpif->channels[idx].sock;
+        pid = sock ? nl_sock_pid(sock) : 0;
     }
     ovs_mutex_unlock(&dpif->upcall_lock);
 
@@ -739,7 +737,7 @@ dpif_linux_port_dump_start(const struct dpif *dpif, void **statep)
     return 0;
 }
 
-static bool
+static int
 dpif_linux_port_dump_next__(const struct dpif *dpif_, struct nl_dump *dump,
                             struct dpif_linux_vport *vport)
 {
@@ -1016,7 +1014,7 @@ dpif_linux_flow_dump_start(const struct dpif *dpif_, void **statep)
 }
 
 static int
-dpif_linux_flow_dump_next(const struct dpif *dpif_ OVS_UNUSED, void *state_,
+dpif_linux_flow_dump_next(const struct dpif *dpif_, void *state_,
                           const struct nlattr **key, size_t *key_len,
                           const struct nlattr **mask, size_t *mask_len,
                           const struct nlattr **actions, size_t *actions_len,
@@ -1086,10 +1084,11 @@ dpif_linux_encode_execute(int dp_ifindex, const struct dpif_execute *d_exec,
                           struct ofpbuf *buf)
 {
     struct ovs_header *k_exec;
+    size_t key_ofs;
 
     ofpbuf_prealloc_tailroom(buf, (64
                                    + d_exec->packet->size
-                                   + d_exec->key_len
+                                   + ODP_KEY_METADATA_SIZE
                                    + d_exec->actions_len));
 
     nl_msg_put_genlmsghdr(buf, 0, ovs_packet_family, NLM_F_REQUEST,
@@ -1100,7 +1099,11 @@ dpif_linux_encode_execute(int dp_ifindex, const struct dpif_execute *d_exec,
 
     nl_msg_put_unspec(buf, OVS_PACKET_ATTR_PACKET,
                       d_exec->packet->data, d_exec->packet->size);
-    nl_msg_put_unspec(buf, OVS_PACKET_ATTR_KEY, d_exec->key, d_exec->key_len);
+
+    key_ofs = nl_msg_start_nested(buf, OVS_PACKET_ATTR_KEY);
+    odp_key_from_pkt_metadata(buf, &d_exec->md);
+    nl_msg_end_nested(buf, key_ofs);
+
     nl_msg_put_unspec(buf, OVS_PACKET_ATTR_ACTIONS,
                       d_exec->actions, d_exec->actions_len);
 }
@@ -1121,7 +1124,7 @@ dpif_linux_execute__(int dp_ifindex, const struct dpif_execute *execute)
 }
 
 static int
-dpif_linux_execute(struct dpif *dpif_, const struct dpif_execute *execute)
+dpif_linux_execute(struct dpif *dpif_, struct dpif_execute *execute)
 {
     const struct dpif_linux *dpif = dpif_linux_cast(dpif_);
 
@@ -1192,7 +1195,7 @@ dpif_linux_operate__(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops)
             break;
 
         default:
-            NOT_REACHED();
+            OVS_NOT_REACHED();
         }
     }
 
@@ -1253,7 +1256,7 @@ dpif_linux_operate__(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops)
             break;
 
         default:
-            NOT_REACHED();
+            OVS_NOT_REACHED();
         }
 
         ofpbuf_uninit(&aux->request);
@@ -1300,7 +1303,7 @@ dpif_linux_refresh_channels(struct dpif *dpif_)
     dpif->n_events = dpif->event_offset = 0;
 
     dpif_linux_port_dump_start__(dpif_, &dump);
-    while (dpif_linux_port_dump_next__(dpif_, &dump, &vport)) {
+    while (!dpif_linux_port_dump_next__(dpif_, &dump, &vport)) {
         uint32_t port_no = odp_to_u32(vport.port_no);
         struct nl_sock *sock = (port_no < dpif->uc_array_size
                                 ? dpif->channels[port_no].sock
@@ -1459,7 +1462,7 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall,
         return EINVAL;
     }
 
-    memset(upcall, 0, sizeof *upcall);
+    /* (Re)set ALL fields of '*upcall' on successful return. */
     upcall->type = type;
     upcall->key = CONST_CAST(struct nlattr *,
                              nl_attr_get(a[OVS_PACKET_ATTR_KEY]));
@@ -1473,7 +1476,7 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall,
                     nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]) +
                     sizeof(struct nlattr));
     upcall->packet.data = (char *)upcall->packet.data + sizeof(struct nlattr);
-    upcall->packet.size -= sizeof(struct nlattr);
+    upcall->packet.size = nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]);
 
     *dp_ifindex = ovs_header->dp_ifindex;
 
@@ -1611,7 +1614,6 @@ const struct dpif_class dpif_linux_class = {
     dpif_linux_port_del,
     dpif_linux_port_query_by_number,
     dpif_linux_port_query_by_name,
-    dpif_linux_get_max_ports,
     dpif_linux_port_get_pid,
     dpif_linux_port_dump_start,
     dpif_linux_port_dump_next,
@@ -1930,6 +1932,10 @@ dpif_linux_dp_to_ofpbuf(const struct dpif_linux_dp *dp, struct ofpbuf *buf)
         nl_msg_put_u32(buf, OVS_DP_ATTR_UPCALL_PID, *dp->upcall_pid);
     }
 
+    if (dp->user_features) {
+        nl_msg_put_u32(buf, OVS_DP_ATTR_USER_FEATURES, dp->user_features);
+    }
+
     /* Skip OVS_DP_ATTR_STATS since we never have a reason to serialize it. */
 }