当前位置: 首页>>代码示例>>C++>>正文


C++ skb_copy_from_linear_data_offset函数代码示例

本文整理汇总了C++中skb_copy_from_linear_data_offset函数的典型用法代码示例。如果您正苦于以下问题:C++ skb_copy_from_linear_data_offset函数的具体用法?C++ skb_copy_from_linear_data_offset怎么用?C++ skb_copy_from_linear_data_offset使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


在下文中一共展示了skb_copy_from_linear_data_offset函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: br_nf_pre_routing_finish_bridge

/* Obtain the correct destination MAC address, while preserving the original
 * source MAC address. If we already know this address, we just copy it. If we
 * don't, we use the neighbour framework to find out. In both cases, we make
 * sure that br_handle_frame_finish() is called afterwards.
 */
static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
{
	struct nf_bridge_info *nf_bridge = skb->nf_bridge;
	struct neighbour *neigh;
	struct dst_entry *dst;

	skb->dev = bridge_parent(skb->dev);
	if (!skb->dev)
		goto free_skb;
	dst = skb_dst(skb);
	neigh = dst_get_neighbour(dst);
	if (neigh->hh.hh_len) {
		neigh_hh_bridge(&neigh->hh, skb);
		skb->dev = nf_bridge->physindev;
		return br_handle_frame_finish(skb);
	} else {
		/* the neighbour function below overwrites the complete
		 * MAC header, so we save the Ethernet source address and
		 * protocol number. */
		skb_copy_from_linear_data_offset(skb, -(ETH_HLEN-ETH_ALEN), skb->nf_bridge->data, ETH_HLEN-ETH_ALEN);
		/* tell br_dev_xmit to continue with forwarding */
		nf_bridge->mask |= BRNF_BRIDGED_DNAT;
		return neigh->output(neigh, skb);
	}
free_skb:
	kfree_skb(skb);
	return 0;
}
开发者ID:jing-git,项目名称:rt-n56u,代码行数:33,代码来源:br_netfilter.c

示例2: nf_bridge_save_header

static inline void nf_bridge_save_header(struct sk_buff *skb)
{
	int header_size = ETH_HLEN + nf_bridge_encap_header_len(skb);

	skb_copy_from_linear_data_offset(skb, -header_size,
					 skb->nf_bridge->data, header_size);
}
开发者ID:jing-git,项目名称:rt-n56u,代码行数:7,代码来源:br_netfilter.c

示例3: b1dma_dispatch_tx

static void b1dma_dispatch_tx(avmcard *card)
{
	avmcard_dmainfo *dma = card->dma;
	struct sk_buff *skb;
	u8 cmd, subcmd;
	u16 len;
	u32 txlen;
	void *p;

	skb = skb_dequeue(&dma->send_queue);

	len = CAPIMSG_LEN(skb->data);

	if (len) {
		cmd = CAPIMSG_COMMAND(skb->data);
		subcmd = CAPIMSG_SUBCOMMAND(skb->data);

		p = dma->sendbuf.dmabuf;

		if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
			u16 dlen = CAPIMSG_DATALEN(skb->data);
			_put_byte(&p, SEND_DATA_B3_REQ);
			_put_slice(&p, skb->data, len);
			_put_slice(&p, skb->data + len, dlen);
		} else {
			_put_byte(&p, SEND_MESSAGE);
			_put_slice(&p, skb->data, len);
		}
		txlen = (u8 *)p - (u8 *)dma->sendbuf.dmabuf;
#ifdef AVM_B1DMA_DEBUG
		printk(KERN_DEBUG "tx: put msg len=%d\n", txlen);
#endif
	} else {
		txlen = skb->len - 2;
#ifdef AVM_B1DMA_POLLDEBUG
		if (skb->data[2] == SEND_POLLACK)
			printk(KERN_INFO "%s: send ack\n", card->name);
#endif
#ifdef AVM_B1DMA_DEBUG
		printk(KERN_DEBUG "tx: put 0x%x len=%d\n",
		       skb->data[2], txlen);
#endif
		skb_copy_from_linear_data_offset(skb, 2, dma->sendbuf.dmabuf,
						 skb->len - 2);
	}
	txlen = (txlen + 3) & ~3;

	b1dma_writel(card, dma->sendbuf.dmaaddr, AMCC_TXPTR);
	b1dma_writel(card, txlen, AMCC_TXLEN);

	card->csr |= EN_TX_TC_INT;

	dev_kfree_skb_any(skb);
}
开发者ID:romanbb,项目名称:android_kernel_lge_d851,代码行数:54,代码来源:b1dma.c

