Message ID | 350fc449-ae3a-8e48-8a09-6d95cfa9901e@cumulusnetworks.com |
---|---|
State | RFC, archived |
Delegated to: | David Miller |
Headers | show |
On 8/24/16 12:53 PM, David Ahern wrote:
> What change is needed in pop_mpls? It already resets the mac_header and if MPLS labels are removed there is no need to set network_header. I take it you mean if the protocol is still MPLS and there are still labels then the network header needs to be set and that means finding the bottom label. Does OVS set the bottom of stack bit? From what I can tell OVS is not parsing the MPLS label so no requirement that BOS is set. Without that there is no way to tell when the labels are done short of guessing.
I was confusing the inner network layer with the mpls network header. Just sent a v4. can you verify it works for single and multiple labels with OVS?
On Wed, Aug 24, 2016 at 11:53 AM, David Ahern <dsa@cumulusnetworks.com> wrote: > On 8/24/16 11:41 AM, pravin shelar wrote: >> You also need to change pop_mpls(). > > What change is needed in pop_mpls? It already resets the mac_header and if MPLS labels are removed there is no need to set network_header. I take it you mean if the protocol is still MPLS and there are still labels then the network header needs to be set and that means finding the bottom label. Does OVS set the bottom of stack bit? From what I can tell OVS is not parsing the MPLS label so no requirement that BOS is set. Without that there is no way to tell when the labels are done short of guessing. > OVS mpls push and pop action works on outer most mpls label. So according to new mpls offsets tracking scheme on mpls_pop action you need to adjust skb network offset.
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 2ae929f9bd06..9f20a0b8e6be 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1292,12 +1292,16 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) int err; struct net_device *dev = neigh->dev; unsigned int seq; + unsigned int offset = skb_network_offset(skb); + + if (unlikely(skb_mac_header_was_set(skb))) + offset = skb_mac_header(skb) - skb->data; if (dev->header_ops->cache && !neigh->hh.hh_len) neigh_hh_init(neigh); do { - __skb_pull(skb, skb_network_offset(skb)); + __skb_pull(skb, offset); seq = read_seqbegin(&neigh->ha_lock); err = dev_hard_header(skb, dev, ntohs(skb->protocol), neigh->ha, NULL, skb->len);