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 ovs_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 ovs_flow_tun_info_init(&tun_info, ip_hdr(skb), 94 udp_hdr(skb)->source, udp_hdr(skb)->dest, 95 key, flags, 96 geneveh->options, opts_len); 97 98 ovs_vport_receive(vport, skb, &tun_info); 99 } 100 101 static int geneve_get_options(const struct vport *vport, 102 struct sk_buff *skb) 103 { 104 struct geneve_port *geneve_port = geneve_vport(vport); 105 struct inet_sock *sk = inet_sk(geneve_port->gs->sock->sk); 106 107 if (nla_put_u16(skb, OVS_TUNNEL_ATTR_DST_PORT, ntohs(sk->inet_sport))) 108 return -EMSGSIZE; 109 return 0; 110 } 111 112 static void geneve_tnl_destroy(struct vport *vport) 113 { 114 struct geneve_port *geneve_port = geneve_vport(vport); 115 116 geneve_sock_release(geneve_port->gs); 117 118 ovs_vport_deferred_free(vport); 119 } 120 121 static struct vport *geneve_tnl_create(const struct vport_parms *parms) 122 { 123 struct net *net = ovs_dp_get_net(parms->dp); 124 struct nlattr *options = parms->options; 125 struct geneve_port *geneve_port; 126 struct geneve_sock *gs; 127 struct vport *vport; 128 struct nlattr *a; 129 int err; 130 u16 dst_port; 131 132 if (!options) { 133 err = -EINVAL; 134 goto error; 135 } 136 137 a = nla_find_nested(options, OVS_TUNNEL_ATTR_DST_PORT); 138 if (a && nla_len(a) == sizeof(u16)) { 139 dst_port = nla_get_u16(a); 140 } else { 141 /* Require destination port from userspace. */ 142 err = -EINVAL; 143 goto error; 144 } 145 146 vport = ovs_vport_alloc(sizeof(struct geneve_port), 147 &ovs_geneve_vport_ops, parms); 148 if (IS_ERR(vport)) 149 return vport; 150 151 geneve_port = geneve_vport(vport); 152 strncpy(geneve_port->name, parms->name, IFNAMSIZ); 153 154 gs = geneve_sock_add(net, htons(dst_port), geneve_rcv, vport, true, 0); 155 if (IS_ERR(gs)) { 156 ovs_vport_free(vport); 157 return (void *)gs; 158 } 159 geneve_port->gs = gs; 160 161 return vport; 162 error: 163 return ERR_PTR(err); 164 } 165 166 static int geneve_tnl_send(struct vport *vport, struct sk_buff *skb) 167 { 168 const struct ovs_key_ipv4_tunnel *tun_key; 169 struct ovs_tunnel_info *tun_info; 170 struct net *net = ovs_dp_get_net(vport->dp); 171 struct geneve_port *geneve_port = geneve_vport(vport); 172 __be16 dport = inet_sk(geneve_port->gs->sock->sk)->inet_sport; 173 __be16 sport; 174 struct rtable *rt; 175 struct flowi4 fl; 176 u8 vni[3], opts_len, *opts; 177 __be16 df; 178 int err; 179 180 tun_info = OVS_CB(skb)->egress_tun_info; 181 if (unlikely(!tun_info)) { 182 err = -EINVAL; 183 goto error; 184 } 185 186 tun_key = &tun_info->tunnel; 187 rt = ovs_tunnel_route_lookup(net, tun_key, skb->mark, &fl, IPPROTO_UDP); 188 if (IS_ERR(rt)) { 189 err = PTR_ERR(rt); 190 goto error; 191 } 192 193 df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; 194 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true); 195 tunnel_id_to_vni(tun_key->tun_id, vni); 196 skb->ignore_df = 1; 197 198 if (tun_key->tun_flags & TUNNEL_GENEVE_OPT) { 199 opts = (u8 *)tun_info->options; 200 opts_len = tun_info->options_len; 201 } else { 202 opts = NULL; 203 opts_len = 0; 204 } 205 206 err = geneve_xmit_skb(geneve_port->gs, rt, skb, fl.saddr, 207 tun_key->ipv4_dst, tun_key->ipv4_tos, 208 tun_key->ipv4_ttl, df, sport, dport, 209 tun_key->tun_flags, vni, opts_len, opts, 210 !!(tun_key->tun_flags & TUNNEL_CSUM), false); 211 if (err < 0) 212 ip_rt_put(rt); 213 return err; 214 215 error: 216 kfree_skb(skb); 217 return err; 218 } 219 220 static const char *geneve_get_name(const struct vport *vport) 221 { 222 struct geneve_port *geneve_port = geneve_vport(vport); 223 224 return geneve_port->name; 225 } 226 227 static int geneve_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, 228 struct ovs_tunnel_info *egress_tun_info) 229 { 230 struct geneve_port *geneve_port = geneve_vport(vport); 231 struct net *net = ovs_dp_get_net(vport->dp); 232 __be16 dport = inet_sk(geneve_port->gs->sock->sk)->inet_sport; 233 __be16 sport = udp_flow_src_port(net, skb, 1, USHRT_MAX, true); 234 235 /* Get tp_src and tp_dst, refert to geneve_build_header(). 236 */ 237 return ovs_tunnel_get_egress_info(egress_tun_info, 238 ovs_dp_get_net(vport->dp), 239 OVS_CB(skb)->egress_tun_info, 240 IPPROTO_UDP, skb->mark, sport, dport); 241 } 242 243 static struct vport_ops ovs_geneve_vport_ops = { 244 .type = OVS_VPORT_TYPE_GENEVE, 245 .create = geneve_tnl_create, 246 .destroy = geneve_tnl_destroy, 247 .get_name = geneve_get_name, 248 .get_options = geneve_get_options, 249 .send = geneve_tnl_send, 250 .owner = THIS_MODULE, 251 .get_egress_tun_info = geneve_get_egress_tun_info, 252 }; 253 254 static int __init ovs_geneve_tnl_init(void) 255 { 256 return ovs_vport_ops_register(&ovs_geneve_vport_ops); 257 } 258 259 static void __exit ovs_geneve_tnl_exit(void) 260 { 261 ovs_vport_ops_unregister(&ovs_geneve_vport_ops); 262 } 263 264 module_init(ovs_geneve_tnl_init); 265 module_exit(ovs_geneve_tnl_exit); 266 267 MODULE_DESCRIPTION("OVS: Geneve swiching port"); 268 MODULE_LICENSE("GPL"); 269 MODULE_ALIAS("vport-type-5"); 270