Skip to content

Commit

Permalink
dpif: Abstract translation from OpenFlow queue ID into ODP priority v…
Browse files Browse the repository at this point in the history
…alue.

When the QoS code was integrated, I didn't yet know how to abstract the
translation from a queue ID in an OpenFlow OFPAT_ENQUEUE action into a
priority value for an ODP ODPAT_SET_PRIORITY action.  This commit is a
first attempt that works OK for Linux, so far.  It's possible that in fact
this translation needs the 'netdev' as an argument too, but it's not needed
yet.
  • Loading branch information
blp committed Jul 20, 2010
1 parent c4d279a commit aae51f5
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 12 deletions.
14 changes: 14 additions & 0 deletions lib/dpif-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <net/if.h>
#include <linux/types.h>
#include <linux/ethtool.h>
#include <linux/pkt_sched.h>
#include <linux/rtnetlink.h>
#include <linux/sockios.h>
#include <stdlib.h>
Expand Down Expand Up @@ -457,6 +458,18 @@ dpif_linux_set_sflow_probability(struct dpif *dpif_, uint32_t probability)
return do_ioctl(dpif_, ODP_SET_SFLOW_PROBABILITY, &probability);
}

static int
dpif_linux_queue_to_priority(const struct dpif *dpif OVS_UNUSED,
uint32_t queue_id, uint32_t *priority)
{
if (queue_id < 0xf000) {
*priority = TC_H_MAKE(1, queue_id);
return 0;
} else {
return EINVAL;
}
}

