From: Ben Pfaff Date: Fri, 8 Oct 2010 23:36:13 +0000 (-0700) Subject: datapath: Remove implementation of port groups. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1588b1fa1be46231ee079358e428dae74ff09cc;p=openvswitch 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 --- diff --git a/datapath/actions.c b/datapath/actions.c index b75aecda..18c4ea11 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -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) { diff --git a/datapath/datapath.c b/datapath/datapath.c index e9f30f8a..aa563fb6 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -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; + return -EOPNOTSUPP; } } @@ -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; diff --git a/datapath/datapath.h b/datapath/datapath.h index f28513bb..3a38235f 100644 --- a/datapath/datapath.h +++ b/datapath/datapath.h @@ -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]; diff --git a/datapath/odp-compat.h b/datapath/odp-compat.h index 3d7b803f..fc6faa53 100644 --- a/datapath/odp-compat.h +++ b/datapath/odp-compat.h @@ -15,9 +15,7 @@ #include "openvswitch/datapath-protocol.h" #include -#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; diff --git a/include/openvswitch/datapath-protocol.h b/include/openvswitch/datapath-protocol.h index 5759f1e5..a8122631 100644 --- a/include/openvswitch/datapath-protocol.h +++ b/include/openvswitch/datapath-protocol.h @@ -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; diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 635fe941..b08b6593 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -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, diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 60094073..11ad370f 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -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, diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h index 1106db88..5d651c6e 100644 --- a/lib/dpif-provider.h +++ b/lib/dpif-provider.h @@ -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); diff --git a/lib/dpif.c b/lib/dpif.c index 01e905d9..b3e82afc 100644 --- a/lib/dpif.c +++ b/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; } diff --git a/lib/dpif.h b/lib/dpif.h index 1496c227..c844289c 100644 --- a/lib/dpif.h +++ b/lib/dpif.h @@ -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() diff --git a/lib/odp-util.c b/lib/odp-util.c index 798e4254..8278c228 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -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; diff --git a/ofproto/ofproto-sflow.c b/ofproto/ofproto-sflow.c index f129d38b..3739911d 100644 --- a/ofproto/ofproto-sflow.c +++ b/ofproto/ofproto-sflow.c @@ -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) { diff --git a/ofproto/ofproto-sflow.h b/ofproto/ofproto-sflow.h index ec86d115..df897650 100644 --- a/ofproto/ofproto-sflow.h +++ b/ofproto/ofproto-sflow.h @@ -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 *); diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 1b8dfbf0..5e8a1d83 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -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; diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h index 7ba4acb4..3758deca 100644 --- a/ofproto/ofproto.h +++ b/ofproto/ofproto.h @@ -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. */ diff --git a/utilities/ovs-dpctl.8.in b/utilities/ovs-dpctl.8.in index b7965bc3..cb9874d7 100644 --- a/utilities/ovs-dpctl.8.in +++ b/utilities/ovs-dpctl.8.in @@ -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 diff --git a/utilities/ovs-dpctl.c b/utilities/ovs-dpctl.c index fe44f27e..c588221d 100644 --- a/utilities/ovs-dpctl.c +++ b/utilities/ovs-dpctl.c @@ -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 }, };