OSDN Git Service

net: xfrm: use skb_list_walk_safe helper for gso segments
authorJason A. Donenfeld <Jason@zx2c4.com>
Mon, 13 Jan 2020 23:42:28 +0000 (18:42 -0500)
committerDavid S. Miller <davem@davemloft.net>
Tue, 14 Jan 2020 19:48:41 +0000 (11:48 -0800)
This is converts xfrm segment iteration to use the new function, keeping
the flow of the existing code as intact as possible. One case is very
straight-forward, whereas the other case has some more subtle code that
likes to peak at ->next and relink skbs. By keeping the variables the
same as before, we can upgrade this code with minimal surgery required.

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/xfrm/xfrm_device.c
net/xfrm/xfrm_output.c

index 189ef15..50f567a 100644 (file)
@@ -78,7 +78,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
        int err;
        unsigned long flags;
        struct xfrm_state *x;
-       struct sk_buff *skb2;
+       struct sk_buff *skb2, *nskb;
        struct softnet_data *sd;
        netdev_features_t esp_features = features;
        struct xfrm_offload *xo = xfrm_offload(skb);
@@ -148,11 +148,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
                return skb;
        }
 
-       skb2 = skb;
-
-       do {
-               struct sk_buff *nskb = skb2->next;
-
+       skb_list_walk_safe(skb, skb2, nskb) {
                esp_features |= skb->dev->gso_partial_features;
                skb_mark_not_on_list(skb2);
 
@@ -176,14 +172,11 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
                        if (!skb)
                                return NULL;
 
-                       goto skip_push;
+                       continue;
                }
 
                skb_push(skb2, skb2->data - skb_mac_header(skb2));
-
-skip_push:
-               skb2 = nskb;
-       } while (skb2);
+       }
 
        return skb;
 }
index b1db55b..fafc7ab 100644 (file)
@@ -533,7 +533,7 @@ static int xfrm_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
 
 static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb)
 {
-       struct sk_buff *segs;
+       struct sk_buff *segs, *nskb;
 
        BUILD_BUG_ON(sizeof(*IPCB(skb)) > SKB_SGO_CB_OFFSET);
        BUILD_BUG_ON(sizeof(*IP6CB(skb)) > SKB_SGO_CB_OFFSET);
@@ -544,8 +544,7 @@ static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb
        if (segs == NULL)
                return -EINVAL;
 
-       do {
-               struct sk_buff *nskb = segs->next;
+       skb_list_walk_safe(segs, segs, nskb) {
                int err;
 
                skb_mark_not_on_list(segs);
@@ -555,9 +554,7 @@ static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb
                        kfree_skb_list(nskb);
                        return err;
                }
-
-               segs = nskb;
-       } while (segs);
+       }
 
        return 0;
 }