示例4: build_inline_wqe

static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc,
			     const struct sk_buff *skb,
			     const struct skb_shared_info *shinfo,
			     void *fragptr)
{
	struct mlx4_wqe_inline_seg *inl = &tx_desc->inl;
	int spc = MLX4_INLINE_ALIGN - CTRL_SIZE - sizeof(*inl);
	unsigned int hlen = skb_headlen(skb);

	if (skb->len <= spc) {
		if (likely(skb->len >= MIN_PKT_LEN)) {
			inl->byte_count = cpu_to_be32(1 << 31 | skb->len);
		} else {
			inl->byte_count = cpu_to_be32(1 << 31 | MIN_PKT_LEN);
			memset(((void *)(inl + 1)) + skb->len, 0,
			       MIN_PKT_LEN - skb->len);
		}
		skb_copy_from_linear_data(skb, inl + 1, hlen);
		if (shinfo->nr_frags)
			memcpy(((void *)(inl + 1)) + hlen, fragptr,
			       skb_frag_size(&shinfo->frags[0]));

	} else {
		inl->byte_count = cpu_to_be32(1 << 31 | spc);
		if (hlen <= spc) {
			skb_copy_from_linear_data(skb, inl + 1, hlen);
			if (hlen < spc) {
				memcpy(((void *)(inl + 1)) + hlen,
				       fragptr, spc - hlen);
				fragptr +=  spc - hlen;
			}
			inl = (void *) (inl + 1) + spc;
			memcpy(((void *)(inl + 1)), fragptr, skb->len - spc);
		} else {
			skb_copy_from_linear_data(skb, inl + 1, spc);
			inl = (void *) (inl + 1) + spc;
			skb_copy_from_linear_data_offset(skb, spc, inl + 1,
							 hlen - spc);
			if (shinfo->nr_frags)
				memcpy(((void *)(inl + 1)) + hlen - spc,
				       fragptr,
				       skb_frag_size(&shinfo->frags[0]));
		}

		dma_wmb();
		inl->byte_count = cpu_to_be32(1 << 31 | (skb->len - spc));
	}
}
开发者ID:avagin,项目名称:linux,代码行数:48,代码来源:en_tx.c

示例5: __nr_transmit_reply

/*
 * This routine is called to send an error reply.
 */
void __nr_transmit_reply(struct sk_buff *skb, int mine, unsigned char cmdflags)
{
	struct sk_buff *skbn;
	unsigned char *dptr;
	int len;

	len = NR_NETWORK_LEN + NR_TRANSPORT_LEN + 1;

	if ((skbn = alloc_skb(len, GFP_ATOMIC)) == NULL)
		return;

	skb_reserve(skbn, 0);

	dptr = skb_put(skbn, NR_NETWORK_LEN + NR_TRANSPORT_LEN);

	skb_copy_from_linear_data_offset(skb, 7, dptr, AX25_ADDR_LEN);
	dptr[6] &= ~AX25_CBIT;
	dptr[6] &= ~AX25_EBIT;
	dptr[6] |= AX25_SSSID_SPARE;
	dptr += AX25_ADDR_LEN;

	skb_copy_from_linear_data(skb, dptr, AX25_ADDR_LEN);
	dptr[6] &= ~AX25_CBIT;
	dptr[6] |= AX25_EBIT;
	dptr[6] |= AX25_SSSID_SPARE;
	dptr += AX25_ADDR_LEN;

	*dptr++ = sysctl_netrom_network_ttl_initialiser;

	if (mine) {
		*dptr++ = 0;
		*dptr++ = 0;
		*dptr++ = skb->data[15];
		*dptr++ = skb->data[16];
	} else {
		*dptr++ = skb->data[15];
		*dptr++ = skb->data[16];
		*dptr++ = 0;
		*dptr++ = 0;
	}

	*dptr++ = cmdflags;
	*dptr++ = 0;

	if (!nr_route_frame(skbn, NULL))
		kfree_skb(skbn);
}
开发者ID:nos1609,项目名称:Chrono_Kernel-1,代码行数:50,代码来源:nr_subr.c

