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


C++ skb_headroom函数代码示例

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


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

示例1: ath9k_htc_tx

static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
	struct ieee80211_hdr *hdr;
	struct ath9k_htc_priv *priv = hw->priv;
	int padpos, padsize, ret;

	hdr = (struct ieee80211_hdr *) skb->data;

	/* Add the padding after the header if this is not already done */
	padpos = ath9k_cmn_padpos(hdr->frame_control);
	padsize = padpos & 3;
	if (padsize && skb->len > padpos) {
		if (skb_headroom(skb) < padsize)
			return -1;
		skb_push(skb, padsize);
		memmove(skb->data, skb->data + padsize, padpos);
	}

	ret = ath9k_htc_tx_start(priv, skb);
	if (ret != 0) {
		if (ret == -ENOMEM) {
			ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
				"Stopping TX queues\n");
			ieee80211_stop_queues(hw);
			spin_lock_bh(&priv->tx_lock);
			priv->tx_queues_stop = true;
			spin_unlock_bh(&priv->tx_lock);
		} else {
			ath_dbg(ath9k_hw_common(priv->ah), ATH_DBG_XMIT,
				"Tx failed\n");
		}
		goto fail_tx;
	}

	return 0;

fail_tx:
	dev_kfree_skb_any(skb);
	return 0;
}
开发者ID:Meticulus,项目名称:vendor_st-ericsson_u8500,代码行数:40,代码来源:htc_drv_main.c

示例2: vrf_finish_direct

static int vrf_finish_direct(struct net *net, struct sock *sk,
			     struct sk_buff *skb)
{
	struct net_device *vrf_dev = skb->dev;

	if (!list_empty(&vrf_dev->ptype_all) &&
	    likely(skb_headroom(skb) >= ETH_HLEN)) {
		struct ethhdr *eth = skb_push(skb, ETH_HLEN);

		ether_addr_copy(eth->h_source, vrf_dev->dev_addr);
		eth_zero_addr(eth->h_dest);
		eth->h_proto = skb->protocol;

		rcu_read_lock_bh();
		dev_queue_xmit_nit(skb, vrf_dev);
		rcu_read_unlock_bh();

		skb_pull(skb, ETH_HLEN);
	}

	return 1;
}
开发者ID:ReneNyffenegger,项目名称:linux,代码行数:22,代码来源:vrf.c

示例3: ip_direct_send

/* Stolen from ip_finish_output2
 * PRE : skb->dev is set to the device we are leaving by
 *       skb->dst is not NULL
 * POST: the packet is sent with the link layer header pushed
 *       the packet is destroyed
 */
static void ip_direct_send(struct sk_buff *skb)
{
	struct dst_entry *dst = skb->dst;
	struct hh_cache *hh = dst->hh;
	struct net_device *dev = dst->dev;
	int hh_len = LL_RESERVED_SPACE(dev);

	/* Be paranoid, rather than too clever. */
	if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) {
		struct sk_buff *skb2;

		skb2 = skb_realloc_headroom(skb, LL_RESERVED_SPACE(dev));
		if (skb2 == NULL) {
			kfree_skb(skb);
			return;
		}
		if (skb->sk)
			skb_set_owner_w(skb2, skb->sk);
		kfree_skb(skb);
		skb = skb2;
	}

	if (hh) {
		int hh_alen;

		read_lock_bh(&hh->hh_lock);
		hh_alen = HH_DATA_ALIGN(hh->hh_len);
  		memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
		read_unlock_bh(&hh->hh_lock);
		skb_push(skb, hh->hh_len);
		hh->hh_output(skb);
	} else if (dst->neighbour)
		dst->neighbour->output(skb);
	else {
		if (net_ratelimit())
			DEBUGP(KERN_DEBUG "ipt_ROUTE: no hdr & no neighbour cache!\n");
		kfree_skb(skb);
	}
}
开发者ID:patrick-ken,项目名称:Vizio_XWR100_GPL,代码行数:45,代码来源:ipt_ROUTE.c

示例4: bcm_fast_path_output

/*
 * Direct send packets to output.
 * Stolen from ip_finish_output2.
 */
