Project

General

Profile

ovs-dev-v1-Basic-GTP-U-tunnel-implementation-in-ovs.patch

ashishbnv, 10/21/2016 10:04 AM

View differences:

datapath/Modules.mk
9 9
	vport_geneve \
10 10
	vport_gre \
11 11
	vport_lisp \
12
	vport_gtp \ /* including gtp virtual port to kernel module */
12 13
	vport_stt \
13 14
	vport_vxlan
14 15
# When changing the name of 'build_modules', please also update the
......
32 33
vport_vxlan_sources = vport-vxlan.c
33 34
vport_gre_sources = vport-gre.c
34 35
vport_lisp_sources = vport-lisp.c
36
vport_gtp_sources = vport-gtp.c /* including the source file to include gtp vport into kernel */
35 37
vport_stt_sources = vport-stt.c
36 38

  
37 39
openvswitch_headers = \
datapath/linux/Modules.mk
14 14
	linux/compat/ip_tunnels_core.c \
15 15
	linux/compat/ip6_output.c \
16 16
	linux/compat/lisp.c \
17
	linux/compat/gtp.c \ /* Did not understand why it is included here also */
17 18
	linux/compat/netdevice.c \
18 19
	linux/compat/net_namespace.c \
19 20
	linux/compat/nf_conntrack_core.c \
......
51 52
	linux/compat/include/linux/kconfig.h \
52 53
	linux/compat/include/linux/kernel.h \
53 54
	linux/compat/include/net/lisp.h \
55
	linux/compat/include/net/gtp.h \ /* including the necessary header files */
54 56
	linux/compat/include/linux/list.h \
55 57
	linux/compat/include/linux/mpls.h \
56 58
	linux/compat/include/linux/net.h \
datapath/linux/compat/gtp.c
1
/*
2
 * Copyright (c) 2015 Nicira, Inc.
3
 * Copyright (c) 2013 Cisco Systems, Inc.
4
 *
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.
8
 *
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.
13
 *
14
 */
15

  
16
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17

  
18
#include <linux/version.h>
19

  
20
#include <linux/in.h>
21
#include <linux/ip.h>
22
#include <linux/net.h>
23
#include <linux/module.h>
24
#include <linux/rculist.h>
25
#include <linux/udp.h>
26

  
27
#include <net/icmp.h>
28
#include <net/ip.h>
29
#include <net/gtp.h>
30
#include <net/net_namespace.h>
31
#include <net/netns/generic.h>
32
#include <net/route.h>
33
#include <net/udp.h>
34
#include <net/udp_tunnel.h>
35
#include <net/xfrm.h>
36

  
37
#include "datapath.h"
38
#include "gso.h"
39
#include "vport.h"
40
#include "gso.h"
41
#include "vport-netdev.h"
42

  
43
#define GTP_UDP_PORT		2152
44
#define GTP_NETDEV_VER		"0.1"
45
static int gtp_net_id;
46

  
47
/* Pseudo network device */
48
struct gtp_dev {
49
    struct net         *net;        /* netns for packet i/o */
50
    struct net_device  *dev;        /* netdev for gtp tunnel */
51
    struct socket      *sock;
52
    __be16             dst_port;
53
    struct list_head   next;  /*pointer to another gtp_dev */
54
};
55

  
56
/* per-network namespace private data for this module */
57
struct gtp_net {
58
    struct list_head gtp_list;/*pointer to another gtp_net */
59
};
60

  
61
/*
62
 *  GTP encapsulation header:
63
 *
64
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
65
 *  |  V  |P|R|E|S|N|  Message Type |        Total Length           |
66
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
67
 *  |                           TEID                                |
68
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
69
 *  |      Sequence Number          | N-PDU Number  | Next Extension|
70
 *  |                               |               |  Header type  |
71
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
72
 *
73
 * Extension Header:
74
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
75
 *  |  Total length |                 Contents                      |
76
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77
 *  |                          Contents                             |
78
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
79
 *  |                   Contents                  | Next Extntn hdr |
80
 *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
81
 */
82

  
83
/**
84
 * struct gtphdr - GTP header:
85
 *
86
 * @version(V): 3-bit field. For GTPv1, this has a value of 1.
87
 * @protocol_type(P): a 1-bit value that differentiates GTP (value 1) from
88
 *                    GTP' (value 0).
89
 * @reserved(R): a 1-bit reserved field (must be 0).
90
 * @extension_header_flag(E): a 1-bit value that states whether there is an
91
 *                            extension header optional field.
92
 * @sequence_number_flag(S): a 1-bit value that states whether there is a
93
 *                           Sequence Number optional field.
94
 * @n_pdu_number_flag(N): a 1-bit value that states whether there is a N-PDU
95
 *                        number optional field.
96
 * @message_type: an 8-bit field that indicates the type of GTP message.
97
 * @total_length: a 16-bit field that indicates the length of the payload in
98
 *                bytes (rest of the packet following the mandatory 8-byte GTP
99
 *                header). Includes the optional fields.
100
 * @teid: A 32-bit(4-octet) field used to multiplex different connections in
101
          the same GTP tunnel.
102
 * @sequence_number: an (optional) 16-bit field. This field exists if any of the
103
 *                   E, S, or PN bits are on. The field must be interpreted only
104
 *                   if the S bit is on.
105
 * @n_pdu_number: an (optional) 8-bit field. This field exists if any of the E,
106
 *                S, or PN bits are on. The field must be interpreted only if
107
 *                the PN bit is on.
108
 * @next_extension_header_type: an (optional) 8-bit field. This field exists if
109
 *                              any of the E, S, or PN bits are on. The field
110
 *                              must be interpreted only if the E bit is on.
111
 *
112
 * Extenstion header:
113
 * @length: an 8-bit field. This field states the length of this extension
114
 *          header, including the length, the contents, and the next extension
115
 *          header field, in 4-octet units, so the length of the extension must
116
 *          always be a multiple of 4.
117
 * @contents: extension header contents.
118
 * @next_extension_header: an 8-bit field. It states the type of the next
119
 *                         extension, or 0 if no next extension exists. This
120
 *                         permits chaining several next extension headers.
121
 */
