+static void
+classifier_update_table_max_priority(struct classifier *cls,
+ struct cls_table *table,
+ unsigned int priority)
+{
+ struct cls_table *iter = table;
+
+ if (priority > table->max_priority) {
+ /* Possibly move 'table' earlier in the priority list. If we break out
+ * of the loop, then 'table' should be moved just after that 'iter'.
+ * If the loop terminates normally, then 'iter' will be the list head
+ * and we'll move table just after that (e.g. to the front of the
+ * list). */
+ LIST_FOR_EACH_REVERSE_CONTINUE (iter, list_node,
+ &cls->tables_priority) {
+ if (iter->max_priority >= priority) {
+ break;
+ }
+ }
+
+ /* Move 'table' just after 'iter' (unless it's already there). */
+ if (iter->list_node.next != &table->list_node) {
+ list_splice(iter->list_node.next,
+ &table->list_node, table->list_node.next);
+ }
+ } else if (priority < table->max_priority) {
+ /* Possibly move 'table' earlier in the priority list. If we break out
+ * of the loop, then 'table' should be moved just before that 'iter'.
+ * If the loop terminates normally, then 'iter' will be the list head
+ * and we'll move table just before that (e.g. to the back of the
+ * list). */
+ LIST_FOR_EACH_CONTINUE (iter, list_node, &cls->tables_priority) {
+ if (iter->max_priority <= priority) {
+ break;
+ }
+ }
+
+ /* Move 'table' just before 'iter' (unless it's already there). */
+ if (iter->list_node.prev != &table->list_node) {
+ list_splice(&iter->list_node,
+ &table->list_node, table->list_node.next);
+ }
+ }
+ table->max_priority = priority;
+}
+