1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
2024-07-22 01:58:46 -03:00

161 lines
3.6 KiB
C
Executable File

#ifndef _LINUX_ECNT_BR_H
#define _LINUX_ECNT_BR_H
#include <linux/foe_hook.h>
#include <ecnt_hook/ecnt_hook.h>
/*TCSUPPORT_MULTICAST_SPEED start*/
#ifdef TCSUPPORT_RA_HWNAT
extern int (*hwnat_set_recover_info_hook)(struct sk_buff* skb, struct sock* sk,int flag);
#else
static int (*hwnat_set_recover_info_hook)(struct sk_buff* skb, struct sock* sk,int flag) = NULL;
#endif
/*TCSUPPORT_MULTICAST_SPEED end*/
#ifdef TCSUPPORT_PON_VLAN
extern int (*pon_check_tpid_hook)(__u16 * buf);
#endif
#define FOEINFOSTORE 0
#define FOEINFORECOVER 1
#define RECEIVE_OR_SEND 0
#define SET_OR_GET_SOCKOPT 1
static void foe_info_op(struct sock *sk,void *ptr,int opmode,int direction)
{
struct sk_buff * skb;
struct SkbFoeInfo *skbfoeinfo;
switch(opmode)
{
case RECEIVE_OR_SEND:
skb = (struct sk_buff *)ptr;
if(hwnat_set_recover_info_hook)
hwnat_set_recover_info_hook(skb,sk,direction);
break;
case SET_OR_GET_SOCKOPT:
skbfoeinfo = (struct SkbFoeInfo *)ptr;
if(FOEINFORECOVER == direction)
{
skbfoeinfo->ppe_ai = sk->sk_foe_info.ppe_ai;
skbfoeinfo->ppe_foe_entry = sk->sk_foe_info.ppe_foe_entry;
skbfoeinfo->ppe_magic = sk->sk_foe_info.ppe_magic;
}
else
{
sk->sk_foe_info.ppe_ai = skbfoeinfo->ppe_ai;
sk->sk_foe_info.ppe_foe_entry = skbfoeinfo->ppe_foe_entry;
sk->sk_foe_info.ppe_magic = skbfoeinfo->ppe_magic;
}
break;
default:
break;
}
}
static inline void ecnt_packet_snd_inline_hook(struct sock *sk,void *ptr,int opmode,int direction)
{
#ifdef TCSUPPORT_MULTICAST_SPEED
foe_info_op(sk , ptr , opmode , direction);
#endif
return ;
}
static inline void ecnt_packet_recvmsg_inline_hook(struct sock *sk,void *ptr,int opmode,int direction)
{
#ifdef TCSUPPORT_MULTICAST_SPEED
foe_info_op(sk , ptr , opmode , direction);
#endif
return ;
}
void ecnt_packet_rcv_inline_hook(struct sk_buff *skb, struct net_device *orig_dev)
{
#if defined(TCSUPPORT_PON_VLAN)
u16 *proto = NULL;
if(orig_dev->name[0] == 'n')
{
proto = (u16*)(skb->data + 12);
while(pon_check_tpid_hook && (pon_check_tpid_hook(proto) == 1))
{
memmove(skb->data + VLAN_HLEN, skb->data, 12);
skb_pull(skb, VLAN_HLEN);
proto = (u16*)(skb->data + 12);
}
}
#endif
return;
}
static inline int ecnt_packet_setsockopt_inline_hook(struct sock *sk,int optname,
char __user *optval,unsigned int optlen )
{
switch (optname)
{
#ifdef TCSUPPORT_MULTICAST_SPEED
case PACKET_SKB_FOE_INFO:
{
struct SkbFoeInfo skbfoeinfo;
if (optlen < sizeof(struct SkbFoeInfo))
return ECNT_HOOK_ERROR;
if (copy_from_user(&skbfoeinfo, optval, sizeof(struct SkbFoeInfo)))
return ECNT_HOOK_ERROR;
foe_info_op(sk,&skbfoeinfo,SET_OR_GET_SOCKOPT,FOEINFOSTORE);
return ECNT_RETURN;
}
#endif
default:
return ECNT_CONTINUE ;
}
return ECNT_CONTINUE ;
}
static inline int ecnt_packet_getsockopt_inline_hook(struct sock *sk,int optname,
char __user *optval,int __user *optlen,int len, int lv,void *data )
{
struct SkbFoeInfo skbfoeinfo;
switch (optname)
{
#ifdef TCSUPPORT_MULTICAST_SPEED
case PACKET_SKB_FOE_INFO:
{
memset(&skbfoeinfo, 0, sizeof(struct SkbFoeInfo));
if (len > sizeof(struct SkbFoeInfo))
len = sizeof(struct SkbFoeInfo);
foe_info_op(sk,&skbfoeinfo,SET_OR_GET_SOCKOPT,FOEINFORECOVER);
data = &skbfoeinfo;
if (put_user(len, optlen))
return ECNT_HOOK_ERROR;
if (copy_to_user(optval, data, len))
return ECNT_HOOK_ERROR;
return ECNT_RETURN;
}
#endif
default:
return ECNT_CONTINUE ;
}
return ECNT_CONTINUE ;
}
#endif