2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-02 07:15:17 +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:
Ben Pfaff
2010-10-08 16:36:13 -07:00
parent 2b9d658984
commit f1588b1fa1
17 changed files with 57 additions and 575 deletions

View File

@@ -398,32 +398,6 @@ error:
kfree_skb(skb); 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, static int output_control(struct datapath *dp, struct sk_buff *skb, u32 arg,
gfp_t gfp) gfp_t gfp)
{ {
@@ -492,11 +466,6 @@ int execute_actions(struct datapath *dp, struct sk_buff *skb,
prev_port = a->output.port; prev_port = a->output.port;
break; break;
case ODPAT_OUTPUT_GROUP:
prev_port = output_group(dp, a->output_group.group,
skb, gfp);
break;
case ODPAT_CONTROLLER: case ODPAT_CONTROLLER:
err = output_control(dp, skb, a->controller.arg, gfp); err = output_control(dp, skb, a->controller.arg, gfp);
if (err) { if (err) {

View File

@@ -325,8 +325,6 @@ static void do_destroy_dp(struct datapath *dp)
for (i = 0; i < DP_N_QUEUES; i++) for (i = 0; i < DP_N_QUEUES; i++)
skb_queue_purge(&dp->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); free_percpu(dp->stats_percpu);
kobject_put(&dp->ifobj); kobject_put(&dp->ifobj);
module_put(THIS_MODULE); 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++) { for (i = 0; i < actions->n_actions; i++) {
const union odp_action *a = &actions->actions[i]; const union odp_action *a = &actions->actions[i];
switch (a->type) { switch (a->type) {
case ODPAT_OUTPUT: case ODPAT_CONTROLLER:
if (a->output.port >= DP_MAX_PORTS) case ODPAT_STRIP_VLAN:
return -EINVAL; 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; break;
case ODPAT_OUTPUT_GROUP: case ODPAT_OUTPUT:
if (a->output_group.group >= DP_MAX_GROUPS) if (a->output.port >= DP_MAX_PORTS)
return -EINVAL; return -EINVAL;
break; break;
@@ -934,9 +942,7 @@ static int validate_actions(const struct sw_flow_actions *actions)
break; break;
default: default:
if (a->type >= ODPAT_N_ACTIONS) return -EOPNOTSUPP;
return -EOPNOTSUPP;
break;
} }
} }
@@ -1352,11 +1358,6 @@ static int do_execute(struct datapath *dp, const struct odp_execute *execute)
if (!skb) if (!skb)
goto error_free_actions; 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; err = -EFAULT;
if (copy_from_user(skb_put(skb, execute->length), execute->data, if (copy_from_user(skb_put(skb, execute->length), execute->data,
execute->length)) execute->length))
@@ -1373,7 +1374,7 @@ static int do_execute(struct datapath *dp, const struct odp_execute *execute)
else else
skb->protocol = htons(ETH_P_802_2); 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) if (err)
goto error_free_skb; 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.max_capacity = TBL_MAX_BUCKETS;
stats.n_ports = dp->n_ports; stats.n_ports = dp->n_ports;
stats.max_ports = DP_MAX_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; stats.n_frags = stats.n_hit = stats.n_missed = stats.n_lost = 0;
for_each_possible_cpu(i) { for_each_possible_cpu(i) {
const struct dp_stats_percpu *percpu_stats; 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); 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) static int get_listen_mask(const struct file *f)
{ {
return (long)f->private_data; 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); err = list_ports(dp, (struct odp_portvec __user *)argp);
break; 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: case ODP_FLOW_FLUSH:
err = flush_flows(dp); err = flush_flows(dp);
break; 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); 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) static int compat_get_flow(struct odp_flow *flow, const struct compat_odp_flow __user *compat)
{ {
compat_uptr_t actions; compat_uptr_t actions;
@@ -2052,7 +1942,6 @@ static int compat_execute(struct datapath *dp, const struct compat_odp_execute _
compat_uptr_t data; compat_uptr_t data;
if (!access_ok(VERIFY_READ, uexecute, sizeof(struct compat_odp_execute)) || 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(actions, &uexecute->actions) ||
__get_user(execute.n_actions, &uexecute->n_actions) || __get_user(execute.n_actions, &uexecute->n_actions) ||
__get_user(data, &uexecute->data) || __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)); err = compat_list_ports(dp, compat_ptr(argp));
break; 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: case ODP_FLOW_PUT32:
err = compat_put_flow(dp, compat_ptr(argp)); err = compat_put_flow(dp, compat_ptr(argp));
break; break;

View File

@@ -31,7 +31,6 @@ struct dp_port;
#define VLAN_PCP_SHIFT 13 #define VLAN_PCP_SHIFT 13
#define DP_MAX_PORTS 1024 #define DP_MAX_PORTS 1024
#define DP_MAX_GROUPS 16
#define DP_N_QUEUES 3 #define DP_N_QUEUES 3
#define DP_MAX_QUEUE_LEN 100 #define DP_MAX_QUEUE_LEN 100
@@ -57,12 +56,6 @@ struct dp_stats_percpu {
seqcount_t seqlock; seqcount_t seqlock;
}; };
struct dp_port_group {
struct rcu_head rcu;
int n_ports;
u16 ports[];
};
/** /**
* struct datapath - datapath for flow-based packet switching * struct datapath - datapath for flow-based packet switching
* @mutex: Mutual exclusion for ioctls. * @mutex: Mutual exclusion for ioctls.
@@ -73,7 +66,6 @@ struct dp_port_group {
* @waitqueue: Waitqueue, for waiting for new packets in @queues. * @waitqueue: Waitqueue, for waiting for new packets in @queues.
* @n_flows: Number of flows currently in flow table. * @n_flows: Number of flows currently in flow table.
* @table: Current flow table (RCU protected). * @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. * @n_ports: Number of ports currently in @ports.
* @ports: Map from port number to &struct dp_port. %ODPP_LOCAL port * @ports: Map from port number to &struct dp_port. %ODPP_LOCAL port
* always exists, other ports may be %NULL. * always exists, other ports may be %NULL.
@@ -97,9 +89,6 @@ struct datapath {
/* Flow table. */ /* Flow table. */
struct tbl *table; struct tbl *table;
/* Port groups. */
struct dp_port_group *groups[DP_MAX_GROUPS];
/* Switch ports. */ /* Switch ports. */
unsigned int n_ports; unsigned int n_ports;
struct dp_port *ports[DP_MAX_PORTS]; struct dp_port *ports[DP_MAX_PORTS];

View File

@@ -15,9 +15,7 @@
#include "openvswitch/datapath-protocol.h" #include "openvswitch/datapath-protocol.h"
#include <linux/compat.h> #include <linux/compat.h>
#define ODP_PORT_LIST32 _IOWR('O', 10, struct compat_odp_portvec) #define ODP_VPORT_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_FLOW_GET32 _IOWR('O', 13, struct compat_odp_flow) #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_PUT32 _IOWR('O', 14, struct compat_odp_flow)
#define ODP_FLOW_LIST32 _IOWR('O', 15, struct compat_odp_flowvec) #define ODP_FLOW_LIST32 _IOWR('O', 15, struct compat_odp_flowvec)
@@ -32,12 +30,6 @@ struct compat_odp_portvec {
u32 n_ports; 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 compat_odp_flow {
struct odp_flow_stats stats; struct odp_flow_stats stats;
struct odp_flow_key key; struct odp_flow_key key;

View File

@@ -79,9 +79,6 @@
#define ODP_PORT_QUERY _IOWR('O', 9, struct odp_port) #define ODP_PORT_QUERY _IOWR('O', 9, struct odp_port)
#define ODP_PORT_LIST _IOWR('O', 10, struct odp_portvec) #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_GET _IOWR('O', 13, struct odp_flow)
#define ODP_FLOW_PUT _IOWR('O', 14, struct odp_flow) #define ODP_FLOW_PUT _IOWR('O', 14, struct odp_flow)
#define ODP_FLOW_LIST _IOWR('O', 15, struct odp_flowvec) #define ODP_FLOW_LIST _IOWR('O', 15, struct odp_flowvec)
@@ -112,8 +109,6 @@ struct odp_stats {
/* Ports. */ /* Ports. */
uint32_t n_ports; /* Current number of ports. */ uint32_t n_ports; /* Current number of ports. */
uint32_t max_ports; /* Maximum supported 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. */ /* Lookups. */
uint64_t n_frags; /* Number of dropped IP fragments. */ uint64_t n_frags; /* Number of dropped IP fragments. */
@@ -198,12 +193,6 @@ struct odp_portvec {
uint32_t n_ports; 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 { struct odp_flow_stats {
uint64_t n_packets; /* Number of matched packets. */ uint64_t n_packets; /* Number of matched packets. */
uint64_t n_bytes; /* Number of matched bytes. */ uint64_t n_bytes; /* Number of matched bytes. */
@@ -266,7 +255,6 @@ struct odp_flowvec {
/* Action types. */ /* Action types. */
#define ODPAT_OUTPUT 0 /* Output to switch port. */ #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_CONTROLLER 2 /* Send copy to controller. */
#define ODPAT_SET_VLAN_VID 3 /* Set the 802.1q VLAN id. */ #define ODPAT_SET_VLAN_VID 3 /* Set the 802.1q VLAN id. */
#define ODPAT_SET_VLAN_PCP 4 /* Set the 802.1q priority. */ #define ODPAT_SET_VLAN_PCP 4 /* Set the 802.1q priority. */
@@ -291,13 +279,6 @@ struct odp_action_output {
uint16_t reserved2; 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 { struct odp_action_controller {
uint16_t type; /* ODPAT_OUTPUT_CONTROLLER. */ uint16_t type; /* ODPAT_OUTPUT_CONTROLLER. */
uint16_t reserved; uint16_t reserved;
@@ -366,7 +347,6 @@ struct odp_action_priority {
union odp_action { union odp_action {
uint16_t type; uint16_t type;
struct odp_action_output output; struct odp_action_output output;
struct odp_action_output_group output_group;
struct odp_action_controller controller; struct odp_action_controller controller;
struct odp_action_tunnel tunnel; struct odp_action_tunnel tunnel;
struct odp_action_vlan_vid vlan_vid; struct odp_action_vlan_vid vlan_vid;
@@ -379,10 +359,6 @@ union odp_action {
}; };
struct odp_execute { struct odp_execute {
uint16_t in_port;
uint16_t reserved1;
uint32_t reserved2;
union odp_action *actions; union odp_action *actions;
uint32_t n_actions; uint32_t n_actions;

View File

@@ -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 static int
dpif_linux_flow_get(const struct dpif *dpif_, struct odp_flow flows[], int n) 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 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 union odp_action actions[], int n_actions,
const struct ofpbuf *buf) const struct ofpbuf *buf)
{ {
struct odp_execute execute; struct odp_execute execute;
memset(&execute, 0, sizeof execute); memset(&execute, 0, sizeof execute);
execute.in_port = in_port;
execute.actions = (union odp_action *) actions; execute.actions = (union odp_action *) actions;
execute.n_actions = n_actions; execute.n_actions = n_actions;
execute.data = buf->data; execute.data = buf->data;
@@ -538,8 +509,6 @@ const struct dpif_class dpif_linux_class = {
dpif_linux_port_list, dpif_linux_port_list,
dpif_linux_port_poll, dpif_linux_port_poll,
dpif_linux_port_poll_wait, dpif_linux_port_poll_wait,
dpif_linux_port_group_get,
dpif_linux_port_group_set,
dpif_linux_flow_get, dpif_linux_flow_get,
dpif_linux_flow_put, dpif_linux_flow_put,
dpif_linux_flow_del, dpif_linux_flow_del,

View File

@@ -52,7 +52,6 @@ VLOG_DEFINE_THIS_MODULE(dpif_netdev)
/* Configuration parameters. */ /* Configuration parameters. */
enum { N_QUEUES = 2 }; /* Number of queues for dpif_recv(). */ enum { N_QUEUES = 2 }; /* Number of queues for dpif_recv(). */
enum { MAX_QUEUE_LEN = 100 }; /* Maximum number of packets per queue. */ 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_PORTS = 256 }; /* Maximum number of ports. */
enum { MAX_FLOWS = 65536 }; /* Maximum number of flows in flow table. */ 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. */ bool drop_frags; /* Drop all IP fragments, if true. */
struct ovs_queue queues[N_QUEUES]; /* Messages queued for dpif_recv(). */ struct ovs_queue queues[N_QUEUES]; /* Messages queued for dpif_recv(). */
struct hmap flow_table; /* Flow table. */ struct hmap flow_table; /* Flow table. */
struct odp_port_group groups[N_GROUPS];
/* Statistics. */ /* Statistics. */
long long int n_frags; /* Number of dropped IP fragments. */ 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]); queue_init(&dp->queues[i]);
} }
hmap_init(&dp->flow_table); 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); list_init(&dp->port_list);
error = do_add_port(dp, name, ODP_PORT_INTERNAL, ODPP_LOCAL); error = do_add_port(dp, name, ODP_PORT_INTERNAL, ODPP_LOCAL);
if (error) { if (error) {
@@ -294,9 +287,6 @@ dp_netdev_free(struct dp_netdev *dp)
queue_destroy(&dp->queues[i]); queue_destroy(&dp->queues[i]);
} }
hmap_destroy(&dp->flow_table); hmap_destroy(&dp->flow_table);
for (i = 0; i < N_GROUPS; i++) {
free(dp->groups[i].ports);
}
dp_netdevs[dp->dp_idx] = NULL; dp_netdevs[dp->dp_idx] = NULL;
list_remove(&dp->node); list_remove(&dp->node);
free(dp); free(dp);
@@ -331,7 +321,6 @@ dpif_netdev_get_stats(const struct dpif *dpif, struct odp_stats *stats)
stats->max_capacity = MAX_FLOWS; stats->max_capacity = MAX_FLOWS;
stats->n_ports = dp->n_ports; stats->n_ports = dp->n_ports;
stats->max_ports = MAX_PORTS; stats->max_ports = MAX_PORTS;
stats->max_groups = N_GROUPS;
stats->n_frags = dp->n_frags; stats->n_frags = dp->n_frags;
stats->n_hit = dp->n_hit; stats->n_hit = dp->n_hit;
stats->n_missed = dp->n_missed; 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 * static struct dp_netdev_flow *
dp_netdev_lookup_flow(const struct dp_netdev *dp, const flow_t *key) 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; break;
case ODPAT_OUTPUT_GROUP:
*mutates = true;
if (a->output_group.group >= N_GROUPS) {
return EINVAL;
}
break;
case ODPAT_CONTROLLER: case ODPAT_CONTROLLER:
break; break;
@@ -894,7 +820,7 @@ dpif_netdev_flow_list(const struct dpif *dpif, struct odp_flow flows[], int n)
} }
static int 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 union odp_action actions[], int n_actions,
const struct ofpbuf *packet) const struct ofpbuf *packet)
{ {
@@ -926,7 +852,7 @@ dpif_netdev_execute(struct dpif *dpif, uint16_t in_port,
* if we don't. */ * if we don't. */
copy = *packet; copy = *packet;
} }
flow_extract(&copy, 0, in_port, &flow); flow_extract(&copy, 0, -1, &flow);
error = dp_netdev_execute_actions(dp, &copy, &flow, actions, n_actions); error = dp_netdev_execute_actions(dp, &copy, &flow, actions, n_actions);
if (mutates) { if (mutates) {
ofpbuf_uninit(&copy); ofpbuf_uninit(&copy);
@@ -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 static int
dp_netdev_output_control(struct dp_netdev *dp, const struct ofpbuf *packet, dp_netdev_output_control(struct dp_netdev *dp, const struct ofpbuf *packet,
int queue_no, int port_no, uint32_t arg) 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); dp_netdev_output_port(dp, packet, a->output.port);
break; break;
case ODPAT_OUTPUT_GROUP:
dp_netdev_output_group(dp, a->output_group.group, key->in_port,
packet);
break;
case ODPAT_CONTROLLER: case ODPAT_CONTROLLER:
dp_netdev_output_control(dp, packet, _ODPL_ACTION_NR, dp_netdev_output_control(dp, packet, _ODPL_ACTION_NR,
key->in_port, a->controller.arg); key->in_port, a->controller.arg);
@@ -1388,8 +1294,6 @@ const struct dpif_class dpif_netdev_class = {
dpif_netdev_port_list, dpif_netdev_port_list,
dpif_netdev_port_poll, dpif_netdev_port_poll,
dpif_netdev_port_poll_wait, dpif_netdev_port_poll_wait,
dpif_netdev_port_group_get,
dpif_netdev_port_group_set,
dpif_netdev_flow_get, dpif_netdev_flow_get,
dpif_netdev_flow_put, dpif_netdev_flow_put,
dpif_netdev_flow_del, dpif_netdev_flow_del,

View File

@@ -183,20 +183,6 @@ struct dpif_class {
* value other than EAGAIN. */ * value other than EAGAIN. */
void (*port_poll_wait)(const struct dpif *dpif); 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': /* For each flow 'flow' in the 'n' flows in 'flows':
* *
* - If a flow matching 'flow->key' exists in 'dpif': * - 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); int (*flow_list)(const struct dpif *dpif, struct odp_flow flows[], int n);
/* Performs the 'n_actions' actions in 'actions' on the Ethernet frame /* Performs the 'n_actions' actions in 'actions' on the Ethernet frame
* specified in 'packet'. * specified in 'packet'. */
* int (*execute)(struct dpif *dpif,
* 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,
const union odp_action actions[], int n_actions, const union odp_action actions[], int n_actions,
const struct ofpbuf *packet); const struct ofpbuf *packet);

View File

@@ -625,68 +625,6 @@ dpif_port_poll_wait(const struct dpif *dpif)
dpif->dpif_class->port_poll_wait(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 /* Deletes all flows from 'dpif'. Returns 0 if successful, otherwise a
* positive errno value. */ * positive errno value. */
int 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 /* Causes 'dpif' to perform the 'n_actions' actions in 'actions' on the
* Ethernet frame specified in 'packet'. * 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. */ * Returns 0 if successful, otherwise a positive errno value. */
int 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 union odp_action actions[], size_t n_actions,
const struct ofpbuf *buf) const struct ofpbuf *buf)
{ {
@@ -933,8 +866,7 @@ dpif_execute(struct dpif *dpif, uint16_t in_port,
COVERAGE_INC(dpif_execute); COVERAGE_INC(dpif_execute);
if (n_actions > 0) { if (n_actions > 0) {
error = dpif->dpif_class->execute(dpif, in_port, actions, error = dpif->dpif_class->execute(dpif, actions, n_actions, buf);
n_actions, buf);
} else { } else {
error = 0; error = 0;
} }

View File

@@ -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); int dpif_port_poll(const struct dpif *, char **devnamep);
void dpif_port_poll_wait(const struct dpif *); 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_flush(struct dpif *);
int dpif_flow_put(struct dpif *, struct odp_flow_put *); int dpif_flow_put(struct dpif *, struct odp_flow_put *);
int dpif_flow_del(struct dpif *, struct odp_flow *); 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 *, int dpif_flow_list_all(const struct dpif *,
struct odp_flow **flowsp, size_t *np); struct odp_flow **flowsp, size_t *np);
int dpif_execute(struct dpif *, uint16_t in_port, int dpif_execute(struct dpif *, const union odp_action[], size_t n_actions,
const union odp_action[], size_t n_actions,
const struct ofpbuf *); const struct ofpbuf *);
/* Minimum number of bytes of headroom for a packet returned by dpif_recv() /* Minimum number of bytes of headroom for a packet returned by dpif_recv()

View File

@@ -46,9 +46,6 @@ format_odp_action(struct ds *ds, const union odp_action *a)
case ODPAT_OUTPUT: case ODPAT_OUTPUT:
ds_put_format(ds, "%"PRIu16, a->output.port); ds_put_format(ds, "%"PRIu16, a->output.port);
break; break;
case ODPAT_OUTPUT_GROUP:
ds_put_format(ds, "g%"PRIu16, a->output_group.group);
break;
case ODPAT_CONTROLLER: case ODPAT_CONTROLLER:
ds_put_format(ds, "ctl(%"PRIu32")", a->controller.arg); ds_put_format(ds, "ctl(%"PRIu32")", a->controller.arg);
break; break;

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright (c) 2009, 2010 InMon Corp. * Copyright (c) 2009, 2010 Nicira Networks.
* Copyright (c) 2009 Nicira Networks. * Copyright (c) 2009 InMon Corp.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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++; n_outputs++;
break; 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: case ODPAT_SET_VLAN_VID:
switchElem.flowType.sw.dst_vlan = ntohs(a->vlan_vid.vlan_vid); switchElem.flowType.sw.dst_vlan = ntohs(a->vlan_vid.vlan_vid);
break; break;
@@ -609,14 +603,6 @@ ofproto_sflow_received(struct ofproto_sflow *os, struct odp_msg *msg)
sfl_sampler_writeFlowSample(sampler, &fs); 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 void
ofproto_sflow_run(struct ofproto_sflow *os) ofproto_sflow_run(struct ofproto_sflow *os)
{ {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009 InMon Corp. * Copyright (c) 2009, 2010 InMon Corp.
* Copyright (c) 2009 Nicira Networks. * Copyright (c) 2009 Nicira Networks.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * 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, void ofproto_sflow_add_port(struct ofproto_sflow *, uint16_t odp_port,
const char *netdev_name); const char *netdev_name);
void ofproto_sflow_del_port(struct ofproto_sflow *, uint16_t odp_port); 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_run(struct ofproto_sflow *);
void ofproto_sflow_wait(struct ofproto_sflow *); void ofproto_sflow_wait(struct ofproto_sflow *);

View File

@@ -336,8 +336,6 @@ static void handle_odp_msg(struct ofproto *, struct ofpbuf *);
static void handle_openflow(struct ofconn *, struct ofproto *, static void handle_openflow(struct ofconn *, struct ofproto *,
struct ofpbuf *); struct ofpbuf *);
static void refresh_port_groups(struct ofproto *);
static struct ofport *get_port(const struct ofproto *, uint16_t odp_port); static struct ofport *get_port(const struct ofproto *, uint16_t odp_port);
static void update_port(struct ofproto *, const char *devname); static void update_port(struct ofproto *, const char *devname);
static int init_ports(struct ofproto *); static int init_ports(struct ofproto *);
@@ -886,7 +884,6 @@ ofproto_set_sflow(struct ofproto *ofproto,
struct ofport *ofport; struct ofport *ofport;
os = ofproto->sflow = ofproto_sflow_create(ofproto->dpif); os = ofproto->sflow = ofproto_sflow_create(ofproto->dpif);
refresh_port_groups(ofproto);
HMAP_FOR_EACH (ofport, hmap_node, &ofproto->ports) { HMAP_FOR_EACH (ofport, hmap_node, &ofproto->ports) {
ofproto_sflow_add_port(os, ofport->odp_port, ofproto_sflow_add_port(os, ofport->odp_port,
netdev_get_name(ofport->netdev)); 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 /* XXX Should we translate the dpif_execute() errno value into an OpenFlow
* error code? */ * error code? */
dpif_execute(p->dpif, flow->in_port, odp_actions.actions, dpif_execute(p->dpif, odp_actions.actions, odp_actions.n_actions, packet);
odp_actions.n_actions, packet);
return 0; return 0;
} }
@@ -1384,38 +1380,6 @@ reinit_ports(struct ofproto *p)
svec_destroy(&devnames); 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 * static struct ofport *
make_ofport(const struct odp_port *odp_port) make_ofport(const struct odp_port *odp_port)
{ {
@@ -1631,9 +1595,6 @@ update_port(struct ofproto *p, const char *devname)
: !new_ofport ? OFPPR_DELETE : !new_ofport ? OFPPR_DELETE
: OFPPR_MODIFY)); : OFPPR_MODIFY));
ofport_free(old_ofport); ofport_free(old_ofport);
/* Update port groups. */
refresh_port_groups(p);
} }
static int static int
@@ -1659,7 +1620,6 @@ init_ports(struct ofproto *p)
} }
} }
free(ports); free(ports);
refresh_port_groups(p);
return 0; return 0;
} }
@@ -1982,8 +1942,7 @@ execute_odp_actions(struct ofproto *ofproto, uint16_t in_port,
} else { } else {
int error; int error;
error = dpif_execute(ofproto->dpif, in_port, error = dpif_execute(ofproto->dpif, actions, n_actions, packet);
actions, n_actions, packet);
ofpbuf_delete(packet); ofpbuf_delete(packet);
return !error; return !error;
} }
@@ -2471,17 +2430,6 @@ handle_set_config(struct ofproto *p, struct ofconn *ofconn,
return 0; 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 static void
add_controller_action(struct odp_actions *actions, uint16_t max_len) 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 static void
xlate_output_action__(struct action_xlate_ctx *ctx, xlate_output_action__(struct action_xlate_ctx *ctx,
uint16_t port, uint16_t max_len) uint16_t port, uint16_t max_len)
@@ -2612,11 +2575,11 @@ xlate_output_action__(struct action_xlate_ctx *ctx,
} }
break; break;
case OFPP_FLOOD: case OFPP_FLOOD:
add_output_group_action(ctx->out, DP_GROUP_FLOOD, flood_packets(ctx->ofproto, ctx->flow.in_port, OFPPC_NO_FLOOD,
&ctx->nf_output_iface); &ctx->nf_output_iface, ctx->out);
break;
case OFPP_ALL: 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; break;
case OFPP_CONTROLLER: case OFPP_CONTROLLER:
add_controller_action(ctx->out, max_len); add_controller_action(ctx->out, max_len);
@@ -2972,8 +2935,7 @@ handle_packet_out(struct ofproto *p, struct ofconn *ofconn,
return error; return error;
} }
dpif_execute(p->dpif, flow.in_port, actions.actions, actions.n_actions, dpif_execute(p->dpif, actions.actions, actions.n_actions, &payload);
&payload);
ofpbuf_delete(buffer); ofpbuf_delete(buffer);
return 0; return 0;
@@ -2991,17 +2953,14 @@ update_port_config(struct ofproto *p, struct ofport *port,
netdev_turn_flags_on(port->netdev, NETDEV_UP, true); 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) { if (mask & REVALIDATE_BITS) {
COVERAGE_INC(ofproto_costly_flags); COVERAGE_INC(ofproto_costly_flags);
port->opp.config ^= mask & REVALIDATE_BITS; port->opp.config ^= mask & REVALIDATE_BITS;
p->need_revalidate = true; p->need_revalidate = true;
} }
#undef REVALIDATE_BITS #undef REVALIDATE_BITS
if (mask & OFPPC_NO_FLOOD) {
port->opp.config ^= OFPPC_NO_FLOOD;
refresh_port_groups(p);
}
if (mask & OFPPC_NO_PACKET_IN) { if (mask & OFPPC_NO_PACKET_IN) {
port->opp.config ^= 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)); memset(&action, 0, sizeof(action));
action.output.type = ODPAT_OUTPUT; action.output.type = ODPAT_OUTPUT;
action.output.port = ODPP_LOCAL; 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); 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, out_port = mac_learning_lookup_tag(ofproto->ml, flow->dl_dst, 0, tags,
NULL); NULL);
if (out_port < 0) { 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) { } else if (out_port != flow->in_port) {
odp_actions_add(actions, ODPAT_OUTPUT)->output.port = out_port; odp_actions_add(actions, ODPAT_OUTPUT)->output.port = out_port;
*nf_output_iface = out_port; *nf_output_iface = out_port;

View File

@@ -35,11 +35,6 @@ struct ofhooks;
struct ofproto; struct ofproto;
struct svec; struct svec;
enum {
DP_GROUP_FLOOD = 0,
DP_GROUP_ALL = 1
};
struct ofexpired { struct ofexpired {
flow_t flow; flow_t flow;
uint64_t packet_count; /* Packets from subrules. */ uint64_t packet_count; /* Packets from subrules. */

View File

@@ -106,16 +106,6 @@ discussed in \fBdump\-flows\fR, these entries are
not OpenFlow flow entries. By deleting them, the process that set them not OpenFlow flow entries. By deleting them, the process that set them
up may be confused about their disappearance. 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 .SH OPTIONS
.TP .TP
\fB\-t\fR, \fB\-\-timeout=\fIsecs\fR \fB\-t\fR, \fB\-\-timeout=\fIsecs\fR

View File

@@ -127,8 +127,7 @@ usage(void)
" show show basic info on all datapaths\n" " show show basic info on all datapaths\n"
" show DP... show basic info on each DP\n" " show DP... show basic info on each DP\n"
" dump-flows DP display flows in DP\n" " dump-flows DP display flows in DP\n"
" del-flows DP delete all flows from DP\n" " del-flows DP delete all flows from DP\n",
" dump-groups DP display port groups in DP\n",
program_name, program_name); program_name, program_name);
vlog_usage(); vlog_usage();
printf("\nOther options:\n" printf("\nOther options:\n"
@@ -354,7 +353,6 @@ show_dpif(struct dpif *dpif)
stats.n_flows, stats.cur_capacity, stats.max_capacity); stats.n_flows, stats.cur_capacity, stats.max_capacity);
printf("\tports: cur:%"PRIu32", max:%"PRIu32"\n", printf("\tports: cur:%"PRIu32", max:%"PRIu32"\n",
stats.n_ports, stats.max_ports); 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", printf("\tlookups: frags:%llu, hit:%llu, missed:%llu, lost:%llu\n",
(unsigned long long int) stats.n_frags, (unsigned long long int) stats.n_frags,
(unsigned long long int) stats.n_hit, (unsigned long long int) stats.n_hit,
@@ -492,33 +490,6 @@ do_del_flows(int argc OVS_UNUSED, char *argv[])
dpif_close(dpif); 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 static void
do_help(int argc OVS_UNUSED, char *argv[] OVS_UNUSED) 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 }, { "show", 0, INT_MAX, do_show },
{ "dump-flows", 1, 1, do_dump_flows }, { "dump-flows", 1, 1, do_dump_flows },
{ "del-flows", 1, 1, do_del_flows }, { "del-flows", 1, 1, do_del_flows },
{ "dump-groups", 1, 1, do_dump_groups },
{ "help", 0, INT_MAX, do_help }, { "help", 0, INT_MAX, do_help },
{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
}; };