/*1* xfrm6_mode_ro.c - Route optimization mode for IPv6.2*3* Copyright (C)2003-2006 Helsinki University of Technology4* Copyright (C)2003-2006 USAGI/WIDE Project5*6* This program is free software; you can redistribute it and/or modify7* it under the terms of the GNU General Public License as published by8* the Free Software Foundation; either version 2 of the License, or9* (at your option) any later version.10*11* This program is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14* GNU General Public License for more details.15*16* You should have received a copy of the GNU General Public License17* along with this program; if not, write to the Free Software18* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA19*/20/*21* Authors:22* Noriaki TAKAMIYA @USAGI23* Masahide NAKAMURA @USAGI24*/2526#include <linux/init.h>27#include <linux/kernel.h>28#include <linux/module.h>29#include <linux/skbuff.h>30#include <linux/spinlock.h>31#include <linux/stringify.h>32#include <linux/time.h>33#include <net/ipv6.h>34#include <net/xfrm.h>3536/* Add route optimization header space.37*38* The IP header and mutable extension headers will be moved forward to make39* space for the route optimization header.40*/41static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)42{43struct ipv6hdr *iph;44u8 *prevhdr;45int hdr_len;4647iph = ipv6_hdr(skb);4849hdr_len = x->type->hdr_offset(x, skb, &prevhdr);50skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);51skb_set_network_header(skb, -x->props.header_len);52skb->transport_header = skb->network_header + hdr_len;53__skb_pull(skb, hdr_len);54memmove(ipv6_hdr(skb), iph, hdr_len);5556x->lastused = get_seconds();5758return 0;59}6061static struct xfrm_mode xfrm6_ro_mode = {62.output = xfrm6_ro_output,63.owner = THIS_MODULE,64.encap = XFRM_MODE_ROUTEOPTIMIZATION,65};6667static int __init xfrm6_ro_init(void)68{69return xfrm_register_mode(&xfrm6_ro_mode, AF_INET6);70}7172static void __exit xfrm6_ro_exit(void)73{74int err;7576err = xfrm_unregister_mode(&xfrm6_ro_mode, AF_INET6);77BUG_ON(err);78}7980module_init(xfrm6_ro_init);81module_exit(xfrm6_ro_exit);82MODULE_LICENSE("GPL");83MODULE_ALIAS_XFRM_MODE(AF_INET6, XFRM_MODE_ROUTEOPTIMIZATION);848586