2 * Copyright (c) 2014 Nicira, Inc.
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.
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/version.h>
16 #include <linux/net.h>
17 #include <linux/rculist.h>
18 #include <linux/udp.h>
19 #include <linux/if_vlan.h>
21 #include <net/geneve.h>
24 #include <net/route.h>
32 * struct geneve_port - Keeps track of open UDP ports
33 * @sock: The socket created for this port number.
37 struct geneve_sock
*gs
;
41 static LIST_HEAD(geneve_ports
);
43 static inline struct geneve_port
*geneve_vport(const struct vport
*vport
)
45 return vport_priv(vport
);
48 static inline struct genevehdr
*geneve_hdr(const struct sk_buff
*skb
)
50 return (struct genevehdr
*)(udp_hdr(skb
) + 1);
53 /* Convert 64 bit tunnel ID to 24 bit VNI. */
54 static void tunnel_id_to_vni(__be64 tun_id
, __u8
*vni
)
57 vni
[0] = (__force __u8
)(tun_id
>> 16);
58 vni
[1] = (__force __u8
)(tun_id
>> 8);
59 vni
[2] = (__force __u8
)tun_id
;
61 vni
[0] = (__force __u8
)((__force u64
)tun_id
>> 40);
62 vni
[1] = (__force __u8
)((__force u64
)tun_id
>> 48);
63 vni
[2] = (__force __u8
)((__force u64
)tun_id
>> 56);
67 /* Convert 24 bit VNI to 64 bit tunnel ID. */
68 static __be64
vni_to_tunnel_id(__u8
*vni
)
71 return (vni
[0] << 16) | (vni
[1] << 8) | vni
[2];
73 return (__force __be64
)(((__force u64
)vni
[0] << 40) |
74 ((__force u64
)vni
[1] << 48) |
75 ((__force u64
)vni
[2] << 56));
79 static void geneve_rcv(struct geneve_sock
*gs
, struct sk_buff
*skb
)
81 struct vport
*vport
= gs
->rcv_data
;
82 struct genevehdr
*geneveh
= geneve_hdr(skb
);
84 struct ovs_tunnel_info tun_info
;
88 opts_len
= geneveh
->opt_len
* 4;
90 flags
= TUNNEL_KEY
| TUNNEL_OPTIONS_PRESENT
|
91 (udp_hdr(skb
)->check
!= 0 ? TUNNEL_CSUM
: 0) |
92 (geneveh
->oam
? TUNNEL_OAM
: 0) |
93 (geneveh
->critical
? TUNNEL_CRIT_OPT
: 0);
95 key
= vni_to_tunnel_id(geneveh
->vni
);
97 ovs_flow_tun_info_init(&tun_info
, ip_hdr(skb
), key
, flags
,
98 geneveh
->options
, opts_len
);
100 ovs_vport_receive(vport
, skb
, &tun_info
);
103 static int geneve_get_options(const struct vport
*vport
,
106 struct geneve_port
*geneve_port
= geneve_vport(vport
);
109 sport
= ntohs(inet_sk(geneve_port
->gs
->sock
->sk
)->inet_sport
);
110 if (nla_put_u16(skb
, OVS_TUNNEL_ATTR_DST_PORT
, sport
))
115 static void geneve_tnl_destroy(struct vport
*vport
)
117 struct geneve_port
*geneve_port
= geneve_vport(vport
);
119 geneve_sock_release(geneve_port
->gs
);
121 ovs_vport_deferred_free(vport
);
124 static struct vport
*geneve_tnl_create(const struct vport_parms
*parms
)
126 struct net
*net
= ovs_dp_get_net(parms
->dp
);
127 struct nlattr
*options
= parms
->options
;
128 struct geneve_port
*geneve_port
;
129 struct geneve_sock
*gs
;
140 a
= nla_find_nested(options
, OVS_TUNNEL_ATTR_DST_PORT
);
141 if (a
&& nla_len(a
) == sizeof(u16
)) {
142 dst_port
= nla_get_u16(a
);
144 /* Require destination port from userspace. */
149 vport
= ovs_vport_alloc(sizeof(struct geneve_port
),
150 &ovs_geneve_vport_ops
, parms
);
154 geneve_port
= geneve_vport(vport
);
155 strncpy(geneve_port
->name
, parms
->name
, IFNAMSIZ
);
157 gs
= geneve_sock_add(net
, htons(dst_port
), geneve_rcv
, vport
, true, 0);
159 ovs_vport_free(vport
);
162 geneve_port
->gs
= gs
;
169 static int geneve_tnl_send(struct vport
*vport
, struct sk_buff
*skb
)
171 struct ovs_key_ipv4_tunnel
*tun_key
;
172 struct ovs_tunnel_info
*tun_info
;
173 struct net
*net
= ovs_dp_get_net(vport
->dp
);
174 struct geneve_port
*geneve_port
= geneve_vport(vport
);
175 __be16 dport
= inet_sk(geneve_port
->gs
->sock
->sk
)->inet_sport
;
183 tun_info
= OVS_CB(skb
)->egress_tun_info
;
184 if (unlikely(!tun_info
)) {
189 tun_key
= &tun_info
->tunnel
;
192 memset(&fl
, 0, sizeof(fl
));
193 fl
.daddr
= tun_key
->ipv4_dst
;
194 fl
.saddr
= tun_key
->ipv4_src
;
195 fl
.flowi4_tos
= RT_TOS(tun_key
->ipv4_tos
);
196 fl
.flowi4_mark
= skb
->mark
;
197 fl
.flowi4_proto
= IPPROTO_UDP
;
199 rt
= ip_route_output_key(net
, &fl
);
205 df
= tun_key
->tun_flags
& TUNNEL_DONT_FRAGMENT
? htons(IP_DF
) : 0;
206 sport
= udp_flow_src_port(net
, skb
, 1, USHRT_MAX
, true);
207 tunnel_id_to_vni(tun_key
->tun_id
, vni
);
210 err
= geneve_xmit_skb(geneve_port
->gs
, rt
, skb
, fl
.saddr
,
211 tun_key
->ipv4_dst
, tun_key
->ipv4_tos
,
212 tun_key
->ipv4_ttl
, df
, sport
, dport
,
213 tun_key
->tun_flags
, vni
,
214 tun_info
->options_len
, (u8
*)tun_info
->options
,
222 static const char *geneve_get_name(const struct vport
*vport
)
224 struct geneve_port
*geneve_port
= geneve_vport(vport
);
226 return geneve_port
->name
;
229 const struct vport_ops ovs_geneve_vport_ops
= {
230 .type
= OVS_VPORT_TYPE_GENEVE
,
231 .create
= geneve_tnl_create
,
232 .destroy
= geneve_tnl_destroy
,
233 .get_name
= geneve_get_name
,
234 .get_options
= geneve_get_options
,
235 .send
= geneve_tnl_send
,