~james-page/ubuntu/saucy/openvswitch/1.12-snapshot

« back to all changes in this revision

Viewing changes to datapath/linux/compat/vxlan.c

  • Committer: James Page
  • Date: 2013-08-21 10:16:57 UTC
  • mfrom: (1.1.20)
  • Revision ID: james.page@canonical.com-20130821101657-3o0z0qeiv5zkwlzi
New upstream snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2007-2013 Nicira, Inc.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of version 2 of the GNU General Public
 
6
 * License as published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
11
 * General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program; if not, write to the Free Software
 
15
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
16
 * 02110-1301, USA
 
17
 *
 
18
 * This code is derived from kernel vxlan module.
 
19
 */
 
20
 
 
21
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
22
 
 
23
#include <linux/kernel.h>
 
24
#include <linux/types.h>
 
25
#include <linux/module.h>
 
26
#include <linux/errno.h>
 
27
#include <linux/slab.h>
 
28
#include <linux/skbuff.h>
 
29
#include <linux/rculist.h>
 
30
#include <linux/netdevice.h>
 
31
#include <linux/in.h>
 
32
#include <linux/ip.h>
 
33
#include <linux/udp.h>
 
34
#include <linux/igmp.h>
 
35
#include <linux/etherdevice.h>
 
36
#include <linux/if_ether.h>
 
37
#include <linux/if_vlan.h>
 
38
#include <linux/hash.h>
 
39
#include <linux/ethtool.h>
 
40
#include <net/arp.h>
 
41
#include <net/ndisc.h>
 
42
#include <net/ip.h>
 
43
#include <net/ip_tunnels.h>
 
44
#include <net/icmp.h>
 
45
#include <net/udp.h>
 
46
#include <net/rtnetlink.h>
 
47
#include <net/route.h>
 
48
#include <net/dsfield.h>
 
49
#include <net/inet_ecn.h>
 
50
#include <net/net_namespace.h>
 
51
#include <net/netns/generic.h>
 
52
#include <net/vxlan.h>
 
53
 
 
54
#include "checksum.h"
 
55
#include "compat.h"
 
56
#include "gso.h"
 
57
#include "vlan.h"
 
58
 
 
59
#define PORT_HASH_BITS  8
 
60
#define PORT_HASH_SIZE  (1<<PORT_HASH_BITS)
 
61
 
 
62
#define VXLAN_N_VID     (1u << 24)
 
63
#define VXLAN_VID_MASK  (VXLAN_N_VID - 1)
 
64
/* IP header + UDP + VXLAN + Ethernet header */
 
65
#define VXLAN_HEADROOM (20 + 8 + 8 + 14)
 
66
#define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr))
 
67
 
 
68
#define VXLAN_FLAGS 0x08000000  /* struct vxlanhdr.vx_flags required value. */
 
69
 
 
70
/* VXLAN protocol header */
 
71
struct vxlanhdr {
 
72
        __be32 vx_flags;
 
73
        __be32 vx_vni;
 
74
};
 
75
 
 
76
static int vxlan_net_id;
 
77
 
 
78
/* per-network namespace private data for this module */
 
79
struct vxlan_net {
 
80
        struct hlist_head sock_list[PORT_HASH_SIZE];
 
81
        struct mutex      sock_lock;    /* RTNL lock nests inside this lock. */
 
82
};
 
83
 
 
84
/* Socket hash table head */
 
85
static inline struct hlist_head *vs_head(struct net *net, __be16 port)
 
86
{
 
87
        struct vxlan_net *vn = net_generic(net, vxlan_net_id);
 
88
 
 
89
        return &vn->sock_list[hash_32(ntohs(port), PORT_HASH_BITS)];
 
90
}
 
91
 
 
92
/* Find VXLAN socket based on network namespace and UDP port */
 
93
static struct vxlan_sock *vxlan_find_port(struct net *net, __be16 port)
 
