blob: 5f2004f088c15293ca52029ae3347c2ba678b751 [file] [log] [blame]
/*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
* interface as the means of communication with the user level.
*
* Definitions for the IP protocol.
*
* Version: @(#)ip.h 1.0.2 04/28/93
*
* Authors: Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#ifndef _LINUX_IP_H
#define _LINUX_IP_H
#include <linux/skbuff.h>
#include <uapi/linux/ip.h>
#define QTN_IP_REALIGN_MAX (4) /* Reserve tailroom for realignment on IP header */
#define QTN_IP_REALIGN_BYTES (2) /* realignment bytes on IP header */
static inline struct iphdr *ip_hdr(const struct sk_buff *skb)
{
return (struct iphdr *)skb_network_header(skb);
}
static inline struct iphdr *inner_ip_hdr(const struct sk_buff *skb)
{
return (struct iphdr *)skb_inner_network_header(skb);
}
static inline struct iphdr *ipip_hdr(const struct sk_buff *skb)
{
return (struct iphdr *)skb_transport_header(skb);
}
static inline struct iphdr *ip_hdr_aligned(struct sk_buff *skb)
{
struct iphdr *iph = ip_hdr(skb);
#ifndef CONFIG_QTN_PLATFORM_MISALIGN_WAR
int err = 0;
if (unlikely(((uint32_t)iph & 0x3) == QTN_IP_REALIGN_BYTES)) {
if (unlikely((skb->end - skb->tail) < QTN_IP_REALIGN_BYTES)) {
err = pskb_expand_head(skb, 0, QTN_IP_REALIGN_MAX, GFP_ATOMIC);
if (err)
panic("###### QTN: %s over panic and expand fail\n", __func__);
}
M_FLAG_SET(skb, M_HAS_MISALIGN);
memmove(skb->head + QTN_IP_REALIGN_BYTES, skb->head, skb->end - skb->head - QTN_IP_REALIGN_BYTES);
skb->data += QTN_IP_REALIGN_BYTES;
skb->tail += QTN_IP_REALIGN_BYTES;
skb->mac_header += QTN_IP_REALIGN_BYTES;
if (skb->network_header)
skb->network_header += QTN_IP_REALIGN_BYTES;
if ( skb->transport_header)
skb->transport_header += QTN_IP_REALIGN_BYTES;
iph = ip_hdr(skb);
}
#endif
return iph;
}
#endif /* _LINUX_IP_H */