18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) 2007-2013 Nicira, Inc.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef FLOW_TABLE_H
78c2ecf20Sopenharmony_ci#define FLOW_TABLE_H 1
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/kernel.h>
108c2ecf20Sopenharmony_ci#include <linux/netlink.h>
118c2ecf20Sopenharmony_ci#include <linux/openvswitch.h>
128c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
138c2ecf20Sopenharmony_ci#include <linux/types.h>
148c2ecf20Sopenharmony_ci#include <linux/rcupdate.h>
158c2ecf20Sopenharmony_ci#include <linux/if_ether.h>
168c2ecf20Sopenharmony_ci#include <linux/in6.h>
178c2ecf20Sopenharmony_ci#include <linux/jiffies.h>
188c2ecf20Sopenharmony_ci#include <linux/time.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <net/inet_ecn.h>
218c2ecf20Sopenharmony_ci#include <net/ip_tunnels.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#include "flow.h"
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistruct mask_cache_entry {
268c2ecf20Sopenharmony_ci	u32 skb_hash;
278c2ecf20Sopenharmony_ci	u32 mask_index;
288c2ecf20Sopenharmony_ci};
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_cistruct mask_cache {
318c2ecf20Sopenharmony_ci	struct rcu_head rcu;
328c2ecf20Sopenharmony_ci	u32 cache_size;  /* Must be ^2 value. */
338c2ecf20Sopenharmony_ci	struct mask_cache_entry __percpu *mask_cache;
348c2ecf20Sopenharmony_ci};
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistruct mask_count {
378c2ecf20Sopenharmony_ci	int index;
388c2ecf20Sopenharmony_ci	u64 counter;
398c2ecf20Sopenharmony_ci};
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_cistruct mask_array_stats {
428c2ecf20Sopenharmony_ci	struct u64_stats_sync syncp;
438c2ecf20Sopenharmony_ci	u64 usage_cntrs[];
448c2ecf20Sopenharmony_ci};
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_cistruct mask_array {
478c2ecf20Sopenharmony_ci	struct rcu_head rcu;
488c2ecf20Sopenharmony_ci	int count, max;
498c2ecf20Sopenharmony_ci	struct mask_array_stats __percpu *masks_usage_stats;
508c2ecf20Sopenharmony_ci	u64 *masks_usage_zero_cntr;
518c2ecf20Sopenharmony_ci	struct sw_flow_mask __rcu *masks[];
528c2ecf20Sopenharmony_ci};
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistruct table_instance {
558c2ecf20Sopenharmony_ci	struct hlist_head *buckets;
568c2ecf20Sopenharmony_ci	unsigned int n_buckets;
578c2ecf20Sopenharmony_ci	struct rcu_head rcu;
588c2ecf20Sopenharmony_ci	int node_ver;
598c2ecf20Sopenharmony_ci	u32 hash_seed;
608c2ecf20Sopenharmony_ci};
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_cistruct flow_table {
638c2ecf20Sopenharmony_ci	struct table_instance __rcu *ti;
648c2ecf20Sopenharmony_ci	struct table_instance __rcu *ufid_ti;
658c2ecf20Sopenharmony_ci	struct mask_cache __rcu *mask_cache;
668c2ecf20Sopenharmony_ci	struct mask_array __rcu *mask_array;
678c2ecf20Sopenharmony_ci	unsigned long last_rehash;
688c2ecf20Sopenharmony_ci	unsigned int count;
698c2ecf20Sopenharmony_ci	unsigned int ufid_count;
708c2ecf20Sopenharmony_ci};
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ciextern struct kmem_cache *flow_stats_cache;
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ciint ovs_flow_init(void);
758c2ecf20Sopenharmony_civoid ovs_flow_exit(void);
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_cistruct sw_flow *ovs_flow_alloc(void);
788c2ecf20Sopenharmony_civoid ovs_flow_free(struct sw_flow *, bool deferred);
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ciint ovs_flow_tbl_init(struct flow_table *);
818c2ecf20Sopenharmony_ciint ovs_flow_tbl_count(const struct flow_table *table);
828c2ecf20Sopenharmony_civoid ovs_flow_tbl_destroy(struct flow_table *table);
838c2ecf20Sopenharmony_ciint ovs_flow_tbl_flush(struct flow_table *flow_table);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ciint ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow,
868c2ecf20Sopenharmony_ci			const struct sw_flow_mask *mask);
878c2ecf20Sopenharmony_civoid ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow);
888c2ecf20Sopenharmony_ciint  ovs_flow_tbl_num_masks(const struct flow_table *table);
898c2ecf20Sopenharmony_ciu32  ovs_flow_tbl_masks_cache_size(const struct flow_table *table);
908c2ecf20Sopenharmony_ciint  ovs_flow_tbl_masks_cache_resize(struct flow_table *table, u32 size);
918c2ecf20Sopenharmony_cistruct sw_flow *ovs_flow_tbl_dump_next(struct table_instance *table,
928c2ecf20Sopenharmony_ci				       u32 *bucket, u32 *idx);
938c2ecf20Sopenharmony_cistruct sw_flow *ovs_flow_tbl_lookup_stats(struct flow_table *,
948c2ecf20Sopenharmony_ci					  const struct sw_flow_key *,
958c2ecf20Sopenharmony_ci					  u32 skb_hash,
968c2ecf20Sopenharmony_ci					  u32 *n_mask_hit,
978c2ecf20Sopenharmony_ci					  u32 *n_cache_hit);
988c2ecf20Sopenharmony_cistruct sw_flow *ovs_flow_tbl_lookup(struct flow_table *,
998c2ecf20Sopenharmony_ci				    const struct sw_flow_key *);
1008c2ecf20Sopenharmony_cistruct sw_flow *ovs_flow_tbl_lookup_exact(struct flow_table *tbl,
1018c2ecf20Sopenharmony_ci					  const struct sw_flow_match *match);
1028c2ecf20Sopenharmony_cistruct sw_flow *ovs_flow_tbl_lookup_ufid(struct flow_table *,
1038c2ecf20Sopenharmony_ci					 const struct sw_flow_id *);
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cibool ovs_flow_cmp(const struct sw_flow *, const struct sw_flow_match *);
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_civoid ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src,
1088c2ecf20Sopenharmony_ci		       bool full, const struct sw_flow_mask *mask);
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_civoid ovs_flow_masks_rebalance(struct flow_table *table);
1118c2ecf20Sopenharmony_civoid table_instance_flow_flush(struct flow_table *table,
1128c2ecf20Sopenharmony_ci			       struct table_instance *ti,
1138c2ecf20Sopenharmony_ci			       struct table_instance *ufid_ti);
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci#endif /* flow_table.h */
116