xfrm4_tunnel.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 145 行

C
145
字号
/* xfrm4_tunnel.c: Generic IP tunnel transformer. * * Copyright (C) 2003 David S. Miller (davem@redhat.com) */#include <linux/skbuff.h>#include <linux/module.h>#include <net/xfrm.h>#include <net/ip.h>#include <net/protocol.h>static int ipip_output(struct sk_buff *skb){	struct iphdr *iph;		iph = skb->nh.iph;	iph->tot_len = htons(skb->len);	ip_send_check(iph);	return 0;}static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb){	return 0;}static struct xfrm_tunnel *ipip_handler;static DECLARE_MUTEX(xfrm4_tunnel_sem);int xfrm4_tunnel_register(struct xfrm_tunnel *handler){	int ret;	down(&xfrm4_tunnel_sem);	ret = 0;	if (ipip_handler != NULL)		ret = -EINVAL;	if (!ret)		ipip_handler = handler;	up(&xfrm4_tunnel_sem);	return ret;}EXPORT_SYMBOL(xfrm4_tunnel_register);int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler){	int ret;	down(&xfrm4_tunnel_sem);	ret = 0;	if (ipip_handler != handler)		ret = -EINVAL;	if (!ret)		ipip_handler = NULL;	up(&xfrm4_tunnel_sem);	synchronize_net();	return ret;}EXPORT_SYMBOL(xfrm4_tunnel_deregister);static int ipip_rcv(struct sk_buff *skb){	struct xfrm_tunnel *handler = ipip_handler;	/* Tunnel devices take precedence.  */	if (handler && handler->handler(skb) == 0)		return 0;	return xfrm4_rcv(skb);}static void ipip_err(struct sk_buff *skb, u32 info){	struct xfrm_tunnel *handler = ipip_handler;	u32 arg = info;	if (handler)		handler->err_handler(skb, &arg);}static int ipip_init_state(struct xfrm_state *x, void *args){	if (!x->props.mode)		return -EINVAL;	if (x->encap)		return -EINVAL;	x->props.header_len = sizeof(struct iphdr);	return 0;}static void ipip_destroy(struct xfrm_state *x){}static struct xfrm_type ipip_type = {	.description	= "IPIP",	.owner		= THIS_MODULE,	.proto	     	= IPPROTO_IPIP,	.init_state	= ipip_init_state,	.destructor	= ipip_destroy,	.input		= ipip_xfrm_rcv,	.output		= ipip_output};static struct net_protocol ipip_protocol = {	.handler	=	ipip_rcv,	.err_handler	=	ipip_err,	.no_policy	=	1,};static int __init ipip_init(void){	if (xfrm_register_type(&ipip_type, AF_INET) < 0) {		printk(KERN_INFO "ipip init: can't add xfrm type\n");		return -EAGAIN;	}	if (inet_add_protocol(&ipip_protocol, IPPROTO_IPIP) < 0) {		printk(KERN_INFO "ipip init: can't add protocol\n");		xfrm_unregister_type(&ipip_type, AF_INET);		return -EAGAIN;	}	return 0;}static void __exit ipip_fini(void){	if (inet_del_protocol(&ipip_protocol, IPPROTO_IPIP) < 0)		printk(KERN_INFO "ipip close: can't remove protocol\n");	if (xfrm_unregister_type(&ipip_type, AF_INET) < 0)		printk(KERN_INFO "ipip close: can't remove xfrm type\n");}module_init(ipip_init);module_exit(ipip_fini);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?