94
{
 
95
        struct vxlan_sock *vs;
 
96
 
 
97
        hlist_for_each_entry_rcu(vs, vs_head(net, port), hlist) {
 
98
                if (inet_sport(vs->sock->sk) == port)
 
99
                        return vs;
 
100
        }
 
101
        return NULL;
 
102
}
 
103
 
 
104
/* Callback from net/ipv4/udp.c to receive packets */
 
105
static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
 
106
{
 
107
        struct vxlan_handler *vh;
 
108
        struct vxlan_sock *vs;
 
109
        struct vxlanhdr *vxh;
 
110
 
 
111
        /* Need Vxlan and inner Ethernet header to be present */
 
112
        if (!pskb_may_pull(skb, VXLAN_HLEN))
 
113
                goto error;
 
114
 
 
115
        /* Return packets with reserved bits set */
 
116
        vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1);
 
117
        if (vxh->vx_flags != htonl(VXLAN_FLAGS) ||
 
118
            (vxh->vx_vni & htonl(0xff))) {
 
119
                pr_warn("invalid vxlan flags=%#x vni=%#x\n",
 
120
                        ntohl(vxh->vx_flags), ntohl(vxh->vx_vni));
 
121
                goto error;
 
122
        }
 
123
 
 
124
        if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB)))
 
125
                goto drop;
 
126
 
 
127
        vs = vxlan_find_port(sock_net(sk), inet_sport(sk));
 
128
        if (!vs)
 
129
                goto drop;
 
130
 
 
131
        list_for_each_entry_rcu(vh, &vs->handler_list, node) {
 
132
                if (vh->rcv(vh, skb, vxh->vx_vni) == PACKET_RCVD)
 
133
                        return 0;
 
134
        }
 
135
 
 
136
drop:
 
137
        /* Consume bad packet */
 
138
        kfree_skb(skb);
 
139
        return 0;
 
140
 
 
141
error:
 
142
        /* Return non vxlan pkt */
 
143
        return 1;
 
144
}
 
145
 
 
146
static void vxlan_sock_put(struct sk_buff *skb)
 
147
{
 
148
        sock_put(skb->sk);
 
149
}
 
150
 
 
151
/* On transmit, associate with the tunnel socket */
 
152
static void vxlan_set_owner(struct sock *sk, struct sk_buff *skb)
 
153
{
 
154
        skb_orphan(skb);
 
155
        sock_hold(sk);
 
156
        skb->sk = sk;
 
157
        skb->destructor = vxlan_sock_put;
 
158
}
 
159
 
 
160
/* Compute source port for outgoing packet
 
161
 *   first choice to use L4 flow hash since it will spread
 
162
 *     better and maybe available from hardware
 
163
 *   secondary choice is to use jhash on the Ethernet header
 
164
 */
 
165
__be16 vxlan_src_port(__u16 port_min, __u16 port_max, struct sk_buff *skb)
 
166
{
 
167
        unsigned int range = (port_max - port_min) + 1;
 
168
        u32 hash;
 
169
 
 
170
        hash = skb_get_rxhash(skb);
 
171
        if (!hash)
 
172
                hash = jhash(skb->data, 2 * ETH_ALEN,
 
173
                             (__force u32) skb->protocol);
 
174
 
 
175
        return htons((((u64) hash * range) >> 32) + port_min);
 
176
}
 
177
 
 
178
static void vxlan_gso(struct sk_buff *skb)
 
179
{
 
180
        int udp_offset = skb_transport_offset(skb);
 
181
        struct udphdr *uh;
 
182
 
 
183
        uh = udp_hdr(skb);
 
184
        uh->len = htons(skb->len - udp_offset);
 
185
 
 
186
        /* csum segment if tunnel sets skb with csum. */
 
187
        if (unlikely(uh->check)) {
 
188
                struct iphdr *iph = ip_hdr(skb);
 
189
 
 
190
                uh->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr,
 
191
                                               skb->len - udp_offset,
 
192
                                               IPPROTO_UDP, 0);
 
193
                uh->check = csum_fold(skb_checksum(skb, udp_offset,
 
194
                                      skb->len - udp_offset, 0));
 
195
 
 
196
                if (uh->check == 0)
 
197
                        uh->check = CSUM_MANGLED_0;
 
198
 
 
199
        }
 