static int
dpif_linux_recv(struct dpif *dpif_, struct ofpbuf **bufp)
{
Expand Down Expand Up @@ -539,6 +552,7 @@ const struct dpif_class dpif_linux_class = {
dpif_linux_recv_set_mask,
dpif_linux_get_sflow_probability,
dpif_linux_set_sflow_probability,
dpif_linux_queue_to_priority,
dpif_linux_recv,
dpif_linux_recv_wait,
};
Expand Down
1 change: 1 addition & 0 deletions lib/dpif-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -1366,6 +1366,7 @@ const struct dpif_class dpif_netdev_class = {
dpif_netdev_recv_set_mask,
NULL, /* get_sflow_probability */
NULL, /* set_sflow_probability */
NULL, /* queue_to_priority */
dpif_netdev_recv,
dpif_netdev_recv_wait,
};
6 changes: 6 additions & 0 deletions lib/dpif-provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,12 @@ struct dpif_class {
* packet. */
int (*set_sflow_probability)(struct dpif *dpif, uint32_t probability);

/* Translates OpenFlow queue ID 'queue_id' (in host byte order) into a
* priority value for use in the ODPAT_SET_PRIORITY action in
* '*priority'. */
int (*queue_to_priority)(const struct dpif *dpif, uint32_t queue_id,
uint32_t *priority);

/* Attempts to receive a message from 'dpif'. If successful, stores the
* message into '*packetp'. The message, if one is received, must begin
* with 'struct odp_msg' as a header, and must have at least
Expand Down
19 changes: 19 additions & 0 deletions lib/dpif.c
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,25 @@ dpif_get_netflow_ids(const struct dpif *dpif,
*engine_type = dpif->netflow_engine_type;
*engine_id = dpif->netflow_engine_id;
}

/* Translates OpenFlow queue ID 'queue_id' (in host byte order) into a priority
* value for use in the ODPAT_SET_PRIORITY action. On success, returns 0 and
* stores the priority into '*priority'. On failure, returns a positive errno
* value and stores 0 into '*priority'. */
int
dpif_queue_to_priority(const struct dpif *dpif, uint32_t queue_id,
uint32_t *priority)
{
int error = (dpif->dpif_class->queue_to_priority
? dpif->dpif_class->queue_to_priority(dpif, queue_id,
priority)
: EOPNOTSUPP);
if (error) {
*priority = 0;
}
log_operation(dpif, "queue_to_priority", error);
return error;
}

void
dpif_init(struct dpif *dpif, const struct dpif_class *dpif_class,
Expand Down
3 changes: 3 additions & 0 deletions lib/dpif.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ void dpif_recv_wait(struct dpif *);
void dpif_get_netflow_ids(const struct dpif *,
uint8_t *engine_type, uint8_t *engine_id);

int dpif_queue_to_priority(const struct dpif *, uint32_t queue_id,
uint32_t *priority);

#ifdef __cplusplus
}
#endif
Expand Down
37 changes: 25 additions & 12 deletions ofproto/ofproto.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,6 @@
#include "vconn.h"
#include "xtoxll.h"

#include <linux/types.h> /* XXX */
#include <linux/pkt_sched.h> /* XXX */

#define THIS_MODULE VLM_ofproto
#include "vlog.h"

Expand Down Expand Up @@ -2280,11 +2277,10 @@ add_output_group_action(struct odp_actions *actions, uint16_t group,
}

static void
add_controller_action(struct odp_actions *actions,
const struct ofp_action_output *oao)
add_controller_action(struct odp_actions *actions, uint16_t max_len)
{
union odp_action *a = odp_actions_add(actions, ODPAT_CONTROLLER);
a->controller.arg = ntohs(oao->max_len);
a->controller.arg = max_len;
}

struct action_xlate_ctx {
Expand Down Expand Up @@ -2376,15 +2372,15 @@ xlate_table_action(struct action_xlate_ctx *ctx, uint16_t in_port)
}

static void
xlate_output_action(struct action_xlate_ctx *ctx,
const struct ofp_action_output *oao)
xlate_output_action__(struct action_xlate_ctx *ctx,
uint16_t port, uint16_t max_len)
{
uint16_t odp_port;
uint16_t prev_nf_output_iface = ctx->nf_output_iface;

ctx->nf_output_iface = NF_OUT_DROP;

switch (ntohs(oao->port)) {
switch (port) {
case OFPP_IN_PORT:
add_output_action(ctx, ctx->flow.in_port);
break;
Expand All @@ -2408,13 +2404,13 @@ xlate_output_action(struct action_xlate_ctx *ctx,
add_output_group_action(ctx->out, DP_GROUP_ALL, &ctx->nf_output_iface);
break;
case OFPP_CONTROLLER:
add_controller_action(ctx->out, oao);
add_controller_action(ctx->out, max_len);
break;
case OFPP_LOCAL:
add_output_action(ctx, ODPP_LOCAL);
break;
default:
odp_port = ofp_port_to_odp_port(ntohs(oao->port));
odp_port = ofp_port_to_odp_port(port);
if (odp_port != ctx->flow.in_port) {
add_output_action(ctx, odp_port);
}
Expand All @@ -2431,6 +2427,13 @@ xlate_output_action(struct action_xlate_ctx *ctx,
}
}

static void
xlate_output_action(struct action_xlate_ctx *ctx,
const struct ofp_action_output *oao)
{
xlate_output_action__(ctx, ntohs(oao->port), ntohs(oao->max_len));
}

/* If the final ODP action in 'ctx' is "pop priority", drop it, as an
* optimization, because we're going to add another action that sets the
* priority immediately after, or because there are no actions following the
Expand All @@ -2449,6 +2452,16 @@ xlate_enqueue_action(struct action_xlate_ctx *ctx,
const struct ofp_action_enqueue *oae)
{
uint16_t ofp_port, odp_port;
uint32_t priority;
int error;

error = dpif_queue_to_priority(ctx->ofproto->dpif, ntohl(oae->queue_id),
&priority);
if (error) {
/* Fall back to ordinary output action. */
xlate_output_action__(ctx, ntohs(oae->port), 0);
return;
}

/* Figure out ODP output port. */
ofp_port = ntohs(oae->port);
Expand All @@ -2461,7 +2474,7 @@ xlate_enqueue_action(struct action_xlate_ctx *ctx,
/* Add ODP actions. */
remove_pop_action(ctx);
odp_actions_add(ctx->out, ODPAT_SET_PRIORITY)->priority.priority
= TC_H_MAKE(1, ntohl(oae->queue_id)); /* XXX */
= priority;
add_output_action(ctx, odp_port);
odp_actions_add(ctx->out, ODPAT_POP_PRIORITY);

Expand Down

0 comments on commit aae51f5

Please sign in to comment.