rmnet_map_command.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  3. */
  4. #include <linux/netdevice.h>
  5. #include "rmnet_config.h"
  6. #include "rmnet_map.h"
  7. #include "rmnet_private.h"
  8. #include "rmnet_vnd.h"
  9. static u8 rmnet_map_do_flow_control(struct sk_buff *skb,
  10. struct rmnet_port *port,
  11. int enable)
  12. {
  13. struct rmnet_endpoint *ep;
  14. struct net_device *vnd;
  15. u8 mux_id;
  16. int r;
  17. mux_id = RMNET_MAP_GET_MUX_ID(skb);
  18. if (mux_id >= RMNET_MAX_LOGICAL_EP) {
  19. kfree_skb(skb);
  20. return RX_HANDLER_CONSUMED;
  21. }
  22. ep = rmnet_get_endpoint(port, mux_id);
  23. if (!ep) {
  24. kfree_skb(skb);
  25. return RX_HANDLER_CONSUMED;
  26. }
  27. vnd = ep->egress_dev;
  28. /* Ignore the ip family and pass the sequence number for both v4 and v6
  29. * sequence. User space does not support creating dedicated flows for
  30. * the 2 protocols
  31. */
  32. r = rmnet_vnd_do_flow_control(vnd, enable);
  33. if (r) {
  34. kfree_skb(skb);
  35. return RMNET_MAP_COMMAND_UNSUPPORTED;
  36. } else {
  37. return RMNET_MAP_COMMAND_ACK;
  38. }
  39. }
  40. static void rmnet_map_send_ack(struct sk_buff *skb,
  41. unsigned char type,
  42. struct rmnet_port *port)
  43. {
  44. struct rmnet_map_control_command *cmd;
  45. struct net_device *dev = skb->dev;
  46. if (port->data_format & RMNET_FLAGS_INGRESS_MAP_CKSUMV4)
  47. skb_trim(skb,
  48. skb->len - sizeof(struct rmnet_map_dl_csum_trailer));
  49. skb->protocol = htons(ETH_P_MAP);
  50. cmd = RMNET_MAP_GET_CMD_START(skb);
  51. cmd->cmd_type = type & 0x03;
  52. netif_tx_lock(dev);
  53. dev->netdev_ops->ndo_start_xmit(skb, dev);
  54. netif_tx_unlock(dev);
  55. }
  56. /* Process MAP command frame and send N/ACK message as appropriate. Message cmd
  57. * name is decoded here and appropriate handler is called.
  58. */
  59. void rmnet_map_command(struct sk_buff *skb, struct rmnet_port *port)
  60. {
  61. struct rmnet_map_control_command *cmd;
  62. unsigned char command_name;
  63. unsigned char rc = 0;
  64. cmd = RMNET_MAP_GET_CMD_START(skb);
  65. command_name = cmd->command_name;
  66. switch (command_name) {
  67. case RMNET_MAP_COMMAND_FLOW_ENABLE:
  68. rc = rmnet_map_do_flow_control(skb, port, 1);
  69. break;
  70. case RMNET_MAP_COMMAND_FLOW_DISABLE:
  71. rc = rmnet_map_do_flow_control(skb, port, 0);
  72. break;
  73. default:
  74. rc = RMNET_MAP_COMMAND_UNSUPPORTED;
  75. kfree_skb(skb);
  76. break;
  77. }
  78. if (rc == RMNET_MAP_COMMAND_ACK)
  79. rmnet_map_send_ack(skb, rc, port);
  80. }