struct sk_buff *skb, *next;
struct list_head sublist;
+ INIT_LIST_HEAD(&sublist);
list_for_each_entry_safe(skb, next, head, list) {
struct dst_entry *dst;
+ list_del(&skb->list);
if (ip_rcv_finish_core(net, sk, skb) == NET_RX_DROP)
continue;
dst = skb_dst(skb);
if (curr_dst != dst) {
/* dispatch old sublist */
- list_cut_before(&sublist, head, &skb->list);
if (!list_empty(&sublist))
ip_sublist_rcv_finish(&sublist);
/* start new sublist */
+ INIT_LIST_HEAD(&sublist);
curr_dst = dst;
}
+ list_add_tail(&skb->list, &sublist);
}
/* dispatch final sublist */
- ip_sublist_rcv_finish(head);
+ ip_sublist_rcv_finish(&sublist);
}
static void ip_sublist_rcv(struct list_head *head, struct net_device *dev,
struct sk_buff *skb, *next;
struct list_head sublist;
+ INIT_LIST_HEAD(&sublist);
list_for_each_entry_safe(skb, next, head, list) {
struct net_device *dev = skb->dev;
struct net *net = dev_net(dev);
+ list_del(&skb->list);
skb = ip_rcv_core(skb, net);
if (skb == NULL)
continue;
if (curr_dev != dev || curr_net != net) {
/* dispatch old sublist */
- list_cut_before(&sublist, head, &skb->list);
if (!list_empty(&sublist))
- ip_sublist_rcv(&sublist, dev, net);
+ ip_sublist_rcv(&sublist, curr_dev, curr_net);
/* start new sublist */
+ INIT_LIST_HEAD(&sublist);
curr_dev = dev;
curr_net = net;
}
+ list_add_tail(&skb->list, &sublist);
}
/* dispatch final sublist */
- ip_sublist_rcv(head, curr_dev, curr_net);
+ ip_sublist_rcv(&sublist, curr_dev, curr_net);
}