for (i = 0; i < NEXTHDR_MAX + 1; i++) {
nhc = lowpan_nexthdr_nhcs[i]; if (!nhc) continue;
if ((id & nhc->idmask) == nhc->id) return nhc;
}
return NULL;
}
int lowpan_nhc_check_compression(struct sk_buff *skb, conststruct ipv6hdr *hdr, u8 **hc_ptr)
{ conststruct lowpan_nhc *nhc; int ret = 0;
spin_lock_bh(&lowpan_nhc_lock);
nhc = lowpan_nexthdr_nhcs[hdr->nexthdr]; if (!(nhc && nhc->compress))
ret = -ENOENT;
spin_unlock_bh(&lowpan_nhc_lock);
return ret;
}
int lowpan_nhc_do_compression(struct sk_buff *skb, conststruct ipv6hdr *hdr,
u8 **hc_ptr)
{ int ret; conststruct lowpan_nhc *nhc;
spin_lock_bh(&lowpan_nhc_lock);
nhc = lowpan_nexthdr_nhcs[hdr->nexthdr]; /* check if the nhc module was removed in unlocked part. * TODO: this is a workaround we should prevent unloading * of nhc modules while unlocked part, this will always drop * the lowpan packet but it's very unlikely. * * Solution isn't easy because we need to decide at * lowpan_nhc_check_compression if we do a compression or not. * Because the inline data which is added to skb, we can't move this * handling.
*/ if (unlikely(!nhc || !nhc->compress)) {
ret = -EINVAL; goto out;
}
/* In the case of RAW sockets the transport header is not set by * the ip6 stack so we must set it ourselves
*/ if (skb->transport_header == skb->network_header)
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
ret = nhc->compress(skb, hc_ptr); if (ret < 0) goto out;
/* skip the transport header */
skb_pull(skb, nhc->nexthdrlen);
out:
spin_unlock_bh(&lowpan_nhc_lock);
return ret;
}
int lowpan_nhc_do_uncompression(struct sk_buff *skb, conststruct net_device *dev, struct ipv6hdr *hdr)
{ conststruct lowpan_nhc *nhc; int ret;
spin_lock_bh(&lowpan_nhc_lock);
nhc = lowpan_nhc_by_nhcid(skb); if (nhc) { if (nhc->uncompress) {
ret = nhc->uncompress(skb, sizeof(struct ipv6hdr) +
nhc->nexthdrlen); if (ret < 0) {
spin_unlock_bh(&lowpan_nhc_lock); return ret;
}
} else {
spin_unlock_bh(&lowpan_nhc_lock);
netdev_warn(dev, "received nhc id for %s which is not implemented.\n",
nhc->name); return -ENOTSUPP;
}
} else {
spin_unlock_bh(&lowpan_nhc_lock);
netdev_warn(dev, "received unknown nhc id which was not found.\n"); return -ENOENT;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.