/* Modifies packet as per logical endpoint configuration and egress data format * for egress device configured in logical endpoint. Packet is then transmitted * on the egress device. */ void rmnet_egress_handler(struct sk_buff *skb) { struct net_device *orig_dev; struct rmnet_port *port; struct rmnet_priv *priv; u8 mux_id; sk_pacing_shift_update(skb->sk, 8); orig_dev = skb->dev; priv = netdev_priv(orig_dev); skb->dev = priv->real_dev; mux_id = priv->mux_id; port = rmnet_get_port(skb->dev); if (!port) goto drop; if (rmnet_map_egress_handler(skb, port, mux_id, orig_dev)) goto drop; rmnet_vnd_tx_fixup(skb, orig_dev); dev_queue_xmit(skb); return; drop: this_cpu_inc(priv->pcpu_stats->stats.tx_drops); kfree_skb(skb); }
/* Processes packet as per ingress data format for receiving device. Logical * endpoint is determined from packet inspection. Packet is then sent to the * egress device listed in the logical endpoint configuration. */ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb) { struct sk_buff *skb = *pskb; struct rmnet_port *port; struct net_device *dev; if (!skb) goto done; if (skb->pkt_type == PACKET_LOOPBACK) return RX_HANDLER_PASS; dev = skb->dev; port = rmnet_get_port(dev); switch (port->rmnet_mode) { case RMNET_EPMODE_VND: rmnet_map_ingress_handler(skb, port); break; case RMNET_EPMODE_BRIDGE: rmnet_bridge_handler(skb, port->bridge_ep); break; } done: return RX_HANDLER_CONSUMED; }
/* Processes packet as per ingress data format for receiving device. Logical * endpoint is determined from packet inspection. Packet is then sent to the * egress device listed in the logical endpoint configuration. */ rx_handler_result_t rmnet_rx_handler(struct sk_buff **pskb) { struct sk_buff *skb = *pskb; struct rmnet_port *port; struct net_device *dev; if (!skb) goto done; dev = skb->dev; port = rmnet_get_port(dev); switch (port->rmnet_mode) { case RMNET_EPMODE_VND: if (port->ingress_data_format & RMNET_INGRESS_FORMAT_MAP) rmnet_map_ingress_handler(skb, port); break; case RMNET_EPMODE_BRIDGE: rmnet_bridge_handler(skb, port->bridge_ep); break; } done: return RX_HANDLER_CONSUMED; }
/* Modifies packet as per logical endpoint configuration and egress data format * for egress device configured in logical endpoint. Packet is then transmitted * on the egress device. */ void rmnet_egress_handler(struct sk_buff *skb) { struct net_device *orig_dev; struct rmnet_port *port; struct rmnet_priv *priv; u8 mux_id; orig_dev = skb->dev; priv = netdev_priv(orig_dev); skb->dev = priv->real_dev; mux_id = priv->mux_id; port = rmnet_get_port(skb->dev); if (!port) { kfree_skb(skb); return; } if (port->egress_data_format & RMNET_EGRESS_FORMAT_MAP) { switch (rmnet_map_egress_handler(skb, port, mux_id, orig_dev)) { case RMNET_MAP_CONSUMED: return; case RMNET_MAP_SUCCESS: break; default: kfree_skb(skb); return; } } rmnet_vnd_tx_fixup(skb, orig_dev); dev_queue_xmit(skb); }