static inline int bcm_fast_path_output(struct sk_buff *skb)
{
	struct dst_entry *dst = skb->dst;
	struct net_device *dev = dst->dev;
	int hh_len = LL_RESERVED_SPACE(dev);
	int ret = 0;

	/* Be paranoid, rather than too clever. */
	if (unlikely(skb_headroom(skb) < hh_len && dev->hard_header)) {
		struct sk_buff *skb2;

		skb2 = skb_realloc_headroom(skb, hh_len);
		if (skb2 == NULL) {
			kfree_skb(skb);
			return -ENOMEM;
		}
		if (skb->sk)
			skb_set_owner_w(skb2, skb->sk);
		kfree_skb(skb);
		skb = skb2;
	}

	if (dst->hh)
		ret = neigh_hh_output(dst->hh, skb);
	else if (dst->neighbour)
		ret = dst->neighbour->output(skb);
	else {
#ifdef DEBUG
		if (net_ratelimit())
			printk(KERN_DEBUG "bcm_fast_path_output: No header cache and no neighbour!\n");
#endif
		kfree_skb(skb);
		return -EINVAL;
	}

	/* Don't return 1 */
	return (ret == 1) ? 0 : ret;
}
开发者ID:qwerty1023,项目名称:wive-rtnl-firmware,代码行数:42,代码来源:bcm_nat.c

示例5: dn_short_output

static int dn_short_output(struct sk_buff *skb)
{
    struct dst_entry *dst = skb->dst;
    struct neighbour *neigh = dst->neighbour;
    struct net_device *dev = neigh->dev;
    int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2;
    struct dn_short_packet *sp;
    unsigned char *data;
    struct dn_skb_cb *cb = DN_SKB_CB(skb);


    if (skb_headroom(skb) < headroom) {
        struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom);
        if (skb2 == NULL) {
            if (net_ratelimit())
                printk(KERN_CRIT "dn_short_output: no memory\n");
            kfree_skb(skb);
            return -ENOBUFS;
        }
        kfree_skb(skb);
        skb = skb2;
        if (net_ratelimit())
            printk(KERN_INFO "dn_short_output: Increasing headroom\n");
    }

    data = skb_push(skb, sizeof(struct dn_short_packet) + 2);
    *((unsigned short *)data) = dn_htons(skb->len - 2);
    sp = (struct dn_short_packet *)(data+2);

    sp->msgflg     = DN_RT_PKT_SHORT|(cb->rt_flags&(DN_RT_F_RQR|DN_RT_F_RTS));
    sp->dstnode    = cb->dst;
    sp->srcnode    = cb->src;
    sp->forward    = cb->hops & 0x3f;

    skb->nh.raw = skb->data;

    return NF_HOOK(PF_DECnet, NF_DN_POST_ROUTING, skb, NULL, neigh->dev, dn_neigh_output_packet);
}
开发者ID:iPodLinux,项目名称:linux-2.6.7-ipod,代码行数:38,代码来源:dn_neigh.c

示例6: x25_output

/*
 *	This is where all X.25 information frames pass.
 *
 *      Returns the amount of user data bytes sent on success
 *      or a negative error code on failure.
 */
