1 /* Copyright (C) 2008 Board of Trustees, Leland Stanford Jr. University.
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 #include "switch-flow.h"
29 struct sw_table_linear {
32 unsigned int max_flows;
37 static struct sw_flow *table_linear_lookup(struct sw_table *swt,
38 const struct sw_flow_key *key)
40 struct sw_table_linear *tl = (struct sw_table_linear *) swt;
42 LIST_FOR_EACH (flow, struct sw_flow, node, &tl->flows) {
43 if (flow_matches(&flow->key, key))
49 static int table_linear_insert(struct sw_table *swt, struct sw_flow *flow)
51 struct sw_table_linear *tl = (struct sw_table_linear *) swt;
54 /* Replace flows that match exactly. */
55 LIST_FOR_EACH (f, struct sw_flow, node, &tl->flows) {
56 if (f->key.wildcards == flow->key.wildcards
57 && flow_matches(&f->key, &flow->key)) {
58 list_replace(&flow->node, &f->node);
65 if (tl->n_flows >= tl->max_flows) {
70 /* FIXME: need to order rules from most to least specific. */
71 list_push_back(&tl->flows, &flow->node);
76 do_delete(struct sw_flow *flow)
78 list_remove(&flow->node);
82 static int table_linear_delete(struct sw_table *swt,
83 const struct sw_flow_key *key, int strict)
85 struct sw_table_linear *tl = (struct sw_table_linear *) swt;
86 struct sw_flow *flow, *n;
87 unsigned int count = 0;
89 LIST_FOR_EACH_SAFE (flow, n, struct sw_flow, node, &tl->flows) {
90 if (flow_del_matches(&flow->key, key, strict)) {
99 static int table_linear_timeout(struct datapath *dp, struct sw_table *swt)
101 struct sw_table_linear *tl = (struct sw_table_linear *) swt;
102 struct sw_flow *flow, *n;
105 LIST_FOR_EACH_SAFE (flow, n, struct sw_flow, node, &tl->flows) {
106 if (flow_timeout(flow)) {
107 dp_send_flow_expired(dp, flow);
112 tl->n_flows -= count;
116 static void table_linear_destroy(struct sw_table *swt)
118 struct sw_table_linear *tl = (struct sw_table_linear *) swt;
120 while (!list_is_empty(&tl->flows)) {
121 struct sw_flow *flow = CONTAINER_OF(list_front(&tl->flows),
122 struct sw_flow, node);
123 list_remove(&flow->node);
129 /* Linear table's private data is just a pointer to the table */
131 static int table_linear_iterator(struct sw_table *swt,
132 struct swt_iterator *swt_iter)
134 struct sw_table_linear *tl = (struct sw_table_linear *) swt;
136 swt_iter->private = tl;
139 swt_iter->flow = NULL;
141 swt_iter->flow = CONTAINER_OF(list_front(&tl->flows), struct sw_flow, node);
146 static void table_linear_next(struct swt_iterator *swt_iter)
148 struct sw_table_linear *tl;
151 if (swt_iter->flow == NULL)
154 tl = (struct sw_table_linear *) swt_iter->private;
156 next = swt_iter->flow->node.next;
157 if (next == &tl->flows)
158 swt_iter->flow = NULL;
160 swt_iter->flow = CONTAINER_OF(next, struct sw_flow, node);
163 static void table_linear_iterator_destroy(struct swt_iterator *swt_iter)
166 static void table_linear_stats(struct sw_table *swt,
167 struct sw_table_stats *stats)
169 struct sw_table_linear *tl = (struct sw_table_linear *) swt;
170 stats->name = "linear";
171 stats->n_flows = tl->n_flows;
172 stats->max_flows = tl->max_flows;
176 struct sw_table *table_linear_create(unsigned int max_flows)
178 struct sw_table_linear *tl;
179 struct sw_table *swt;
181 tl = calloc(1, sizeof *tl);
186 swt->lookup = table_linear_lookup;
187 swt->insert = table_linear_insert;
188 swt->delete = table_linear_delete;
189 swt->timeout = table_linear_timeout;
190 swt->destroy = table_linear_destroy;
191 swt->stats = table_linear_stats;
193 swt->iterator = table_linear_iterator;
194 swt->iterator_next = table_linear_next;
195 swt->iterator_destroy = table_linear_iterator_destroy;
197 tl->max_flows = max_flows;
199 list_init(&tl->flows);