122

  
123
struct gtp_extension_hdr {
124
    u8 length;
125
    u8 next_extension_hdr_type;
126
    u8 extension_data[];
127
};
128

  
129
struct gtphdr {
130
#ifdef __LITTLE_ENDIAN_BITFIELD
131
    __u8 n_pdu_number_flag:1;
132
    __u8 sequence_hdr_flag:1;
133
    __u8 extension_hdr_flag:1;
134
    __u8 reserved:1;
135
    __u8 protocol_type:1;
136
    __u8 version:2;
137
#else
138
    __u8 version:2;
139
    __u8 protocol_type:1;
140
    __u8 reserved:1;
141
    __u8 extension_hdr_flag:1;
142
    __u8 sequence_hdr_flag:1;
143
    __u8 n_pdu_number_flag:1;
144
#endif
145
    __u8 message_type;
146
    __be16 total_length;
147
    __be32 teid;
148
    struct gtp_extension_hdr extensions[];
149
};
150

  
151
#define GTP_HLEN (sizeof(struct udphdr) + sizeof(struct gtphdr))
152

  
153
static inline struct gtphdr *gtp_hdr(const struct sk_buff *skb)
154
{
155
    return (struct gtphdr *)(udp_hdr(skb) + 1); /* Did not understand this command and also the struct declaration */
156
}
157

  
158
/* Compute source UDP port for outgoing packet.
159
 * Currently we use the flow hash.
160
 */
161
static u16 get_src_port(struct net *net, struct sk_buff *skb)
162
{
163
    u32 hash = skb_get_hash(skb);
164
    unsigned int range;
165
    int high;/* Not defined any value */
166
    int low;/* Not defined any value */
167

  
168
    if (!hash) {
169
        if (skb->protocol == htons(ETH_P_IP)) {
170
            struct iphdr *iph;
171
            int size = (sizeof(iph->saddr) * 2) / sizeof(u32);
172

  
173
            iph = (struct iphdr *) skb_network_header(skb); /* Did not understand */
174
            hash = jhash2((const u32 *)&iph->saddr, size, 0); /* Did not understand */
175
        } else if (skb->protocol == htons(ETH_P_IPV6)) {
176
            struct ipv6hdr *ipv6hdr;
177

  
178
            ipv6hdr = (struct ipv6hdr *) skb_network_header(skb);
179
            hash = jhash2((const u32 *)&ipv6hdr->saddr,
180
                          (sizeof(struct in6_addr) * 2) / sizeof(u32), 0); /* Did not understand */
181
        } else {
182
            pr_warn_once("GTP inner protocol is not IP when "
183
                         "calculating hash.\n");
184
        }
185
    }
186

  
187
    inet_get_local_port_range(net, &low, &high);
188
    range = (high - low) + 1;
189
    return (((u64) hash * range) >> 32) + low; /* Did not understand */
190
}
191

  
192
static void gtp_build_header(struct sk_buff *skb,
193
                             const struct ip_tunnel_key *tun_key)