int x25_output(struct sock *sk, struct sk_buff *skb)
{
	struct sk_buff *skbn;
	unsigned char header[X25_EXT_MIN_LEN];
	int err, frontlen, len;
	int sent=0, noblock = X25_SKB_CB(skb)->flags & MSG_DONTWAIT;
	struct x25_sock *x25 = x25_sk(sk);
	int header_len = x25->neighbour->extended ? X25_EXT_MIN_LEN :
						    X25_STD_MIN_LEN;
	int max_len = x25_pacsize_to_bytes(x25->facilities.pacsize_out);

	if (skb->len - header_len > max_len) {
		/* Save a copy of the Header */
		skb_copy_from_linear_data(skb, header, header_len);
		skb_pull(skb, header_len);

		frontlen = skb_headroom(skb);

		while (skb->len > 0) {
<<<<<<< HEAD
			release_sock(sk);
			skbn = sock_alloc_send_skb(sk, frontlen + max_len,
						   noblock, &err);
			lock_sock(sk);
			if (!skbn) {
=======
			if ((skbn = sock_alloc_send_skb(sk, frontlen + max_len,
							noblock, &err)) == NULL){
>>>>>>> 296c66da8a02d52243f45b80521febece5ed498a
				if (err == -EWOULDBLOCK && noblock){
					kfree_skb(skb);
					return sent;
				}
				SOCK_DEBUG(sk, "x25_output: fragment alloc"
					       " failed, err=%d, %d bytes "
					       "sent\n", err, sent);
				return err;
			}
开发者ID:Core2idiot,项目名称:Kernel-Samsung-3.0...-,代码行数:44,代码来源:x25_out.c

示例7: tipc_l2_send_msg

/**
 * tipc_l2_send_msg - send a TIPC packet out over an L2 interface
 * @skb: the packet to be sent
 * @b: the bearer through which the packet is to be sent
 * @dest: peer destination address
 */
int tipc_l2_send_msg(struct net *net, struct sk_buff *skb,
		     struct tipc_bearer *b, struct tipc_media_addr *dest)
{
	struct net_device *dev;
	int delta;

	dev = (struct net_device *)rcu_dereference_rtnl(b->media_ptr);
	if (!dev)
		return 0;

	delta = SKB_DATA_ALIGN(dev->hard_header_len - skb_headroom(skb));
	if ((delta > 0) && pskb_expand_head(skb, delta, 0, GFP_ATOMIC)) {
		kfree_skb(skb);
		return 0;
	}
	skb_reset_network_header(skb);
	skb->dev = dev;
	skb->protocol = htons(ETH_P_TIPC);
	dev_hard_header(skb, dev, ETH_P_TIPC, dest->value,
			dev->dev_addr, skb->len);
	dev_queue_xmit(skb);
	return 0;
}
开发者ID:krzk,项目名称:linux,代码行数:29,代码来源:bearer.c

示例8: ircomm_lmp_connect_response

static int ircomm_lmp_connect_response(struct ircomm_cb *self,
				       struct sk_buff *userdata)
{
	struct sk_buff *tx_skb;

	IRDA_DEBUG(0, "%s()\n", __func__ );

	
	if (userdata == NULL) {
		tx_skb = alloc_skb(LMP_MAX_HEADER, GFP_ATOMIC);
		if (!tx_skb)
			return -ENOMEM;

		
		skb_reserve(tx_skb, LMP_MAX_HEADER);
	} else {
		IRDA_ASSERT(skb_headroom(userdata) >= LMP_MAX_HEADER,
			    return -1;);

		
		skb_get(userdata);
		tx_skb = userdata;
	}
开发者ID:MiniBlu,项目名称:cm11_kernel_htc_msm8974a3ul,代码行数:23,代码来源:ircomm_lmp.c

示例9: ircomm_lmp_connect_response

/*
 * Function ircomm_lmp_connect_response (self, skb)
 *
 *    
 *
 */
int ircomm_lmp_connect_response(struct ircomm_cb *self, struct sk_buff *userdata)
{
	struct sk_buff *skb;
	int ret;

	IRDA_DEBUG(0, "%s()\n", __FUNCTION__);
	
	/* Any userdata supplied? */
	if (userdata == NULL) {
		skb = dev_alloc_skb(64);
		if (!skb)
			return -ENOMEM;

		/* Reserve space for MUX and LAP header */
		skb_reserve(skb, LMP_MAX_HEADER);
	} else {
		skb = userdata;
		/*  
		 *  Check that the client has reserved enough space for 
		 *  headers
		 */
		ASSERT(skb_headroom(skb) >= LMP_MAX_HEADER, return -1;);
	}
开发者ID:JBTech,项目名称:ralink_rt5350,代码行数:29,代码来源:ircomm_lmp.c

示例10: ip_xfrm_me_harder

int ip_xfrm_me_harder(struct sk_buff **pskb)
{
	struct flowi fl;
	unsigned int hh_len;
	struct dst_entry *dst;

	if (IPCB(*pskb)->flags & IPSKB_XFRM_TRANSFORMED)
		return 0;
	if (xfrm_decode_session(*pskb, &fl, AF_INET) < 0)
		return -1;

	dst = (*pskb)->dst;
	if (dst->xfrm)
		dst = ((struct xfrm_dst *)dst)->route;
	dst_hold(dst);

	if (xfrm_lookup(&dst, &fl, (*pskb)->sk, 0) < 0)
		return -1;

	dst_release((*pskb)->dst);
	(*pskb)->dst = dst;

	/* Change in oif may mean change in hh_len. */
	hh_len = (*pskb)->dst->dev->hard_header_len;
	if (skb_headroom(*pskb) < hh_len) {
		struct sk_buff *nskb;

		nskb = skb_realloc_headroom(*pskb, hh_len);
		if (!nskb)
			return -1;
		if ((*pskb)->sk)
			skb_set_owner_w(nskb, (*pskb)->sk);
		kfree_skb(*pskb);
		*pskb = nskb;
	}
	return 0;
}
开发者ID:xiandaicxsj,项目名称:copyKvm,代码行数:37,代码来源:netfilter.c

示例11: vlan_dev_hard_start_xmit

static int vlan_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct net_device_stats *stats = &dev->stats;
	struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data);

	/* Handle non-VLAN frames if they are sent to us, for example by DHCP.
	 *
	 * NOTE: THIS ASSUMES DIX ETHERNET, SPECIFICALLY NOT SUPPORTING
	 * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs...
	 */
	if (veth->h_vlan_proto != htons(ETH_P_8021Q) ||
	    vlan_dev_info(dev)->flags & VLAN_FLAG_REORDER_HDR) {
		unsigned int orig_headroom = skb_headroom(skb);
		u16 vlan_tci;

		vlan_dev_info(dev)->cnt_encap_on_xmit++;

		vlan_tci = vlan_dev_info(dev)->vlan_id;
		vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb);
		skb = __vlan_put_tag(skb, vlan_tci);
		if (!skb) {
			stats->tx_dropped++;
			return NETDEV_TX_OK;
		}

		if (orig_headroom < VLAN_HLEN)
			vlan_dev_info(dev)->cnt_inc_headroom_on_tx++;
	}

	stats->tx_packets++;
	stats->tx_bytes += skb->len;

	skb->dev = vlan_dev_info(dev)->real_dev;
	dev_queue_xmit(skb);
	return NETDEV_TX_OK;
}
开发者ID:abhijpandey,项目名称:rowboat-kernel-net,代码行数:36,代码来源:vlan_dev.c

示例12: a_netbuf_headroom

/*
 * Returns the number of bytes available to a a_netbuf_push()
 */
A_INT32
a_netbuf_headroom(void *bufPtr)
{
    return (skb_headroom((struct sk_buff *)bufPtr));
}
开发者ID:Findlee,项目名称:huawei_atheros_wifi_driver,代码行数:8,代码来源:netbuf.c

示例13: process_rxed_802_11_packet

/**
 *  @brief This function processes a received 802.11 packet and forwards it
 *  to kernel/upper layer
 *
 *  @param priv    A pointer to struct lbs_private
 *  @param skb     A pointer to skb which includes the received packet
 *  @return 	   0 or -1
 */
static int process_rxed_802_11_packet(struct lbs_private *priv,
	struct sk_buff *skb)
{
	int ret = 0;
	struct net_device *dev = priv->dev;
	struct rx80211packethdr *p_rx_pkt;
	struct rxpd *prxpd;
	struct rx_radiotap_hdr radiotap_hdr;
	struct rx_radiotap_hdr *pradiotap_hdr;

	lbs_deb_enter(LBS_DEB_RX);

	p_rx_pkt = (struct rx80211packethdr *) skb->data;
	prxpd = &p_rx_pkt->rx_pd;

	// lbs_deb_hex(LBS_DEB_RX, "RX Data: Before chop rxpd", skb->data, min(skb->len, 100));

	if (skb->len < (ETH_HLEN + 8 + sizeof(struct rxpd))) {
		lbs_deb_rx("rx err: frame received with bad length\n");
		dev->stats.rx_length_errors++;
		ret = -EINVAL;
		kfree_skb(skb);
		goto done;
	}

	/*
	 * Check rxpd status and update 802.3 stat,
	 */
	if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) {
		//lbs_deb_rx("rx err: frame received with bad status\n");
		dev->stats.rx_errors++;
	}

	lbs_deb_rx("rx data: skb->len-sizeof(RxPd) = %d-%zd = %zd\n",
	       skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));

	/* create the exported radio header */

	/* radiotap header */
	radiotap_hdr.hdr.it_version = 0;
	/* XXX must check this value for pad */
	radiotap_hdr.hdr.it_pad = 0;
	radiotap_hdr.hdr.it_len = cpu_to_le16 (sizeof(struct rx_radiotap_hdr));
	radiotap_hdr.hdr.it_present = cpu_to_le32 (RX_RADIOTAP_PRESENT);
	if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK)))
		radiotap_hdr.flags |= IEEE80211_RADIOTAP_F_BADFCS;
	radiotap_hdr.rate = convert_mv_rate_to_radiotap(prxpd->rx_rate);
	/* XXX must check no carryout */
	radiotap_hdr.antsignal = prxpd->snr + prxpd->nf;

	/* chop the rxpd */
	skb_pull(skb, sizeof(struct rxpd));

	/* add space for the new radio header */
	if ((skb_headroom(skb) < sizeof(struct rx_radiotap_hdr)) &&
	    pskb_expand_head(skb, sizeof(struct rx_radiotap_hdr), 0, GFP_ATOMIC)) {
		lbs_pr_alert("%s: couldn't pskb_expand_head\n", __func__);
		ret = -ENOMEM;
		kfree_skb(skb);
		goto done;
	}

	pradiotap_hdr = (void *)skb_push(skb, sizeof(struct rx_radiotap_hdr));
	memcpy(pradiotap_hdr, &radiotap_hdr, sizeof(struct rx_radiotap_hdr));

	/* Take the data rate from the rxpd structure
	 * only if the rate is auto
	 */
	if (priv->enablehwauto)
		priv->cur_rate = lbs_fw_index_to_data_rate(prxpd->rx_rate);

	lbs_compute_rssi(priv, prxpd);

	lbs_deb_rx("rx data: size of actual packet %d\n", skb->len);
	dev->stats.rx_bytes += skb->len;
	dev->stats.rx_packets++;

	skb->protocol = eth_type_trans(skb, priv->rtap_net_dev);
	netif_rx(skb);

	ret = 0;

