/* hfi1_vnic_update_rx_counters - update receive counters */ static void hfi1_vnic_update_rx_counters(struct hfi1_vnic_vport_info *vinfo, u8 q_idx, struct sk_buff *skb, int err) { struct ethhdr *mac_hdr = (struct ethhdr *)skb->data; struct opa_vnic_stats *stats = &vinfo->stats[q_idx]; struct opa_vnic_grp_stats *rx_grp = &stats->rx_grp; u16 vlan_tci; stats->netstats.rx_packets++; stats->netstats.rx_bytes += skb->len + ETH_FCS_LEN; update_len_counters(rx_grp, skb->len); /* rest of the counts are for good packets only */ if (unlikely(err)) return; if (is_multicast_ether_addr(mac_hdr->h_dest)) rx_grp->mcastbcast++; else rx_grp->unicast++; if (!__vlan_get_tag(skb, &vlan_tci)) rx_grp->vlan++; else rx_grp->untagged++; }
static struct sk_buff *cdc_mbim_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) { struct sk_buff *skb_out; struct cdc_mbim_state *info = (void *)&dev->data; struct cdc_ncm_ctx *ctx = info->ctx; __le32 sign = cpu_to_le32(USB_CDC_MBIM_NDP16_IPS_SIGN); u16 tci = 0; bool is_ip; u8 *c; if (!ctx) goto error; if (skb) { if (skb->len <= ETH_HLEN) goto error; /* Some applications using e.g. packet sockets will * bypass the VLAN acceleration and create tagged * ethernet frames directly. We primarily look for * the accelerated out-of-band tag, but fall back if * required */ skb_reset_mac_header(skb); if (vlan_get_tag(skb, &tci) < 0 && skb->len > VLAN_ETH_HLEN && __vlan_get_tag(skb, &tci) == 0) { is_ip = is_ip_proto(vlan_eth_hdr(skb)->h_vlan_encapsulated_proto); skb_pull(skb, VLAN_ETH_HLEN); } else { is_ip = is_ip_proto(eth_hdr(skb)->h_proto); skb_pull(skb, ETH_HLEN); } /* Is IP session <0> tagged too? */ if (info->flags & FLAG_IPS0_VLAN) { /* drop all untagged packets */ if (!tci) goto error; /* map MBIM_IPS0_VID to IPS<0> */ if (tci == MBIM_IPS0_VID) tci = 0; } /* mapping VLANs to MBIM sessions: * no tag => IPS session <0> if !FLAG_IPS0_VLAN * 1 - 255 => IPS session <vlanid> * 256 - 511 => DSS session <vlanid - 256> * 512 - 4093 => unsupported, drop * 4094 => IPS session <0> if FLAG_IPS0_VLAN */ switch (tci & 0x0f00) { case 0x0000: /* VLAN ID 0 - 255 */ if (!is_ip) goto error; c = (u8 *)&sign; c[3] = tci; break; case 0x0100: /* VLAN ID 256 - 511 */ if (is_ip) goto error; sign = cpu_to_le32(USB_CDC_MBIM_NDP16_DSS_SIGN); c = (u8 *)&sign; c[3] = tci; break; default: netif_err(dev, tx_err, dev->net, "unsupported tci=0x%04x\n", tci); goto error; } } spin_lock_bh(&ctx->mtx); skb_out = cdc_ncm_fill_tx_frame(dev, skb, sign); spin_unlock_bh(&ctx->mtx); return skb_out; error: if (skb) dev_kfree_skb_any(skb); return NULL; }
static struct sk_buff * mvswitch_mangle_tx(struct net_device *dev, struct sk_buff *skb) { struct mvswitch_priv *priv; char *buf = NULL; u16 vid; priv = dev->phy_ptr; if (unlikely(!priv)) goto error; if (unlikely(skb->len < 16)) goto error; #ifdef HEADER_MODE if (__vlan_hwaccel_get_tag(skb, &vid)) goto error; if (skb_cloned(skb) || (skb->len <= 62) || (skb_headroom(skb) < MV_HEADER_SIZE)) { if (pskb_expand_head(skb, MV_HEADER_SIZE, (skb->len < 62 ? 62 - skb->len : 0), GFP_ATOMIC)) goto error_expand; if (skb->len < 62) skb->len = 62; } buf = skb_push(skb, MV_HEADER_SIZE); #else if (__vlan_get_tag(skb, &vid)) goto error; if (unlikely((vid > 15 || !priv->vlans[vid]))) goto error; if (skb->len <= 64) { if (pskb_expand_head(skb, 0, 64 + MV_TRAILER_SIZE - skb->len, GFP_ATOMIC)) goto error_expand; buf = skb->data + 64; skb->len = 64 + MV_TRAILER_SIZE; } else { if (skb_cloned(skb) || unlikely(skb_tailroom(skb) < 4)) { if (pskb_expand_head(skb, 0, 4, GFP_ATOMIC)) goto error_expand; } buf = skb_put(skb, 4); } /* move the ethernet header 4 bytes forward, overwriting the vlan tag */ memmove(skb->data + 4, skb->data, 12); skb->data += 4; skb->len -= 4; skb->mac_header += 4; #endif if (!buf) goto error; #ifdef HEADER_MODE /* prepend the tag */ *((__be16 *) buf) = cpu_to_be16( ((vid << MV_HEADER_VLAN_S) & MV_HEADER_VLAN_M) | ((priv->vlans[vid] << MV_HEADER_PORTS_S) & MV_HEADER_PORTS_M) ); #else /* append the tag */ *((__be32 *) buf) = cpu_to_be32(( (MV_TRAILER_OVERRIDE << MV_TRAILER_FLAGS_S) | ((priv->vlans[vid] & MV_TRAILER_PORTS_M) << MV_TRAILER_PORTS_S) )); #endif return skb; error_expand: if (net_ratelimit()) printk("%s: failed to expand/update skb for the switch\n", dev->name); error: /* any errors? drop the packet! */ dev_kfree_skb_any(skb); return NULL; }