194
{
195
    struct gtphdr *gtph;
196

  
197
    gtph = (struct gtphdr *)__skb_push(skb, sizeof(struct gtphdr)); /* Did not understand */
198
    gtph->version = 1;       /* GTP-U version 1 */
199
    gtph->protocol_type = 1; /* GTP Protocol */
200
    gtph->reserved = 0;    /* Reserved flags, set to 0  */
201
    gtph->extension_hdr_flag = 0; /* No extension header present */
202
    gtph->sequence_hdr_flag = 0; /* No Sequence No. present  */
203
    gtph->n_pdu_number_flag = 0;      /* No N PDU present */
204
    gtph->message_type = 255; /* GPDU Packets */
205
    /* mandatory part of GTP header first 8 octets */
206
    gtph->total_length = htons(skb->len) - htons(sizeof(struct gtphdr));
207
    gtph->teid = htonl(be64_to_cpu(tun_key->tun_id));
208
}
209

  
210
/* Called with rcu_read_lock and BH disabled. */
211
static int gtp_rcv(struct sock *sk, struct sk_buff *skb)
212
{
213
    struct net_device *dev;
214
    struct gtphdr *gtph;
215
    struct iphdr *inner_iph;
216
    struct metadata_dst *tun_dst;
217
#ifndef HAVE_METADATA_DST
218
    struct metadata_dst temp;
219
#endif
220
    __be64 key;
221
    struct ethhdr *ethh;
222
    __be16 protocol;
223

  
224
    dev = rcu_dereference_sk_user_data(sk);
225
    if (unlikely(!dev))
226
        goto error;
227

  
228
    if (iptunnel_pull_header(skb, GTP_HLEN, 0)) /* Did not understand */
229
        goto error;
230

  
231
    gtph = gtp_hdr(skb);
232

  
233
    key = cpu_to_be64(ntohl(gtph->teid));
234

  
235
    /* Save outer tunnel values */
236
#ifndef HAVE_METADATA_DST
237
    tun_dst = &temp;
238
    ovs_udp_tun_rx_dst(&tun_dst->u.tun_info, skb, AF_INET, TUNNEL_KEY, key, 0); /* Did not understand */
239
#else
240
    tun_dst = udp_tun_rx_dst(skb, AF_INET, TUNNEL_KEY, key, 0);
241
#endif
242
    /* Drop non-IP inner packets */
243
    inner_iph = (struct iphdr *)(gtph + 1);
244
    switch (inner_iph->version) {
245
    case 4:
246
        protocol = htons(ETH_P_IP);
247
        break;
248
    case 6:
249
        protocol = htons(ETH_P_IPV6);
250
        break;
251
    default:
252
        goto error;
253
    }
254
    skb->protocol = protocol;
255

  
256
    /* Add Ethernet header */
257
    ethh = (struct ethhdr *)skb_push(skb, ETH_HLEN); /* Did not understand */
258
    memset(ethh, 0, ETH_HLEN);
259
    ethh->h_dest[0] = 0x06;
260
    ethh->h_source[0] = 0x06;
261
    ethh->h_proto = protocol;
262

  
263
    ovs_ip_tunnel_rcv(dev, skb, tun_dst);
264
    goto out;
265

  
266
error:
267
    kfree_skb(skb);
268
out:
269
    return 0;
270
}
271

  
272
netdev_tx_t rpl_gtp_xmit(struct sk_buff *skb)
273
{
274
    struct net_device *dev = skb->dev;
275
    struct gtp_dev *gtp_dev = netdev_priv(dev);
276
    struct net *net = gtp_dev->net;
277
    int network_offset = skb_network_offset(skb);
278
    struct ip_tunnel_info *info;
279
    struct ip_tunnel_key *tun_key;
280
    struct rtable *rt;
281
    int min_headroom;
282
    __be16 src_port, dst_port;
283
    struct flowi4 fl;
284
    __be16 df;
285
    int err;
286

  
287
    info = skb_tunnel_info(skb);
288
    if (unlikely(!info)) {
289
        err = -EINVAL;
290
        goto error;
291
    }
292

  
293
    if (skb->protocol != htons(ETH_P_IP) &&
294
        skb->protocol != htons(ETH_P_IPV6)) {
295
        err = 0;
296
        goto error;
297
    }
298

  
299
    tun_key = &info->key;
300

  
301
    /* Route lookup */
302
    memset(&fl, 0, sizeof(fl));
303
    fl.daddr = tun_key->u.ipv4.dst;
304
    fl.saddr = tun_key->u.ipv4.src;
305
    fl.flowi4_tos = RT_TOS(tun_key->tos);
306
    fl.flowi4_mark = skb->mark;
307
    fl.flowi4_proto = IPPROTO_UDP;
308
    rt = ip_route_output_key(net, &fl);
309
    if (IS_ERR(rt)) {
310
        err = PTR_ERR(rt);
311
        goto error;
312
    }
313

  
314
    min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
315
                   + sizeof(struct iphdr) + GTP_HLEN;
316

  
317
    if (skb_headroom(skb) < min_headroom || skb_header_cloned(skb)) {
318
        int head_delta = SKB_DATA_ALIGN(min_headroom -
319
                                        skb_headroom(skb) + 16);
320

  
321
        err = pskb_expand_head(skb, max_t(int, head_delta, 0),
322
                               0, GFP_ATOMIC);
323
        if (unlikely(err))
324
            goto err_free_rt;
325
    }
326

  
327
    /* Reset l2 headers. */
328
    skb_pull(skb, network_offset);
329
    skb_reset_mac_header(skb);
330
    vlan_set_tci(skb, 0);
331

  
332
    skb = udp_tunnel_handle_offloads(skb, false, 0, false);
333
    if (IS_ERR(skb)) {
334
        err = PTR_ERR(skb);
335
        skb = NULL;
336
        goto err_free_rt;
337
    }
338

  
339
    src_port = htons(get_src_port(net, skb));
340
    dst_port = gtp_dev->dst_port;
341

  
342
    gtp_build_header(skb, tun_key);
343

  
344
    skb->ignore_df = 1;
345

  
346
    ovs_skb_set_inner_protocol(skb, skb->protocol);
347

  
348
    df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
349
    err = udp_tunnel_xmit_skb(rt, gtp_dev->sock->sk, skb,
350
                              fl.saddr, tun_key->u.ipv4.dst,
351
                              tun_key->tos, tun_key->ttl,
352
                              df, src_port, dst_port, false, true);
353

  
354
    iptunnel_xmit_stats(err, &dev->stats,
355
                       (struct pcpu_sw_netstats __percpu *)dev->tstats);
356
    return NETDEV_TX_OK;
357

  
358
err_free_rt:
359
    ip_rt_put(rt);
360
error:
361
    kfree_skb(skb);
362
    return NETDEV_TX_OK;
363
}
364
EXPORT_SYMBOL(rpl_gtp_xmit);
365

  
366
#ifdef HAVE_DEV_TSTATS
367
/* Setup stats when device is created */
368
static int gtp_init(struct net_device *dev)
369
{
370
    dev->tstats = (typeof(dev->tstats))
371
                  netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
372
    if (!dev->tstats)
373
        return -ENOMEM;
374

  
375
    return 0;
376
}
377

  
378
static void gtp_uninit(struct net_device *dev)
379
{
380
    free_percpu(dev->tstats);
381
}
382
#endif
383

  
384
static struct socket *create_sock(struct net *net, bool ipv6,
385
                                  __be16 port)
