X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fdpif-linux.c;h=497a5bd863d5793a2e7722bfcfa712a7a25f9545;hb=1e827902be9194d71ea851c9ce2676f65eeed33a;hp=d75bc95edd19c7211d210f4a30946c1ba54dbaa3;hpb=428b2eddc9c47d8306252f0fc5218839d2ff017c;p=sliver-openvswitch.git diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index d75bc95ed..497a5bd86 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -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) { @@ -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_); @@ -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])); @@ -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. */ }