On Mon, Jul 1, 2019 at 8:31 AM John Hurley <john.hur...@netronome.com> wrote:
>
> Open vSwitch allows the updating of an existing MPLS header on a packet.
> In preparation for supporting similar functionality in TC, move this to a
> common skb helper function.
>
> Signed-off-by: John Hurley <john.hur...@netronome.com>
> Reviewed-by: Jakub Kicinski <jakub.kicin...@netronome.com>
> Reviewed-by: Simon Horman <simon.hor...@netronome.com>
> ---
>  /**
> + * skb_mpls_update_lse() - modify outermost MPLS header and update csum
> + *
> + * @skb: buffer
> + * @mpls_lse: new MPLS label stack entry to update to
> + *
> + * Expects skb->data at mac header.
> + *
> + * Returns 0 on success, -errno otherwise.
> + */
> +int skb_mpls_update_lse(struct sk_buff *skb, __be32 mpls_lse)
> +{
> +       struct mpls_shim_hdr *old_lse = mpls_hdr(skb);
> +       int err;
> +
> +       if (unlikely(!eth_p_mpls(skb->protocol)))
> +               return -EINVAL;
> +
> +       err = skb_ensure_writable(skb, skb->mac_len + MPLS_HLEN);
> +       if (unlikely(err))
> +               return err;
> +
> +       if (skb->ip_summed == CHECKSUM_COMPLETE) {
> +               __be32 diff[] = { ~old_lse->label_stack_entry, mpls_lse };
> +
> +               skb->csum = csum_partial((char *)diff, sizeof(diff), 
> skb->csum);
> +       }
> +
> +       old_lse->label_stack_entry = mpls_lse;

skb_ensure_writable may have reallocated the skb linear. old_lse needs
to be loaded after. Or, safer:

  mpls_hdr(skb)->label_stack_entry = mpls_lse;

Reply via email to