Loading core/rmnet_config.c +3 −1 Original line number Diff line number Diff line Loading @@ -331,7 +331,9 @@ static int rmnet_config_notify_cb(struct notifier_block *nb, netdev_dbg(dev, "Kernel unregister\n"); rmnet_force_unassociate_device(dev); break; case NETDEV_DOWN: rmnet_vnd_reset_mac_addr(dev); break; default: break; } Loading core/rmnet_descriptor.c +33 −7 Original line number Diff line number Diff line Loading @@ -558,20 +558,36 @@ int rmnet_frag_flow_command(struct rmnet_frag_descriptor *frag_desc, } EXPORT_SYMBOL(rmnet_frag_flow_command); static int rmnet_frag_deaggregate_one(struct skb_shared_info *shinfo, static int rmnet_frag_deaggregate_one(struct sk_buff *skb, struct rmnet_port *port, struct list_head *list, u32 start_frag) { struct skb_shared_info *shinfo = skb_shinfo(skb); struct rmnet_frag_descriptor *frag_desc; struct rmnet_map_header *maph; struct rmnet_map_header *maph, __maph; skb_frag_t *frag; u32 i; u32 pkt_len; int rc; frag = &shinfo->frags[start_frag]; /* Grab the QMAP header. Careful, as there's no guarantee that it's * continugous! */ if (likely(skb_frag_size(frag) >= sizeof(*maph))) { maph = skb_frag_address(frag); } else { /* The header's split across pages. We can rebuild it. * Probably not faster or stronger than before. But certainly * more linear. */ if (skb_copy_bits(skb, 0, &__maph, sizeof(__maph)) < 0) return -1; maph = &__maph; } pkt_len = ntohs(maph->pkt_len); /* Catch empty frames */ if (!pkt_len) Loading @@ -590,9 +606,19 @@ static int rmnet_frag_deaggregate_one(struct skb_shared_info *shinfo, u32 hsize = 0; u8 type; type = ((struct rmnet_map_v5_coal_header *) (maph + 1))->header_type; switch (type) { /* Check the type. This seems like should be overkill for less * than a single byte, doesn't it? */ if (likely(skb_frag_size(frag) >= sizeof(*maph) + 1)) { type = *((u8 *)maph + sizeof(*maph)); } else { if (skb_copy_bits(skb, sizeof(*maph), &type, sizeof(type)) < 0) return -1; } /* Type only uses the first 7 bits */ switch ((type & 0xFE) >> 1) { case RMNET_MAP_HEADER_TYPE_COALESCING: hsize = sizeof(struct rmnet_map_v5_coal_header); break; Loading Loading @@ -647,7 +673,7 @@ void rmnet_frag_deaggregate(struct sk_buff *skb, struct rmnet_port *port, int rc; while (i < shinfo->nr_frags) { rc = rmnet_frag_deaggregate_one(shinfo, port, list, i); rc = rmnet_frag_deaggregate_one(skb, port, list, i); if (rc < 0) return; Loading core/rmnet_vnd.c +9 −1 Original line number Diff line number Diff line Loading @@ -357,7 +357,7 @@ void rmnet_vnd_setup(struct net_device *rmnet_dev) rmnet_dev->netdev_ops = &rmnet_vnd_ops; rmnet_dev->mtu = RMNET_DFLT_PACKET_SIZE; rmnet_dev->needed_headroom = RMNET_NEEDED_HEADROOM; random_ether_addr(rmnet_dev->dev_addr); random_ether_addr(rmnet_dev->perm_addr); rmnet_dev->tx_queue_len = RMNET_TX_QUEUE_LEN; /* Raw IP mode */ Loading Loading @@ -444,3 +444,11 @@ int rmnet_vnd_do_flow_control(struct net_device *rmnet_dev, int enable) return 0; } void rmnet_vnd_reset_mac_addr(struct net_device *dev) { if (dev->netdev_ops != &rmnet_vnd_ops) return; random_ether_addr(dev->perm_addr); } core/rmnet_vnd.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2018, 2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -27,4 +27,5 @@ void rmnet_vnd_rx_fixup(struct net_device *dev, u32 skb_len); void rmnet_vnd_tx_fixup(struct net_device *dev, u32 skb_len); u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev); void rmnet_vnd_setup(struct net_device *dev); void rmnet_vnd_reset_mac_addr(struct net_device *dev); #endif /* _RMNET_VND_H_ */ Loading
core/rmnet_config.c +3 −1 Original line number Diff line number Diff line Loading @@ -331,7 +331,9 @@ static int rmnet_config_notify_cb(struct notifier_block *nb, netdev_dbg(dev, "Kernel unregister\n"); rmnet_force_unassociate_device(dev); break; case NETDEV_DOWN: rmnet_vnd_reset_mac_addr(dev); break; default: break; } Loading
core/rmnet_descriptor.c +33 −7 Original line number Diff line number Diff line Loading @@ -558,20 +558,36 @@ int rmnet_frag_flow_command(struct rmnet_frag_descriptor *frag_desc, } EXPORT_SYMBOL(rmnet_frag_flow_command); static int rmnet_frag_deaggregate_one(struct skb_shared_info *shinfo, static int rmnet_frag_deaggregate_one(struct sk_buff *skb, struct rmnet_port *port, struct list_head *list, u32 start_frag) { struct skb_shared_info *shinfo = skb_shinfo(skb); struct rmnet_frag_descriptor *frag_desc; struct rmnet_map_header *maph; struct rmnet_map_header *maph, __maph; skb_frag_t *frag; u32 i; u32 pkt_len; int rc; frag = &shinfo->frags[start_frag]; /* Grab the QMAP header. Careful, as there's no guarantee that it's * continugous! */ if (likely(skb_frag_size(frag) >= sizeof(*maph))) { maph = skb_frag_address(frag); } else { /* The header's split across pages. We can rebuild it. * Probably not faster or stronger than before. But certainly * more linear. */ if (skb_copy_bits(skb, 0, &__maph, sizeof(__maph)) < 0) return -1; maph = &__maph; } pkt_len = ntohs(maph->pkt_len); /* Catch empty frames */ if (!pkt_len) Loading @@ -590,9 +606,19 @@ static int rmnet_frag_deaggregate_one(struct skb_shared_info *shinfo, u32 hsize = 0; u8 type; type = ((struct rmnet_map_v5_coal_header *) (maph + 1))->header_type; switch (type) { /* Check the type. This seems like should be overkill for less * than a single byte, doesn't it? */ if (likely(skb_frag_size(frag) >= sizeof(*maph) + 1)) { type = *((u8 *)maph + sizeof(*maph)); } else { if (skb_copy_bits(skb, sizeof(*maph), &type, sizeof(type)) < 0) return -1; } /* Type only uses the first 7 bits */ switch ((type & 0xFE) >> 1) { case RMNET_MAP_HEADER_TYPE_COALESCING: hsize = sizeof(struct rmnet_map_v5_coal_header); break; Loading Loading @@ -647,7 +673,7 @@ void rmnet_frag_deaggregate(struct sk_buff *skb, struct rmnet_port *port, int rc; while (i < shinfo->nr_frags) { rc = rmnet_frag_deaggregate_one(shinfo, port, list, i); rc = rmnet_frag_deaggregate_one(skb, port, list, i); if (rc < 0) return; Loading
core/rmnet_vnd.c +9 −1 Original line number Diff line number Diff line Loading @@ -357,7 +357,7 @@ void rmnet_vnd_setup(struct net_device *rmnet_dev) rmnet_dev->netdev_ops = &rmnet_vnd_ops; rmnet_dev->mtu = RMNET_DFLT_PACKET_SIZE; rmnet_dev->needed_headroom = RMNET_NEEDED_HEADROOM; random_ether_addr(rmnet_dev->dev_addr); random_ether_addr(rmnet_dev->perm_addr); rmnet_dev->tx_queue_len = RMNET_TX_QUEUE_LEN; /* Raw IP mode */ Loading Loading @@ -444,3 +444,11 @@ int rmnet_vnd_do_flow_control(struct net_device *rmnet_dev, int enable) return 0; } void rmnet_vnd_reset_mac_addr(struct net_device *dev) { if (dev->netdev_ops != &rmnet_vnd_ops) return; random_ether_addr(dev->perm_addr); }
core/rmnet_vnd.h +2 −1 Original line number Diff line number Diff line /* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved. /* Copyright (c) 2013-2018, 2020 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -27,4 +27,5 @@ void rmnet_vnd_rx_fixup(struct net_device *dev, u32 skb_len); void rmnet_vnd_tx_fixup(struct net_device *dev, u32 skb_len); u8 rmnet_vnd_get_mux(struct net_device *rmnet_dev); void rmnet_vnd_setup(struct net_device *dev); void rmnet_vnd_reset_mac_addr(struct net_device *dev); #endif /* _RMNET_VND_H_ */