Hi Sharath, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on ipvs/master] [also build test WARNING on linus/master sparc-next/master v5.11-rc7 next-20210211] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Sharath-Chandra-Vurukala/docs-networking-Add-documentation-for-MAP-v5/20210212-063547 base: https://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs.git master config: x86_64-randconfig-a012-20210209 (attached as .config) compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project c9439ca36342fb6013187d0a69aef92736951476) reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # install x86_64 cross compiling tool for clang build # apt-get install binutils-x86-64-linux-gnu # https://github.com/0day-ci/linux/commit/7f0a1e35c1d1c17de5873aded88d5dadfedce2fb git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Sharath-Chandra-Vurukala/docs-networking-Add-documentation-for-MAP-v5/20210212-063547 git checkout 7f0a1e35c1d1c17de5873aded88d5dadfedce2fb # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot All warnings (new ones prefixed by >>): >> drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:266:6: warning: no previous prototype for function 'rmnet_map_v5_checksum_uplink_packet' [-Wmissing-prototypes] void rmnet_map_v5_checksum_uplink_packet(struct sk_buff *skb, ^ drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:266:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void rmnet_map_v5_checksum_uplink_packet(struct sk_buff *skb, ^ static >> drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:459:6: warning: no previous prototype for function 'rmnet_map_v4_checksum_uplink_packet' [-Wmissing-prototypes] void rmnet_map_v4_checksum_uplink_packet(struct sk_buff *skb, ^ drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c:459:1: note: declare 'static' if the function is not intended to be used outside of this translation unit void rmnet_map_v4_checksum_uplink_packet(struct sk_buff *skb, ^ static 2 warnings generated. vim +/rmnet_map_v5_checksum_uplink_packet +266 drivers/net/ethernet/qualcomm/rmnet/rmnet_map_data.c 265 > 266 void rmnet_map_v5_checksum_uplink_packet(struct sk_buff *skb, 267 struct rmnet_port *port, 268 struct net_device *orig_dev) 269 { 270 struct rmnet_priv *priv = netdev_priv(orig_dev); 271 struct rmnet_map_v5_csum_header *ul_header; 272 273 if (!(port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV5)) 274 return; 275 276 ul_header = (struct rmnet_map_v5_csum_header *) 277 skb_push(skb, sizeof(*ul_header)); 278 memset(ul_header, 0, sizeof(*ul_header)); 279 ul_header->header_type = RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD; 280 281 if (skb->ip_summed == CHECKSUM_PARTIAL) { 282 void *iph = (char *)ul_header + sizeof(*ul_header); 283 __sum16 *check; 284 void *trans; 285 u8 proto; 286 287 if (skb->protocol == htons(ETH_P_IP)) { 288 u16 ip_len = ((struct iphdr *)iph)->ihl * 4; 289 290 proto = ((struct iphdr *)iph)->protocol; 291 trans = iph + ip_len; 292 } 293 #if IS_ENABLED(CONFIG_IPV6) 294 else if (skb->protocol == htons(ETH_P_IPV6)) { 295 u16 ip_len = sizeof(struct ipv6hdr); 296 297 proto = ((struct ipv6hdr *)iph)->nexthdr; 298 trans = iph + ip_len; 299 } 300 #endif /* CONFIG_IPV6 */ 301 else { 302 priv->stats.csum_err_invalid_ip_version++; 303 goto sw_csum; 304 } 305 306 check = rmnet_map_get_csum_field(proto, trans); 307 if (check) { 308 skb->ip_summed = CHECKSUM_NONE; 309 /* Ask for checksum offloading */ 310 ul_header->csum_valid_required = 1; 311 priv->stats.csum_hw++; 312 return; 313 } 314 } 315 316 sw_csum: 317 priv->stats.csum_sw++; 318 } 319 320 /* Adds MAP header to front of skb->data 321 * Padding is calculated and set appropriately in MAP header. Mux ID is 322 * initialized to 0. 323 */ 324 struct rmnet_map_header *rmnet_map_add_map_header(struct sk_buff *skb, 325 int hdrlen, 326 struct rmnet_port *port, 327 int pad) 328 { 329 struct rmnet_map_header *map_header; 330 u32 padding, map_datalen; 331 u8 *padbytes; 332 333 map_datalen = skb->len - hdrlen; 334 map_header = (struct rmnet_map_header *) 335 skb_push(skb, sizeof(struct rmnet_map_header)); 336 memset(map_header, 0, sizeof(struct rmnet_map_header)); 337 338 /* Set next_hdr bit for csum offload packets */ 339 if (port->data_format & RMNET_FLAGS_EGRESS_MAP_CKSUMV5) { 340 map_header->next_hdr = 1; 341 } 342 343 if (pad == RMNET_MAP_NO_PAD_BYTES) { 344 map_header->pkt_len = htons(map_datalen); 345 return map_header; 346 } 347 348 padding = ALIGN(map_datalen, 4) - map_datalen; 349 350 if (padding == 0) 351 goto done; 352 353 if (skb_tailroom(skb) < padding) 354 return NULL; 355 356 padbytes = (u8 *)skb_put(skb, padding); 357 memset(padbytes, 0, padding); 358 359 done: 360 map_header->pkt_len = htons(map_datalen + padding); 361 map_header->pad_len = padding & 0x3F; 362 363 return map_header; 364 } 365 366 /* Deaggregates a single packet 367 * A whole new buffer is allocated for each portion of an aggregated frame. 368 * Caller should keep calling deaggregate() on the source skb until 0 is 369 * returned, indicating that there are no more packets to deaggregate. Caller 370 * is responsible for freeing the original skb. 371 */ 372 struct sk_buff *rmnet_map_deaggregate(struct sk_buff *skb, 373 struct rmnet_port *port) 374 { 375 unsigned char *data = skb->data, *next_hdr = NULL; 376 struct rmnet_map_header *maph; 377 struct sk_buff *skbn; 378 u32 packet_len; 379 380 if (skb->len == 0) 381 return NULL; 382 383 maph = (struct rmnet_map_header *)skb->data; 384 packet_len = ntohs(maph->pkt_len) + sizeof(struct rmnet_map_header); 385 386 if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4) 387 packet_len += sizeof(struct rmnet_map_dl_csum_trailer); 388 else if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV5) { 389 if (!maph->cd_bit) { 390 packet_len += sizeof(struct rmnet_map_v5_csum_header); 391 next_hdr = data + sizeof(*maph); 392 } 393 } 394 395 if (((int)skb->len - (int)packet_len) < 0) 396 return NULL; 397 398 /* Some hardware can send us empty frames. Catch them */ 399 if (ntohs(maph->pkt_len) == 0) 400 return NULL; 401 402 if (next_hdr && 403 ((struct rmnet_map_v5_csum_header *)next_hdr)->header_type != 404 RMNET_MAP_HEADER_TYPE_CSUM_OFFLOAD) 405 return NULL; 406 407 skbn = alloc_skb(packet_len + RMNET_MAP_DEAGGR_SPACING, GFP_ATOMIC); 408 if (!skbn) 409 return NULL; 410 411 skb_reserve(skbn, RMNET_MAP_DEAGGR_HEADROOM); 412 skb_put(skbn, packet_len); 413 memcpy(skbn->data, skb->data, packet_len); 414 skb_pull(skb, packet_len); 415 416 return skbn; 417 } 418 419 /* Validates packet checksums. Function takes a pointer to 420 * the beginning of a buffer which contains the IP payload + 421 * padding + checksum trailer. 422 * Only IPv4 and IPv6 are supported along with TCP & UDP. 423 * Fragmented or tunneled packets are not supported. 424 */ 425 int rmnet_map_checksum_downlink_packet(struct sk_buff *skb, u16 len) 426 { 427 struct rmnet_priv *priv = netdev_priv(skb->dev); 428 struct rmnet_map_dl_csum_trailer *csum_trailer; 429 430 if (unlikely(!(skb->dev->features & NETIF_F_RXCSUM))) { 431 priv->stats.csum_sw++; 432 return -EOPNOTSUPP; 433 } 434 435 csum_trailer = (struct rmnet_map_dl_csum_trailer *)(skb->data + len); 436 437 if (!csum_trailer->valid) { 438 priv->stats.csum_valid_unset++; 439 return -EINVAL; 440 } 441 442 if (skb->protocol == htons(ETH_P_IP)) { 443 return rmnet_map_ipv4_dl_csum_trailer(skb, csum_trailer, priv); 444 } else if (skb->protocol == htons(ETH_P_IPV6)) { 445 #if IS_ENABLED(CONFIG_IPV6) 446 return rmnet_map_ipv6_dl_csum_trailer(skb, csum_trailer, priv); 447 #else 448 priv->stats.csum_err_invalid_ip_version++; 449 return -EPROTONOSUPPORT; 450 #endif 451 } else { 452 priv->stats.csum_err_invalid_ip_version++; 453 return -EPROTONOSUPPORT; 454 } 455 456 return 0; 457 } 458 > 459 void rmnet_map_v4_checksum_uplink_packet(struct sk_buff *skb, 460 struct net_device *orig_dev) 461 { 462 struct rmnet_priv *priv = netdev_priv(orig_dev); 463 struct rmnet_map_ul_csum_header *ul_header; 464 void *iphdr; 465 466 ul_header = (struct rmnet_map_ul_csum_header *) 467 skb_push(skb, sizeof(struct rmnet_map_ul_csum_header)); 468 469 if (unlikely(!(orig_dev->features & 470 (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)))) 471 goto sw_csum; 472 473 if (skb->ip_summed == CHECKSUM_PARTIAL) { 474 iphdr = (char *)ul_header + 475 sizeof(struct rmnet_map_ul_csum_header); 476 477 if (skb->protocol == htons(ETH_P_IP)) { 478 rmnet_map_ipv4_ul_csum_header(iphdr, ul_header, skb); 479 priv->stats.csum_hw++; 480 return; 481 } else if (skb->protocol == htons(ETH_P_IPV6)) { 482 #if IS_ENABLED(CONFIG_IPV6) 483 rmnet_map_ipv6_ul_csum_header(iphdr, ul_header, skb); 484 priv->stats.csum_hw++; 485 return; 486 #else 487 priv->stats.csum_err_invalid_ip_version++; 488 goto sw_csum; 489 #endif 490 } else { 491 priv->stats.csum_err_invalid_ip_version++; 492 } 493 } 494 495 sw_csum: 496 ul_header->csum_start_offset = 0; 497 ul_header->csum_insert_offset = 0; 498 ul_header->csum_enabled = 0; 499 ul_header->udp_ind = 0; 500 501 priv->stats.csum_sw++; 502 } 503 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org