162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2007-2012 Nicira, Inc. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef VPORT_H 762306a36Sopenharmony_ci#define VPORT_H 1 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/if_tunnel.h> 1062306a36Sopenharmony_ci#include <linux/list.h> 1162306a36Sopenharmony_ci#include <linux/netlink.h> 1262306a36Sopenharmony_ci#include <linux/openvswitch.h> 1362306a36Sopenharmony_ci#include <linux/reciprocal_div.h> 1462306a36Sopenharmony_ci#include <linux/skbuff.h> 1562306a36Sopenharmony_ci#include <linux/spinlock.h> 1662306a36Sopenharmony_ci#include <linux/u64_stats_sync.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include "datapath.h" 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_cistruct vport; 2162306a36Sopenharmony_cistruct vport_parms; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* The following definitions are for users of the vport subsystem: */ 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ciint ovs_vport_init(void); 2662306a36Sopenharmony_civoid ovs_vport_exit(void); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistruct vport *ovs_vport_add(const struct vport_parms *); 2962306a36Sopenharmony_civoid ovs_vport_del(struct vport *); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_cistruct vport *ovs_vport_locate(const struct net *net, const char *name); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_civoid ovs_vport_get_stats(struct vport *, struct ovs_vport_stats *); 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ciint ovs_vport_get_upcall_stats(struct vport *vport, struct sk_buff *skb); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ciint ovs_vport_set_options(struct vport *, struct nlattr *options); 3862306a36Sopenharmony_ciint ovs_vport_get_options(const struct vport *, struct sk_buff *); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciint ovs_vport_set_upcall_portids(struct vport *, const struct nlattr *pids); 4162306a36Sopenharmony_ciint ovs_vport_get_upcall_portids(const struct vport *, struct sk_buff *); 4262306a36Sopenharmony_ciu32 ovs_vport_find_upcall_portid(const struct vport *, struct sk_buff *); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/** 4562306a36Sopenharmony_ci * struct vport_portids - array of netlink portids of a vport. 4662306a36Sopenharmony_ci * must be protected by rcu. 4762306a36Sopenharmony_ci * @rn_ids: The reciprocal value of @n_ids. 4862306a36Sopenharmony_ci * @rcu: RCU callback head for deferred destruction. 4962306a36Sopenharmony_ci * @n_ids: Size of @ids array. 5062306a36Sopenharmony_ci * @ids: Array storing the Netlink socket pids to be used for packets received 5162306a36Sopenharmony_ci * on this port that miss the flow table. 5262306a36Sopenharmony_ci */ 5362306a36Sopenharmony_cistruct vport_portids { 5462306a36Sopenharmony_ci struct reciprocal_value rn_ids; 5562306a36Sopenharmony_ci struct rcu_head rcu; 5662306a36Sopenharmony_ci u32 n_ids; 5762306a36Sopenharmony_ci u32 ids[]; 5862306a36Sopenharmony_ci}; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci/** 6162306a36Sopenharmony_ci * struct vport - one port within a datapath 6262306a36Sopenharmony_ci * @dev: Pointer to net_device. 6362306a36Sopenharmony_ci * @dev_tracker: refcount tracker for @dev reference 6462306a36Sopenharmony_ci * @dp: Datapath to which this port belongs. 6562306a36Sopenharmony_ci * @upcall_portids: RCU protected 'struct vport_portids'. 6662306a36Sopenharmony_ci * @port_no: Index into @dp's @ports array. 6762306a36Sopenharmony_ci * @hash_node: Element in @dev_table hash table in vport.c. 6862306a36Sopenharmony_ci * @dp_hash_node: Element in @datapath->ports hash table in datapath.c. 6962306a36Sopenharmony_ci * @ops: Class structure. 7062306a36Sopenharmony_ci * @upcall_stats: Upcall stats of every ports. 7162306a36Sopenharmony_ci * @detach_list: list used for detaching vport in net-exit call. 7262306a36Sopenharmony_ci * @rcu: RCU callback head for deferred destruction. 7362306a36Sopenharmony_ci */ 7462306a36Sopenharmony_cistruct vport { 7562306a36Sopenharmony_ci struct net_device *dev; 7662306a36Sopenharmony_ci netdevice_tracker dev_tracker; 7762306a36Sopenharmony_ci struct datapath *dp; 7862306a36Sopenharmony_ci struct vport_portids __rcu *upcall_portids; 7962306a36Sopenharmony_ci u16 port_no; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci struct hlist_node hash_node; 8262306a36Sopenharmony_ci struct hlist_node dp_hash_node; 8362306a36Sopenharmony_ci const struct vport_ops *ops; 8462306a36Sopenharmony_ci struct vport_upcall_stats_percpu __percpu *upcall_stats; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci struct list_head detach_list; 8762306a36Sopenharmony_ci struct rcu_head rcu; 8862306a36Sopenharmony_ci}; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci/** 9162306a36Sopenharmony_ci * struct vport_parms - parameters for creating a new vport 9262306a36Sopenharmony_ci * 9362306a36Sopenharmony_ci * @name: New vport's name. 9462306a36Sopenharmony_ci * @type: New vport's type. 9562306a36Sopenharmony_ci * @options: %OVS_VPORT_ATTR_OPTIONS attribute from Netlink message, %NULL if 9662306a36Sopenharmony_ci * none was supplied. 9762306a36Sopenharmony_ci * @desired_ifindex: New vport's ifindex. 9862306a36Sopenharmony_ci * @dp: New vport's datapath. 9962306a36Sopenharmony_ci * @port_no: New vport's port number. 10062306a36Sopenharmony_ci */ 10162306a36Sopenharmony_cistruct vport_parms { 10262306a36Sopenharmony_ci const char *name; 10362306a36Sopenharmony_ci enum ovs_vport_type type; 10462306a36Sopenharmony_ci int desired_ifindex; 10562306a36Sopenharmony_ci struct nlattr *options; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci /* For ovs_vport_alloc(). */ 10862306a36Sopenharmony_ci struct datapath *dp; 10962306a36Sopenharmony_ci u16 port_no; 11062306a36Sopenharmony_ci struct nlattr *upcall_portids; 11162306a36Sopenharmony_ci}; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci/** 11462306a36Sopenharmony_ci * struct vport_ops - definition of a type of virtual port 11562306a36Sopenharmony_ci * 11662306a36Sopenharmony_ci * @type: %OVS_VPORT_TYPE_* value for this type of virtual port. 11762306a36Sopenharmony_ci * @create: Create a new vport configured as specified. On success returns 11862306a36Sopenharmony_ci * a new vport allocated with ovs_vport_alloc(), otherwise an ERR_PTR() value. 11962306a36Sopenharmony_ci * @destroy: Destroys a vport. Must call vport_free() on the vport but not 12062306a36Sopenharmony_ci * before an RCU grace period has elapsed. 12162306a36Sopenharmony_ci * @set_options: Modify the configuration of an existing vport. May be %NULL 12262306a36Sopenharmony_ci * if modification is not supported. 12362306a36Sopenharmony_ci * @get_options: Appends vport-specific attributes for the configuration of an 12462306a36Sopenharmony_ci * existing vport to a &struct sk_buff. May be %NULL for a vport that does not 12562306a36Sopenharmony_ci * have any configuration. 12662306a36Sopenharmony_ci * @send: Send a packet on the device. 12762306a36Sopenharmony_ci * zero for dropped packets or negative for error. 12862306a36Sopenharmony_ci */ 12962306a36Sopenharmony_cistruct vport_ops { 13062306a36Sopenharmony_ci enum ovs_vport_type type; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci /* Called with ovs_mutex. */ 13362306a36Sopenharmony_ci struct vport *(*create)(const struct vport_parms *); 13462306a36Sopenharmony_ci void (*destroy)(struct vport *); 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci int (*set_options)(struct vport *, struct nlattr *); 13762306a36Sopenharmony_ci int (*get_options)(const struct vport *, struct sk_buff *); 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci int (*send)(struct sk_buff *skb); 14062306a36Sopenharmony_ci struct module *owner; 14162306a36Sopenharmony_ci struct list_head list; 14262306a36Sopenharmony_ci}; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci/** 14562306a36Sopenharmony_ci * struct vport_upcall_stats_percpu - per-cpu packet upcall statistics for 14662306a36Sopenharmony_ci * a given vport. 14762306a36Sopenharmony_ci * @n_success: Number of packets that upcall to userspace succeed. 14862306a36Sopenharmony_ci * @n_fail: Number of packets that upcall to userspace failed. 14962306a36Sopenharmony_ci */ 15062306a36Sopenharmony_cistruct vport_upcall_stats_percpu { 15162306a36Sopenharmony_ci struct u64_stats_sync syncp; 15262306a36Sopenharmony_ci u64_stats_t n_success; 15362306a36Sopenharmony_ci u64_stats_t n_fail; 15462306a36Sopenharmony_ci}; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_cistruct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *, 15762306a36Sopenharmony_ci const struct vport_parms *); 15862306a36Sopenharmony_civoid ovs_vport_free(struct vport *); 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci#define VPORT_ALIGN 8 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci/** 16362306a36Sopenharmony_ci * vport_priv - access private data area of vport 16462306a36Sopenharmony_ci * 16562306a36Sopenharmony_ci * @vport: vport to access 16662306a36Sopenharmony_ci * 16762306a36Sopenharmony_ci * If a nonzero size was passed in priv_size of vport_alloc() a private data 16862306a36Sopenharmony_ci * area was allocated on creation. This allows that area to be accessed and 16962306a36Sopenharmony_ci * used for any purpose needed by the vport implementer. 17062306a36Sopenharmony_ci */ 17162306a36Sopenharmony_cistatic inline void *vport_priv(const struct vport *vport) 17262306a36Sopenharmony_ci{ 17362306a36Sopenharmony_ci return (u8 *)(uintptr_t)vport + ALIGN(sizeof(struct vport), VPORT_ALIGN); 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci/** 17762306a36Sopenharmony_ci * vport_from_priv - lookup vport from private data pointer 17862306a36Sopenharmony_ci * 17962306a36Sopenharmony_ci * @priv: Start of private data area. 18062306a36Sopenharmony_ci * 18162306a36Sopenharmony_ci * It is sometimes useful to translate from a pointer to the private data 18262306a36Sopenharmony_ci * area to the vport, such as in the case where the private data pointer is 18362306a36Sopenharmony_ci * the result of a hash table lookup. @priv must point to the start of the 18462306a36Sopenharmony_ci * private data area. 18562306a36Sopenharmony_ci */ 18662306a36Sopenharmony_cistatic inline struct vport *vport_from_priv(void *priv) 18762306a36Sopenharmony_ci{ 18862306a36Sopenharmony_ci return (struct vport *)((u8 *)priv - ALIGN(sizeof(struct vport), VPORT_ALIGN)); 18962306a36Sopenharmony_ci} 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_ciint ovs_vport_receive(struct vport *, struct sk_buff *, 19262306a36Sopenharmony_ci const struct ip_tunnel_info *); 19362306a36Sopenharmony_ci 19462306a36Sopenharmony_cistatic inline const char *ovs_vport_name(struct vport *vport) 19562306a36Sopenharmony_ci{ 19662306a36Sopenharmony_ci return vport->dev->name; 19762306a36Sopenharmony_ci} 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ciint __ovs_vport_ops_register(struct vport_ops *ops); 20062306a36Sopenharmony_ci#define ovs_vport_ops_register(ops) \ 20162306a36Sopenharmony_ci ({ \ 20262306a36Sopenharmony_ci (ops)->owner = THIS_MODULE; \ 20362306a36Sopenharmony_ci __ovs_vport_ops_register(ops); \ 20462306a36Sopenharmony_ci }) 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_civoid ovs_vport_ops_unregister(struct vport_ops *ops); 20762306a36Sopenharmony_civoid ovs_vport_send(struct vport *vport, struct sk_buff *skb, u8 mac_proto); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci#endif /* vport.h */ 210