2 * Copyright (c) 2011 Nicira, Inc.
3 * Copyright (c) 2012 Cisco Systems, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of version 2 of the GNU General Public
7 * License as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
22 #include <linux/version.h>
23 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
27 #include <linux/net.h>
28 #include <linux/rculist.h>
29 #include <linux/udp.h>
39 #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */
42 * struct vxlanhdr - VXLAN header
43 * @vx_flags: Must have the exact value %VXLAN_FLAGS.
44 * @vx_vni: VXLAN Network Identifier (VNI) in top 24 bits, low 8 bits zeroed.
51 #define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr))
54 * struct vxlan_port - Keeps track of open UDP ports
55 * @dst_port: vxlan UDP port no.
56 * @list: list element in @vxlan_ports.
57 * @vxlan_rcv_socket: The socket created for this port number.
62 struct list_head list;
63 struct socket *vxlan_rcv_socket;
67 static LIST_HEAD(vxlan_ports);
69 static inline struct vxlan_port *vxlan_vport(const struct vport *vport)
71 return vport_priv(vport);
74 static struct vxlan_port *vxlan_find_port(struct net *net, __be16 port)
76 struct vxlan_port *vxlan_port;
78 list_for_each_entry_rcu(vxlan_port, &vxlan_ports, list) {
80 if (vxlan_port->dst_port == port &&
81 net_eq(sock_net(vxlan_port->vxlan_rcv_socket->sk), net))
88 static inline struct vxlanhdr *vxlan_hdr(const struct sk_buff *skb)
90 return (struct vxlanhdr *)(udp_hdr(skb) + 1);
93 static void vxlan_build_header(const struct vport *vport,
97 struct vxlan_port *vxlan_port = vxlan_vport(vport);
98 struct udphdr *udph = udp_hdr(skb);
99 struct vxlanhdr *vxh = (struct vxlanhdr *)(udph + 1);
100 const struct ovs_key_ipv4_tunnel *tun_key = OVS_CB(skb)->tun_key;
102 udph->dest = vxlan_port->dst_port;
103 udph->source = htons(ovs_tnl_get_src_port(skb));
105 udph->len = htons(skb->len - skb_transport_offset(skb));
107 vxh->vx_flags = htonl(VXLAN_FLAGS);
108 vxh->vx_vni = htonl(be64_to_cpu(tun_key->tun_id) << 8);
111 /* Called with rcu_read_lock and BH disabled. */
112 static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
114 struct vxlan_port *vxlan_vport;
115 struct vxlanhdr *vxh;
117 struct ovs_key_ipv4_tunnel tun_key;
120 vxlan_vport = vxlan_find_port(dev_net(skb->dev), udp_hdr(skb)->dest);
121 if (unlikely(!vxlan_vport))
124 if (unlikely(!pskb_may_pull(skb, VXLAN_HLEN + ETH_HLEN)))
127 vxh = vxlan_hdr(skb);
128 if (unlikely(vxh->vx_flags != htonl(VXLAN_FLAGS) ||
129 vxh->vx_vni & htonl(0xff)))
132 __skb_pull(skb, VXLAN_HLEN);
133 skb_postpull_rcsum(skb, skb_transport_header(skb), VXLAN_HLEN + ETH_HLEN);
135 key = cpu_to_be64(ntohl(vxh->vx_vni) >> 8);
137 /* Save outer tunnel values */
139 tnl_tun_key_init(&tun_key, iph, key, OVS_TNL_F_KEY);
140 OVS_CB(skb)->tun_key = &tun_key;
142 ovs_tnl_rcv(vport_from_priv(vxlan_vport), skb);
151 /* Random value. Irrelevant as long as it's not 0 since we set the handler. */
152 #define UDP_ENCAP_VXLAN 1
153 static int vxlan_socket_init(struct vxlan_port *vxlan_port, struct net *net)
155 struct sockaddr_in sin;
158 err = sock_create_kern(AF_INET, SOCK_DGRAM, 0,
159 &vxlan_port->vxlan_rcv_socket);
163 /* release net ref. */
164 sk_change_net(vxlan_port->vxlan_rcv_socket->sk, net);
166 sin.sin_family = AF_INET;
167 sin.sin_addr.s_addr = htonl(INADDR_ANY);
168 sin.sin_port = vxlan_port->dst_port;
170 err = kernel_bind(vxlan_port->vxlan_rcv_socket, (struct sockaddr *)&sin,
171 sizeof(struct sockaddr_in));
175 udp_sk(vxlan_port->vxlan_rcv_socket->sk)->encap_type = UDP_ENCAP_VXLAN;
176 udp_sk(vxlan_port->vxlan_rcv_socket->sk)->encap_rcv = vxlan_rcv;
183 sk_release_kernel(vxlan_port->vxlan_rcv_socket->sk);
185 pr_warn("cannot register vxlan protocol handler\n");
189 static int vxlan_get_options(const struct vport *vport, struct sk_buff *skb)
191 struct vxlan_port *vxlan_port = vxlan_vport(vport);
193 if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, ntohs(vxlan_port->dst_port)))
198 static void vxlan_tnl_destroy(struct vport *vport)
200 struct vxlan_port *vxlan_port = vxlan_vport(vport);
202 list_del_rcu(&vxlan_port->list);
204 sk_release_kernel(vxlan_port->vxlan_rcv_socket->sk);
206 ovs_vport_deferred_free(vport);
209 static struct vport *vxlan_tnl_create(const struct vport_parms *parms)
211 struct net *net = ovs_dp_get_net(parms->dp);
212 struct nlattr *options = parms->options;
213 struct vxlan_port *vxlan_port;
223 a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT);
224 if (a && nla_len(a) == sizeof(u16)) {
225 dst_port = nla_get_u16(a);
227 /* Require destination port from userspace. */
232 /* Verify if we already have a socket created for this port */
233 if (vxlan_find_port(net, htons(dst_port))) {
238 vport = ovs_vport_alloc(sizeof(struct vxlan_port),
239 &ovs_vxlan_vport_ops, parms);
243 vxlan_port = vxlan_vport(vport);
244 vxlan_port->dst_port = htons(dst_port);
245 strncpy(vxlan_port->name, parms->name, IFNAMSIZ);
247 err = vxlan_socket_init(vxlan_port, net);
251 list_add_tail_rcu(&vxlan_port->list, &vxlan_ports);
255 ovs_vport_free(vport);
260 static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
262 if (unlikely(!OVS_CB(skb)->tun_key))
265 return ovs_tnl_send(vport, skb, IPPROTO_UDP,
266 VXLAN_HLEN, vxlan_build_header);
269 static const char *vxlan_get_name(const struct vport *vport)
271 struct vxlan_port *vxlan_port = vxlan_vport(vport);
272 return vxlan_port->name;
275 const struct vport_ops ovs_vxlan_vport_ops = {
276 .type = OVS_VPORT_TYPE_VXLAN,
277 .flags = VPORT_F_TUN_ID,
278 .create = vxlan_tnl_create,
279 .destroy = vxlan_tnl_destroy,
280 .get_name = vxlan_get_name,
281 .get_options = vxlan_get_options,
282 .send = vxlan_tnl_send,
285 #warning VXLAN tunneling will not be available on kernels before 2.6.26
286 #endif /* Linux kernel < 2.6.26 */