示例6: build_inline_wqe

static void build_inline_wqe(struct mlx4_en_tx_desc *tx_desc, struct sk_buff *skb,
			     int real_size, u16 *vlan_tag, int tx_ind, void *fragptr)
{
	struct mlx4_wqe_inline_seg *inl = &tx_desc->inl;
	int spc = MLX4_INLINE_ALIGN - CTRL_SIZE - sizeof *inl;

	if (skb->len <= spc) {
		inl->byte_count = cpu_to_be32(1 << 31 | skb->len);
		skb_copy_from_linear_data(skb, inl + 1, skb_headlen(skb));
		if (skb_shinfo(skb)->nr_frags)
			memcpy(((void *)(inl + 1)) + skb_headlen(skb), fragptr,
			       skb_frag_size(&skb_shinfo(skb)->frags[0]));

	} else {
		inl->byte_count = cpu_to_be32(1 << 31 | spc);
		if (skb_headlen(skb) <= spc) {
			skb_copy_from_linear_data(skb, inl + 1, skb_headlen(skb));
			if (skb_headlen(skb) < spc) {
				memcpy(((void *)(inl + 1)) + skb_headlen(skb),
					fragptr, spc - skb_headlen(skb));
				fragptr +=  spc - skb_headlen(skb);
			}
			inl = (void *) (inl + 1) + spc;
			memcpy(((void *)(inl + 1)), fragptr, skb->len - spc);
		} else {
			skb_copy_from_linear_data(skb, inl + 1, spc);
			inl = (void *) (inl + 1) + spc;
			skb_copy_from_linear_data_offset(skb, spc, inl + 1,
					skb_headlen(skb) - spc);
			if (skb_shinfo(skb)->nr_frags)
				memcpy(((void *)(inl + 1)) + skb_headlen(skb) - spc,
					fragptr, skb_frag_size(&skb_shinfo(skb)->frags[0]));
		}

		wmb();
		inl->byte_count = cpu_to_be32(1 << 31 | (skb->len - spc));
	}
	tx_desc->ctrl.vlan_tag = cpu_to_be16(*vlan_tag);
	tx_desc->ctrl.ins_vlan = MLX4_WQE_CTRL_INS_VLAN *
		(!!vlan_tx_tag_present(skb));
	tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
}
开发者ID:pombredanne,项目名称:https-git.sfconservancy.org-vmkdrivers,代码行数:42,代码来源:en_tx.c

示例7: dn_nsp_conn_conf

static void dn_nsp_conn_conf(struct sock *sk, struct sk_buff *skb)
{
	struct dn_skb_cb *cb = DN_SKB_CB(skb);
	struct dn_scp *scp = DN_SK(sk);
	unsigned char *ptr;

	if (skb->len < 4)
		goto out;

	ptr = skb->data;
	cb->services = *ptr++;
	cb->info = *ptr++;
	cb->segsize = le16_to_cpu(*(__le16 *)ptr);

	if ((scp->state == DN_CI) || (scp->state == DN_CD)) {
		scp->persist = 0;
		scp->addrrem = cb->src_port;
		sk->sk_state = TCP_ESTABLISHED;
		scp->state = DN_RUN;
		scp->services_rem = cb->services;
		scp->info_rem = cb->info;
		scp->segsize_rem = cb->segsize;

		if ((scp->services_rem & NSP_FC_MASK) == NSP_FC_NONE)
			scp->max_window = decnet_no_fc_max_cwnd;

		if (skb->len > 0) {
			u16 dlen = *skb->data;
			if ((dlen <= 16) && (dlen <= skb->len)) {
				scp->conndata_in.opt_optl = cpu_to_le16(dlen);
				skb_copy_from_linear_data_offset(skb, 1,
					      scp->conndata_in.opt_data, dlen);
			}
		}
		dn_nsp_send_link(sk, DN_NOCHANGE, 0);
		if (!sock_flag(sk, SOCK_DEAD))
			sk->sk_state_change(sk);
	}

out:
	kfree_skb(skb);
}
开发者ID:AlexShiLucky,项目名称:linux,代码行数:42,代码来源:dn_nsp_in.c

示例8: br_nf_pre_routing_finish_bridge