200
        skb->ip_summed = CHECKSUM_NONE;
 
201
}
 
202
 
 
203
static int handle_offloads(struct sk_buff *skb)
 
204
{
 
205
        if (skb_is_gso(skb)) {
 
206
                OVS_GSO_CB(skb)->fix_segment = vxlan_gso;
 
207
        } else {
 
208
                if (skb->ip_summed != CHECKSUM_PARTIAL)
 
209
                        skb->ip_summed = CHECKSUM_NONE;
 
210
        }
 
211
        return 0;
 
212
}
 
213
 
 
214
int vxlan_xmit_skb(struct net *net, struct vxlan_handler *vh,
 
215
                   struct rtable *rt, struct sk_buff *skb,
 
216
                   __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
 
217
                   __be16 src_port, __be16 dst_port, __be32 vni)
 
218
{
 
219
        struct vxlanhdr *vxh;
 
220
        struct udphdr *uh;
 
221
        int min_headroom;
 
222
        int err;
 
223
 
 
224
        skb_reset_inner_headers(skb);
 
225
 
 
226
        min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
 
227
                        + VXLAN_HLEN + sizeof(struct iphdr)
 
228
                        + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
 
229
 
 
230
        /* Need space for new headers (invalidates iph ptr) */
 
231
        err = skb_cow_head(skb, min_headroom);
 
232
        if (unlikely(err))
 
233
                return err;
 
234
 
 
235
        if (unlikely(vlan_deaccel_tag(skb)))
 
236
                return -ENOMEM;
 
237
 
 
238
        vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh));
 
239
        vxh->vx_flags = htonl(VXLAN_FLAGS);
 
240
        vxh->vx_vni = vni;
 
241
 
 
242
        __skb_push(skb, sizeof(*uh));
 
243
        skb_reset_transport_header(skb);
 
244
        uh = udp_hdr(skb);
 
245
 
 
246
        uh->dest = dst_port;
 
247
        uh->source = src_port;
 
248
 
 
249
        uh->len = htons(skb->len);
 
250
        uh->check = 0;
 
251
 
 
252
        vxlan_set_owner(vh->vs->sock->sk, skb);
 
253
 
 
254
        err = handle_offloads(skb);
 
255
        if (err)
 
256
                return err;
 
257
 
 
258
        return iptunnel_xmit(net, rt, skb, src, dst,
 
259
                        IPPROTO_UDP, tos, ttl, df);
 
260
}
 
261
 
 
262
static struct vxlan_sock *vxlan_socket_create(struct net *net, __be16 port)
 
