ofproto: Match VLAN PCP and rewrite ToS bits (OpenFlow 0.9)
[sliver-openvswitch.git] / lib / classifier.h
1 /*
2  * Copyright (c) 2009 Nicira Networks.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #ifndef CLASSIFIER_H
18 #define CLASSIFIER_H 1
19
20 /* Flow classifier.
21  *
22  * This flow classifier assumes that we can arrange the fields in a flow in an
23  * order such that the set of wildcarded fields in a rule tend to fall toward
24  * the end of the ordering.  That is, if field F is wildcarded, then all the
25  * fields after F tend to be wildcarded as well.  If this assumption is
26  * violated, then the classifier will still classify flows correctly, but its
27  * performance will suffer.
28  *
29  * The classifier uses a collection of CLS_N_FIELDS hash tables for wildcarded
30  * flows.  Each of these tables contains the flows that wildcard a given field
31  * and do not wildcard any of the fields that precede F in the ordering.  The
32  * key for each hash table is the value of the fields preceding F that are not
33  * wildcarded.  All the flows that fall within a table and have the same key
34  * are kept as a linked list ordered from highest to lowest priority.
35  *
36  * The classifier also maintains a separate hash table of exact-match flows.
37  *
38  * To search the classifier we first search the table of exact-match flows,
39  * since exact-match flows always have highest priority.  If there is a match,
40  * we're done.  Otherwise, we search each of the CLS_N_FIELDS hash tables in
41  * turn, looking for the highest-priority match, and return it (if any).
42  */
43
44 #include "flow.h"
45 #include "hmap.h"
46 #include "list.h"
47 #include "openflow/openflow.h"
48
49 /* Number of bytes of fields in a rule. */
50 #define CLS_N_BYTES 31
51
52 /* Fields in a rule.
53  *
54  * This definition sets the ordering of fields, which is important for
55  * performance (see above).  To adjust the ordering, change the order of the
56  * lines. */
57 #define CLS_FIELDS                                          \
58     /*                           flow_t       all-caps */   \
59     /*        wildcard bit(s)    member name  name     */   \
60     /*        -----------------  -----------  -------- */   \
61     CLS_FIELD(OFPFW_IN_PORT,     in_port,     IN_PORT)      \
62     CLS_FIELD(OFPFW_DL_VLAN,     dl_vlan,     DL_VLAN)      \
63     CLS_FIELD(OFPFW_DL_VLAN_PCP, dl_vlan_pcp, DL_VLAN_PCP)  \
64     CLS_FIELD(OFPFW_DL_SRC,      dl_src,      DL_SRC)       \
65     CLS_FIELD(OFPFW_DL_DST,      dl_dst,      DL_DST)       \
66     CLS_FIELD(OFPFW_DL_TYPE,     dl_type,     DL_TYPE)      \
67     CLS_FIELD(OFPFW_NW_SRC_MASK, nw_src,      NW_SRC)       \
68     CLS_FIELD(OFPFW_NW_DST_MASK, nw_dst,      NW_DST)       \
69     CLS_FIELD(OFPFW_NW_PROTO,    nw_proto,    NW_PROTO)     \
70     CLS_FIELD(OFPFW_TP_SRC,      tp_src,      TP_SRC)       \
71     CLS_FIELD(OFPFW_TP_DST,      tp_dst,      TP_DST)
72
73 /* Field indexes.
74  *
75  * (These are also indexed into struct classifier's 'tables' array.) */
76 enum {
77 #define CLS_FIELD(WILDCARDS, MEMBER, NAME) CLS_F_IDX_##NAME,
78     CLS_FIELDS
79 #undef CLS_FIELD
80     CLS_F_IDX_EXACT,            /* Exact-match table. */
81     CLS_N_FIELDS = CLS_F_IDX_EXACT
82 };
83
84 /* Field information. */
85 struct cls_field {
86     int ofs;                    /* Offset in flow_t. */
87     int len;                    /* Length in bytes. */
88     uint32_t wildcards;         /* OFPFW_* bit or bits for this field. */
89     const char *name;           /* Name (for debugging). */
90 };
91 extern const struct cls_field cls_fields[CLS_N_FIELDS + 1];
92
93 /* A flow classifier. */
94 struct classifier {
95     int n_rules;                /* Sum of hmap_count() over tables[]. */
96     struct hmap tables[CLS_N_FIELDS]; /* Contain cls_bucket elements. */
97     struct hmap exact_table;          /* Contain cls_rule elements. */
98 };
99
100 /* A group of rules with the same fixed values for initial fields. */
101 struct cls_bucket {
102     struct hmap_node hmap_node; /* Within struct classifier 'tables'. */
103     struct list rules;          /* In order from highest to lowest priority. */
104     flow_t fixed;               /* Values for fixed fields. */
105 };
106
107 /* A flow classification rule.
108  *
109  * Use cls_rule_from_flow() or cls_rule_from_match() to initialize a cls_rule
110  * or you will almost certainly not initialize 'table_idx' correctly, with
111  * disastrous results! */
112 struct cls_rule {
113     union {
114         struct list list;       /* Within struct cls_bucket 'rules'. */
115         struct hmap_node hmap;  /* Within struct classifier 'exact_table'. */
116     } node;
117     flow_t flow;                /* All field values. */
118     struct flow_wildcards wc;   /* Wildcards for fields. */
119     unsigned int priority;      /* Larger numbers are higher priorities. */
120     unsigned int table_idx;     /* Index into struct classifier 'tables'. */
121 };
122
123 void cls_rule_from_flow(struct cls_rule *, const flow_t *, uint32_t wildcards,
124                         unsigned int priority);
125 void cls_rule_from_match(struct cls_rule *, const struct ofp_match *,
126                          unsigned int priority);
127 void cls_rule_print(const struct cls_rule *);
128 void cls_rule_moved(struct classifier *,
129                     struct cls_rule *old, struct cls_rule *new);
130 void cls_rule_replace(struct classifier *, const struct cls_rule *old,
131                       struct cls_rule *new);
132
133 void classifier_init(struct classifier *);
134 void classifier_destroy(struct classifier *);
135 bool classifier_is_empty(const struct classifier *);
136 int classifier_count(const struct classifier *);
137 int classifier_count_exact(const struct classifier *);
138 struct cls_rule *classifier_insert(struct classifier *, struct cls_rule *);
139 void classifier_insert_exact(struct classifier *, struct cls_rule *);
140 void classifier_remove(struct classifier *, struct cls_rule *);
141 struct cls_rule *classifier_lookup(const struct classifier *, const flow_t *);
142 struct cls_rule *classifier_lookup_wild(const struct classifier *,
143                                         const flow_t *);
144 struct cls_rule *classifier_lookup_exact(const struct classifier *,
145                                          const flow_t *);
146
147 typedef void cls_cb_func(struct cls_rule *, void *aux);
148
149 enum {
150     CLS_INC_EXACT = 1 << 0,     /* Include exact-match flows? */
151     CLS_INC_WILD = 1 << 1,      /* Include flows with wildcards? */
152     CLS_INC_ALL = CLS_INC_EXACT | CLS_INC_WILD
153 };
154 void classifier_for_each(const struct classifier *, int include,
155                          cls_cb_func *, void *aux);
156 void classifier_for_each_match(const struct classifier *,
157                                const struct cls_rule *,
158                                int include, cls_cb_func *, void *aux);
159 struct cls_rule *classifier_find_rule_exactly(const struct classifier *,
160                                               const flow_t *target,
161                                               uint32_t wildcards,
162                                               unsigned int priority);
163
164 #endif /* classifier.h */