1 /* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * RMNET Data ingress/egress handler
16 #include <linux/netdevice.h>
17 #include <linux/netdev_features.h>
18 #include "rmnet_private.h"
19 #include "rmnet_config.h"
20 #include "rmnet_vnd.h"
21 #include "rmnet_map.h"
22 #include "rmnet_handlers.h"
24 #define RMNET_IP_VERSION_4 0x40
25 #define RMNET_IP_VERSION_6 0x60
27 /* Helper Functions */
29 static void rmnet_set_skb_proto(struct sk_buff *skb)
31 switch (skb->data[0] & 0xF0) {
32 case RMNET_IP_VERSION_4:
33 skb->protocol = htons(ETH_P_IP);
35 case RMNET_IP_VERSION_6:
36 skb->protocol = htons(ETH_P_IPV6);
39 skb->protocol = htons(ETH_P_MAP);
47 rmnet_deliver_skb(struct sk_buff *skb)
49 struct rmnet_priv *priv = netdev_priv(skb->dev);
51 skb_reset_transport_header(skb);
52 skb_reset_network_header(skb);
53 rmnet_vnd_rx_fixup(skb, skb->dev);
55 skb->pkt_type = PACKET_HOST;
56 skb_set_mac_header(skb, 0);
57 gro_cells_receive(&priv->gro_cells, skb);
63 __rmnet_map_ingress_handler(struct sk_buff *skb,
64 struct rmnet_port *port)
66 struct rmnet_endpoint *ep;
70 if (RMNET_MAP_GET_CD_BIT(skb)) {
71 if (port->ingress_data_format
72 & RMNET_INGRESS_FORMAT_MAP_COMMANDS)
73 return rmnet_map_command(skb, port);
78 mux_id = RMNET_MAP_GET_MUX_ID(skb);
79 len = RMNET_MAP_GET_LENGTH(skb) - RMNET_MAP_GET_PAD(skb);
81 if (mux_id >= RMNET_MAX_LOGICAL_EP)
84 ep = rmnet_get_endpoint(port, mux_id);
88 skb->dev = ep->egress_dev;
90 /* Subtract MAP header */
91 skb_pull(skb, sizeof(struct rmnet_map_header));
93 rmnet_set_skb_proto(skb);
94 rmnet_deliver_skb(skb);
102 rmnet_map_ingress_handler(struct sk_buff *skb,
103 struct rmnet_port *port)
105 struct sk_buff *skbn;
107 if (port->ingress_data_format & RMNET_INGRESS_FORMAT_DEAGGREGATION) {
108 while ((skbn = rmnet_map_deaggregate(skb)) != NULL)
109 __rmnet_map_ingress_handler(skbn, port);
113 __rmnet_map_ingress_handler(skb, port);
117 static int rmnet_map_egress_handler(struct sk_buff *skb,
118 struct rmnet_port *port, u8 mux_id,
119 struct net_device *orig_dev)
121 int required_headroom, additional_header_len;
122 struct rmnet_map_header *map_header;
124 additional_header_len = 0;
125 required_headroom = sizeof(struct rmnet_map_header);
127 if (skb_headroom(skb) < required_headroom) {
128 if (pskb_expand_head(skb, required_headroom, 0, GFP_KERNEL))
132 map_header = rmnet_map_add_map_header(skb, additional_header_len, 0);
136 if (port->egress_data_format & RMNET_EGRESS_FORMAT_MUXING) {
138 map_header->mux_id = 0;
140 map_header->mux_id = mux_id;
143 skb->protocol = htons(ETH_P_MAP);
145 return RMNET_MAP_SUCCESS;
149 return RMNET_MAP_CONSUMED;
153 rmnet_bridge_handler(struct sk_buff *skb, struct net_device *bridge_dev)
156 skb->dev = bridge_dev;
161 /* Ingress / Egress Entry Points */
163 /* Processes packet as per ingress data format for receiving device. Logical
164 * endpoint is determined from packet inspection. Packet is then sent to the
165 * egress device listed in the logical endpoint configuration.
167 rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb)
169 struct sk_buff *skb = *pskb;
170 struct rmnet_port *port;
171 struct net_device *dev;
177 port = rmnet_get_port(dev);
179 switch (port->rmnet_mode) {
180 case RMNET_EPMODE_VND:
181 if (port->ingress_data_format & RMNET_INGRESS_FORMAT_MAP)
182 rmnet_map_ingress_handler(skb, port);
184 case RMNET_EPMODE_BRIDGE:
185 rmnet_bridge_handler(skb, port->bridge_ep);
190 return RX_HANDLER_CONSUMED;
193 /* Modifies packet as per logical endpoint configuration and egress data format
194 * for egress device configured in logical endpoint. Packet is then transmitted
195 * on the egress device.
197 void rmnet_egress_handler(struct sk_buff *skb)
199 struct net_device *orig_dev;
200 struct rmnet_port *port;
201 struct rmnet_priv *priv;
205 priv = netdev_priv(orig_dev);
206 skb->dev = priv->real_dev;
207 mux_id = priv->mux_id;
209 port = rmnet_get_port(skb->dev);
215 if (port->egress_data_format & RMNET_EGRESS_FORMAT_MAP) {
216 switch (rmnet_map_egress_handler(skb, port, mux_id, orig_dev)) {
217 case RMNET_MAP_CONSUMED:
220 case RMNET_MAP_SUCCESS:
229 rmnet_vnd_tx_fixup(skb, orig_dev);