done:
	lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
	return ret;
}
开发者ID:ClarkChen633,项目名称:rtl819x-toolchain,代码行数:94,代码来源:rx.c

示例14: ax25_output

/*
 *	All outgoing AX.25 I frames pass via this routine. Therefore this is
 *	where the fragmentation of frames takes place. If fragment is set to
 *	zero then we are not allowed to do fragmentation, even if the frame
 *	is too large.
 */
void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
{
    struct sk_buff *skbn;
    unsigned char *p;
    int frontlen, len, fragno, ka9qfrag, first = 1;

    if (paclen < 16) {
        WARN_ON_ONCE(1);
        kfree_skb(skb);
        return;
    }

    if ((skb->len - 1) > paclen) {
        if (*skb->data == AX25_P_TEXT) {
            skb_pull(skb, 1); /* skip PID */
            ka9qfrag = 0;
        } else {
            paclen -= 2;	/* Allow for fragment control info */
            ka9qfrag = 1;
        }

        fragno = skb->len / paclen;
        if (skb->len % paclen == 0) fragno--;

        frontlen = skb_headroom(skb);	/* Address space + CTRL */

        while (skb->len > 0) {
            spin_lock_bh(&ax25_frag_lock);
            if ((skbn = alloc_skb(paclen + 2 + frontlen, GFP_ATOMIC)) == NULL) {
                spin_unlock_bh(&ax25_frag_lock);
                printk(KERN_CRIT "AX.25: ax25_output - out of memory\n");
                return;
            }

            if (skb->sk != NULL)
                skb_set_owner_w(skbn, skb->sk);

            spin_unlock_bh(&ax25_frag_lock);

            len = (paclen > skb->len) ? skb->len : paclen;

            if (ka9qfrag == 1) {
                skb_reserve(skbn, frontlen + 2);
                skb_set_network_header(skbn,
                                       skb_network_offset(skb));
                skb_copy_from_linear_data(skb, skb_put(skbn, len), len);
                p = skb_push(skbn, 2);

                *p++ = AX25_P_SEGMENT;

                *p = fragno--;
                if (first) {
                    *p |= AX25_SEG_FIRST;
                    first = 0;
                }
            } else {
                skb_reserve(skbn, frontlen + 1);
                skb_set_network_header(skbn,
                                       skb_network_offset(skb));
                skb_copy_from_linear_data(skb, skb_put(skbn, len), len);
                p = skb_push(skbn, 1);
                *p = AX25_P_TEXT;
            }

            skb_pull(skb, len);
            skb_queue_tail(&ax25->write_queue, skbn); /* Throw it on the queue */
        }

        kfree_skb(skb);
    } else {
        skb_queue_tail(&ax25->write_queue, skb);	  /* Throw it on the queue */
    }

    switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
    case AX25_PROTO_STD_SIMPLEX:
    case AX25_PROTO_STD_DUPLEX:
        ax25_kick(ax25);
        break;

#ifdef CONFIG_AX25_DAMA_SLAVE
    /*
     * A DAMA slave is _required_ to work as normal AX.25L2V2
     * if no DAMA master is available.
     */
    case AX25_PROTO_DAMA_SLAVE:
        if (!ax25->ax25_dev->dama.slave) ax25_kick(ax25);
        break;
#endif
    }
}
开发者ID:openube,项目名称:android_kernel_sony_c2305,代码行数:96,代码来源:ax25_out.c

