mirror of
https://github.com/openvswitch/ovs
synced 2025-09-01 23:05:29 +00:00
datapath: Remove implementation of port groups.
The "port group" concept seems like a good one, but it has not been used very much in userspace so far, so before we commit ourselves to a frozen API that we must maintain forever, remove it. We can always add it back in later as a new kind of vport. Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
@@ -398,32 +398,6 @@ error:
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
/* Never consumes 'skb'. Returns a port that 'skb' should be sent to, -1 if
|
||||
* none. */
|
||||
static int output_group(struct datapath *dp, __u16 group,
|
||||
struct sk_buff *skb, gfp_t gfp)
|
||||
{
|
||||
struct dp_port_group *g = rcu_dereference(dp->groups[group]);
|
||||
int prev_port = -1;
|
||||
int i;
|
||||
|
||||
if (!g)
|
||||
return -1;
|
||||
for (i = 0; i < g->n_ports; i++) {
|
||||
struct dp_port *p = rcu_dereference(dp->ports[g->ports[i]]);
|
||||
if (!p || OVS_CB(skb)->dp_port == p)
|
||||
continue;
|
||||
if (prev_port != -1) {
|
||||
struct sk_buff *clone = skb_clone(skb, gfp);
|
||||
if (!clone)
|
||||
return -1;
|
||||
do_output(dp, clone, prev_port);
|
||||
}
|
||||
prev_port = p->port_no;
|
||||
}
|
||||
return prev_port;
|
||||
}
|
||||
|
||||
static int output_control(struct datapath *dp, struct sk_buff *skb, u32 arg,
|
||||
gfp_t gfp)
|
||||
{
|
||||
@@ -492,11 +466,6 @@ int execute_actions(struct datapath *dp, struct sk_buff *skb,
|
||||
prev_port = a->output.port;
|
||||
break;
|
||||
|
||||
case ODPAT_OUTPUT_GROUP:
|
||||
prev_port = output_group(dp, a->output_group.group,
|
||||
skb, gfp);
|
||||
break;
|
||||
|
||||
case ODPAT_CONTROLLER:
|
||||
err = output_control(dp, skb, a->controller.arg, gfp);
|
||||
if (err) {
|
||||
|
@@ -325,8 +325,6 @@ static void do_destroy_dp(struct datapath *dp)
|
||||
|
||||
for (i = 0; i < DP_N_QUEUES; i++)
|
||||
skb_queue_purge(&dp->queues[i]);
|
||||
for (i = 0; i < DP_MAX_GROUPS; i++)
|
||||
kfree(dp->groups[i]);
|
||||
free_percpu(dp->stats_percpu);
|
||||
kobject_put(&dp->ifobj);
|
||||
module_put(THIS_MODULE);
|
||||
@@ -907,13 +905,23 @@ static int validate_actions(const struct sw_flow_actions *actions)
|
||||
for (i = 0; i < actions->n_actions; i++) {
|
||||
const union odp_action *a = &actions->actions[i];
|
||||
switch (a->type) {
|
||||
case ODPAT_OUTPUT:
|
||||
if (a->output.port >= DP_MAX_PORTS)
|
||||
return -EINVAL;
|
||||
case ODPAT_CONTROLLER:
|
||||
case ODPAT_STRIP_VLAN:
|
||||
case ODPAT_SET_DL_SRC:
|
||||
case ODPAT_SET_DL_DST:
|
||||
case ODPAT_SET_NW_SRC:
|
||||
case ODPAT_SET_NW_DST:
|
||||
case ODPAT_SET_TP_SRC:
|
||||
case ODPAT_SET_TP_DST:
|
||||
case ODPAT_SET_TUNNEL:
|
||||
case ODPAT_SET_PRIORITY:
|
||||
case ODPAT_POP_PRIORITY:
|
||||
case ODPAT_DROP_SPOOFED_ARP:
|
||||
/* No validation needed. */
|
||||
break;
|
||||
|
||||
case ODPAT_OUTPUT_GROUP:
|
||||
if (a->output_group.group >= DP_MAX_GROUPS)
|
||||
case ODPAT_OUTPUT:
|
||||
if (a->output.port >= DP_MAX_PORTS)
|
||||
return -EINVAL;
|
||||
break;
|
||||
|
||||
@@ -934,9 +942,7 @@ static int validate_actions(const struct sw_flow_actions *actions)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (a->type >= ODPAT_N_ACTIONS)
|
||||
return -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1352,11 +1358,6 @@ static int do_execute(struct datapath *dp, const struct odp_execute *execute)
|
||||
if (!skb)
|
||||
goto error_free_actions;
|
||||
|
||||
if (execute->in_port < DP_MAX_PORTS)
|
||||
OVS_CB(skb)->dp_port = dp->ports[execute->in_port];
|
||||
else
|
||||
OVS_CB(skb)->dp_port = NULL;
|
||||
|
||||
err = -EFAULT;
|
||||
if (copy_from_user(skb_put(skb, execute->length), execute->data,
|
||||
execute->length))
|
||||
@@ -1373,7 +1374,7 @@ static int do_execute(struct datapath *dp, const struct odp_execute *execute)
|
||||
else
|
||||
skb->protocol = htons(ETH_P_802_2);
|
||||
|
||||
err = flow_extract(skb, execute->in_port, &key, &is_frag);
|
||||
err = flow_extract(skb, -1, &key, &is_frag);
|
||||
if (err)
|
||||
goto error_free_skb;
|
||||
|
||||
@@ -1414,7 +1415,6 @@ static int get_dp_stats(struct datapath *dp, struct odp_stats __user *statsp)
|
||||
stats.max_capacity = TBL_MAX_BUCKETS;
|
||||
stats.n_ports = dp->n_ports;
|
||||
stats.max_ports = DP_MAX_PORTS;
|
||||
stats.max_groups = DP_MAX_GROUPS;
|
||||
stats.n_frags = stats.n_hit = stats.n_missed = stats.n_lost = 0;
|
||||
for_each_possible_cpu(i) {
|
||||
const struct dp_stats_percpu *percpu_stats;
|
||||
@@ -1574,87 +1574,6 @@ static int list_ports(struct datapath *dp, struct odp_portvec __user *upv)
|
||||
return put_user(retval, &upv->n_ports);
|
||||
}
|
||||
|
||||
/* RCU callback for freeing a dp_port_group */
|
||||
static void free_port_group(struct rcu_head *rcu)
|
||||
{
|
||||
struct dp_port_group *g = container_of(rcu, struct dp_port_group, rcu);
|
||||
kfree(g);
|
||||
}
|
||||
|
||||
static int do_set_port_group(struct datapath *dp, u16 __user *ports,
|
||||
int n_ports, int group)
|
||||
{
|
||||
struct dp_port_group *new_group, *old_group;
|
||||
int error;
|
||||
|
||||
error = -EINVAL;
|
||||
if (n_ports > DP_MAX_PORTS || group >= DP_MAX_GROUPS)
|
||||
goto error;
|
||||
|
||||
error = -ENOMEM;
|
||||
new_group = kmalloc(sizeof *new_group + sizeof(u16) * n_ports, GFP_KERNEL);
|
||||
if (!new_group)
|
||||
goto error;
|
||||
|
||||
new_group->n_ports = n_ports;
|
||||
error = -EFAULT;
|
||||
if (copy_from_user(new_group->ports, ports, sizeof(u16) * n_ports))
|
||||
goto error_free;
|
||||
|
||||
old_group = rcu_dereference(dp->groups[group]);
|
||||
rcu_assign_pointer(dp->groups[group], new_group);
|
||||
if (old_group)
|
||||
call_rcu(&old_group->rcu, free_port_group);
|
||||
return 0;
|
||||
|
||||
error_free:
|
||||
kfree(new_group);
|
||||
error:
|
||||
return error;
|
||||
}
|
||||
|
||||
static int set_port_group(struct datapath *dp,
|
||||
const struct odp_port_group __user *upg)
|
||||
{
|
||||
struct odp_port_group pg;
|
||||
|
||||
if (copy_from_user(&pg, upg, sizeof pg))
|
||||
return -EFAULT;
|
||||
|
||||
return do_set_port_group(dp, pg.ports, pg.n_ports, pg.group);
|
||||
}
|
||||
|
||||
static int do_get_port_group(struct datapath *dp,
|
||||
u16 __user *ports, int n_ports, int group,
|
||||
u16 __user *n_portsp)
|
||||
{
|
||||
struct dp_port_group *g;
|
||||
u16 n_copy;
|
||||
|
||||
if (group >= DP_MAX_GROUPS)
|
||||
return -EINVAL;
|
||||
|
||||
g = dp->groups[group];
|
||||
n_copy = g ? min_t(int, g->n_ports, n_ports) : 0;
|
||||
if (n_copy && copy_to_user(ports, g->ports, n_copy * sizeof(u16)))
|
||||
return -EFAULT;
|
||||
|
||||
if (put_user(g ? g->n_ports : 0, n_portsp))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_port_group(struct datapath *dp, struct odp_port_group __user *upg)
|
||||
{
|
||||
struct odp_port_group pg;
|
||||
|
||||
if (copy_from_user(&pg, upg, sizeof pg))
|
||||
return -EFAULT;
|
||||
|
||||
return do_get_port_group(dp, pg.ports, pg.n_ports, pg.group, &upg->n_ports);
|
||||
}
|
||||
|
||||
static int get_listen_mask(const struct file *f)
|
||||
{
|
||||
return (long)f->private_data;
|
||||
@@ -1789,14 +1708,6 @@ static long openvswitch_ioctl(struct file *f, unsigned int cmd,
|
||||
err = list_ports(dp, (struct odp_portvec __user *)argp);
|
||||
break;
|
||||
|
||||
case ODP_PORT_GROUP_SET:
|
||||
err = set_port_group(dp, (struct odp_port_group __user *)argp);
|
||||
break;
|
||||
|
||||
case ODP_PORT_GROUP_GET:
|
||||
err = get_port_group(dp, (struct odp_port_group __user *)argp);
|
||||
break;
|
||||
|
||||
case ODP_FLOW_FLUSH:
|
||||
err = flush_flows(dp);
|
||||
break;
|
||||
@@ -1856,27 +1767,6 @@ static int compat_list_ports(struct datapath *dp, struct compat_odp_portvec __us
|
||||
return put_user(retval, &upv->n_ports);
|
||||
}
|
||||
|
||||
static int compat_set_port_group(struct datapath *dp, const struct compat_odp_port_group __user *upg)
|
||||
{
|
||||
struct compat_odp_port_group pg;
|
||||
|
||||
if (copy_from_user(&pg, upg, sizeof pg))
|
||||
return -EFAULT;
|
||||
|
||||
return do_set_port_group(dp, compat_ptr(pg.ports), pg.n_ports, pg.group);
|
||||
}
|
||||
|
||||
static int compat_get_port_group(struct datapath *dp, struct compat_odp_port_group __user *upg)
|
||||
{
|
||||
struct compat_odp_port_group pg;
|
||||
|
||||
if (copy_from_user(&pg, upg, sizeof pg))
|
||||
return -EFAULT;
|
||||
|
||||
return do_get_port_group(dp, compat_ptr(pg.ports), pg.n_ports,
|
||||
pg.group, &upg->n_ports);
|
||||
}
|
||||
|
||||
static int compat_get_flow(struct odp_flow *flow, const struct compat_odp_flow __user *compat)
|
||||
{
|
||||
compat_uptr_t actions;
|
||||
@@ -2052,7 +1942,6 @@ static int compat_execute(struct datapath *dp, const struct compat_odp_execute _
|
||||
compat_uptr_t data;
|
||||
|
||||
if (!access_ok(VERIFY_READ, uexecute, sizeof(struct compat_odp_execute)) ||
|
||||
__get_user(execute.in_port, &uexecute->in_port) ||
|
||||
__get_user(actions, &uexecute->actions) ||
|
||||
__get_user(execute.n_actions, &uexecute->n_actions) ||
|
||||
__get_user(data, &uexecute->data) ||
|
||||
@@ -2115,14 +2004,6 @@ static long openvswitch_compat_ioctl(struct file *f, unsigned int cmd, unsigned
|
||||
err = compat_list_ports(dp, compat_ptr(argp));
|
||||
break;
|
||||
|
||||
case ODP_PORT_GROUP_SET32:
|
||||
err = compat_set_port_group(dp, compat_ptr(argp));
|
||||
break;
|
||||
|
||||
case ODP_PORT_GROUP_GET32:
|
||||
err = compat_get_port_group(dp, compat_ptr(argp));
|
||||
break;
|
||||
|
||||
case ODP_FLOW_PUT32:
|
||||
err = compat_put_flow(dp, compat_ptr(argp));
|
||||
break;
|
||||
|
@@ -31,7 +31,6 @@ struct dp_port;
|
||||
#define VLAN_PCP_SHIFT 13
|
||||
|
||||
#define DP_MAX_PORTS 1024
|
||||
#define DP_MAX_GROUPS 16
|
||||
|
||||
#define DP_N_QUEUES 3
|
||||
#define DP_MAX_QUEUE_LEN 100
|
||||
@@ -57,12 +56,6 @@ struct dp_stats_percpu {
|
||||
seqcount_t seqlock;
|
||||
};
|
||||
|
||||
struct dp_port_group {
|
||||
struct rcu_head rcu;
|
||||
int n_ports;
|
||||
u16 ports[];
|
||||
};
|
||||
|
||||
/**
|
||||
* struct datapath - datapath for flow-based packet switching
|
||||
* @mutex: Mutual exclusion for ioctls.
|
||||
@@ -73,7 +66,6 @@ struct dp_port_group {
|
||||
* @waitqueue: Waitqueue, for waiting for new packets in @queues.
|
||||
* @n_flows: Number of flows currently in flow table.
|
||||
* @table: Current flow table (RCU protected).
|
||||
* @groups: Port groups, used by ODPAT_OUTPUT_GROUP action (RCU protected).
|
||||
* @n_ports: Number of ports currently in @ports.
|
||||
* @ports: Map from port number to &struct dp_port. %ODPP_LOCAL port
|
||||
* always exists, other ports may be %NULL.
|
||||
@@ -97,9 +89,6 @@ struct datapath {
|
||||
/* Flow table. */
|
||||
struct tbl *table;
|
||||
|
||||
/* Port groups. */
|
||||
struct dp_port_group *groups[DP_MAX_GROUPS];
|
||||
|
||||
/* Switch ports. */
|
||||
unsigned int n_ports;
|
||||
struct dp_port *ports[DP_MAX_PORTS];
|
||||
|
@@ -15,9 +15,7 @@
|
||||
#include "openvswitch/datapath-protocol.h"
|
||||
#include <linux/compat.h>
|
||||
|
||||
#define ODP_PORT_LIST32 _IOWR('O', 10, struct compat_odp_portvec)
|
||||
#define ODP_PORT_GROUP_SET32 _IOR('O', 11, struct compat_odp_port_group)
|
||||
#define ODP_PORT_GROUP_GET32 _IOWR('O', 12, struct compat_odp_port_group)
|
||||
#define ODP_VPORT_LIST32 _IOWR('O', 10, struct compat_odp_portvec)
|
||||
#define ODP_FLOW_GET32 _IOWR('O', 13, struct compat_odp_flow)
|
||||
#define ODP_FLOW_PUT32 _IOWR('O', 14, struct compat_odp_flow)
|
||||
#define ODP_FLOW_LIST32 _IOWR('O', 15, struct compat_odp_flowvec)
|
||||
@@ -32,12 +30,6 @@ struct compat_odp_portvec {
|
||||
u32 n_ports;
|
||||
};
|
||||
|
||||
struct compat_odp_port_group {
|
||||
compat_uptr_t ports;
|
||||
u16 n_ports; /* Number of ports. */
|
||||
u16 group; /* Group number. */
|
||||
};
|
||||
|
||||
struct compat_odp_flow {
|
||||
struct odp_flow_stats stats;
|
||||
struct odp_flow_key key;
|
||||
|
@@ -79,9 +79,6 @@
|
||||
#define ODP_PORT_QUERY _IOWR('O', 9, struct odp_port)
|
||||
#define ODP_PORT_LIST _IOWR('O', 10, struct odp_portvec)
|
||||
|
||||
#define ODP_PORT_GROUP_SET _IOR('O', 11, struct odp_port_group)
|
||||
#define ODP_PORT_GROUP_GET _IOWR('O', 12, struct odp_port_group)
|
||||
|
||||
#define ODP_FLOW_GET _IOWR('O', 13, struct odp_flow)
|
||||
#define ODP_FLOW_PUT _IOWR('O', 14, struct odp_flow)
|
||||
#define ODP_FLOW_LIST _IOWR('O', 15, struct odp_flowvec)
|
||||
@@ -112,8 +109,6 @@ struct odp_stats {
|
||||
/* Ports. */
|
||||
uint32_t n_ports; /* Current number of ports. */
|
||||
uint32_t max_ports; /* Maximum supported number of ports. */
|
||||
uint16_t max_groups; /* Maximum number of port groups. */
|
||||
uint16_t reserved;
|
||||
|
||||
/* Lookups. */
|
||||
uint64_t n_frags; /* Number of dropped IP fragments. */
|
||||
@@ -198,12 +193,6 @@ struct odp_portvec {
|
||||
uint32_t n_ports;
|
||||
};
|
||||
|
||||
struct odp_port_group {
|
||||
uint16_t *ports;
|
||||
uint16_t n_ports; /* Number of ports. */
|
||||
uint16_t group; /* Group number. */
|
||||
};
|
||||
|
||||
struct odp_flow_stats {
|
||||
uint64_t n_packets; /* Number of matched packets. */
|
||||
uint64_t n_bytes; /* Number of matched bytes. */
|
||||
@@ -266,7 +255,6 @@ struct odp_flowvec {
|
||||
|
||||
/* Action types. */
|
||||
#define ODPAT_OUTPUT 0 /* Output to switch port. */
|
||||
#define ODPAT_OUTPUT_GROUP 1 /* Output to all ports in group. */
|
||||
#define ODPAT_CONTROLLER 2 /* Send copy to controller. */
|
||||
#define ODPAT_SET_VLAN_VID 3 /* Set the 802.1q VLAN id. */
|
||||
#define ODPAT_SET_VLAN_PCP 4 /* Set the 802.1q priority. */
|
||||
@@ -291,13 +279,6 @@ struct odp_action_output {
|
||||
uint16_t reserved2;
|
||||
};
|
||||
|
||||
struct odp_action_output_group {
|
||||
uint16_t type; /* ODPAT_OUTPUT_GROUP. */
|
||||
uint16_t group; /* Group number. */
|
||||
uint16_t reserved1;
|
||||
uint16_t reserved2;
|
||||
};
|
||||
|
||||
struct odp_action_controller {
|
||||
uint16_t type; /* ODPAT_OUTPUT_CONTROLLER. */
|
||||
uint16_t reserved;
|
||||
@@ -366,7 +347,6 @@ struct odp_action_priority {
|
||||
union odp_action {
|
||||
uint16_t type;
|
||||
struct odp_action_output output;
|
||||
struct odp_action_output_group output_group;
|
||||
struct odp_action_controller controller;
|
||||
struct odp_action_tunnel tunnel;
|
||||
struct odp_action_vlan_vid vlan_vid;
|
||||
@@ -379,10 +359,6 @@ union odp_action {
|
||||
};
|
||||
|
||||
struct odp_execute {
|
||||
uint16_t in_port;
|
||||
uint16_t reserved1;
|
||||
uint32_t reserved2;
|
||||
|
||||
union odp_action *actions;
|
||||
uint32_t n_actions;
|
||||
|
||||
|
@@ -356,34 +356,6 @@ dpif_linux_port_poll_wait(const struct dpif *dpif_)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dpif_linux_port_group_get(const struct dpif *dpif_, int group,
|
||||
uint16_t ports[], int n)
|
||||
{
|
||||
struct odp_port_group pg;
|
||||
int error;
|
||||
|
||||
assert(n <= UINT16_MAX);
|
||||
pg.group = group;
|
||||
pg.ports = ports;
|
||||
pg.n_ports = n;
|
||||
error = do_ioctl(dpif_, ODP_PORT_GROUP_GET, &pg);
|
||||
return error ? -error : pg.n_ports;
|
||||
}
|
||||
|
||||
static int
|
||||
dpif_linux_port_group_set(struct dpif *dpif_, int group,
|
||||
const uint16_t ports[], int n)
|
||||
{
|
||||
struct odp_port_group pg;
|
||||
|
||||
assert(n <= UINT16_MAX);
|
||||
pg.group = group;
|
||||
pg.ports = (uint16_t *) ports;
|
||||
pg.n_ports = n;
|
||||
return do_ioctl(dpif_, ODP_PORT_GROUP_SET, &pg);
|
||||
}
|
||||
|
||||
static int
|
||||
dpif_linux_flow_get(const struct dpif *dpif_, struct odp_flow flows[], int n)
|
||||
{
|
||||
@@ -418,13 +390,12 @@ dpif_linux_flow_list(const struct dpif *dpif_, struct odp_flow flows[], int n)
|
||||
}
|
||||
|
||||
static int
|
||||
dpif_linux_execute(struct dpif *dpif_, uint16_t in_port,
|
||||
dpif_linux_execute(struct dpif *dpif_,
|
||||
const union odp_action actions[], int n_actions,
|
||||
const struct ofpbuf *buf)
|
||||
{
|
||||
struct odp_execute execute;
|
||||
memset(&execute, 0, sizeof execute);
|
||||
execute.in_port = in_port;
|
||||
execute.actions = (union odp_action *) actions;
|
||||
execute.n_actions = n_actions;
|
||||
execute.data = buf->data;
|
||||
@@ -538,8 +509,6 @@ const struct dpif_class dpif_linux_class = {
|
||||
dpif_linux_port_list,
|
||||
dpif_linux_port_poll,
|
||||
dpif_linux_port_poll_wait,
|
||||
dpif_linux_port_group_get,
|
||||
dpif_linux_port_group_set,
|
||||
dpif_linux_flow_get,
|
||||
dpif_linux_flow_put,
|
||||
dpif_linux_flow_del,
|
||||
|
@@ -52,7 +52,6 @@ VLOG_DEFINE_THIS_MODULE(dpif_netdev)
|
||||
/* Configuration parameters. */
|
||||
enum { N_QUEUES = 2 }; /* Number of queues for dpif_recv(). */
|
||||
enum { MAX_QUEUE_LEN = 100 }; /* Maximum number of packets per queue. */
|
||||
enum { N_GROUPS = 16 }; /* Number of port groups. */
|
||||
enum { MAX_PORTS = 256 }; /* Maximum number of ports. */
|
||||
enum { MAX_FLOWS = 65536 }; /* Maximum number of flows in flow table. */
|
||||
|
||||
@@ -70,7 +69,6 @@ struct dp_netdev {
|
||||
bool drop_frags; /* Drop all IP fragments, if true. */
|
||||
struct ovs_queue queues[N_QUEUES]; /* Messages queued for dpif_recv(). */
|
||||
struct hmap flow_table; /* Flow table. */
|
||||
struct odp_port_group groups[N_GROUPS];
|
||||
|
||||
/* Statistics. */
|
||||
long long int n_frags; /* Number of dropped IP fragments. */
|
||||
@@ -228,11 +226,6 @@ create_dp_netdev(const char *name, int dp_idx, struct dpif **dpifp)
|
||||
queue_init(&dp->queues[i]);
|
||||
}
|
||||
hmap_init(&dp->flow_table);
|
||||
for (i = 0; i < N_GROUPS; i++) {
|
||||
dp->groups[i].ports = NULL;
|
||||
dp->groups[i].n_ports = 0;
|
||||
dp->groups[i].group = i;
|
||||
}
|
||||
list_init(&dp->port_list);
|
||||
error = do_add_port(dp, name, ODP_PORT_INTERNAL, ODPP_LOCAL);
|
||||
if (error) {
|
||||
@@ -294,9 +287,6 @@ dp_netdev_free(struct dp_netdev *dp)
|
||||
queue_destroy(&dp->queues[i]);
|
||||
}
|
||||
hmap_destroy(&dp->flow_table);
|
||||
for (i = 0; i < N_GROUPS; i++) {
|
||||
free(dp->groups[i].ports);
|
||||
}
|
||||
dp_netdevs[dp->dp_idx] = NULL;
|
||||
list_remove(&dp->node);
|
||||
free(dp);
|
||||
@@ -331,7 +321,6 @@ dpif_netdev_get_stats(const struct dpif *dpif, struct odp_stats *stats)
|
||||
stats->max_capacity = MAX_FLOWS;
|
||||
stats->n_ports = dp->n_ports;
|
||||
stats->max_ports = MAX_PORTS;
|
||||
stats->max_groups = N_GROUPS;
|
||||
stats->n_frags = dp->n_frags;
|
||||
stats->n_hit = dp->n_hit;
|
||||
stats->n_missed = dp->n_missed;
|
||||
@@ -598,62 +587,6 @@ dpif_netdev_port_poll_wait(const struct dpif *dpif_)
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
get_port_group(const struct dpif *dpif, int group_no,
|
||||
struct odp_port_group **groupp)
|
||||
{
|
||||
struct dp_netdev *dp = get_dp_netdev(dpif);
|
||||
|
||||
if (group_no >= 0 && group_no < N_GROUPS) {
|
||||
*groupp = &dp->groups[group_no];
|
||||
return 0;
|
||||
} else {
|
||||
*groupp = NULL;
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dpif_netdev_port_group_get(const struct dpif *dpif, int group_no,
|
||||
uint16_t ports[], int n)
|
||||
{
|
||||
struct odp_port_group *group;
|
||||
int error;
|
||||
|
||||
if (n < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
error = get_port_group(dpif, group_no, &group);
|
||||
if (!error) {
|
||||
memcpy(ports, group->ports, MIN(n, group->n_ports) * sizeof *ports);
|
||||
return group->n_ports;
|
||||
} else {
|
||||
return -error;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dpif_netdev_port_group_set(struct dpif *dpif, int group_no,
|
||||
const uint16_t ports[], int n)
|
||||
{
|
||||
struct odp_port_group *group;
|
||||
int error;
|
||||
|
||||
if (n < 0 || n > MAX_PORTS) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
error = get_port_group(dpif, group_no, &group);
|
||||
if (!error) {
|
||||
free(group->ports);
|
||||
group->ports = xmemdup(ports, n * sizeof *group->ports);
|
||||
group->n_ports = n;
|
||||
group->group = group_no;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
static struct dp_netdev_flow *
|
||||
dp_netdev_lookup_flow(const struct dp_netdev *dp, const flow_t *key)
|
||||
{
|
||||
@@ -727,13 +660,6 @@ dpif_netdev_validate_actions(const union odp_action *actions, int n_actions,
|
||||
}
|
||||
break;
|
||||
|
||||
case ODPAT_OUTPUT_GROUP:
|
||||
*mutates = true;
|
||||
if (a->output_group.group >= N_GROUPS) {
|
||||
return EINVAL;
|
||||
}
|
||||
break;
|
||||
|
||||
case ODPAT_CONTROLLER:
|
||||
break;
|
||||
|
||||
@@ -894,7 +820,7 @@ dpif_netdev_flow_list(const struct dpif *dpif, struct odp_flow flows[], int n)
|
||||
}
|
||||
|
||||
static int
|
||||
dpif_netdev_execute(struct dpif *dpif, uint16_t in_port,
|
||||
dpif_netdev_execute(struct dpif *dpif,
|
||||
const union odp_action actions[], int n_actions,
|
||||
const struct ofpbuf *packet)
|
||||
{
|
||||
@@ -926,7 +852,7 @@ dpif_netdev_execute(struct dpif *dpif, uint16_t in_port,
|
||||
* if we don't. */
|
||||
copy = *packet;
|
||||
}
|
||||
flow_extract(©, 0, in_port, &flow);
|
||||
flow_extract(©, 0, -1, &flow);
|
||||
error = dp_netdev_execute_actions(dp, ©, &flow, actions, n_actions);
|
||||
if (mutates) {
|
||||
ofpbuf_uninit(©);
|
||||
@@ -1229,21 +1155,6 @@ dp_netdev_output_port(struct dp_netdev *dp, struct ofpbuf *packet,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dp_netdev_output_group(struct dp_netdev *dp, uint16_t group, uint16_t in_port,
|
||||
struct ofpbuf *packet)
|
||||
{
|
||||
struct odp_port_group *g = &dp->groups[group];
|
||||
int i;
|
||||
|
||||
for (i = 0; i < g->n_ports; i++) {
|
||||
uint16_t out_port = g->ports[i];
|
||||
if (out_port != in_port) {
|
||||
dp_netdev_output_port(dp, packet, out_port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
dp_netdev_output_control(struct dp_netdev *dp, const struct ofpbuf *packet,
|
||||
int queue_no, int port_no, uint32_t arg)
|
||||
@@ -1313,11 +1224,6 @@ dp_netdev_execute_actions(struct dp_netdev *dp,
|
||||
dp_netdev_output_port(dp, packet, a->output.port);
|
||||
break;
|
||||
|
||||
case ODPAT_OUTPUT_GROUP:
|
||||
dp_netdev_output_group(dp, a->output_group.group, key->in_port,
|
||||
packet);
|
||||
break;
|
||||
|
||||
case ODPAT_CONTROLLER:
|
||||
dp_netdev_output_control(dp, packet, _ODPL_ACTION_NR,
|
||||
key->in_port, a->controller.arg);
|
||||
@@ -1388,8 +1294,6 @@ const struct dpif_class dpif_netdev_class = {
|
||||
dpif_netdev_port_list,
|
||||
dpif_netdev_port_poll,
|
||||
dpif_netdev_port_poll_wait,
|
||||
dpif_netdev_port_group_get,
|
||||
dpif_netdev_port_group_set,
|
||||
dpif_netdev_flow_get,
|
||||
dpif_netdev_flow_put,
|
||||
dpif_netdev_flow_del,
|
||||
|
@@ -183,20 +183,6 @@ struct dpif_class {
|
||||
* value other than EAGAIN. */
|
||||
void (*port_poll_wait)(const struct dpif *dpif);
|
||||
|
||||
/* Stores in 'ports' the port numbers of up to 'n' ports that belong to
|
||||
* 'group' in 'dpif'. Returns the number of ports in 'group' (not the
|
||||
* number stored), if successful, otherwise a negative errno value. */
|
||||
int (*port_group_get)(const struct dpif *dpif, int group,
|
||||
uint16_t ports[], int n);
|
||||
|
||||
/* Changes port group 'group' in 'dpif' to consist of the 'n' ports whose
|
||||
* numbers are given in 'ports'.
|
||||
*
|
||||
* Use the get_stats member function to obtain the number of supported port
|
||||
* groups. */
|
||||
int (*port_group_set)(struct dpif *dpif, int group,
|
||||
const uint16_t ports[], int n);
|
||||
|
||||
/* For each flow 'flow' in the 'n' flows in 'flows':
|
||||
*
|
||||
* - If a flow matching 'flow->key' exists in 'dpif':
|
||||
@@ -262,14 +248,8 @@ struct dpif_class {
|
||||
int (*flow_list)(const struct dpif *dpif, struct odp_flow flows[], int n);
|
||||
|
||||
/* Performs the 'n_actions' actions in 'actions' on the Ethernet frame
|
||||
* specified in 'packet'.
|
||||
*
|
||||
* Pretends that the frame was originally received on the port numbered
|
||||
* 'in_port'. This affects only ODPAT_OUTPUT_GROUP actions, which will not
|
||||
* send a packet out their input port. Specify the number of an unused
|
||||
* port (e.g. UINT16_MAX is currently always unused) to avoid this
|
||||
* behavior. */
|
||||
int (*execute)(struct dpif *dpif, uint16_t in_port,
|
||||
* specified in 'packet'. */
|
||||
int (*execute)(struct dpif *dpif,
|
||||
const union odp_action actions[], int n_actions,
|
||||
const struct ofpbuf *packet);
|
||||
|
||||
|
72
lib/dpif.c
72
lib/dpif.c
@@ -625,68 +625,6 @@ dpif_port_poll_wait(const struct dpif *dpif)
|
||||
dpif->dpif_class->port_poll_wait(dpif);
|
||||
}
|
||||
|
||||
/* Retrieves a list of the port numbers in port group 'group' in 'dpif'.
|
||||
*
|
||||
* On success, returns 0 and points '*ports' to a newly allocated array of
|
||||
* integers, each of which is a 'dpif' port number for a port in
|
||||
* 'group'. Stores the number of elements in the array in '*n_ports'. The
|
||||
* caller is responsible for freeing '*ports' by calling free().
|
||||
*
|
||||
* On failure, returns a positive errno value and sets '*ports' to NULL and
|
||||
* '*n_ports' to 0. */
|
||||
int
|
||||
dpif_port_group_get(const struct dpif *dpif, uint16_t group,
|
||||
uint16_t **ports, size_t *n_ports)
|
||||
{
|
||||
int error;
|
||||
|
||||
*ports = NULL;
|
||||
*n_ports = 0;
|
||||
for (;;) {
|
||||
int retval = dpif->dpif_class->port_group_get(dpif, group,
|
||||
*ports, *n_ports);
|
||||
if (retval < 0) {
|
||||
/* Hard error. */
|
||||
error = -retval;
|
||||
free(*ports);
|
||||
*ports = NULL;
|
||||
*n_ports = 0;
|
||||
break;
|
||||
} else if (retval <= *n_ports) {
|
||||
/* Success. */
|
||||
error = 0;
|
||||
*n_ports = retval;
|
||||
break;
|
||||
} else {
|
||||
/* Soft error: there were more ports than we expected in the
|
||||
* group. Try again. */
|
||||
free(*ports);
|
||||
*ports = xcalloc(retval, sizeof **ports);
|
||||
*n_ports = retval;
|
||||
}
|
||||
}
|
||||
log_operation(dpif, "port_group_get", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Updates port group 'group' in 'dpif', making it contain the 'n_ports' ports
|
||||
* whose 'dpif' port numbers are given in 'n_ports'. Returns 0 if
|
||||
* successful, otherwise a positive errno value.
|
||||
*
|
||||
* Behavior is undefined if the values in ports[] are not unique. */
|
||||
int
|
||||
dpif_port_group_set(struct dpif *dpif, uint16_t group,
|
||||
const uint16_t ports[], size_t n_ports)
|
||||
{
|
||||
int error;
|
||||
|
||||
COVERAGE_INC(dpif_port_group_set);
|
||||
|
||||
error = dpif->dpif_class->port_group_set(dpif, group, ports, n_ports);
|
||||
log_operation(dpif, "port_group_set", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Deletes all flows from 'dpif'. Returns 0 if successful, otherwise a
|
||||
* positive errno value. */
|
||||
int
|
||||
@@ -918,14 +856,9 @@ dpif_flow_list_all(const struct dpif *dpif,
|
||||
/* Causes 'dpif' to perform the 'n_actions' actions in 'actions' on the
|
||||
* Ethernet frame specified in 'packet'.
|
||||
*
|
||||
* Pretends that the frame was originally received on the port numbered
|
||||
* 'in_port'. This affects only ODPAT_OUTPUT_GROUP actions, which will not
|
||||
* send a packet out their input port. Specify the number of an unused port
|
||||
* (e.g. UINT16_MAX is currently always unused) to avoid this behavior.
|
||||
*
|
||||
* Returns 0 if successful, otherwise a positive errno value. */
|
||||
int
|
||||
dpif_execute(struct dpif *dpif, uint16_t in_port,
|
||||
dpif_execute(struct dpif *dpif,
|
||||
const union odp_action actions[], size_t n_actions,
|
||||
const struct ofpbuf *buf)
|
||||
{
|
||||
@@ -933,8 +866,7 @@ dpif_execute(struct dpif *dpif, uint16_t in_port,
|
||||
|
||||
COVERAGE_INC(dpif_execute);
|
||||
if (n_actions > 0) {
|
||||
error = dpif->dpif_class->execute(dpif, in_port, actions,
|
||||
n_actions, buf);
|
||||
error = dpif->dpif_class->execute(dpif, actions, n_actions, buf);
|
||||
} else {
|
||||
error = 0;
|
||||
}
|
||||
|
@@ -73,11 +73,6 @@ int dpif_port_list(const struct dpif *, struct odp_port **, size_t *n_ports);
|
||||
int dpif_port_poll(const struct dpif *, char **devnamep);
|
||||
void dpif_port_poll_wait(const struct dpif *);
|
||||
|
||||
int dpif_port_group_get(const struct dpif *, uint16_t group,
|
||||
uint16_t **ports, size_t *n_ports);
|
||||
int dpif_port_group_set(struct dpif *, uint16_t group,
|
||||
const uint16_t ports[], size_t n_ports);
|
||||
|
||||
int dpif_flow_flush(struct dpif *);
|
||||
int dpif_flow_put(struct dpif *, struct odp_flow_put *);
|
||||
int dpif_flow_del(struct dpif *, struct odp_flow *);
|
||||
@@ -88,8 +83,7 @@ int dpif_flow_list(const struct dpif *, struct odp_flow[], size_t n,
|
||||
int dpif_flow_list_all(const struct dpif *,
|
||||
struct odp_flow **flowsp, size_t *np);
|
||||
|
||||
int dpif_execute(struct dpif *, uint16_t in_port,
|
||||
const union odp_action[], size_t n_actions,
|
||||
int dpif_execute(struct dpif *, const union odp_action[], size_t n_actions,
|
||||
const struct ofpbuf *);
|
||||
|
||||
/* Minimum number of bytes of headroom for a packet returned by dpif_recv()
|
||||
|
@@ -46,9 +46,6 @@ format_odp_action(struct ds *ds, const union odp_action *a)
|
||||
case ODPAT_OUTPUT:
|
||||
ds_put_format(ds, "%"PRIu16, a->output.port);
|
||||
break;
|
||||
case ODPAT_OUTPUT_GROUP:
|
||||
ds_put_format(ds, "g%"PRIu16, a->output_group.group);
|
||||
break;
|
||||
case ODPAT_CONTROLLER:
|
||||
ds_put_format(ds, "ctl(%"PRIu32")", a->controller.arg);
|
||||
break;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2009, 2010 InMon Corp.
|
||||
* Copyright (c) 2009 Nicira Networks.
|
||||
* Copyright (c) 2009, 2010 Nicira Networks.
|
||||
* Copyright (c) 2009 InMon Corp.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -573,12 +573,6 @@ ofproto_sflow_received(struct ofproto_sflow *os, struct odp_msg *msg)
|
||||
n_outputs++;
|
||||
break;
|
||||
|
||||
case ODPAT_OUTPUT_GROUP:
|
||||
n_outputs += (a->output_group.group == DP_GROUP_FLOOD ? os->n_flood
|
||||
: a->output_group.group == DP_GROUP_ALL ? os->n_all
|
||||
: 0);
|
||||
break;
|
||||
|
||||
case ODPAT_SET_VLAN_VID:
|
||||
switchElem.flowType.sw.dst_vlan = ntohs(a->vlan_vid.vlan_vid);
|
||||
break;
|
||||
@@ -609,14 +603,6 @@ ofproto_sflow_received(struct ofproto_sflow *os, struct odp_msg *msg)
|
||||
sfl_sampler_writeFlowSample(sampler, &fs);
|
||||
}
|
||||
|
||||
void
|
||||
ofproto_sflow_set_group_sizes(struct ofproto_sflow *os,
|
||||
size_t n_flood, size_t n_all)
|
||||
{
|
||||
os->n_flood = n_flood;
|
||||
os->n_all = n_all;
|
||||
}
|
||||
|
||||
void
|
||||
ofproto_sflow_run(struct ofproto_sflow *os)
|
||||
{
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2009 InMon Corp.
|
||||
* Copyright (c) 2009, 2010 InMon Corp.
|
||||
* Copyright (c) 2009 Nicira Networks.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@@ -35,8 +35,6 @@ bool ofproto_sflow_is_enabled(const struct ofproto_sflow *);
|
||||
void ofproto_sflow_add_port(struct ofproto_sflow *, uint16_t odp_port,
|
||||
const char *netdev_name);
|
||||
void ofproto_sflow_del_port(struct ofproto_sflow *, uint16_t odp_port);
|
||||
void ofproto_sflow_set_group_sizes(struct ofproto_sflow *,
|
||||
size_t n_flood, size_t n_all);
|
||||
|
||||
void ofproto_sflow_run(struct ofproto_sflow *);
|
||||
void ofproto_sflow_wait(struct ofproto_sflow *);
|
||||
|
@@ -336,8 +336,6 @@ static void handle_odp_msg(struct ofproto *, struct ofpbuf *);
|
||||
static void handle_openflow(struct ofconn *, struct ofproto *,
|
||||
struct ofpbuf *);
|
||||
|
||||
static void refresh_port_groups(struct ofproto *);
|
||||
|
||||
static struct ofport *get_port(const struct ofproto *, uint16_t odp_port);
|
||||
static void update_port(struct ofproto *, const char *devname);
|
||||
static int init_ports(struct ofproto *);
|
||||
@@ -886,7 +884,6 @@ ofproto_set_sflow(struct ofproto *ofproto,
|
||||
struct ofport *ofport;
|
||||
|
||||
os = ofproto->sflow = ofproto_sflow_create(ofproto->dpif);
|
||||
refresh_port_groups(ofproto);
|
||||
HMAP_FOR_EACH (ofport, hmap_node, &ofproto->ports) {
|
||||
ofproto_sflow_add_port(os, ofport->odp_port,
|
||||
netdev_get_name(ofport->netdev));
|
||||
@@ -1296,8 +1293,7 @@ ofproto_send_packet(struct ofproto *p, const flow_t *flow,
|
||||
|
||||
/* XXX Should we translate the dpif_execute() errno value into an OpenFlow
|
||||
* error code? */
|
||||
dpif_execute(p->dpif, flow->in_port, odp_actions.actions,
|
||||
odp_actions.n_actions, packet);
|
||||
dpif_execute(p->dpif, odp_actions.actions, odp_actions.n_actions, packet);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1384,38 +1380,6 @@ reinit_ports(struct ofproto *p)
|
||||
svec_destroy(&devnames);
|
||||
}
|
||||
|
||||
static size_t
|
||||
refresh_port_group(struct ofproto *p, unsigned int group)
|
||||
{
|
||||
uint16_t *ports;
|
||||
size_t n_ports;
|
||||
struct ofport *port;
|
||||
|
||||
assert(group == DP_GROUP_ALL || group == DP_GROUP_FLOOD);
|
||||
|
||||
ports = xmalloc(hmap_count(&p->ports) * sizeof *ports);
|
||||
n_ports = 0;
|
||||
HMAP_FOR_EACH (port, hmap_node, &p->ports) {
|
||||
if (group == DP_GROUP_ALL || !(port->opp.config & OFPPC_NO_FLOOD)) {
|
||||
ports[n_ports++] = port->odp_port;
|
||||
}
|
||||
}
|
||||
dpif_port_group_set(p->dpif, group, ports, n_ports);
|
||||
free(ports);
|
||||
|
||||
return n_ports;
|
||||
}
|
||||
|
||||
static void
|
||||
refresh_port_groups(struct ofproto *p)
|
||||
{
|
||||
size_t n_flood = refresh_port_group(p, DP_GROUP_FLOOD);
|
||||
size_t n_all = refresh_port_group(p, DP_GROUP_ALL);
|
||||
if (p->sflow) {
|
||||
ofproto_sflow_set_group_sizes(p->sflow, n_flood, n_all);
|
||||
}
|
||||
}
|
||||
|
||||
static struct ofport *
|
||||
make_ofport(const struct odp_port *odp_port)
|
||||
{
|
||||
@@ -1631,9 +1595,6 @@ update_port(struct ofproto *p, const char *devname)
|
||||
: !new_ofport ? OFPPR_DELETE
|
||||
: OFPPR_MODIFY));
|
||||
ofport_free(old_ofport);
|
||||
|
||||
/* Update port groups. */
|
||||
refresh_port_groups(p);
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1659,7 +1620,6 @@ init_ports(struct ofproto *p)
|
||||
}
|
||||
}
|
||||
free(ports);
|
||||
refresh_port_groups(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1982,8 +1942,7 @@ execute_odp_actions(struct ofproto *ofproto, uint16_t in_port,
|
||||
} else {
|
||||
int error;
|
||||
|
||||
error = dpif_execute(ofproto->dpif, in_port,
|
||||
actions, n_actions, packet);
|
||||
error = dpif_execute(ofproto->dpif, actions, n_actions, packet);
|
||||
ofpbuf_delete(packet);
|
||||
return !error;
|
||||
}
|
||||
@@ -2471,17 +2430,6 @@ handle_set_config(struct ofproto *p, struct ofconn *ofconn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
add_output_group_action(struct odp_actions *actions, uint16_t group,
|
||||
uint16_t *nf_output_iface)
|
||||
{
|
||||
odp_actions_add(actions, ODPAT_OUTPUT_GROUP)->output_group.group = group;
|
||||
|
||||
if (group == DP_GROUP_ALL || group == DP_GROUP_FLOOD) {
|
||||
*nf_output_iface = NF_OUT_FLOOD;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_controller_action(struct odp_actions *actions, uint16_t max_len)
|
||||
{
|
||||
@@ -2586,6 +2534,21 @@ xlate_table_action(struct action_xlate_ctx *ctx, uint16_t in_port)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
flood_packets(struct ofproto *ofproto, uint16_t odp_in_port, uint32_t mask,
|
||||
uint16_t *nf_output_iface, struct odp_actions *actions)
|
||||
{
|
||||
struct ofport *ofport;
|
||||
|
||||
HMAP_FOR_EACH (ofport, hmap_node, &ofproto->ports) {
|
||||
uint16_t odp_port = ofport->odp_port;
|
||||
if (odp_port != odp_in_port && !(ofport->opp.config & mask)) {
|
||||
odp_actions_add(actions, ODPAT_OUTPUT)->output.port = odp_port;
|
||||
}
|
||||
}
|
||||
*nf_output_iface = NF_OUT_FLOOD;
|
||||
}
|
||||
|
||||
static void
|
||||
xlate_output_action__(struct action_xlate_ctx *ctx,
|
||||
uint16_t port, uint16_t max_len)
|
||||
@@ -2612,11 +2575,11 @@ xlate_output_action__(struct action_xlate_ctx *ctx,
|
||||
}
|
||||
break;
|
||||
case OFPP_FLOOD:
|
||||
add_output_group_action(ctx->out, DP_GROUP_FLOOD,
|
||||
&ctx->nf_output_iface);
|
||||
break;
|
||||
flood_packets(ctx->ofproto, ctx->flow.in_port, OFPPC_NO_FLOOD,
|
||||
&ctx->nf_output_iface, ctx->out);
|
||||
case OFPP_ALL:
|
||||
add_output_group_action(ctx->out, DP_GROUP_ALL, &ctx->nf_output_iface);
|
||||
flood_packets(ctx->ofproto, ctx->flow.in_port, 0,
|
||||
&ctx->nf_output_iface, ctx->out);
|
||||
break;
|
||||
case OFPP_CONTROLLER:
|
||||
add_controller_action(ctx->out, max_len);
|
||||
@@ -2972,8 +2935,7 @@ handle_packet_out(struct ofproto *p, struct ofconn *ofconn,
|
||||
return error;
|
||||
}
|
||||
|
||||
dpif_execute(p->dpif, flow.in_port, actions.actions, actions.n_actions,
|
||||
&payload);
|
||||
dpif_execute(p->dpif, actions.actions, actions.n_actions, &payload);
|
||||
ofpbuf_delete(buffer);
|
||||
|
||||
return 0;
|
||||
@@ -2991,17 +2953,14 @@ update_port_config(struct ofproto *p, struct ofport *port,
|
||||
netdev_turn_flags_on(port->netdev, NETDEV_UP, true);
|
||||
}
|
||||
}
|
||||
#define REVALIDATE_BITS (OFPPC_NO_RECV | OFPPC_NO_RECV_STP | OFPPC_NO_FWD)
|
||||
#define REVALIDATE_BITS (OFPPC_NO_RECV | OFPPC_NO_RECV_STP | \
|
||||
OFPPC_NO_FWD | OFPPC_NO_FLOOD)
|
||||
if (mask & REVALIDATE_BITS) {
|
||||
COVERAGE_INC(ofproto_costly_flags);
|
||||
port->opp.config ^= mask & REVALIDATE_BITS;
|
||||
p->need_revalidate = true;
|
||||
}
|
||||
#undef REVALIDATE_BITS
|
||||
if (mask & OFPPC_NO_FLOOD) {
|
||||
port->opp.config ^= OFPPC_NO_FLOOD;
|
||||
refresh_port_groups(p);
|
||||
}
|
||||
if (mask & OFPPC_NO_PACKET_IN) {
|
||||
port->opp.config ^= OFPPC_NO_PACKET_IN;
|
||||
}
|
||||
@@ -4175,7 +4134,7 @@ handle_odp_miss_msg(struct ofproto *p, struct ofpbuf *packet)
|
||||
memset(&action, 0, sizeof(action));
|
||||
action.output.type = ODPAT_OUTPUT;
|
||||
action.output.port = ODPP_LOCAL;
|
||||
dpif_execute(p->dpif, flow.in_port, &action, 1, &payload);
|
||||
dpif_execute(p->dpif, &action, 1, &payload);
|
||||
}
|
||||
|
||||
rule = lookup_valid_rule(p, &flow);
|
||||
@@ -4847,7 +4806,8 @@ default_normal_ofhook_cb(const flow_t *flow, const struct ofpbuf *packet,
|
||||
out_port = mac_learning_lookup_tag(ofproto->ml, flow->dl_dst, 0, tags,
|
||||
NULL);
|
||||
if (out_port < 0) {
|
||||
add_output_group_action(actions, DP_GROUP_FLOOD, nf_output_iface);
|
||||
flood_packets(ofproto, flow->in_port, OFPPC_NO_FLOOD,
|
||||
nf_output_iface, actions);
|
||||
} else if (out_port != flow->in_port) {
|
||||
odp_actions_add(actions, ODPAT_OUTPUT)->output.port = out_port;
|
||||
*nf_output_iface = out_port;
|
||||
|
@@ -35,11 +35,6 @@ struct ofhooks;
|
||||
struct ofproto;
|
||||
struct svec;
|
||||
|
||||
enum {
|
||||
DP_GROUP_FLOOD = 0,
|
||||
DP_GROUP_ALL = 1
|
||||
};
|
||||
|
||||
struct ofexpired {
|
||||
flow_t flow;
|
||||
uint64_t packet_count; /* Packets from subrules. */
|
||||
|
@@ -106,16 +106,6 @@ discussed in \fBdump\-flows\fR, these entries are
|
||||
not OpenFlow flow entries. By deleting them, the process that set them
|
||||
up may be confused about their disappearance.
|
||||
.
|
||||
.IP "\fBdump\-groups \fIdp\fR"
|
||||
Prints to the console the sets of port groups maintained by datapath
|
||||
\fIdp\fR. Ordinarily there are at least 2 port groups in a datapath
|
||||
that \fBovs\-openflowd\fR or \fBovs\-vswitch\fR is controlling: group
|
||||
0 contains
|
||||
all ports except those disabled by STP, and group 1 contains all
|
||||
ports. Additional or different groups might be used in the future.
|
||||
.IP
|
||||
This command is primarily useful for debugging Open vSwitch. OpenFlow
|
||||
does not have a concept of port groups.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-t\fR, \fB\-\-timeout=\fIsecs\fR
|
||||
|
@@ -127,8 +127,7 @@ usage(void)
|
||||
" show show basic info on all datapaths\n"
|
||||
" show DP... show basic info on each DP\n"
|
||||
" dump-flows DP display flows in DP\n"
|
||||
" del-flows DP delete all flows from DP\n"
|
||||
" dump-groups DP display port groups in DP\n",
|
||||
" del-flows DP delete all flows from DP\n",
|
||||
program_name, program_name);
|
||||
vlog_usage();
|
||||
printf("\nOther options:\n"
|
||||
@@ -354,7 +353,6 @@ show_dpif(struct dpif *dpif)
|
||||
stats.n_flows, stats.cur_capacity, stats.max_capacity);
|
||||
printf("\tports: cur:%"PRIu32", max:%"PRIu32"\n",
|
||||
stats.n_ports, stats.max_ports);
|
||||
printf("\tgroups: max:%"PRIu16"\n", stats.max_groups);
|
||||
printf("\tlookups: frags:%llu, hit:%llu, missed:%llu, lost:%llu\n",
|
||||
(unsigned long long int) stats.n_frags,
|
||||
(unsigned long long int) stats.n_hit,
|
||||
@@ -492,33 +490,6 @@ do_del_flows(int argc OVS_UNUSED, char *argv[])
|
||||
dpif_close(dpif);
|
||||
}
|
||||
|
||||
static void
|
||||
do_dump_groups(int argc OVS_UNUSED, char *argv[])
|
||||
{
|
||||
struct odp_stats stats;
|
||||
struct dpif *dpif;
|
||||
unsigned int i;
|
||||
|
||||
run(parsed_dpif_open(argv[1], false, &dpif), "opening datapath");
|
||||
run(dpif_get_dp_stats(dpif, &stats), "get datapath stats");
|
||||
for (i = 0; i < stats.max_groups; i++) {
|
||||
uint16_t *ports;
|
||||
size_t n_ports;
|
||||
|
||||
if (!dpif_port_group_get(dpif, i, &ports, &n_ports) && n_ports) {
|
||||
size_t j;
|
||||
|
||||
printf("group %u:", i);
|
||||
for (j = 0; j < n_ports; j++) {
|
||||
printf(" %"PRIu16, ports[j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
free(ports);
|
||||
}
|
||||
dpif_close(dpif);
|
||||
}
|
||||
|
||||
static void
|
||||
do_help(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
|
||||
{
|
||||
@@ -534,7 +505,6 @@ static const struct command all_commands[] = {
|
||||
{ "show", 0, INT_MAX, do_show },
|
||||
{ "dump-flows", 1, 1, do_dump_flows },
|
||||
{ "del-flows", 1, 1, do_del_flows },
|
||||
{ "dump-groups", 1, 1, do_dump_groups },
|
||||
{ "help", 0, INT_MAX, do_help },
|
||||
{ NULL, 0, 0, NULL },
|
||||
};
|
||||
|
Reference in New Issue
Block a user