263
{
 
264
        struct vxlan_sock *vs;
 
265
        struct sock *sk;
 
266
        struct sockaddr_in vxlan_addr = {
 
267
                .sin_family = AF_INET,
 
268
                .sin_addr.s_addr = htonl(INADDR_ANY),
 
269
                .sin_port = port,
 
270
        };
 
271
        int rc;
 
272
 
 
273
        vs = kmalloc(sizeof(*vs), GFP_KERNEL);
 
274
        if (!vs)
 
275
                return ERR_PTR(-ENOMEM);
 
276
 
 
277
        /* Create UDP socket for encapsulation receive. */
 
278
        rc = sock_create_kern(AF_INET, SOCK_DGRAM, IPPROTO_UDP, &vs->sock);
 
279
        if (rc < 0) {
 
280
                pr_debug("UDP socket create failed\n");
 
281
                kfree(vs);
 
282
                return ERR_PTR(rc);
 
283
        }
 
284
 
 
285
        /* Put in proper namespace */
 
286
        sk = vs->sock->sk;
 
287
        sk_change_net(sk, net);
 
288
 
 
289
        rc = kernel_bind(vs->sock, (struct sockaddr *) &vxlan_addr,
 
290
                         sizeof(vxlan_addr));
 
291
        if (rc < 0) {
 
292
                pr_debug("bind for UDP socket %pI4:%u (%d)\n",
 
293
                         &vxlan_addr.sin_addr, ntohs(vxlan_addr.sin_port), rc);
 
294
                sk_release_kernel(sk);
 
295
                kfree(vs);
 
296
                return ERR_PTR(rc);
 
297
        }
 
298
 
 
299
        /* Disable multicast loopback */
 
300
        inet_sk(sk)->mc_loop = 0;
 
301
        INIT_LIST_HEAD(&vs->handler_list);
 
302
        hlist_add_head_rcu(&vs->hlist, vs_head(net, port));
 
303
 
 
304
        /* Mark socket as an encapsulation socket. */
 
305
        udp_sk(sk)->encap_type = 1;
 
306
        udp_sk(sk)->encap_rcv = vxlan_udp_encap_recv;
 
307
        udp_encap_enable();
 
308
 
 
309
        return vs;
 
310
}
 
311
 
 
312
static void rcu_free_vs_callback(struct rcu_head *rcu)
 
313
{
 
314
        struct vxlan_sock *vs = container_of(rcu, struct vxlan_sock, rcu);
 
315
 
 
316
        kfree(vs);
 
317
}
 
318
 
 
319
static void vxlan_socket_del(struct vxlan_sock *vs)
 
320
{
 
321
        if (list_empty(&vs->handler_list)) {
 
322
                hlist_del_rcu(&vs->hlist);
 
323
 
 
324
                sk_release_kernel(vs->sock->sk);
 
325
                call_rcu(&vs->rcu, rcu_free_vs_callback);
 
326
        }
 
327
}
 
328
 
 
329
static int vxlan_init_module(void);
 
330
static void vxlan_cleanup_module(void);
 
331
 
 
332
static void rcu_free_vh_callback(struct rcu_head *rcu)
 
333
{
 
334
        struct vxlan_handler *vh = container_of(rcu, struct vxlan_handler, rcu);
 
335
 
 
336
        kfree(vh);
 
337
}
 
338
 
 
339
static void vh_del_work(struct work_struct *work)
 
340
{
 
341
        struct vxlan_handler *vh = container_of(work, struct vxlan_handler, del_work);
 
342
        struct vxlan_sock *vs = vh->vs;
 
343
        struct net *net = sock_net(vs->sock->sk);
 
344
        struct vxlan_net *vn = net_generic(net, vxlan_net_id);
 
345
 
 
346
        mutex_lock(&vn->sock_lock);
 
347
 
 
348
        list_del_rcu(&vh->node);
 
349
        call_rcu(&vh->rcu, rcu_free_vh_callback);
 
350
        vxlan_socket_del(vs);
 
351
 
 
352
        mutex_unlock(&vn->sock_lock);
 
353
 
 
354
        vxlan_cleanup_module();
 
355
}
 
356
 
 
357
struct vxlan_handler *vxlan_handler_add(struct net *net,
 
358
                                        __be16 portno, vxlan_rcv_t *rcv,
 
359
                                        void *data, int priority, bool create)
 
