From: Jesse Gross Date: Mon, 6 Jun 2011 23:11:47 +0000 (-0700) Subject: datapath: Use strip_vlan() for modify_vlan_tci(). X-Git-Tag: v1.2.0~174 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=1d0f14d4c1da6e67234c0c43db66721cd7fbac98;p=sliver-openvswitch.git datapath: Use strip_vlan() for modify_vlan_tci(). The sematics for setting a vlan tag are to modify the existing tag if one exists. This can be expressed as removing the existing tag first and then adding a new one. This simplifies the code by not requiring two copies of the logic that manipulates non-accelerated vlans and should not make a performance difference because the vlan tag is contained in a single cache line. Signed-off-by: Jesse Gross Acked-by: Ben Pfaff --- diff --git a/datapath/actions.c b/datapath/actions.c index 6c1ca49cc..319c783ff 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -62,7 +62,7 @@ static struct sk_buff *strip_vlan(struct sk_buff *skb) return skb; } - if (unlikely(vlan_eth_hdr(skb)->h_vlan_proto != htons(ETH_P_8021Q) || + if (unlikely(skb->protocol != htons(ETH_P_8021Q) || skb->len < VLAN_ETH_HLEN)) return skb; @@ -86,30 +86,16 @@ static struct sk_buff *strip_vlan(struct sk_buff *skb) static struct sk_buff *modify_vlan_tci(struct sk_buff *skb, __be16 tci) { - struct vlan_ethhdr *vh; - __be16 old_tci; - - if (vlan_tx_tag_present(skb) || skb->protocol != htons(ETH_P_8021Q)) - return __vlan_hwaccel_put_tag(skb, ntohs(tci)); - - skb = make_writable(skb, 0); - if (unlikely(!skb)) - return NULL; - - if (unlikely(skb->len < VLAN_ETH_HLEN)) - return skb; - - vh = vlan_eth_hdr(skb); - - old_tci = vh->h_vlan_TCI; - vh->h_vlan_TCI = tci; + if (!vlan_tx_tag_present(skb) && skb->protocol == htons(ETH_P_8021Q)) { + if (unlikely(skb->len < VLAN_ETH_HLEN)) + return skb; - if (get_ip_summed(skb) == OVS_CSUM_COMPLETE) { - __be16 diff[] = { ~old_tci, vh->h_vlan_TCI }; - skb->csum = ~csum_partial((char *)diff, sizeof(diff), ~skb->csum); + skb = strip_vlan(skb); + if (unlikely(!skb)) + return NULL; } - return skb; + return __vlan_hwaccel_put_tag(skb, ntohs(tci)); } static bool is_ip(struct sk_buff *skb)