1 /* 2 * Copyright (c) 2014 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/geneve.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 30 static struct vport_ops ovs_geneve_vport_ops; 31 32 /** 33 * struct geneve_port - Keeps track of open UDP ports 34 * @gs: The socket created for this port number. 35 * @name: vport name. 36 */ 37 struct geneve_port { 38 struct geneve_sock *gs; 39 char name[IFNAMSIZ]; 40 }; 41 42 static LIST_HEAD(geneve_ports); 43 44 static inline struct geneve_port *geneve_vport(const struct vport *vport) 45 { 46 return vport_priv(vport); 47 } 48 49 /* Convert 64 bit tunnel ID to 24 bit VNI. */ 50 static void tunnel_id_to_vni(__be64 tun_id, __u8 *vni) 51 { 52 #ifdef __BIG_ENDIAN 53 vni[0] = (__force __u8)(tun_id >> 16); 54 vni[1] = (__force __u8)(tun_id >> 8); 55 vni[2] = (__force __u8)tun_id; 56 #else 57 vni[0] = (__force __u8)((__force u64)tun_id >> 40); 58 vni[1] = (__force __u8)((__force u64)tun_id >> 48); 59 vni[2] = (__force __u8)((__force u64)tun_id >> 56); 60 #endif 61 } 62 63 /* Convert 24 bit VNI to 64 bit tunnel ID. */ 64 static __be64 vni_to_tunnel_id(const __u8 *vni) 65 { 66 #ifdef __BIG_ENDIAN 67 return (vni[0] << 16) | (vni[1] << 8) | vni[2]; 68 #else 69 return (__force __be64)(((__force u64)vni[0] << 40) | 70 ((__force u64)vni[1] << 48) | 71 ((__force u64)vni[2] << 56)); 72 #endif 73 } 74 75 static void geneve_rcv(struct geneve_sock *gs, struct sk_buff *skb) 76 { 77 struct vport *vport = gs->rcv_data; 78 struct genevehdr *geneveh = geneve_hdr(skb); 79 int opts_len; 80 struct ip_tunnel_info tun_info; 81 __be64 key; 82 __be16 flags; 83 84 opts_len = geneveh->opt_len * 4; 85 86 flags = TUNNEL_KEY | TUNNEL_GENEVE_OPT | 87 (udp_hdr(skb)->check != 0 ? TUNNEL_CSUM : 0) | 88 (geneveh->oam ? TUNNEL_OAM : 0) | 89 (geneveh->critical ? TUNNEL_CRIT_OPT : 0); 90 91 key = vni_to_tunnel_id(geneveh->vni); 92 93 ip_tunnel_info_init(&tun_info, ip_hdr(skb), 94 udp_hdr(skb)->source, udp_hdr(skb)->dest, 95 key, flags, geneveh->options, opts_len); 96 97 ovs_vport_receive(vport, skb, &tun_info); 98 } 99 100 static int geneve_get_options(const struct vport *vport, 101 struct sk_buff *skb) 102 { 103 struct geneve_port *geneve_port = geneve_vport(vport); 104 struct inet_sock *sk = inet_sk(geneve_port->gs->sock->sk); 105 106 if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, ntohs(sk->inet_sport))) 107 return -EMSGSIZE; 108 return 0; 109 } 110 111 static void geneve_tnl_destroy(struct vport *vport) 112 { 113 struct geneve_port *geneve_port = geneve_vport(vport); 114 115 geneve_sock_release(geneve_port->gs); 116 117 ovs_vport_deferred_free(vport); 118 } 119 120 static struct vport *geneve_tnl_create(const struct vport_parms *parms) 121 { 122 struct net *net = ovs_dp_get_net(parms->dp); 123 struct nlattr *options = parms->options; 124 struct geneve_port *geneve_port; 125 struct geneve_sock *gs; 126 struct vport *vport; 127 struct nlattr *a; 128 int err; 129 u16 dst_port; 130 131 if (!options) { 132 err = -EINVAL; 133 goto error; 134 } 135 136 a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT); 137 if (a && nla_len(a) == sizeof(u16)) { 138 dst_port = nla_get_u16(a); 139 } else { 140 /* Require destination port from userspace. */ 141 err = -EINVAL; 142 goto error; 143 } 144 145 vport = ovs_vport_alloc(sizeof(struct geneve_port), 146 &ovs_geneve_vport_ops, parms); 147 if (IS_ERR(vport)) 148 return vport; 149 150 geneve_port = geneve_vport(vport); 151 strncpy(geneve_port->name, parms->name, IFNAMSIZ); 152 153 gs = geneve_sock_add(net, htons(dst_port), geneve_rcv, vport, true, 0); 154 if (IS_ERR(gs)) { 155 ovs_vport_free(vport); 156 return (void *)gs; 157 } 158 geneve_port->gs = gs; 159 160 return vport; 161 error: 162 return ERR_PTR(err); 163 } 164 165 static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb) 166 { 167 const struct ip_tunnel_key *tun_key; 168 struct ip_tunnel_info *tun_info; 169 struct net *net = ovs_dp_get_net(vport->dp); 170 struct geneve_port *geneve_port = geneve_vport(vport); 171 __be16 dport = inet_sk(geneve_port->gs->sock->sk)->inet_sport; 172 __be16 sport; 173 struct rtable *rt; 174 struct flowi4 fl; 175 u8 vni[3], opts_len, *opts; 176 __be16 df; 177 int err; 178 179 tun_info = OVS_CB(skb)->egress_tun_info; 180 if (unlikely(!tun_info)) { 181 err = -EINVAL; 182 goto error; 183 } 184 185 tun_key = &tun_info->key; 186 rt = ovs_tunnel_route_lookup(net, tun_key, skb->mark, &fl, IPPROTO_UDP); 187 if (IS_ERR(rt)) { 188 err = PTR_ERR(rt); 189 goto error; 190 } 191 192 df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; 193 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true); 194 tunnel_id_to_vni(tun_key->tun_id, vni); 195 skb->ignore_df = 1; 196 197 if (tun_key->tun_flags & TUNNEL_GENEVE_OPT) { 198 opts = (u8 *)tun_info->options; 199 opts_len = tun_info->options_len; 200 } else { 201 opts = NULL; 202 opts_len = 0; 203 } 204 205 err = geneve_xmit_skb(geneve_port->gs, rt, skb, fl.saddr, 206 tun_key->ipv4_dst, tun_key->ipv4_tos, 207 tun_key->ipv4_ttl, df, sport, dport, 208 tun_key->tun_flags, vni, opts_len, opts, 209 !!(tun_key->tun_flags & TUNNEL_CSUM), false); 210 if (err < 0) 211 ip_rt_put(rt); 212 return err; 213 214 error: 215 kfree_skb(skb); 216 return err; 217 } 218 219 static const char *geneve_get_name(const struct vport *vport) 220 { 221 struct geneve_port *geneve_port = geneve_vport(vport); 222 223 return geneve_port->name; 224 } 225 226 static int geneve_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, 227 struct ip_tunnel_info *egress_tun_info) 228 { 229 struct geneve_port *geneve_port = geneve_vport(vport); 230 struct net *net = ovs_dp_get_net(vport->dp); 231 __be16 dport = inet_sk(geneve_port->gs->sock->sk)->inet_sport; 232 __be16 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true); 233 234 /* Get tp_src and tp_dst, refert to geneve_build_header(). 235 */ 236 return ovs_tunnel_get_egress_info(egress_tun_info, 237 ovs_dp_get_net(vport->dp), 238 OVS_CB(skb)->egress_tun_info, 239 IPPROTO_UDP, skb->mark, sport, dport); 240 } 241 242 static struct vport_ops ovs_geneve_vport_ops = { 243 .type = OVS_VPORT_TYPE_GENEVE, 244 .create = geneve_tnl_create, 245 .destroy = geneve_tnl_destroy, 246 .get_name = geneve_get_name, 247 .get_options = geneve_get_options, 248 .send = geneve_tnl_send, 249 .owner = THIS_MODULE, 250 .get_egress_tun_info = geneve_get_egress_tun_info, 251 }; 252 253 static int __init ovs_geneve_tnl_init(void) 254 { 255 return ovs_vport_ops_register(&ovs_geneve_vport_ops); 256 } 257 258 static void __exit ovs_geneve_tnl_exit(void) 259 { 260 ovs_vport_ops_unregister(&ovs_geneve_vport_ops); 261 } 262 263 module_init(ovs_geneve_tnl_init); 264 module_exit(ovs_geneve_tnl_exit); 265 266 MODULE_DESCRIPTION("OVS: Geneve swiching port"); 267 MODULE_LICENSE("GPL"); 268 MODULE_ALIAS("vport-type-5"); 269