360
{
 
361
        struct vxlan_net *vn;
 
362
        struct vxlan_sock *vs;
 
363
        struct vxlan_handler *vh;
 
364
        struct vxlan_handler *new;
 
365
        int err;
 
366
 
 
367
        err = vxlan_init_module();
 
368
        if (err)
 
369
                return ERR_PTR(err);
 
370
 
 
371
        vn = net_generic(net, vxlan_net_id);
 
372
        mutex_lock(&vn->sock_lock);
 
373
        /* Look to see if can reuse socket */
 
374
        vs = vxlan_find_port(net, portno);
 
375
        if (!vs) {
 
376
                vs = vxlan_socket_create(net, portno);
 
377
                if (IS_ERR(vs)) {
 
378
                        new = (void *) vs;
 
379
                        goto out;
 
380
                }
 
381
        }
 
382
 
 
383
        /* Try existing vxlan hanlders for this socket. */
 
384
        list_for_each_entry(vh, &vs->handler_list, node) {
 
385
                if (vh->rcv == rcv) {
 
386
                        if (create) {
 
387
                                vxlan_socket_del(vs);
 
388
                                new = ERR_PTR(-EEXIST);
 
389
                                goto out;
 
390
                        }
 
391
                        atomic_inc(&vh->refcnt);
 
392
                        new = vh;
 
393
                        goto out;
 
394
                }
 
395
        }
 
396
 
 
397
        new = kzalloc(sizeof(*new), GFP_KERNEL);
 
398
        if (!new) {
 
399
                vxlan_socket_del(vs);
 
400
                new = ERR_PTR(-ENOMEM);
 
401
                goto out;
 
402
        }
 
403
 
 
404
        new->rcv = rcv;
 
405
        new->vs = vs;
 
406
        atomic_set(&new->refcnt, 1);
 
407
        INIT_WORK(&new->del_work, vh_del_work);
 
408
        new->data = data;
 
409
        new->priority = priority;
 
410
 
 
411
        list_for_each_entry(vh, &vs->handler_list, node) {
 
412
                if (vh->priority > priority) {
 
413
                        list_add_tail_rcu(&new->node, &vh->node);
 
414
                        goto out;
 
415
                }
 
416
        }
 
417
 
 
418
        list_add_tail_rcu(&new->node, &vs->handler_list);
 
419
out:
 
420
        mutex_unlock(&vn->sock_lock);
 
421
        return new;
 
422
}
 
423
 
 
424
void vxlan_handler_put(struct vxlan_handler *vh)
 
425
{
 
426
        BUG_ON(!vh->vs);
 
427
 
 
428
        if (atomic_dec_and_test(&vh->refcnt))
 
429
                queue_work(&vh->del_work);
 
430
}
 
431
 
 
432
static __net_init int vxlan_init_net(struct net *net)
 
433
{
 
434
        struct vxlan_net *vn = net_generic(net, vxlan_net_id);
 
435
        unsigned int h;
 
436
 
 
437
        mutex_init(&vn->sock_lock);
 
438
 
 
439
        for (h = 0; h < PORT_HASH_SIZE; ++h)
 
440
                INIT_HLIST_HEAD(&vn->sock_list[h]);
 
441
 
 
442
        return 0;
 
443
}
 
444
 
 
445
static struct pernet_operations vxlan_net_ops = {
 
446
        .init = vxlan_init_net,
 
447
        .id   = &vxlan_net_id,
 
448
        .size = sizeof(struct vxlan_net),
 
449
};
 
450
 
 
451
static int refcnt;
 
452
static DEFINE_MUTEX(init_lock);
 
453
DEFINE_COMPAT_PNET_REG_FUNC(device);
 
454
 
 
455
static int vxlan_init_module(void)
 
456
{
 
457
        int err = 0;
 
458
 
 
459
        mutex_lock(&init_lock);
 
460
        if (refcnt)
 
461
                goto out;
 
462
        err = register_pernet_device(&vxlan_net_ops);
 
463
out:
 
464
        if (!err)
 
465
                refcnt++;
 
466
        mutex_unlock(&init_lock);
 
467
        return err;
 
468
}
 
469
 
 
470
static void vxlan_cleanup_module(void)
 
471
{
 
472
        mutex_lock(&init_lock);
 
473
        refcnt--;
 
474
        if (refcnt)
 
475
                goto out;
 
476
        unregister_pernet_device(&vxlan_net_ops);
 
477
out:
 
478
        mutex_unlock(&init_lock);
 
479
}