ofproto: Match on IP ToS/DSCP bits (OpenFlow 1.0)
[sliver-openvswitch.git] / lib / classifier.h
1 /*
2  * Copyright (c) 2009, 2010 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_NW_TOS,      nw_tos,      NW_TOS)       \
71     CLS_FIELD(OFPFW_TP_SRC,      tp_src,      TP_SRC)       \
72     CLS_FIELD(OFPFW_TP_DST,      tp_dst,      TP_DST)
73
74 /* Field indexes.
75  *
76  * (These are also indexed into struct classifier's 'tables' array.) */
77 enum {
78 #define CLS_FIELD(WILDCARDS, MEMBER, NAME) CLS_F_IDX_##NAME,
79     CLS_FIELDS
80 #undef CLS_FIELD
81     CLS_F_IDX_EXACT,            /* Exact-match table. */
82     CLS_N_FIELDS = CLS_F_IDX_EXACT
83 };
84
85 /* Field information. */
86 struct cls_field {
87     int ofs;                    /* Offset in flow_t. */
88     int len;                    /* Length in bytes. */
89     uint32_t wildcards;         /* OFPFW_* bit or bits for this field. */
90     const char *name;           /* Name (for debugging). */
91 };
92 extern const struct cls_field cls_fields[CLS_N_FIELDS + 1];
93
94 /* A flow classifier. */
95 struct classifier {
96     int n_rules;                /* Sum of hmap_count() over tables[]. */
97     struct hmap tables[CLS_N_FIELDS]; /* Contain cls_bucket elements. */
98     struct hmap exact_table;          /* Contain cls_rule elements. */
99 };
100
101 /* A group of rules with the same fixed values for initial fields. */
102 struct cls_bucket {
103     struct hmap_node hmap_node; /* Within struct classifier 'tables'. */
104     struct list rules;          /* In order from highest to lowest priority. */
105     flow_t fixed;               /* Values for fixed fields. */
106 };
107
108 /* A flow classification rule.
109  *
110  * Use cls_rule_from_flow() or cls_rule_from_match() to initialize a cls_rule
111  * or you will almost certainly not initialize 'table_idx' correctly, with
112  * disastrous results! */
113 struct cls_rule {
114     union {
115         struct list list;       /* Within struct cls_bucket 'rules'. */
116         struct hmap_node hmap;  /* Within struct classifier 'exact_table'. */
117     } node;
118     flow_t flow;                /* All field values. */
119     struct flow_wildcards wc;   /* Wildcards for fields. */
120     unsigned int priority;      /* Larger numbers are higher priorities. */
121     unsigned int table_idx;     /* Index into struct classifier 'tables'. */
122 };
123
124 void cls_rule_from_flow(struct cls_rule *, const flow_t *, uint32_t wildcards,
125                         unsigned int priority);
126 void cls_rule_from_match(struct cls_rule *, const struct ofp_match *,
127                          unsigned int priority);
128 void cls_rule_print(const struct cls_rule *);
129 void cls_rule_moved(struct classifier *,
130                     struct cls_rule *old, struct cls_rule *new);
131 void cls_rule_replace(struct classifier *, const struct cls_rule *old,
132                       struct cls_rule *new);
133
134 void classifier_init(struct classifier *);
135 void classifier_destroy(struct classifier *);
136 bool classifier_is_empty(const struct classifier *);
137 int classifier_count(const struct classifier *);
138 int classifier_count_exact(const struct classifier *);
139 struct cls_rule *classifier_insert(struct classifier *, struct cls_rule *);
140 void classifier_insert_exact(struct classifier *, struct cls_rule *);
141 void classifier_remove(struct classifier *, struct cls_rule *);
142 struct cls_rule *classifier_lookup(const struct classifier *, const flow_t *);
143 struct cls_rule *classifier_lookup_wild(const struct classifier *,
144                                         const flow_t *);
145 struct cls_rule *classifier_lookup_exact(const struct classifier *,
146                                          const flow_t *);
147 bool classifier_rule_overlaps(const struct classifier *, const flow_t *, 
148                               uint32_t wildcards, unsigned int priority);
149
150 typedef void cls_cb_func(struct cls_rule *, void *aux);
151
152 enum {
153     CLS_INC_EXACT = 1 << 0,     /* Include exact-match flows? */
154     CLS_INC_WILD = 1 << 1,      /* Include flows with wildcards? */
155     CLS_INC_ALL = CLS_INC_EXACT | CLS_INC_WILD
156 };
157 void classifier_for_each(const struct classifier *, int include,
158                          cls_cb_func *, void *aux);
159 void classifier_for_each_match(const struct classifier *,
160                                const struct cls_rule *,
161                                int include, cls_cb_func *, void *aux);
162 struct cls_rule *classifier_find_rule_exactly(const struct classifier *,
163                                               const flow_t *target,
164                                               uint32_t wildcards,
165                                               unsigned int priority);
166
167 #endif /* classifier.h */