aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Pirko <jiri@resnulli.us>2014-11-19 08:04:59 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-21 14:20:17 -0500
commit5968250c868ceee680aa77395b24e6ddcae17d36 (patch)
tree2275b3b1db667b6362d7b528a66337f5f1f96eb7
parent62749e2cb3c4a7da3eaa5c01a7e787aebeff8536 (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.c22
-rw-r--r--include/linux/if_vlan.h34
-rw-r--r--net/core/dev.c8
-rw-r--r--net/core/netpoll.c4
-rw-r--r--net/ipv4/geneve.c11
-rw-r--r--net/openvswitch/datapath.c4
-rw-r--r--net/openvswitch/vport-gre.c12
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 */
353static 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 */
371static 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. */