1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#ifndef VPORT_H
20#define VPORT_H 1
21
22#include <linux/if_tunnel.h>
23#include <linux/list.h>
24#include <linux/netlink.h>
25#include <linux/openvswitch.h>
26#include <linux/reciprocal_div.h>
27#include <linux/skbuff.h>
28#include <linux/spinlock.h>
29#include <linux/u64_stats_sync.h>
30
31#include "datapath.h"
32
33struct vport;
34struct vport_parms;
35
36
37
38struct vport_net {
39 struct vport __rcu *gre_vport;
40};
41
42int ovs_vport_init(void);
43void ovs_vport_exit(void);
44
45struct vport *ovs_vport_add(const struct vport_parms *);
46void ovs_vport_del(struct vport *);
47
48struct vport *ovs_vport_locate(const struct net *net, const char *name);
49
50void ovs_vport_get_stats(struct vport *, struct ovs_vport_stats *);
51
52int ovs_vport_set_options(struct vport *, struct nlattr *options);
53int ovs_vport_get_options(const struct vport *, struct sk_buff *);
54
55int ovs_vport_set_upcall_portids(struct vport *, const struct nlattr *pids);
56int ovs_vport_get_upcall_portids(const struct vport *, struct sk_buff *);
57u32 ovs_vport_find_upcall_portid(const struct vport *, struct sk_buff *);
58
59int ovs_vport_send(struct vport *, struct sk_buff *);
60
61int ovs_tunnel_get_egress_info(struct ovs_tunnel_info *egress_tun_info,
62 struct net *net,
63 const struct ovs_tunnel_info *tun_info,
64 u8 ipproto,
65 u32 skb_mark,
66 __be16 tp_src,
67 __be16 tp_dst);
68int ovs_vport_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
69 struct ovs_tunnel_info *info);
70
71
72
73struct vport_err_stats {
74 atomic_long_t rx_dropped;
75 atomic_long_t rx_errors;
76 atomic_long_t tx_dropped;
77 atomic_long_t tx_errors;
78};
79
80
81
82
83
84
85
86
87
88struct vport_portids {
89 struct reciprocal_value rn_ids;
90 struct rcu_head rcu;
91 u32 n_ids;
92 u32 ids[];
93};
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108struct vport {
109 struct rcu_head rcu;
110 struct datapath *dp;
111 struct vport_portids __rcu *upcall_portids;
112 u16 port_no;
113
114 struct hlist_node hash_node;
115 struct hlist_node dp_hash_node;
116 const struct vport_ops *ops;
117
118 struct pcpu_sw_netstats __percpu *percpu_stats;
119
120 struct vport_err_stats err_stats;
121 struct list_head detach_list;
122};
123
124
125
126
127
128
129
130
131
132
133
134struct vport_parms {
135 const char *name;
136 enum ovs_vport_type type;
137 struct nlattr *options;
138
139
140 struct datapath *dp;
141 u16 port_no;
142 struct nlattr *upcall_portids;
143};
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164struct vport_ops {
165 enum ovs_vport_type type;
166
167
168 struct vport *(*create)(const struct vport_parms *);
169 void (*destroy)(struct vport *);
170
171 int (*set_options)(struct vport *, struct nlattr *);
172 int (*get_options)(const struct vport *, struct sk_buff *);
173
174
175 const char *(*get_name)(const struct vport *);
176
177 int (*send)(struct vport *, struct sk_buff *);
178 int (*get_egress_tun_info)(struct vport *, struct sk_buff *,
179 struct ovs_tunnel_info *);
180
181 struct module *owner;
182 struct list_head list;
183};
184
185enum vport_err_type {
186 VPORT_E_RX_DROPPED,
187 VPORT_E_RX_ERROR,
188 VPORT_E_TX_DROPPED,
189 VPORT_E_TX_ERROR,
190};
191
192struct vport *ovs_vport_alloc(int priv_size, const struct vport_ops *,
193 const struct vport_parms *);
194void ovs_vport_free(struct vport *);
195void ovs_vport_deferred_free(struct vport *vport);
196
197#define VPORT_ALIGN 8
198
199
200
201
202
203
204
205
206
207
208static inline void *vport_priv(const struct vport *vport)
209{
210 return (u8 *)(uintptr_t)vport + ALIGN(sizeof(struct vport), VPORT_ALIGN);
211}
212
213
214
215
216
217
218
219
220
221
222
223static inline struct vport *vport_from_priv(void *priv)
224{
225 return (struct vport *)((u8 *)priv - ALIGN(sizeof(struct vport), VPORT_ALIGN));
226}
227
228void ovs_vport_receive(struct vport *, struct sk_buff *,
229 const struct ovs_tunnel_info *);
230
231static inline void ovs_skb_postpush_rcsum(struct sk_buff *skb,
232 const void *start, unsigned int len)
233{
234 if (skb->ip_summed == CHECKSUM_COMPLETE)
235 skb->csum = csum_add(skb->csum, csum_partial(start, len, 0));
236}
237
238int ovs_vport_ops_register(struct vport_ops *ops);
239void ovs_vport_ops_unregister(struct vport_ops *ops);
240
241static inline struct rtable *ovs_tunnel_route_lookup(struct net *net,
242 const struct ovs_key_ipv4_tunnel *key,
243 u32 mark,
244 struct flowi4 *fl,
245 u8 protocol)
246{
247 struct rtable *rt;
248
249 memset(fl, 0, sizeof(*fl));
250 fl->daddr = key->ipv4_dst;
251 fl->saddr = key->ipv4_src;
252 fl->flowi4_tos = RT_TOS(key->ipv4_tos);
253 fl->flowi4_mark = mark;
254 fl->flowi4_proto = protocol;
255
256 rt = ip_route_output_key(net, fl);
257 return rt;
258}
259#endif
260