[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1462347393-22354-4-git-send-email-simon.horman@netronome.com>
Date: Wed, 4 May 2016 16:36:29 +0900
From: Simon Horman <simon.horman@...ronome.com>
To: netdev@...r.kernel.org, dev@...nvswitch.org
Cc: Simon Horman <simon.horman@...ronome.com>
Subject: [PATCH v9 net-next 3/7] openvswitch: add support to push and pop mpls for layer3 packets
Allow push and pop mpls actions to act on layer 3 packets by teaching
them not to access non-existent L2 headers of such packets.
Signed-off-by: Simon Horman <simon.horman@...ronome.com>
---
v9
* New Patch
---
net/openvswitch/actions.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 879185fe183f..fe885a89f501 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -160,8 +160,10 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
skb_postpush_rcsum(skb, new_mpls_lse, MPLS_HLEN);
- hdr = eth_hdr(skb);
- hdr->h_proto = mpls->mpls_ethertype;
+ if (skb->mac_len) {
+ hdr = eth_hdr(skb);
+ hdr->h_proto = mpls->mpls_ethertype;
+ }
if (!skb->inner_protocol)
skb_set_inner_protocol(skb, skb->protocol);
@@ -174,7 +176,6 @@ static int push_mpls(struct sk_buff *skb, struct sw_flow_key *key,
static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key,
const __be16 ethertype)
{
- struct ethhdr *hdr;
int err;
err = skb_ensure_writable(skb, skb->mac_len + MPLS_HLEN);
@@ -189,11 +190,16 @@ static int pop_mpls(struct sk_buff *skb, struct sw_flow_key *key,
__skb_pull(skb, MPLS_HLEN);
skb_reset_mac_header(skb);
- /* skb_mpls_header() is used to locate the ethertype
- * field correctly in the presence of VLAN tags.
- */
- hdr = (struct ethhdr *)(skb_mpls_header(skb) - ETH_HLEN);
- hdr->h_proto = ethertype;
+ if (skb->mac_len) {
+ /* skb_mpls_header() is used to locate the ethertype
+ * field correctly in the presence of VLAN tags.
+ */
+ struct ethhdr *hdr;
+
+ hdr = (struct ethhdr *)(skb_mpls_header(skb) - ETH_HLEN);
+ BUG_ON((unsigned char *)hdr < skb_mac_header(skb));
+ hdr->h_proto = ethertype;
+ }
if (eth_p_mpls(skb->protocol))
skb->protocol = ethertype;
--
2.7.0.rc3.207.g0ac5344
Powered by blists - more mailing lists