本文整理汇总了C++中skb_headroom函数的典型用法代码示例。如果您正苦于以下问题:C++ skb_headroom函数的具体用法?C++ skb_headroom怎么用?C++ skb_headroom使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了skb_headroom函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的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
示例16: ipip_tunnel_xmit
static int ipip_tunnel_xmit(struct sk_buff *skb, struct device *dev)
{
struct ip_tunnel *tunnel = (struct ip_tunnel*)dev->priv;
struct net_device_stats *stats = &tunnel->stat;
struct iphdr *tiph = &tunnel->parms.iph;
u8 tos = tunnel->parms.iph.tos;
u16 df = tiph->frag_off;
struct rtable *rt; /* Route to the other host */
struct device *tdev; /* Device to other host */
struct iphdr *old_iph = skb->nh.iph;
struct iphdr *iph; /* Our new IP header */
int max_headroom; /* The extra header space needed */
u32 dst = tiph->daddr;
int mtu;
if (tunnel->recursion++) {
tunnel->stat.collisions++;
goto tx_error;
}
if (skb->protocol != __constant_htons(ETH_P_IP))
goto tx_error;
if (tos&1)
tos = old_iph->tos;
if (!dst) {
/* NBMA tunnel */
if ((rt = (struct rtable*)skb->dst) == NULL) {
tunnel->stat.tx_fifo_errors++;
goto tx_error;
}
if ((dst = rt->rt_gateway) == 0)
goto tx_error_icmp;
}
if (ip_route_output(&rt, dst, tiph->saddr, RT_TOS(tos), tunnel->parms.link)) {
tunnel->stat.tx_carrier_errors++;
goto tx_error_icmp;
}
tdev = rt->u.dst.dev;
if (tdev == dev) {
ip_rt_put(rt);
tunnel->stat.collisions++;
goto tx_error;
}
mtu = rt->u.dst.pmtu - sizeof(struct iphdr);
if (mtu < 68) {
tunnel->stat.collisions++;
ip_rt_put(rt);
goto tx_error;
}
if (skb->dst && mtu < skb->dst->pmtu)
skb->dst->pmtu = mtu;
df |= (old_iph->frag_off&__constant_htons(IP_DF));
if ((old_iph->frag_off&__constant_htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) {
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
ip_rt_put(rt);
goto tx_error;
}
if (tunnel->err_count > 0) {
if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) {
tunnel->err_count--;
dst_link_failure(skb);
} else
tunnel->err_count = 0;
}
skb->h.raw = skb->nh.raw;
/*
* Okay, now see if we can stuff it in the buffer as-is.
*/
max_headroom = (((tdev->hard_header_len+15)&~15)+sizeof(struct iphdr));
if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
if (!new_skb) {
ip_rt_put(rt);
stats->tx_dropped++;
dev_kfree_skb(skb);
tunnel->recursion--;
return 0;
}
if (skb->sk)
skb_set_owner_w(new_skb, skb->sk);
dev_kfree_skb(skb);
skb = new_skb;
}
skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
dst_release(skb->dst);
skb->dst = &rt->u.dst;
//.........这里部分代码省略.........
开发者ID:GNUHurdTR,项目名称:hurd,代码行数:101,代码来源:ipip.c
示例17: 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_opt *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 */
memcpy(header, skb->data, header_len);
skb_pull(skb, header_len);
frontlen = skb_headroom(skb);
while (skb->len > 0) {
if ((skbn = sock_alloc_send_skb(sk, frontlen + max_len,
noblock, &err)) == NULL){
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;
}
skb_reserve(skbn, frontlen);
len = max_len > skb->len ? skb->len : max_len;
/* Copy the user data */
memcpy(skb_put(skbn, len), skb->data, len);
skb_pull(skb, len);
/* Duplicate the Header */
skb_push(skbn, header_len);
memcpy(skbn->data, header, header_len);
if (skb->len > 0) {
if (x25->neighbour->extended)
skbn->data[3] |= X25_EXT_M_BIT;
else
skbn->data[2] |= X25_STD_M_BIT;
}
skb_queue_tail(&sk->sk_write_queue, skbn);
sent += len;
}
kfree_skb(skb);
} else {
skb_queue_tail(&sk->sk_write_queue, skb);
sent = skb->len - header_len;
}
return sent;
}
开发者ID:FelipeFernandes1988,项目名称:Alice-1121-Modem,代码行数:67,代码来源:x25_out.c
示例18: pptp_xmit
static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
{
struct sock *sk = (struct sock *) chan->private;
struct pppox_sock *po = pppox_sk(sk);
struct pptp_opt *opt=&po->proto.pptp;
struct pptp_gre_header *hdr;
unsigned int header_len=sizeof(*hdr);
int len=skb?skb->len:0;
int err=0;
int window;
struct rtable *rt; /* Route to the other host */
struct net_device *tdev; /* Device to other host */
struct iphdr *iph; /* Our new IP header */
int max_headroom; /* The extra header space needed */
INC_TX_PACKETS;
spin_lock_bh(&opt->xmit_lock);
window=WRAPPED(opt->ack_recv,opt->seq_sent)?(__u32)0xffffffff-opt->seq_sent+opt->ack_recv:opt->seq_sent-opt->ack_recv;
if (!skb){
if (opt->ack_sent == opt->seq_recv) goto exit;
}else if (window>opt->window){
__set_bit(PPTP_FLAG_PAUSE,(unsigned long*)&opt->flags);
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
mod_timer(&opt->ack_timeout_timer,opt->stat->rtt/100*HZ/10000);
#else
schedule_delayed_work(&opt->ack_timeout_work,opt->stat->rtt/100*HZ/10000);
#endif
goto exit;
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
{
struct rt_key key = {
.dst=opt->dst_addr.sin_addr.s_addr,
.src=opt->src_addr.sin_addr.s_addr,
.tos=RT_TOS(0),
};
if ((err=ip_route_output_key(&rt, &key))) {
goto tx_error;
}
}
#else
{
struct flowi fl = { .oif = 0,
.nl_u = { .ip4_u =
{ .daddr = opt->dst_addr.sin_addr.s_addr,
.saddr = opt->src_addr.sin_addr.s_addr,
.tos = RT_TOS(0) } },
.proto = IPPROTO_GRE };
if ((err=ip_route_output_key(&rt, &fl))) {
goto tx_error;
}
}
#endif
tdev = rt->u.dst.dev;
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
max_headroom = ((tdev->hard_header_len+15)&~15) + sizeof(*iph)+sizeof(*hdr)+2;
#else
max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(*iph)+sizeof(*hdr)+2;
#endif
if (!skb){
skb=dev_alloc_skb(max_headroom);
if (!skb) {
ip_rt_put(rt);
goto tx_error;
}
skb_reserve(skb,max_headroom-skb_headroom(skb));
}else if (skb_headroom(skb) < max_headroom ||
skb_cloned(skb) || skb_shared(skb)) {
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
if (!new_skb) {
ip_rt_put(rt);
goto tx_error;
}
if (skb->sk)
skb_set_owner_w(new_skb, skb->sk);
kfree_skb(skb);
skb = new_skb;
}
if (skb->len){
int islcp;
unsigned char *data=skb->data;
islcp=((data[0] << 8) + data[1])== PPP_LCP && 1 <= data[2] && data[2] <= 7;
/* compress protocol field */
if ((opt->ppp_flags & SC_COMP_PROT) && data[0]==0 && !islcp)
skb_pull(skb,1);
/*
* Put in the address/control bytes if necessary
*/
if ((opt->ppp_flags & SC_COMP_AC) == 0 || islcp) {
//.........这里部分代码省略.........
开发者ID:BackupTheBerlios,项目名称:tew632-brp-svn,代码行数:101,代码来源:pptp.c
示例19: ipip6_tunnel_xmit
static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
struct net_device_stats *stats = &tunnel->stat;
struct iphdr *tiph = &tunnel->parms.iph;
struct ipv6hdr *iph6 = ipv6_hdr(skb);
u8 tos = tunnel->parms.iph.tos;
struct rtable *rt; /* Route to the other host */
struct net_device *tdev; /* Device to other host */
struct iphdr *iph; /* Our new IP header */
unsigned int max_headroom; /* The extra header space needed */
__be32 dst = tiph->daddr;
int mtu;
if (tunnel->recursion++) {
tunnel->stat.collisions++;
goto tx_error;
}
if (skb->protocol != htons(ETH_P_IPV6))
goto tx_error;
if (extract_ipv4_endpoint(&iph6->daddr, &dst) < 0)
goto tx_error_icmp;
{
struct flowi fl = { .nl_u = { .ip4_u =
{ .daddr = dst,
.saddr = tiph->saddr,
.tos = RT_TOS(tos) } },
.oif = tunnel->parms.link,
.proto = IPPROTO_IPV6 };
if (ip_route_output_key(&rt, &fl)) {
tunnel->stat.tx_carrier_errors++;
goto tx_error_icmp;
}
}
if (rt->rt_type != RTN_UNICAST) {
ip_rt_put(rt);
tunnel->stat.tx_carrier_errors++;
goto tx_error_icmp;
}
tdev = rt->u.dst.dev;
if (tdev == dev) {
ip_rt_put(rt);
tunnel->stat.collisions++;
goto tx_error;
}
if (tiph->frag_off)
mtu = dst_mtu(&rt->u.dst) - sizeof(struct iphdr);
else
mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
if (mtu < 68) {
tunnel->stat.collisions++;
ip_rt_put(rt);
goto tx_error;
}
if (mtu < IPV6_MIN_MTU)
mtu = IPV6_MIN_MTU;
if (tunnel->parms.iph.daddr && skb->dst)
skb->dst->ops->update_pmtu(skb->dst, mtu);
if (skb->len > mtu) {
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, dev);
ip_rt_put(rt);
goto tx_error;
}
if (tunnel->err_count > 0) {
if (jiffies - tunnel->err_time < IPTUNNEL_ERR_TIMEO) {
tunnel->err_count--;
dst_link_failure(skb);
} else
tunnel->err_count = 0;
}
/*
* Okay, now see if we can stuff it in the buffer as-is.
*/
max_headroom = LL_RESERVED_SPACE(tdev)+sizeof(struct iphdr);
if (skb_headroom(skb) < max_headroom || skb_shared(skb) ||
(skb_cloned(skb) && !skb_clone_writable(skb, 0))) {
struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom);
if (!new_skb) {
ip_rt_put(rt);
stats->tx_dropped++;
dev_kfree_skb(skb);
tunnel->recursion--;
return 0;
}
if (skb->sk)
skb_set_owner_w(new_skb, skb->sk);
dev_kfree_skb(skb);
skb = new_skb;
iph6 = ipv6_hdr(skb);
}
//.........这里部分代码省略.........
开发者ID:edesiocs,项目名称:stubl,代码行数:101,代码来源:stubl.c
示例20: ip6_fragment
int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
{
struct sk_buff *frag;
struct rt6_info *rt = (struct rt6_info*)skb_dst(skb);
struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
struct ipv6hdr *tmp_hdr;
struct frag_hdr *fh;
unsigned int mtu, hlen, left, len;
__be32 frag_id = 0;
int ptr, offset = 0, err=0;
u8 *prevhdr, nexthdr = 0;
struct net *net = dev_net(skb_dst(skb)->dev);
hlen = ip6_find_1stfragopt(skb, &prevhdr);
nexthdr = *prevhdr;
mtu = ip6_skb_dst_mtu(skb);
/* We must not fragment if the socket is set to force MTU discovery
* or if the skb it not generated by a local socket.
*/
if (!skb->local_df && skb->len > mtu) {
skb->dev = skb_dst(skb)->dev;
icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
IPSTATS_MIB_FRAGFAILS);
kfree_skb(skb);
return -EMSGSIZE;
}
if (np && np->frag_size < mtu) {
if (np->frag_size)
mtu = np->frag_size;
}
mtu -= hlen + sizeof(struct frag_hdr);
if (skb_has_frag_list(skb)) {
int first_len = skb_pagelen(skb);
struct sk_buff *frag2;
if (first_len - hlen > mtu ||
((first_len - hlen) & 7) ||
skb_cloned(skb))
goto slow_path;
skb_walk_frags(skb, frag) {
/* Correct geometry. */
if (frag->len > mtu ||
((frag->len & 7) && frag->next) ||
skb_headroom(frag) < hlen)
goto slow_path_clean;
/* Partially cloned skb? */
if (skb_shared(frag))
goto slow_path_clean;
BUG_ON(frag->sk);
if (skb->sk) {
frag->sk = skb->sk;
frag->destructor = sock_wfree;
}
skb->truesize -= frag->truesize;
}
err = 0;
offset = 0;
frag = skb_shinfo(skb)->frag_list;
skb_frag_list_init(skb);
/* BUILD HEADER */
*prevhdr = NEXTHDR_FRAGMENT;
tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
if (!tmp_hdr) {
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
IPSTATS_MIB_FRAGFAILS);
return -ENOMEM;
}
__skb_pull(skb, hlen);
fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr));
__skb_push(skb, hlen);
skb_reset_network_header(skb);
memcpy(skb_network_header(skb), tmp_hdr, hlen);
ipv6_select_ident(fh, &rt->rt6i_dst.addr);
fh->nexthdr = nexthdr;
fh->reserved = 0;
fh->frag_off = htons(IP6_MF);
frag_id = fh->identification;
first_len = skb_pagelen(skb);
skb->data_len = first_len - skb_headlen(skb);
skb->len = first_len;
ipv6_hdr(skb)->payload_len = htons(first_len -
sizeof(struct ipv6hdr));
dst_hold(&rt->dst);
for (;;) {
/* Prepare header of the next frame,
//.........这里部分代码省略.........
开发者ID:caoxin1988,项目名称:linux-3.0.86,代码行数:101,代码来源:ip6_output.c
注:本文中的skb_headroom函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论