/* Obtain the correct destination MAC address, while preserving the original
 * source MAC address. If we already know this address, we just copy it. If we
 * don't, we use the neighbour framework to find out. In both cases, we make
 * sure that br_handle_frame_finish() is called afterwards.
 */
int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	struct neighbour *neigh;
	struct dst_entry *dst;

	skb->dev = bridge_parent(skb->dev);
	if (!skb->dev)
		goto free_skb;
	dst = skb_dst(skb);
	neigh = dst_neigh_lookup_skb(dst, skb);
	if (neigh) {
		struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
		int ret;

		if (neigh->hh.hh_len) {
			neigh_hh_bridge(&neigh->hh, skb);
			skb->dev = nf_bridge->physindev;
			ret = br_handle_frame_finish(net, sk, skb);
		} else {
			/* the neighbour function below overwrites the complete
			 * MAC header, so we save the Ethernet source address and
			 * protocol number.
			 */
			skb_copy_from_linear_data_offset(skb,
							 -(ETH_HLEN-ETH_ALEN),
							 nf_bridge->neigh_header,
							 ETH_HLEN-ETH_ALEN);
			/* tell br_dev_xmit to continue with forwarding */
			nf_bridge->bridged_dnat = 1;
			/* FIXME Need to refragment */
			ret = neigh->output(neigh, skb);
		}
		neigh_release(neigh);
		return ret;
	}
free_skb:
	kfree_skb(skb);
	return 0;
}
开发者ID:AshishNamdev,项目名称:linux,代码行数:44,代码来源:br_netfilter_hooks.c

示例9: br_nf_dev_queue_xmit

static int br_nf_dev_queue_xmit(struct sock *sk, struct sk_buff *skb)
{
    int ret;
    int frag_max_size;
    unsigned int mtu_reserved;

    if (skb_is_gso(skb) || skb->protocol != htons(ETH_P_IP))
        return br_dev_queue_push_xmit(sk, skb);

    mtu_reserved = nf_bridge_mtu_reduction(skb);
    /* This is wrong! We should preserve the original fragment
     * boundaries by preserving frag_list rather than refragmenting.
     */
    if (skb->len + mtu_reserved > skb->dev->mtu) {
        struct brnf_frag_data *data;

        frag_max_size = BR_INPUT_SKB_CB(skb)->frag_max_size;
        if (br_parse_ip_options(skb))
            /* Drop invalid packet */
            return NF_DROP;
        IPCB(skb)->frag_max_size = frag_max_size;

        nf_bridge_update_protocol(skb);

        data = this_cpu_ptr(&brnf_frag_data_storage);
        data->encap_size = nf_bridge_encap_header_len(skb);
        data->size = ETH_HLEN + data->encap_size;

        skb_copy_from_linear_data_offset(skb, -data->size, data->mac,
                                         data->size);

        ret = ip_fragment(sk, skb, br_nf_push_frag_xmit);
    } else {
        ret = br_dev_queue_push_xmit(sk, skb);
    }

    return ret;
}
开发者ID:coderkan,项目名称:linux,代码行数:38,代码来源:br_netfilter.c

示例10: capi_decode_conn_actv_ind

int capi_decode_conn_actv_ind(struct pcbit_chan *chan, struct sk_buff *skb)
{
	ushort len;
#ifdef DEBUG
	char str[32];
#endif

	/* Yet Another Bearer Capability */
	skb_pull(skb, *(skb->data) + 1);


	/* Connected Party Number */
	len = *(skb->data);

#ifdef DEBUG
	if (len > 1 && len < 31) {
		skb_copy_from_linear_data_offset(skb, 2, str, len - 1);
		str[len] = 0;
		printk(KERN_DEBUG "Connected Party Number: %s\n", str);
	}
	else
		printk(KERN_DEBUG "actv_ind CPN len = %d\n", len);
#endif

	skb_pull(skb, len + 1);

	/* Connected Subaddress */
	skb_pull(skb, *(skb->data) + 1);

	/* Low Layer Capability */
	skb_pull(skb, *(skb->data) + 1);

	/* High Layer Capability */
	skb_pull(skb, *(skb->data) + 1);

	return 0;
}
开发者ID:forgivemyheart,项目名称:linux,代码行数:37,代码来源:capi.c

示例11: skb_copy_from_linear_data_offset

struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user)
{
	struct iphdr iph;
	u32 len;

	if (skb->protocol != htons(ETH_P_IP))
		return skb;
#if 0
	if (!skb_copy_bits(skb, 0, &iph, skb,sizeof(iph)))
		return skb;
#else
	skb_copy_from_linear_data_offset(skb,0,&iph,sizeof(iph));
#endif

	if (iph.ihl < 5 || iph.version != 4)
		return skb;

	len = ntohs(iph.tot_len);
	if (skb->len < len || len < (iph.ihl * 4))
		return skb;

	if (ip_is_fragment(&iph)) {
		skb = skb_share_check(skb, GFP_ATOMIC);
		if (skb) {
			if (!pskb_may_pull(skb, iph.ihl*4))
				return skb;
			if (pskb_trim_rcsum(skb, len))
				return skb;
			memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
			if (ip_defrag(skb, user))
				return NULL;
			skb_clear_hash(skb);
		}
	}
	return skb;
}
开发者ID:Lanyaaki,项目名称:ipaugenblick,代码行数:36,代码来源:ip_fragment.c

示例12: dn_nsp_disc_init

static void dn_nsp_disc_init(struct sock *sk, struct sk_buff *skb)
{
	struct dn_scp *scp = DN_SK(sk);
	struct dn_skb_cb *cb = DN_SKB_CB(skb);
	unsigned short reason;

	if (skb->len < 2)
		goto out;

	reason = le16_to_cpu(*(__le16 *)skb->data);
	skb_pull(skb, 2);

	scp->discdata_in.opt_status = cpu_to_le16(reason);
	scp->discdata_in.opt_optl   = 0;
	memset(scp->discdata_in.opt_data, 0, 16);

	if (skb->len > 0) {
		u16 dlen = *skb->data;
		if ((dlen <= 16) && (dlen <= skb->len)) {
			scp->discdata_in.opt_optl = cpu_to_le16(dlen);
			skb_copy_from_linear_data_offset(skb, 1, scp->discdata_in.opt_data, dlen);
		}
	}

	scp->addrrem = cb->src_port;
	sk->sk_state = TCP_CLOSE;

	switch (scp->state) {
	case DN_CI:
	case DN_CD:
		scp->state = DN_RJ;
		sk->sk_err = ECONNREFUSED;
		break;
	case DN_RUN:
		sk->sk_shutdown |= SHUTDOWN_MASK;
		scp->state = DN_DN;
		break;
	case DN_DI:
		scp->state = DN_DIC;
		break;
	}

	if (!sock_flag(sk, SOCK_DEAD)) {
		if (sk->sk_socket->state != SS_UNCONNECTED)
			sk->sk_socket->state = SS_DISCONNECTING;
		sk->sk_state_change(sk);
	}

	/*
	 * It appears that its possible for remote machines to send disc
	 * init messages with no port identifier if we are in the CI and
	 * possibly also the CD state. Obviously we shouldn't reply with
	 * a message if we don't know what the end point is.
	 */
	if (scp->addrrem) {
		dn_nsp_send_disc(sk, NSP_DISCCONF, NSP_REASON_DC, GFP_ATOMIC);
	}
	scp->persist_fxn = dn_destroy_timer;
	scp->persist = dn_nsp_persist(sk);

out:
	kfree_skb(skb);
}
开发者ID:AlexShiLucky,项目名称:linux,代码行数:63,代码来源:dn_nsp_in.c

示例13: bgmac_dma_rx_read

