diff options
author | Jiri Pirko <jiri@resnulli.us> | 2014-11-19 08:04:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-11-21 14:20:17 -0500 |
commit | 5968250c868ceee680aa77395b24e6ddcae17d36 (patch) | |
tree | 2275b3b1db667b6362d7b528a66337f5f1f96eb7 | |
parent | 62749e2cb3c4a7da3eaa5c01a7e787aebeff8536 (diff) |
vlan: introduce *vlan_hwaccel_push_inside helpers
Use them to push skb->vlan_tci into the payload and avoid code
duplication.
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/vxlan.c | 22 | ||||
-rw-r--r-- | include/linux/if_vlan.h | 34 | ||||
-rw-r--r-- | net/core/dev.c | 8 | ||||
-rw-r--r-- | net/core/netpoll.c | 4 | ||||
-rw-r--r-- | net/ipv4/geneve.c | 11 | ||||
-rw-r--r-- | net/openvswitch/datapath.c | 4 | ||||
-rw-r--r-- | net/openvswitch/vport-gre.c | 12 |
7 files changed, 51 insertions, 44 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index bb8fbab438e8..64d45fa3d997 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -1599,14 +1599,9 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs, | |||
1599 | if (unlikely(err)) | 1599 | if (unlikely(err)) |
1600 | return err; | 1600 | return err; |
1601 | 1601 | ||
1602 | if (vlan_tx_tag_present(skb)) { | 1602 | skb = vlan_hwaccel_push_inside(skb); |
1603 | skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, | 1603 | if (WARN_ON(!skb)) |
1604 | vlan_tx_tag_get(skb)); | 1604 | return -ENOMEM; |
1605 | if (WARN_ON(!skb)) | ||
1606 | return -ENOMEM; | ||
1607 | |||
1608 | skb->vlan_tci = 0; | ||
1609 | } | ||
1610 | 1605 | ||
1611 | vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); | 1606 | vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); |
1612 | vxh->vx_flags = htonl(VXLAN_FLAGS); | 1607 | vxh->vx_flags = htonl(VXLAN_FLAGS); |
@@ -1643,14 +1638,9 @@ int vxlan_xmit_skb(struct vxlan_sock *vs, | |||
1643 | if (unlikely(err)) | 1638 | if (unlikely(err)) |
1644 | return err; | 1639 | return err; |
1645 | 1640 | ||
1646 | if (vlan_tx_tag_present(skb)) { | 1641 | skb = vlan_hwaccel_push_inside(skb); |
1647 | skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, | 1642 | if (WARN_ON(!skb)) |
1648 | vlan_tx_tag_get(skb)); | 1643 | return -ENOMEM; |
1649 | if (WARN_ON(!skb)) | ||
1650 | return -ENOMEM; | ||
1651 | |||
1652 | skb->vlan_tci = 0; | ||
1653 | } | ||
1654 | 1644 | ||
1655 | vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); | 1645 | vxh = (struct vxlanhdr *) __skb_push(skb, sizeof(*vxh)); |
1656 | vxh->vx_flags = htonl(VXLAN_FLAGS); | 1646 | vxh->vx_flags = htonl(VXLAN_FLAGS); |
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h index 46e4a15b9b55..291e6706876e 100644 --- a/include/linux/if_vlan.h +++ b/include/linux/if_vlan.h | |||
@@ -341,6 +341,40 @@ static inline struct sk_buff *vlan_insert_tag_set_proto(struct sk_buff *skb, | |||
341 | return skb; | 341 | return skb; |
342 | } | 342 | } |
343 | 343 | ||
344 | /* | ||
345 | * __vlan_hwaccel_push_inside - pushes vlan tag to the payload | ||
346 | * @skb: skbuff to tag | ||
347 | * | ||
348 | * Pushes the VLAN tag from @skb->vlan_tci inside to the payload. | ||
349 | * | ||
350 | * Following the skb_unshare() example, in case of error, the calling function | ||
351 | * doesn't have to worry about freeing the original skb. | ||
352 | */ | ||
353 | static inline struct sk_buff *__vlan_hwaccel_push_inside(struct sk_buff *skb) | ||
354 | { | ||
355 | skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, | ||
356 | vlan_tx_tag_get(skb)); | ||
357 | if (likely(skb)) | ||
358 | skb->vlan_tci = 0; | ||
359 | return skb; | ||
360 | } | ||
361 | /* | ||
362 | * vlan_hwaccel_push_inside - pushes vlan tag to the payload | ||
363 | * @skb: skbuff to tag | ||
364 | * | ||
365 | * Checks is tag is present in @skb->vlan_tci and if it is, it pushes the | ||
366 | * VLAN tag from @skb->vlan_tci inside to the payload. | ||
367 | * | ||
368 | * Following the skb_unshare() example, in case of error, the calling function | ||
369 | * doesn't have to worry about freeing the original skb. | ||
370 | */ | ||
371 | static inline struct sk_buff *vlan_hwaccel_push_inside(struct sk_buff *skb) | ||
372 | { | ||
373 | if (vlan_tx_tag_present(skb)) | ||
374 | skb = __vlan_hwaccel_push_inside(skb); | ||
375 | return skb; | ||
376 | } | ||
377 | |||
344 | /** | 378 | /** |
345 | * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting | 379 | * __vlan_hwaccel_put_tag - hardware accelerated VLAN inserting |
346 | * @skb: skbuff to tag | 380 | * @skb: skbuff to tag |
diff --git a/net/core/dev.c b/net/core/dev.c index 3611e60df407..ac4836241a96 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2644,12 +2644,8 @@ static struct sk_buff *validate_xmit_vlan(struct sk_buff *skb, | |||
2644 | netdev_features_t features) | 2644 | netdev_features_t features) |
2645 | { | 2645 | { |
2646 | if (vlan_tx_tag_present(skb) && | 2646 | if (vlan_tx_tag_present(skb) && |
2647 | !vlan_hw_offload_capable(features, skb->vlan_proto)) { | 2647 | !vlan_hw_offload_capable(features, skb->vlan_proto)) |
2648 | skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, | 2648 | skb = __vlan_hwaccel_push_inside(skb); |
2649 | vlan_tx_tag_get(skb)); | ||
2650 | if (skb) | ||
2651 | skb->vlan_tci = 0; | ||
2652 | } | ||
2653 | return skb; | 2649 | return skb; |
2654 | } | 2650 | } |
2655 | 2651 | ||
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 65d372384a3f..e0ad5d16c9c5 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -79,8 +79,7 @@ static int netpoll_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
79 | 79 | ||
80 | if (vlan_tx_tag_present(skb) && | 80 | if (vlan_tx_tag_present(skb) && |
81 | !vlan_hw_offload_capable(features, skb->vlan_proto)) { | 81 | !vlan_hw_offload_capable(features, skb->vlan_proto)) { |
82 | skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, | 82 | skb = __vlan_hwaccel_push_inside(skb); |
83 | vlan_tx_tag_get(skb)); | ||
84 | if (unlikely(!skb)) { | 83 | if (unlikely(!skb)) { |
85 | /* This is actually a packet drop, but we | 84 | /* This is actually a packet drop, but we |
86 | * don't want the code that calls this | 85 | * don't want the code that calls this |
@@ -88,7 +87,6 @@ static int netpoll_start_xmit(struct sk_buff *skb, struct net_device *dev, | |||
88 | */ | 87 | */ |
89 | goto out; | 88 | goto out; |
90 | } | 89 | } |
91 | skb->vlan_tci = 0; | ||
92 | } | 90 | } |
93 | 91 | ||
94 | status = netdev_start_xmit(skb, dev, txq, false); | 92 | status = netdev_start_xmit(skb, dev, txq, false); |
diff --git a/net/ipv4/geneve.c b/net/ipv4/geneve.c index fd430a6a1c37..a457232f0131 100644 --- a/net/ipv4/geneve.c +++ b/net/ipv4/geneve.c | |||
@@ -131,14 +131,9 @@ int geneve_xmit_skb(struct geneve_sock *gs, struct rtable *rt, | |||
131 | if (unlikely(err)) | 131 | if (unlikely(err)) |
132 | return err; | 132 | return err; |
133 | 133 | ||
134 | if (vlan_tx_tag_present(skb)) { | 134 | skb = vlan_hwaccel_push_inside(skb); |
135 | skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, | 135 | if (unlikely(!skb)) |
136 | vlan_tx_tag_get(skb)); | 136 | return -ENOMEM; |
137 | if (unlikely(!skb) | ||
138 | return -ENOMEM; | ||
139 | |||
140 | skb->vlan_tci = 0; | ||
141 | } | ||
142 | 137 | ||
143 | gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len); | 138 | gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len); |
144 | geneve_build_header(gnvh, tun_flags, vni, opt_len, opt); | 139 | geneve_build_header(gnvh, tun_flags, vni, opt_len, opt); |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index c63e60e4d947..f37ca3e5824c 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -425,12 +425,10 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb, | |||
425 | if (!nskb) | 425 | if (!nskb) |
426 | return -ENOMEM; | 426 | return -ENOMEM; |
427 | 427 | ||
428 | nskb = vlan_insert_tag_set_proto(nskb, nskb->vlan_proto, | 428 | nskb = __vlan_hwaccel_push_inside(nskb); |
429 | vlan_tx_tag_get(nskb)); | ||
430 | if (!nskb) | 429 | if (!nskb) |
431 | return -ENOMEM; | 430 | return -ENOMEM; |
432 | 431 | ||
433 | nskb->vlan_tci = 0; | ||
434 | skb = nskb; | 432 | skb = nskb; |
435 | } | 433 | } |
436 | 434 | ||
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index 777cd8c71d53..6b69df545b1d 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c | |||
@@ -175,14 +175,10 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
175 | goto err_free_rt; | 175 | goto err_free_rt; |
176 | } | 176 | } |
177 | 177 | ||
178 | if (vlan_tx_tag_present(skb)) { | 178 | skb = vlan_hwaccel_push_inside(skb); |
179 | skb = vlan_insert_tag_set_proto(skb, skb->vlan_proto, | 179 | if (unlikely(!skb)) { |
180 | vlan_tx_tag_get(skb)); | 180 | err = -ENOMEM; |
181 | if (unlikely(!skb) { | 181 | goto err_free_rt; |
182 | err = -ENOMEM; | ||
183 | goto err_free_rt; | ||
184 | } | ||
185 | skb->vlan_tci = 0; | ||
186 | } | 182 | } |
187 | 183 | ||
188 | /* Push Tunnel header. */ | 184 | /* Push Tunnel header. */ |