1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2017 - Cambridge Greys Limited 4 * Copyright (C) 2011 - 2014 Cisco Systems Inc 5 */ 6 7 #include <linux/etherdevice.h> 8 #include <linux/netdevice.h> 9 #include <linux/skbuff.h> 10 #include <linux/slab.h> 11 #include <asm/byteorder.h> 12 #include <uapi/linux/ip.h> 13 #include <uapi/linux/virtio_net.h> 14 #include <linux/virtio_net.h> 15 #include <linux/virtio_byteorder.h> 16 #include <linux/netdev_features.h> 17 #include "vector_user.h" 18 #include "vector_kern.h" 19 20 #define GOOD_LINEAR 512 21 #define GSO_ERROR "Incoming GSO frames and GRO disabled on the interface" 22 23 struct gre_minimal_header { 24 uint16_t header; 25 uint16_t arptype; 26 }; 27 28 29 struct uml_gre_data { 30 uint32_t rx_key; 31 uint32_t tx_key; 32 uint32_t sequence; 33 34 bool ipv6; 35 bool has_sequence; 36 bool pin_sequence; 37 bool checksum; 38 bool key; 39 struct gre_minimal_header expected_header; 40 41 uint32_t checksum_offset; 42 uint32_t key_offset; 43 uint32_t sequence_offset; 44 45 }; 46 47 struct uml_l2tpv3_data { 48 uint64_t rx_cookie; 49 uint64_t tx_cookie; 50 uint64_t rx_session; 51 uint64_t tx_session; 52 uint32_t counter; 53 54 bool udp; 55 bool ipv6; 56 bool has_counter; 57 bool pin_counter; 58 bool cookie; 59 bool cookie_is_64; 60 61 uint32_t cookie_offset; 62 uint32_t session_offset; 63 uint32_t counter_offset; 64 }; 65 66 static int l2tpv3_form_header(uint8_t *header, 67 struct sk_buff *skb, struct vector_private *vp) 68 { 69 struct uml_l2tpv3_data *td = vp->transport_data; 70 uint32_t *counter; 71 72 if (td->udp) 73 *(uint32_t *) header = cpu_to_be32(L2TPV3_DATA_PACKET); 74 (*(uint32_t *) (header + td->session_offset)) = td->tx_session; 75 76 if (td->cookie) { 77 if (td->cookie_is_64) 78 (*(uint64_t *)(header + td->cookie_offset)) = 79 td->tx_cookie; 80 else 81 (*(uint32_t *)(header + td->cookie_offset)) = 82 td->tx_cookie; 83 } 84 if (td->has_counter) { 85 counter = (uint32_t *)(header + td->counter_offset); 86 if (td->pin_counter) { 87 *counter = 0; 88 } else { 89 td->counter++; 90 *counter = cpu_to_be32(td->counter); 91 } 92 } 93 return 0; 94 } 95 96 static int gre_form_header(uint8_t *header, 97 struct sk_buff *skb, struct vector_private *vp) 98 { 99 struct uml_gre_data *td = vp->transport_data; 100 uint32_t *sequence; 101 *((uint32_t *) header) = *((uint32_t *) &td->expected_header); 102 if (td->key) 103 (*(uint32_t *) (header + td->key_offset)) = td->tx_key; 104 if (td->has_sequence) { 105 sequence = (uint32_t *)(header + td->sequence_offset); 106 if (td->pin_sequence) 107 *sequence = 0; 108 else 109 *sequence = cpu_to_be32(++td->sequence); 110 } 111 return 0; 112 } 113 114 static int raw_form_header(uint8_t *header, 115 struct sk_buff *skb, struct vector_private *vp) 116 { 117 struct virtio_net_hdr *vheader = (struct virtio_net_hdr *) header; 118 119 virtio_net_hdr_from_skb( 120 skb, 121 vheader, 122 virtio_legacy_is_little_endian(), 123 false, 124 0 125 ); 126 127 return 0; 128 } 129 130 static int l2tpv3_verify_header( 131 uint8_t *header, struct sk_buff *skb, struct vector_private *vp) 132 { 133 struct uml_l2tpv3_data *td = vp->transport_data; 134 uint32_t *session; 135 uint64_t cookie; 136 137 if ((!td->udp) && (!td->ipv6)) 138 header += sizeof(struct iphdr) /* fix for ipv4 raw */; 139 140 /* we do not do a strict check for "data" packets as per 141 * the RFC spec because the pure IP spec does not have 142 * that anyway. 143 */ 144 145 if (td->cookie) { 146 if (td->cookie_is_64) 147 cookie = *(uint64_t *)(header + td->cookie_offset); 148 else 149 cookie = *(uint32_t *)(header + td->cookie_offset); 150 if (cookie != td->rx_cookie) { 151 if (net_ratelimit()) 152 netdev_err(vp->dev, "uml_l2tpv3: unknown cookie id"); 153 return -1; 154 } 155 } 156 session = (uint32_t *) (header + td->session_offset); 157 if (*session != td->rx_session) { 158 if (net_ratelimit()) 159 netdev_err(vp->dev, "uml_l2tpv3: session mismatch"); 160 return -1; 161 } 162 return 0; 163 } 164 165 static int gre_verify_header( 166 uint8_t *header, struct sk_buff *skb, struct vector_private *vp) 167 { 168 169 uint32_t key; 170 struct uml_gre_data *td = vp->transport_data; 171 172 if (!td->ipv6) 173 header += sizeof(struct iphdr) /* fix for ipv4 raw */; 174 175 if (*((uint32_t *) header) != *((uint32_t *) &td->expected_header)) { 176 if (net_ratelimit()) 177 netdev_err(vp->dev, "header type disagreement, expecting %0x, got %0x", 178 *((uint32_t *) &td->expected_header), 179 *((uint32_t *) header) 180 ); 181 return -1; 182 } 183 184 if (td->key) { 185 key = (*(uint32_t *)(header + td->key_offset)); 186 if (key != td->rx_key) { 187 if (net_ratelimit()) 188 netdev_err(vp->dev, "unknown key id %0x, expecting %0x", 189 key, td->rx_key); 190 return -1; 191 } 192 } 193 return 0; 194 } 195 196 static int raw_verify_header( 197 uint8_t *header, struct sk_buff *skb, struct vector_private *vp) 198 { 199 struct virtio_net_hdr *vheader = (struct virtio_net_hdr *) header; 200 201 if ((vheader->gso_type != VIRTIO_NET_HDR_GSO_NONE) && 202 (vp->req_size != 65536)) { 203 if (net_ratelimit()) 204 netdev_err( 205 vp->dev, 206 GSO_ERROR 207 ); 208 } 209 if ((vheader->flags & VIRTIO_NET_HDR_F_DATA_VALID) > 0) 210 return 1; 211 212 virtio_net_hdr_to_skb(skb, vheader, virtio_legacy_is_little_endian()); 213 return 0; 214 } 215 216 static bool get_uint_param( 217 struct arglist *def, char *param, unsigned int *result) 218 { 219 char *arg = uml_vector_fetch_arg(def, param); 220 221 if (arg != NULL) { 222 if (kstrtoint(arg, 0, result) == 0) 223 return true; 224 } 225 return false; 226 } 227 228 static bool get_ulong_param( 229 struct arglist *def, char *param, unsigned long *result) 230 { 231 char *arg = uml_vector_fetch_arg(def, param); 232 233 if (arg != NULL) { 234 if (kstrtoul(arg, 0, result) == 0) 235 return true; 236 return true; 237 } 238 return false; 239 } 240 241 static int build_gre_transport_data(struct vector_private *vp) 242 { 243 struct uml_gre_data *td; 244 int temp_int; 245 int temp_rx; 246 int temp_tx; 247 248 vp->transport_data = kmalloc_obj(struct uml_gre_data); 249 if (vp->transport_data == NULL) 250 return -ENOMEM; 251 td = vp->transport_data; 252 td->sequence = 0; 253 254 td->expected_header.arptype = GRE_IRB; 255 td->expected_header.header = 0; 256 257 vp->form_header = &gre_form_header; 258 vp->verify_header = &gre_verify_header; 259 vp->header_size = 4; 260 td->key_offset = 4; 261 td->sequence_offset = 4; 262 td->checksum_offset = 4; 263 264 td->ipv6 = false; 265 if (get_uint_param(vp->parsed, "v6", &temp_int)) { 266 if (temp_int > 0) 267 td->ipv6 = true; 268 } 269 td->key = false; 270 if (get_uint_param(vp->parsed, "rx_key", &temp_rx)) { 271 if (get_uint_param(vp->parsed, "tx_key", &temp_tx)) { 272 td->key = true; 273 td->expected_header.header |= GRE_MODE_KEY; 274 td->rx_key = cpu_to_be32(temp_rx); 275 td->tx_key = cpu_to_be32(temp_tx); 276 vp->header_size += 4; 277 td->sequence_offset += 4; 278 } else { 279 return -EINVAL; 280 } 281 } 282 283 td->sequence = false; 284 if (get_uint_param(vp->parsed, "sequence", &temp_int)) { 285 if (temp_int > 0) { 286 vp->header_size += 4; 287 td->has_sequence = true; 288 td->expected_header.header |= GRE_MODE_SEQUENCE; 289 if (get_uint_param( 290 vp->parsed, "pin_sequence", &temp_int)) { 291 if (temp_int > 0) 292 td->pin_sequence = true; 293 } 294 } 295 } 296 vp->rx_header_size = vp->header_size; 297 if (!td->ipv6) 298 vp->rx_header_size += sizeof(struct iphdr); 299 return 0; 300 } 301 302 static int build_l2tpv3_transport_data(struct vector_private *vp) 303 { 304 305 struct uml_l2tpv3_data *td; 306 int temp_int, temp_rxs, temp_txs; 307 unsigned long temp_rx; 308 unsigned long temp_tx; 309 310 vp->transport_data = kmalloc_obj(struct uml_l2tpv3_data); 311 312 if (vp->transport_data == NULL) 313 return -ENOMEM; 314 315 td = vp->transport_data; 316 317 vp->form_header = &l2tpv3_form_header; 318 vp->verify_header = &l2tpv3_verify_header; 319 td->counter = 0; 320 321 vp->header_size = 4; 322 td->session_offset = 0; 323 td->cookie_offset = 4; 324 td->counter_offset = 4; 325 326 327 td->ipv6 = false; 328 if (get_uint_param(vp->parsed, "v6", &temp_int)) { 329 if (temp_int > 0) 330 td->ipv6 = true; 331 } 332 333 if (get_uint_param(vp->parsed, "rx_session", &temp_rxs)) { 334 if (get_uint_param(vp->parsed, "tx_session", &temp_txs)) { 335 td->tx_session = cpu_to_be32(temp_txs); 336 td->rx_session = cpu_to_be32(temp_rxs); 337 } else { 338 return -EINVAL; 339 } 340 } else { 341 return -EINVAL; 342 } 343 344 td->cookie_is_64 = false; 345 if (get_uint_param(vp->parsed, "cookie64", &temp_int)) { 346 if (temp_int > 0) 347 td->cookie_is_64 = true; 348 } 349 td->cookie = false; 350 if (get_ulong_param(vp->parsed, "rx_cookie", &temp_rx)) { 351 if (get_ulong_param(vp->parsed, "tx_cookie", &temp_tx)) { 352 td->cookie = true; 353 if (td->cookie_is_64) { 354 td->rx_cookie = cpu_to_be64(temp_rx); 355 td->tx_cookie = cpu_to_be64(temp_tx); 356 vp->header_size += 8; 357 td->counter_offset += 8; 358 } else { 359 td->rx_cookie = cpu_to_be32(temp_rx); 360 td->tx_cookie = cpu_to_be32(temp_tx); 361 vp->header_size += 4; 362 td->counter_offset += 4; 363 } 364 } else { 365 return -EINVAL; 366 } 367 } 368 369 td->has_counter = false; 370 if (get_uint_param(vp->parsed, "counter", &temp_int)) { 371 if (temp_int > 0) { 372 td->has_counter = true; 373 vp->header_size += 4; 374 if (get_uint_param( 375 vp->parsed, "pin_counter", &temp_int)) { 376 if (temp_int > 0) 377 td->pin_counter = true; 378 } 379 } 380 } 381 382 if (get_uint_param(vp->parsed, "udp", &temp_int)) { 383 if (temp_int > 0) { 384 td->udp = true; 385 vp->header_size += 4; 386 td->counter_offset += 4; 387 td->session_offset += 4; 388 td->cookie_offset += 4; 389 } 390 } 391 392 vp->rx_header_size = vp->header_size; 393 if ((!td->ipv6) && (!td->udp)) 394 vp->rx_header_size += sizeof(struct iphdr); 395 396 return 0; 397 } 398 399 static int build_raw_transport_data(struct vector_private *vp) 400 { 401 if (uml_raw_enable_vnet_headers(vp->fds->rx_fd)) { 402 if (!uml_raw_enable_vnet_headers(vp->fds->tx_fd)) 403 return -1; 404 vp->form_header = &raw_form_header; 405 vp->verify_header = &raw_verify_header; 406 vp->header_size = sizeof(struct virtio_net_hdr); 407 vp->rx_header_size = sizeof(struct virtio_net_hdr); 408 vp->dev->hw_features |= (NETIF_F_TSO | NETIF_F_GRO); 409 vp->dev->features |= 410 (NETIF_F_RXCSUM | NETIF_F_HW_CSUM | 411 NETIF_F_TSO | NETIF_F_GRO); 412 netdev_info( 413 vp->dev, 414 "raw: using vnet headers for tso and tx/rx checksum" 415 ); 416 } 417 return 0; 418 } 419 420 static int build_hybrid_transport_data(struct vector_private *vp) 421 { 422 if (uml_raw_enable_vnet_headers(vp->fds->rx_fd)) { 423 vp->form_header = &raw_form_header; 424 vp->verify_header = &raw_verify_header; 425 vp->header_size = sizeof(struct virtio_net_hdr); 426 vp->rx_header_size = sizeof(struct virtio_net_hdr); 427 vp->dev->hw_features |= 428 (NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); 429 vp->dev->features |= 430 (NETIF_F_RXCSUM | NETIF_F_HW_CSUM | 431 NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); 432 netdev_info( 433 vp->dev, 434 "tap/raw hybrid: using vnet headers for tso and tx/rx checksum" 435 ); 436 } else { 437 return 0; /* do not try to enable tap too if raw failed */ 438 } 439 if (uml_tap_enable_vnet_headers(vp->fds->tx_fd)) 440 return 0; 441 return -1; 442 } 443 444 static int build_tap_transport_data(struct vector_private *vp) 445 { 446 /* "Pure" tap uses the same fd for rx and tx */ 447 if (uml_tap_enable_vnet_headers(vp->fds->tx_fd)) { 448 vp->form_header = &raw_form_header; 449 vp->verify_header = &raw_verify_header; 450 vp->header_size = sizeof(struct virtio_net_hdr); 451 vp->rx_header_size = sizeof(struct virtio_net_hdr); 452 vp->dev->hw_features |= 453 (NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); 454 vp->dev->features |= 455 (NETIF_F_RXCSUM | NETIF_F_HW_CSUM | 456 NETIF_F_TSO | NETIF_F_GSO | NETIF_F_GRO); 457 netdev_info( 458 vp->dev, 459 "tap: using vnet headers for tso and tx/rx checksum" 460 ); 461 return 0; 462 } 463 return -1; 464 } 465 466 467 static int build_bess_transport_data(struct vector_private *vp) 468 { 469 vp->form_header = NULL; 470 vp->verify_header = NULL; 471 vp->header_size = 0; 472 vp->rx_header_size = 0; 473 return 0; 474 } 475 476 int build_transport_data(struct vector_private *vp) 477 { 478 char *transport = uml_vector_fetch_arg(vp->parsed, "transport"); 479 480 if (strncmp(transport, TRANS_GRE, TRANS_GRE_LEN) == 0) 481 return build_gre_transport_data(vp); 482 if (strncmp(transport, TRANS_L2TPV3, TRANS_L2TPV3_LEN) == 0) 483 return build_l2tpv3_transport_data(vp); 484 if (strncmp(transport, TRANS_RAW, TRANS_RAW_LEN) == 0) 485 return build_raw_transport_data(vp); 486 if (strncmp(transport, TRANS_TAP, TRANS_TAP_LEN) == 0) 487 return build_tap_transport_data(vp); 488 if (strncmp(transport, TRANS_HYBRID, TRANS_HYBRID_LEN) == 0) 489 return build_hybrid_transport_data(vp); 490 if (strncmp(transport, TRANS_BESS, TRANS_BESS_LEN) == 0) 491 return build_bess_transport_data(vp); 492 return 0; 493 } 494 495