386
{
387
    struct socket *sock;
388
    struct udp_port_cfg udp_conf;
389
    int err;
390

  
391
    memset(&udp_conf, 0, sizeof(udp_conf));
392

  
393
    if (ipv6) {
394
        udp_conf.family = AF_INET6;
395
    } else {
396
        udp_conf.family = AF_INET;
397
        udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
398
    }
399

  
400
    udp_conf.local_udp_port = port;
401

  
402
    /* Open UDP socket */
403
    err = udp_sock_create(net, &udp_conf, &sock);
404
    if (err < 0)
405
        return ERR_PTR(err);
406

  
407
    return sock;
408
}
409

  
410
static int gtp_open(struct net_device *dev)
411
{
412
    struct gtp_dev *gtp = netdev_priv(dev);
413
    struct udp_tunnel_sock_cfg tunnel_cfg;
414
    struct net *net = gtp->net;
415

  
416
    gtp->sock = create_sock(net, false, gtp->dst_port);
417
    if (IS_ERR(gtp->sock))
418
        return PTR_ERR(gtp->sock);
419

  
420
    /* Mark socket as an encapsulation socket */
421
    tunnel_cfg.sk_user_data = dev;
422
    tunnel_cfg.encap_type = 1;
423
    tunnel_cfg.encap_rcv = gtp_rcv;
424
    tunnel_cfg.encap_destroy = NULL;
425
    setup_udp_tunnel_sock(net, gtp->sock, &tunnel_cfg);
426
    return 0;
427
}
428

  
429
static int gtp_stop(struct net_device *dev)
430
{
431
    struct gtp_dev *gtp = netdev_priv(dev);
432

  
433
    udp_tunnel_sock_release(gtp->sock);
434
    gtp->sock = NULL;
435
    return 0;
436
}
437

  
438
static netdev_tx_t gtp_dev_xmit(struct sk_buff *skb, struct net_device *dev)
439
{
440
#ifdef HAVE_METADATA_DST
441
    return rpl_gtp_xmit(skb);
442
#else
443
    /* Drop All packets coming from networking stack. OVS-CB is
444
     * not initialized for these packets.
445
     */
446

  
447
    dev_kfree_skb(skb);
448
    dev->stats.tx_dropped++;
449
    return NETDEV_TX_OK;
450
#endif
451
}
452

  
453
static const struct net_device_ops gtp_netdev_ops = {
454
#ifdef HAVE_DEV_TSTATS
455
    .ndo_init               = gtp_init,
456
    .ndo_uninit             = gtp_uninit,
457
    .ndo_get_stats64        = ip_tunnel_get_stats64,
458
#endif
459
    .ndo_open               = gtp_open,
460
    .ndo_stop               = gtp_stop,
461
    .ndo_start_xmit         = gtp_dev_xmit,
462
    .ndo_change_mtu         = eth_change_mtu,
463
    .ndo_validate_addr      = eth_validate_addr,
464
    .ndo_set_mac_address    = eth_mac_addr,
465
};
466

  
467
static void gtp_get_drvinfo(struct net_device *dev,
468
                            struct ethtool_drvinfo *drvinfo)
469
{
470
    strlcpy(drvinfo->version, GTP_NETDEV_VER, sizeof(drvinfo->version));
471
    strlcpy(drvinfo->driver, "gtp", sizeof(drvinfo->driver));
472
}
473

  
474
static const struct ethtool_ops gtp_ethtool_ops = {
475
    .get_drvinfo    = gtp_get_drvinfo,
476
    .get_link       = ethtool_op_get_link,
477
};
478

  
479
/* Info for udev, that this is a virtual tunnel endpoint */
480
static struct device_type gtp_type = {
481
    .name = "gtp",
482
};
483

  
484
/* Initialize the device structure. */
485
static void gtp_setup(struct net_device *dev)
486
{
487
    ether_setup(dev);
488

  
489
    dev->netdev_ops = &gtp_netdev_ops;
490
    dev->ethtool_ops = &gtp_ethtool_ops;
491
    dev->destructor = free_netdev;
492

  
493
    SET_NETDEV_DEVTYPE(dev, &gtp_type);
494

  
495
    dev->features    |= NETIF_F_LLTX | NETIF_F_NETNS_LOCAL;
496
    dev->features    |= NETIF_F_SG | NETIF_F_HW_CSUM;
497
    dev->features    |= NETIF_F_RXCSUM;
498
    dev->features    |= NETIF_F_GSO_SOFTWARE;
499

  
500
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
501
    dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
502
    dev->hw_features |= NETIF_F_GSO_SOFTWARE;
503
#endif
504
#ifdef HAVE_METADATA_DST
505
    netif_keep_dst(dev);
506
#endif
507
    dev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_NO_QUEUE;
508
    eth_hw_addr_random(dev);
509
}
510

  
511
static const struct nla_policy gtp_policy[IFLA_GTP_MAX + 1] = {
512
    [IFLA_GTP_PORT] = { .type = NLA_U16 },
513
};
514

  
515
static int gtp_validate(struct nlattr *tb[], struct nlattr *data[])
516
{
517
    if (tb[IFLA_ADDRESS]) {
518
        if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
519
            return -EINVAL;
520

  
521
        if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
522
            return -EADDRNOTAVAIL;
523
    }
524

  
525
    return 0;
526
}
527

  
528
static struct gtp_dev *find_dev(struct net *net, __be16 dst_port)
529
{
530
    struct gtp_net *ln = net_generic(net, gtp_net_id);
531
    struct gtp_dev *dev;
532

  
533
    list_for_each_entry(dev, &ln->gtp_list, next) {
534
        if (dev->dst_port == dst_port)
535
            return dev;
536
    }
537
    return NULL;
538
}
539

  
540
static int gtp_configure(struct net *net, struct net_device *dev,
541
			  __be16 dst_port)
542
{
543
    struct gtp_net *ln = net_generic(net, gtp_net_id);
544
    struct gtp_dev *gtp = netdev_priv(dev);
545
    int err;
546

  
547
    gtp->net = net;
548
    gtp->dev = dev;
549

  
550
    gtp->dst_port = dst_port;
551

  
552
    if (find_dev(net, dst_port))
553
        return -EBUSY;
554

  
555
    err = register_netdevice(dev);
556
    if (err)
557
        return err;
558

  
559
    list_add(&gtp->next, &ln->gtp_list);
560
    return 0;
561
}
562

  
563
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
564
static int gtp_newlink(struct net *net, struct net_device *dev,
565
                       struct nlattr *tb[], struct nlattr *data[])
