cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ip6table_mangle.c (3669B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * IPv6 packet mangling table, a port of the IPv4 mangle table to IPv6
      4 *
      5 * Copyright (C) 2000-2001 by Harald Welte <laforge@gnumonks.org>
      6 * Copyright (C) 2000-2004 Netfilter Core Team <coreteam@netfilter.org>
      7 */
      8#include <linux/module.h>
      9#include <linux/netfilter_ipv6/ip6_tables.h>
     10#include <linux/slab.h>
     11#include <net/ipv6.h>
     12
     13MODULE_LICENSE("GPL");
     14MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
     15MODULE_DESCRIPTION("ip6tables mangle table");
     16
     17#define MANGLE_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | \
     18			    (1 << NF_INET_LOCAL_IN) | \
     19			    (1 << NF_INET_FORWARD) | \
     20			    (1 << NF_INET_LOCAL_OUT) | \
     21			    (1 << NF_INET_POST_ROUTING))
     22
     23static const struct xt_table packet_mangler = {
     24	.name		= "mangle",
     25	.valid_hooks	= MANGLE_VALID_HOOKS,
     26	.me		= THIS_MODULE,
     27	.af		= NFPROTO_IPV6,
     28	.priority	= NF_IP6_PRI_MANGLE,
     29};
     30
     31static unsigned int
     32ip6t_mangle_out(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
     33{
     34	unsigned int ret;
     35	struct in6_addr saddr, daddr;
     36	u_int8_t hop_limit;
     37	u_int32_t flowlabel, mark;
     38	int err;
     39
     40	/* save source/dest address, mark, hoplimit, flowlabel, priority,  */
     41	memcpy(&saddr, &ipv6_hdr(skb)->saddr, sizeof(saddr));
     42	memcpy(&daddr, &ipv6_hdr(skb)->daddr, sizeof(daddr));
     43	mark = skb->mark;
     44	hop_limit = ipv6_hdr(skb)->hop_limit;
     45
     46	/* flowlabel and prio (includes version, which shouldn't change either */
     47	flowlabel = *((u_int32_t *)ipv6_hdr(skb));
     48
     49	ret = ip6t_do_table(priv, skb, state);
     50
     51	if (ret != NF_DROP && ret != NF_STOLEN &&
     52	    (!ipv6_addr_equal(&ipv6_hdr(skb)->saddr, &saddr) ||
     53	     !ipv6_addr_equal(&ipv6_hdr(skb)->daddr, &daddr) ||
     54	     skb->mark != mark ||
     55	     ipv6_hdr(skb)->hop_limit != hop_limit ||
     56	     flowlabel != *((u_int32_t *)ipv6_hdr(skb)))) {
     57		err = ip6_route_me_harder(state->net, state->sk, skb);
     58		if (err < 0)
     59			ret = NF_DROP_ERR(err);
     60	}
     61
     62	return ret;
     63}
     64
     65/* The work comes in here from netfilter.c. */
     66static unsigned int
     67ip6table_mangle_hook(void *priv, struct sk_buff *skb,
     68		     const struct nf_hook_state *state)
     69{
     70	if (state->hook == NF_INET_LOCAL_OUT)
     71		return ip6t_mangle_out(priv, skb, state);
     72	return ip6t_do_table(priv, skb, state);
     73}
     74
     75static struct nf_hook_ops *mangle_ops __read_mostly;
     76static int ip6table_mangle_table_init(struct net *net)
     77{
     78	struct ip6t_replace *repl;
     79	int ret;
     80
     81	repl = ip6t_alloc_initial_table(&packet_mangler);
     82	if (repl == NULL)
     83		return -ENOMEM;
     84	ret = ip6t_register_table(net, &packet_mangler, repl, mangle_ops);
     85	kfree(repl);
     86	return ret;
     87}
     88
     89static void __net_exit ip6table_mangle_net_pre_exit(struct net *net)
     90{
     91	ip6t_unregister_table_pre_exit(net, "mangle");
     92}
     93
     94static void __net_exit ip6table_mangle_net_exit(struct net *net)
     95{
     96	ip6t_unregister_table_exit(net, "mangle");
     97}
     98
     99static struct pernet_operations ip6table_mangle_net_ops = {
    100	.pre_exit = ip6table_mangle_net_pre_exit,
    101	.exit = ip6table_mangle_net_exit,
    102};
    103
    104static int __init ip6table_mangle_init(void)
    105{
    106	int ret = xt_register_template(&packet_mangler,
    107				       ip6table_mangle_table_init);
    108
    109	if (ret < 0)
    110		return ret;
    111
    112	mangle_ops = xt_hook_ops_alloc(&packet_mangler, ip6table_mangle_hook);
    113	if (IS_ERR(mangle_ops)) {
    114		xt_unregister_template(&packet_mangler);
    115		return PTR_ERR(mangle_ops);
    116	}
    117
    118	ret = register_pernet_subsys(&ip6table_mangle_net_ops);
    119	if (ret < 0) {
    120		xt_unregister_template(&packet_mangler);
    121		kfree(mangle_ops);
    122		return ret;
    123	}
    124
    125	return ret;
    126}
    127
    128static void __exit ip6table_mangle_fini(void)
    129{
    130	unregister_pernet_subsys(&ip6table_mangle_net_ops);
    131	xt_unregister_template(&packet_mangler);
    132	kfree(mangle_ops);
    133}
    134
    135module_init(ip6table_mangle_init);
    136module_exit(ip6table_mangle_fini);