示例15: skb_cow_data

int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer)
{
	int copyflag;
	int elt;
	struct sk_buff *skb1, **skb_p;

	/* If skb is cloned or its head is paged, reallocate
	 * head pulling out all the pages (pages are considered not writable
	 * at the moment even if they are anonymous).
	 */
	if ((skb_cloned(skb) || skb_shinfo(skb)->nr_frags) &&
	    __pskb_pull_tail(skb, skb_pagelen(skb)-skb_headlen(skb)) == NULL)
		return -ENOMEM;

	/* Easy case. Most of packets will go this way. */
	if (!skb_shinfo(skb)->frag_list) {
		/* A little of trouble, not enough of space for trailer.
		 * This should not happen, when stack is tuned to generate
		 * good frames. OK, on miss we reallocate and reserve even more
		 * space, 128 bytes is fair. */

		if (skb_tailroom(skb) < tailbits &&
		    pskb_expand_head(skb, 0, tailbits-skb_tailroom(skb)+128, GFP_ATOMIC))
			return -ENOMEM;

		/* Voila! */
		*trailer = skb;
		return 1;
	}

	/* Misery. We are in troubles, going to mincer fragments... */

	elt = 1;
	skb_p = &skb_shinfo(skb)->frag_list;
	copyflag = 0;

	while ((skb1 = *skb_p) != NULL) {
		int ntail = 0;

		/* The fragment is partially pulled by someone,
		 * this can happen on input. Copy it and everything
		 * after it. */

		if (skb_shared(skb1))
			copyflag = 1;

		/* If the skb is the last, worry about trailer. */

		if (skb1->next == NULL && tailbits) {
			if (skb_shinfo(skb1)->nr_frags ||
			    skb_shinfo(skb1)->frag_list ||
			    skb_tailroom(skb1) < tailbits)
				ntail = tailbits + 128;
		}

		if (copyflag ||
		    skb_cloned(skb1) ||
		    ntail ||
		    skb_shinfo(skb1)->nr_frags ||
		    skb_shinfo(skb1)->frag_list) {
			struct sk_buff *skb2;

			/* Fuck, we are miserable poor guys... */
			if (ntail == 0)
				skb2 = skb_copy(skb1, GFP_ATOMIC);
			else
				skb2 = skb_copy_expand(skb1,
						       skb_headroom(skb1),
						       ntail,
						       GFP_ATOMIC);
			if (unlikely(skb2 == NULL))
				return -ENOMEM;

			if (skb1->sk)
				skb_set_owner_w(skb2, skb1->sk);

			/* Looking around. Are we still alive?
			 * OK, link new skb, drop old one */

			skb2->next = skb1->next;
			*skb_p = skb2;
			kfree_skb(skb1);
			skb1 = skb2;
		}
		elt++;
		*trailer = skb1;
		skb_p = &skb1->next;
	}

	return elt;
}
开发者ID:me-oss,项目名称:me-linux,代码行数:91,代码来源:xfrm_algo.c


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