566
{
567
#else
568
static int gtp_newlink(struct net_device *dev,
569
                       struct nlattr *tb[], struct nlattr *data[])
570

  
571
{
572
    struct net *net = &init_net;
573
#endif
574
    __be16 dst_port = htons(GTP_UDP_PORT);
575

  
576
    if (data[IFLA_GTP_PORT])
577
        dst_port = nla_get_be16(data[IFLA_GTP_PORT]);
578

  
579
    return gtp_configure(net, dev, dst_port);
580
}
581

  
582
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
583
static void gtp_dellink(struct net_device *dev, struct list_head *head)
584
#else
585
static void gtp_dellink(struct net_device *dev)
586
#endif
587
{
588
    struct gtp_dev *gtp = netdev_priv(dev);
589

  
590
    list_del(&gtp->next);
591
    unregister_netdevice_queue(dev, head);
592
}
593

  
594
static size_t gtp_get_size(const struct net_device *dev)
595
{
596
    return nla_total_size(sizeof(__be32));  /* IFLA_GTP_PORT */
597
}
598

  
599
static int gtp_fill_info(struct sk_buff *skb, const struct net_device *dev)
600
{
601
    struct gtp_dev *gtp = netdev_priv(dev);
602

  
603
    if (nla_put_be16(skb, IFLA_GTP_PORT, gtp->dst_port))
604
        goto nla_put_failure;
605

  
606
    return 0;
607

  
608
nla_put_failure:
609
    return -EMSGSIZE;
610
}
611

  
612
static struct rtnl_link_ops gtp_link_ops __read_mostly = {
613
    .kind           = "gtp",
614
    .maxtype        = IFLA_GTP_MAX,
615
    .policy         = gtp_policy,
616
    .priv_size      = sizeof(struct gtp_dev),
617
    .setup          = gtp_setup,
618
    .validate       = gtp_validate,
619
    .newlink        = gtp_newlink,
620
    .dellink        = gtp_dellink,
621
    .get_size       = gtp_get_size,
622
    .fill_info      = gtp_fill_info,
623
};
624

  
625
struct net_device *rpl_gtp_dev_create_fb(struct net *net, const char *name,
626
                                         u8 name_assign_type, u16 dst_port)
627
{
628
    struct nlattr *tb[IFLA_MAX + 1];
629
    struct net_device *dev;
630
    int err;
631

  
632
    memset(tb, 0, sizeof(tb));
633
    dev = rtnl_create_link(net, (char *) name, name_assign_type,
634
                           &gtp_link_ops, tb);
635
    if (IS_ERR(dev))
636
        return dev;
637

  
638
    err = gtp_configure(net, dev, htons(dst_port));
639
    if (err) {
640
        free_netdev(dev);
641
        return ERR_PTR(err);
642
    }
643
    return dev;
644
}
645
EXPORT_SYMBOL_GPL(rpl_gtp_dev_create_fb);
646

  
647
static int gtp_init_net(struct net *net)
648
{
649
    struct gtp_net *ln = net_generic(net, gtp_net_id);
650

  
651
    INIT_LIST_HEAD(&ln->gtp_list);
652
    return 0;
653
}
654

  
655
static void gtp_exit_net(struct net *net)
656
{
657
    struct gtp_net *ln = net_generic(net, gtp_net_id);
658
    struct gtp_dev *gtp, *next;
659
    struct net_device *dev, *aux;
660
    LIST_HEAD(list);
661

  
662
    rtnl_lock();
663

  
664
    /* gather any gtp devices that were moved into this ns */
665
    for_each_netdev_safe(net, dev, aux)
666
    if (dev->rtnl_link_ops == &gtp_link_ops)
667
        unregister_netdevice_queue(dev, &list);
668

  
669
    list_for_each_entry_safe(gtp, next, &ln->gtp_list, next) {
670
        /* If gtp->dev is in the same netns, it was already added
671
         * to the gtp by the previous loop.
672
         */
673
        if (!net_eq(dev_net(gtp->dev), net))
674
            unregister_netdevice_queue(gtp->dev, &list);
675
    }
676

  
677
    /* unregister the devices gathered above */
678
    unregister_netdevice_many(&list);
679
    rtnl_unlock();
680
}
681

  
682
static struct pernet_operations gtp_net_ops = {
683
    .init = gtp_init_net,
684
    .exit = gtp_exit_net,
685
    .id   = &gtp_net_id,
686
    .size = sizeof(struct gtp_net),
687
};
688

  
689
DEFINE_COMPAT_PNET_REG_FUNC(device)
690
int rpl_gtp_init_module(void)
691
{
692
    int rc;
693

  
694
    rc = register_pernet_subsys(&gtp_net_ops);
695
    if (rc)
696
        goto out1;
697

  
698
    rc = rtnl_link_register(&gtp_link_ops);
699
    if (rc)
700
        goto out2;
701

  
702
    pr_info("GTP tunneling driver\n");
703
    return 0;
704
out2:
705
    unregister_pernet_subsys(&gtp_net_ops);
706
out1:
707
    return rc;
708
}
709

  
710
void rpl_gtp_cleanup_module(void)
711
{
712
    rtnl_link_unregister(&gtp_link_ops);
713
    unregister_pernet_subsys(&gtp_net_ops);
714
}
datapath/linux/compat/include/linux/if_link.h
46 46
};
47 47
#define IFLA_LISP_MAX	(__IFLA_LISP_MAX - 1)
48 48

  
49
/* GTP section */
50
enum {
51
	IFLA_GTP_PORT,	/* destination port */
52
	__IFLA_GTP_MAX
53
};
54
#define IFLA_GTP_MAX	(__IFLA_GTP_MAX - 1)
55

  
49 56
/* VXLAN section */
50 57
enum {
51 58
#define IFLA_VXLAN_UNSPEC rpl_IFLA_VXLAN_UNSPEC
datapath/linux/compat/include/linux/openvswitch.h
235 235
	OVS_VPORT_TYPE_GENEVE,	 /* Geneve tunnel. */
236 236
	OVS_VPORT_TYPE_LISP = 105,  /* LISP tunnel */
237 237
	OVS_VPORT_TYPE_STT = 106, /* STT tunnel */
238
	OVS_VPORT_TYPE_GTP = 107,  /* GTP tunnel */
238 239
	__OVS_VPORT_TYPE_MAX
239 240
};
240 241

  
datapath/linux/compat/include/net/gtp.h
1
#ifndef __NET_GTP_WRAPPER_H
2
#define __NET_GTP_WRAPPER_H  1
3

  
4
#ifdef CONFIG_INET
5
#include <net/udp_tunnel.h>
6
#endif
7

  
8

  
9
#ifdef CONFIG_INET
10
#define gtp_dev_create_fb rpl_gtp_dev_create_fb
11
struct net_device *rpl_gtp_dev_create_fb(struct net *net, const char *name,
12
                                         u8 name_assign_type, u16 dst_port);