static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring,
			     int weight)
{
	u32 end_slot;
	int handled = 0;

	end_slot = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_STATUS);
	end_slot &= BGMAC_DMA_RX_STATDPTR;
	end_slot /= sizeof(struct bgmac_dma_desc);

	ring->end = end_slot;

	while (ring->start != ring->end) {
		struct device *dma_dev = bgmac->core->dma_dev;
		struct bgmac_slot_info *slot = &ring->slots[ring->start];
		struct sk_buff *skb = slot->skb;
		struct sk_buff *new_skb;
		struct bgmac_rx_header *rx;
		u16 len, flags;

		/* Unmap buffer to make it accessible to the CPU */
		dma_sync_single_for_cpu(dma_dev, slot->dma_addr,
					BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);

		/* Get info from the header */
		rx = (struct bgmac_rx_header *)skb->data;
		len = le16_to_cpu(rx->len);
		flags = le16_to_cpu(rx->flags);

		/* Check for poison and drop or pass the packet */
		if (len == 0xdead && flags == 0xbeef) {
			bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n",
				  ring->start);
		} else {
			/* Omit CRC. */
			len -= ETH_FCS_LEN;

			new_skb = netdev_alloc_skb_ip_align(bgmac->net_dev, len);
			if (new_skb) {
				skb_put(new_skb, len);
				skb_copy_from_linear_data_offset(skb, BGMAC_RX_FRAME_OFFSET,
								 new_skb->data,
								 len);
				skb_checksum_none_assert(skb);
				new_skb->protocol =
					eth_type_trans(new_skb, bgmac->net_dev);
				netif_receive_skb(new_skb);
				handled++;
			} else {
				bgmac->net_dev->stats.rx_dropped++;
				bgmac_err(bgmac, "Allocation of skb for copying packet failed!\n");
			}

			/* Poison the old skb */
			rx->len = cpu_to_le16(0xdead);
			rx->flags = cpu_to_le16(0xbeef);
		}

		/* Make it back accessible to the hardware */
		dma_sync_single_for_device(dma_dev, slot->dma_addr,
					   BGMAC_RX_BUF_SIZE, DMA_FROM_DEVICE);

		if (++ring->start >= BGMAC_RX_RING_SLOTS)
			ring->start = 0;

		if (handled >= weight) /* Should never be greater */
			break;
	}

	return handled;
}
开发者ID:AiWinters,项目名称:linux,代码行数:71,代码来源:bgmac.c

示例14: br_nf_dev_queue_xmit

static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff *skb)
{
	struct nf_bridge_info *nf_bridge;
	unsigned int mtu_reserved;

	mtu_reserved = nf_bridge_mtu_reduction(skb);

	if (skb_is_gso(skb) || skb->len + mtu_reserved <= skb->dev->mtu) {
		nf_bridge_info_free(skb);
		return br_dev_queue_push_xmit(net, sk, skb);
	}

	nf_bridge = nf_bridge_info_get(skb);

	/* This is wrong! We should preserve the original fragment
	 * boundaries by preserving frag_list rather than refragmenting.
	 */
	if (IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) &&
	    skb->protocol == htons(ETH_P_IP)) {
		struct brnf_frag_data *data;

		if (br_validate_ipv4(net, skb))
			goto drop;

		IPCB(skb)->frag_max_size = nf_bridge->frag_max_size;

		nf_bridge_update_protocol(skb);

		data = this_cpu_ptr(&brnf_frag_data_storage);

		data->vlan_tci = skb->vlan_tci;
		data->vlan_proto = skb->vlan_proto;
		data->encap_size = nf_bridge_encap_header_len(skb);
		data->size = ETH_HLEN + data->encap_size;

		skb_copy_from_linear_data_offset(skb, -data->size, data->mac,
						 data->size);

		return br_nf_ip_fragment(net, sk, skb, br_nf_push_frag_xmit);
	}
	if (IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) &&
	    skb->protocol == htons(ETH_P_IPV6)) {
		const struct nf_ipv6_ops *v6ops = nf_get_ipv6_ops();
		struct brnf_frag_data *data;

		if (br_validate_ipv6(net, skb))
			goto drop;

		IP6CB(skb)->frag_max_size = nf_bridge->frag_max_size;

		nf_bridge_update_protocol(skb);

		data = this_cpu_ptr(&brnf_frag_data_storage);
		data->encap_size = nf_bridge_encap_header_len(skb);
		data->size = ETH_HLEN + data->encap_size;

		skb_copy_from_linear_data_offset(skb, -data->size, data->mac,
						 data->size);

		if (v6ops)
			return v6ops->fragment(net, sk, skb, br_nf_push_frag_xmit);

		kfree_skb(skb);
		return -EMSGSIZE;
	}
	nf_bridge_info_free(skb);
	return br_dev_queue_push_xmit(net, sk, skb);
 drop:
	kfree_skb(skb);
	return 0;
}
开发者ID:AshishNamdev,项目名称:linux,代码行数:71,代码来源:br_netfilter_hooks.c

示例15: hostap_data_start_xmit

/* hard_start_xmit function for data interfaces (wlan#, wlan#wds#, wlan#sta)
 * Convert Ethernet header into a suitable IEEE 802.11 header depending on
 * device configuration. */