13
#endif /*ifdef CONFIG_INET */
14

  
15
#define gtp_init_module rpl_gtp_init_module
16
int rpl_gtp_init_module(void);
17

  
18
#define gtp_cleanup_module rpl_gtp_cleanup_module
19
void rpl_gtp_cleanup_module(void);
20

  
21
#define gtp_xmit rpl_gtp_xmit
22
netdev_tx_t rpl_gtp_xmit(struct sk_buff *skb);
23

  
24
#endif /*ifdef__NET_GTP_H */
datapath/vport-gtp.c
1
/*
2
 * Copyright (c) 2015 Nicira, Inc.
3
 *
4
 * This program is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU General Public License
6
 * as published by the Free Software Foundation; either version
7
 * 2 of the License, or (at your option) any later version.
8
 */
9

  
10
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11

  
12
#include <linux/in.h>
13
#include <linux/ip.h>
14
#include <linux/net.h>
15
#include <linux/rculist.h>
16
#include <linux/udp.h>
17
#include <linux/if_vlan.h>
18
#include <linux/module.h>
19

  
20
#include <net/gtp.h>
21
#include <net/icmp.h>
22
#include <net/ip.h>
23
#include <net/route.h>
24
#include <net/udp.h>
25
#include <net/xfrm.h>
26

  
27
#include "datapath.h"
28
#include "vport.h"
29
#include "vport-netdev.h"
30

  
31
static struct vport_ops ovs_gtp_vport_ops;
32
/**
33
 * struct gtp_port - Keeps track of open UDP ports
34
 * @dst_port: destination port.
35
 */
36
struct gtp_port {
37
    u16 port_no;
38
};
39

  
40
static inline struct gtp_port *gtp_vport(const struct vport *vport)
41
{
42
    return vport_priv(vport);
43
}
44

  
45
static int gtp_get_options(const struct vport *vport,
46
                           struct sk_buff *skb)
47
{
48
    struct gtp_port *gtp_port = gtp_vport(vport);
49

  
50
    if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, gtp_port->port_no))
51
        return -EMSGSIZE;
52
    return 0;
53
}
54

  
55
static int gtp_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
56
                                   struct dp_upcall_info *upcall)
57
{
58
    struct gtp_port *gtp_port = gtp_vport(vport);
59
    struct net *net = ovs_dp_get_net(vport->dp);
60
    __be16 dport = htons(gtp_port->port_no);
61
    __be16 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true);
62

  
63
    return ovs_tunnel_get_egress_info(upcall, ovs_dp_get_net(vport->dp),
64
                                      skb, IPPROTO_UDP, sport, dport);
65
}
66

  
67
static struct vport *gtp_tnl_create(const struct vport_parms *parms)
68
{
69
    struct net *net = ovs_dp_get_net(parms->dp);
70
    struct nlattr *options = parms->options;
71
    struct gtp_port *gtp_port;
72
    struct net_device *dev;
73
    struct vport *vport;
74
    struct nlattr *a;
75
    u16 dst_port;
76
    int err;
77

  
78
    if (!options) {
79
        err = -EINVAL;
80
        goto error;
81
    }
82

  
83
    a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT);
84
    if (a && nla_len(a) == sizeof(u16)) {
85
        dst_port = nla_get_u16(a);
86
    } else {
87
        /* Require destination port from userspace. */
88
        err = -EINVAL;
89
        goto error;
90
    }
91

  
92
    vport = ovs_vport_alloc(sizeof(struct gtp_port),
93
                            &ovs_gtp_vport_ops, parms);
94
    if (IS_ERR(vport))
95
        return vport;
96

  
97
    gtp_port = gtp_vport(vport);
98
    gtp_port->port_no = dst_port;
99

  
100
    rtnl_lock();
101
    dev = gtp_dev_create_fb(net, parms->name, NET_NAME_USER, dst_port);
102
    if (IS_ERR(dev)) {
103
        rtnl_unlock();
104
        ovs_vport_free(vport);
105
        return ERR_CAST(dev);
106
    }
107

  
108
    dev_change_flags(dev, dev->flags | IFF_UP);
109
    rtnl_unlock();
110
    return vport;
111
error:
112
    return ERR_PTR(err);
113
}
114

  
115
static struct vport *gtp_create(const struct vport_parms *parms)
116
{
117
    struct vport *vport;
118

  
119
    vport = gtp_tnl_create(parms);
120
    if (IS_ERR(vport))
121
        return vport;
122

  
123
    return ovs_netdev_link(vport, parms->name);
124
}
125

  
126
static struct vport_ops ovs_gtp_vport_ops = {
127
    .type                = OVS_VPORT_TYPE_GTP,
128
    .create              = gtp_create,
129
    .destroy             = ovs_netdev_tunnel_destroy,
130
    .get_options         = gtp_get_options,
131
    .send                = gtp_xmit,
132
    .get_egress_tun_info = gtp_get_egress_tun_info,
133
};
134

  
135
static int __init ovs_gtp_tnl_init(void)
136
{
137
    return ovs_vport_ops_register(&ovs_gtp_vport_ops);
138
}
139

  
140
static void __exit ovs_gtp_tnl_exit(void)
141
{
142
    ovs_vport_ops_unregister(&ovs_gtp_vport_ops);
143
}
144

  
145
module_init(ovs_gtp_tnl_init);
146
module_exit(ovs_gtp_tnl_exit);
147

  
148
MODULE_DESCRIPTION("OVS: Gtp switching port");
149
MODULE_LICENSE("GPL");
150
MODULE_ALIAS("vport-type-107");
datapath/vport.c
31 31
#include <linux/if_link.h>
32 32
#include <net/net_namespace.h>
33 33
#include <net/lisp.h>
34
#include <net/gtp.h>
34 35
#include <net/gre.h>
35 36
#include <net/geneve.h>
36 37
#include <net/vxlan.h>
......
64 65
	err = lisp_init_module();
65 66
	if (err)
66 67
		goto err_lisp;
68
	err = gtp_init_module();
69
	if (err)
70
		goto err_gtp;
67 71
	err = ipgre_init();
68 72
	if (err)
69 73
		goto err_gre;
......
86 90
err_geneve:
87 91
	ipgre_fini();
88 92
err_gre:
93
	gtp_cleanup_module();
94
err_gtp:
89 95
	lisp_cleanup_module();
90 96
err_lisp:
91 97
	kfree(dev_table);
......
103 109
	vxlan_cleanup_module();
104 110
	geneve_cleanup_module();
105 111
	ipgre_fini();
112
	gtp_cleanup_module();
106 113
	lisp_cleanup_module();
107 114
	kfree(dev_table);
108 115
}
lib/dpif-netlink.c
766 766
    case OVS_VPORT_TYPE_LISP:
767 767
        return "lisp";
768 768

  
769
    case OVS_VPORT_TYPE_GTP:
770
        return "gtp";
771

  
769 772
    case OVS_VPORT_TYPE_STT:
770 773
        return "stt";
771 774

  
......
798 801
        return OVS_VPORT_TYPE_VXLAN;
799 802
    } else if (!strcmp(type, "lisp")) {
800 803
        return OVS_VPORT_TYPE_LISP;
804
    } else if (!strcmp(type, "gtp")) {
805
        return OVS_VPORT_TYPE_GTP;
801 806
    } else {
802 807
        return OVS_VPORT_TYPE_UNSPEC;
803 808
    }
lib/netdev-vport.c
56 56
#define GENEVE_DST_PORT 6081
57 57
#define VXLAN_DST_PORT 4789
58 58
#define LISP_DST_PORT 4341
59
#define GTP_DST_PORT 2152
59 60
#define STT_DST_PORT 7471
60 61

  
61 62
#define VXLAN_HLEN   (sizeof(struct udp_header) +         \
......
156 157

  
157 158
    return (class->get_config == get_tunnel_config &&
158 159
            (!strcmp("geneve", type) || !strcmp("vxlan", type) ||
159
             !strcmp("lisp", type) || !strcmp("stt", type)) );
160
             !strcmp("lisp", type) || !strcmp("gtp", type) ||
161
             !strcmp("stt", type)) );
160 162
}
161 163

  
162 164
const char *
......
255 257
        dev->tnl_cfg.dst_port = htons(VXLAN_DST_PORT);
256 258
    } else if (!strcmp(type, "lisp")) {
257 259
        dev->tnl_cfg.dst_port = htons(LISP_DST_PORT);
260
    } else if (!strcmp(type, "gtp")) {
261
        dev->tnl_cfg.dst_port = htons(GTP_DST_PORT);
258 262
    } else if (!strcmp(type, "stt")) {
259 263
        dev->tnl_cfg.dst_port = htons(STT_DST_PORT);
260 264
    }
......
481 485
        tnl_cfg.dst_port = htons(LISP_DST_PORT);
482 486
    }
483 487

  
488
    if (!strcmp(type, "gtp")) {
489
        tnl_cfg.dst_port = htons(GTP_DST_PORT);
490
    }
491

  
484 492
    if (!strcmp(type, "stt")) {
485 493
        tnl_cfg.dst_port = htons(STT_DST_PORT);
486 494
    }
......
728 736
        if ((!strcmp("geneve", type) && dst_port != GENEVE_DST_PORT) ||
729 737
            (!strcmp("vxlan", type) && dst_port != VXLAN_DST_PORT) ||
730 738
            (!strcmp("lisp", type) && dst_port != LISP_DST_PORT) ||
739
            (!strcmp("gtp", type) && dst_port != GTP_DST_PORT) ||
731 740
            (!strcmp("stt", type) && dst_port != STT_DST_PORT)) {
732 741
            smap_add_format(args, "dst_port", "%d", dst_port);
733 742
        }
......
1563 1572
                                           push_udp_header,
1564 1573
                                           netdev_vxlan_pop_header),
1565 1574
        TUNNEL_CLASS("lisp", "lisp_sys", NULL, NULL, NULL),
1575
        TUNNEL_CLASS("gtp", "gtp_sys", NULL, NULL, NULL),
1566 1576
        TUNNEL_CLASS("stt", "stt_sys", NULL, NULL, NULL),
1567 1577
    };
1568 1578
    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
ofproto/ofproto-dpif-ipfix.c
71 71
    DPIF_IPFIX_TUNNEL_STT = 0x04,
72 72
    DPIF_IPFIX_TUNNEL_IPSEC_GRE = 0x05,
73 73
    DPIF_IPFIX_TUNNEL_GENEVE = 0x07,
74
    DPIF_IPFIX_TUNNEL_GTP = 0x08,
74 75
    NUM_DPIF_IPFIX_TUNNEL
75 76
};
76 77

  
......
308 309
    IPPROTO_GRE,    /* DPIF_IPFIX_TUNNEL_IPSEC_GRE */
309 310
    0          ,    /* reserved */
310 311
    IPPROTO_UDP,    /* DPIF_IPFIX_TUNNEL_GENEVE*/
312
    IPPROTO_UDP,    /* DPIF_IPFIX_TUNNEL_GTP*/