netdev_tx_t hostap_data_start_xmit(struct sk_buff *skb,
				   struct net_device *dev)
{
	struct hostap_interface *iface;
	local_info_t *local;
	int need_headroom, need_tailroom = 0;
	struct ieee80211_hdr hdr;
	u16 fc, ethertype = 0;
	enum {
		WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
	} use_wds = WDS_NO;
	u8 *encaps_data;
	int hdr_len, encaps_len, skip_header_bytes;
	int to_assoc_ap = 0;
	struct hostap_skb_tx_data *meta;

	iface = netdev_priv(dev);
	local = iface->local;

	if (skb->len < ETH_HLEN) {
		printk(KERN_DEBUG "%s: hostap_data_start_xmit: short skb "
		       "(len=%d)\n", dev->name, skb->len);
		kfree_skb(skb);
		return NETDEV_TX_OK;
	}

	if (local->ddev != dev) {
		use_wds = (local->iw_mode == IW_MODE_MASTER &&
			   !(local->wds_type & HOSTAP_WDS_STANDARD_FRAME)) ?
			WDS_OWN_FRAME : WDS_COMPLIANT_FRAME;
		if (dev == local->stadev) {
			to_assoc_ap = 1;
			use_wds = WDS_NO;
		} else if (dev == local->apdev) {
			printk(KERN_DEBUG "%s: prism2_tx: trying to use "
			       "AP device with Ethernet net dev\n", dev->name);
			kfree_skb(skb);
			return NETDEV_TX_OK;
		}
	} else {
		if (local->iw_mode == IW_MODE_REPEAT) {
			printk(KERN_DEBUG "%s: prism2_tx: trying to use "
			       "non-WDS link in Repeater mode\n", dev->name);
			kfree_skb(skb);
			return NETDEV_TX_OK;
		} else if (local->iw_mode == IW_MODE_INFRA &&
			   (local->wds_type & HOSTAP_WDS_AP_CLIENT) &&
			   !ether_addr_equal(skb->data + ETH_ALEN, dev->dev_addr)) {
			/* AP client mode: send frames with foreign src addr
			 * using 4-addr WDS frames */
			use_wds = WDS_COMPLIANT_FRAME;
		}
	}

	/* Incoming skb->data: dst_addr[6], src_addr[6], proto[2], payload
	 * ==>
	 * Prism2 TX frame with 802.11 header:
	 * txdesc (address order depending on used mode; includes dst_addr and
	 * src_addr), possible encapsulation (RFC1042/Bridge-Tunnel;
	 * proto[2], payload {, possible addr4[6]} */

	ethertype = (skb->data[12] << 8) | skb->data[13];

	memset(&hdr, 0, sizeof(hdr));

	/* Length of data after IEEE 802.11 header */
	encaps_data = NULL;
	encaps_len = 0;
	skip_header_bytes = ETH_HLEN;
	if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) {
		encaps_data = bridge_tunnel_header;
		encaps_len = sizeof(bridge_tunnel_header);
		skip_header_bytes -= 2;
	} else if (ethertype >= 0x600) {
		encaps_data = rfc1042_header;
		encaps_len = sizeof(rfc1042_header);
		skip_header_bytes -= 2;
	}

	fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
	hdr_len = IEEE80211_DATA_HDR3_LEN;

	if (use_wds != WDS_NO) {
		/* Note! Prism2 station firmware has problems with sending real
		 * 802.11 frames with four addresses; until these problems can
		 * be fixed or worked around, 4-addr frames needed for WDS are
		 * using incompatible format: FromDS flag is not set and the
		 * fourth address is added after the frame payload; it is
		 * assumed, that the receiving station knows how to handle this
		 * frame format */

		if (use_wds == WDS_COMPLIANT_FRAME) {
			fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS;
			/* From&To DS: Addr1 = RA, Addr2 = TA, Addr3 = DA,
			 * Addr4 = SA */
			skb_copy_from_linear_data_offset(skb, ETH_ALEN,
							 &hdr.addr4, ETH_ALEN);
//.........这里部分代码省略.........
开发者ID:020gzh,项目名称:linux,代码行数:101,代码来源:hostap_80211_tx.c


注:本文中的skb_copy_from_linear_data_offset函数示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。