311 313
};
312 314

  
313 315
OVS_PACKED(
......
358 360
 * VxLAN: 24-bit VIN,
359 361
 * GRE: 32-bit key,
360 362
 * LISP: 24-bit instance ID
363
 * GTP: 32-bit key
361 364
 * STT: 64-bit key
362 365
 */
363 366
#define MAX_TUNNEL_KEY_LEN 8
......
602 605
    } else if (strcmp(type, "lisp") == 0) {
603 606
        dip->tunnel_type = DPIF_IPFIX_TUNNEL_LISP;
604 607
        dip->tunnel_key_length = 3;
608
    } else if (strcmp(type, "gtp") == 0) {
609
        dip->tunnel_type = DPIF_IPFIX_TUNNEL_GTP;tun_src
610
        dip->tunnel_key_length = 4;
605 611
    } else if (strcmp(type, "geneve") == 0) {
606 612
        dip->tunnel_type = DPIF_IPFIX_TUNNEL_GENEVE;
607 613
        dip->tunnel_key_length = 3;
ofproto/ofproto-dpif-sflow.c
62 62
    DPIF_SFLOW_TUNNEL_GRE,
63 63
    DPIF_SFLOW_TUNNEL_LISP,
64 64
    DPIF_SFLOW_TUNNEL_IPSEC_GRE,
65
    DPIF_SFLOW_TUNNEL_GENEVE
65
    DPIF_SFLOW_TUNNEL_GENEVE,
66
    DPIF_SFLOW_TUNNEL_GTP
66 67
};
67 68

  
68 69
struct dpif_sflow_port {
......
592 593
	    return DPIF_SFLOW_TUNNEL_VXLAN;
593 594
	} else if (strcmp(type, "lisp") == 0) {
594 595
	    return DPIF_SFLOW_TUNNEL_LISP;
596
	} else if (strcmp(type, "gtp") == 0) {
597
	    return DPIF_SFLOW_TUNNEL_GTP;
595 598
	} else if (strcmp(type, "geneve") == 0) {
596 599
	    return DPIF_SFLOW_TUNNEL_GENEVE;
597 600
	}
......
616 619

  
617 620
    case DPIF_SFLOW_TUNNEL_VXLAN:
618 621
    case DPIF_SFLOW_TUNNEL_LISP:
622
    case DPIF_SFLOW_TUNNEL_GTP:
619 623
    case DPIF_SFLOW_TUNNEL_GENEVE:
620 624
        ipproto = IPPROTO_UDP;
621 625

  
tests/ovs-vsctl.at
1235 1235
[genev_sys],
1236 1236
[gre_sys],
1237 1237
[lisp_sys],
1238
[gtp_sys],
1238 1239
[vxlan_sys]],
1239 1240
[
1240 1241
# Try creating the port
......
1263 1264
                    -- add-port br0 p4 -- set Interface p4 type=vxlan \
1264 1265
                    options:remote_ip=2.2.2.2 ofport_request=4 \
1265 1266
                    -- add-port br0 p5 -- set Interface p5 type=geneve \
1266
                    options:remote_ip=2.2.2.2 ofport_request=5])
1267
                    options:remote_ip=2.2.2.2 ofport_request=5 \
1268
                    -- add-port br0 p6 -- set Interface p6 type=gtp \
1269
                    options:remote_ip=2.2.2.2 ofport_request=6])
1267 1270

  
1268 1271
# Test creating all reserved tunnel port names
1269 1272
m4_foreach(
......
1271 1274
[[genev_sys],
1272 1275
[gre_sys],
1273 1276
[lisp_sys],
1277
[gtp_sys],
1274 1278
[vxlan_sys]],
1275 1279
[
1276 1280
# Try creating the port
tests/system-kmod-macros.at
18 18
m4_define([OVS_TRAFFIC_VSWITCHD_START],
19 19
  [AT_CHECK([modprobe openvswitch])
20 20
   on_exit 'modprobe -r openvswitch'
21
   m4_foreach([mod], [[vport_geneve], [vport_gre], [vport_lisp], [vport_stt], [vport_vxlan]],
21
   m4_foreach([mod], [[vport_geneve], [vport_gre], [vport_lisp], [vport_stt], [vport_vxlan], [vport_gtp]],
22 22
              [modprobe -q mod || echo "Module mod not loaded."
23 23
               on_exit 'modprobe -q -r mod'])
24 24
   on_exit 'ovs-dpctl del-dp ovs-system'
tests/tunnel.at
352 352
OVS_VSWITCHD_STOP
353 353
AT_CLEANUP
354 354

  
355
AT_SETUP([tunnel - GTP])
356
OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=gtp \
357
                    options:remote_ip=1.1.1.1 ofport_request=1])
358

  
359
AT_CHECK([ovs-appctl dpif/show | tail -n +3], [0], [dnl
360
		br0 65534/100: (dummy)
361
		p1 1/2152: (gtp: remote_ip=1.1.1.1)
362
])
363

  
364
OVS_VSWITCHD_STOP
365
AT_CLEANUP
366

  
355 367
AT_SETUP([tunnel - different VXLAN UDP port])
356 368
OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=vxlan \
357 369
                    options:remote_ip=1.1.1.1 ofport_request=1 options:dst_port=4341])
vswitchd/vswitch.xml
1897 1897
            </p>
1898 1898
          </dd>
1899 1899

  
1900
          <dt><code>gtp</code></dt>
1901
          <dd>
1902
              GPRS Tunneling Protocol (GTP) is a group of IP-based communications
1903
              protocols used to carry general packet radio service (GPRS) within GSM,
1904
              UMTS and LTE networks.GTP-U is used for carrying user data within the GPRS
1905
              core network and between the radio access network and the core network.
1906
              The user data transported can be packets in any of IPv4, IPv6, or PPP
1907
              formats.
1908
              The protocol is documented at
1909
              http://www.3gpp.org/DynaReport/29281.htm
1910

  
1911
              Open vSwitch uses UDP destination port 2152.  The source port used for
1912
              GTP traffic varies on a per-flow basis and is in the ephemeral port
1913
              range.
1914
          </dd>
1915

  
1900 1916
          <dt><code>stt</code></dt>
1901 1917
          <dd>
1902 1918
            The Stateless TCP Tunnel (STT) is particularly useful when tunnel
Add picture from clipboard (Maximum size: 48.8 MB)