[NETFILTER]: Replace sk_buff ** with sk_buff *
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / net / ipv6 / netfilter / ip6t_HL.c
CommitLineData
1ab1457c 1/*
0ac4f893
HW
2 * Hop Limit modification target for ip6tables
3 * Maciej Soltysiak <solt@dns.toxicfilms.tv>
4 * Based on HW's TTL module
5 *
6 * This software is distributed under the terms of GNU GPL
7 */
8
9#include <linux/module.h>
10#include <linux/skbuff.h>
11#include <linux/ip.h>
6709dbbb 12#include <linux/ipv6.h>
0ac4f893 13
6709dbbb 14#include <linux/netfilter/x_tables.h>
0ac4f893
HW
15#include <linux/netfilter_ipv6/ip6t_HL.h>
16
17MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
6709dbbb 18MODULE_DESCRIPTION("IP6 tables Hop Limit modification module");
0ac4f893
HW
19MODULE_LICENSE("GPL");
20
3db05fea 21static unsigned int ip6t_hl_target(struct sk_buff *skb,
0ac4f893
HW
22 const struct net_device *in,
23 const struct net_device *out,
24 unsigned int hooknum,
c4986734 25 const struct xt_target *target,
fe1cb108 26 const void *targinfo)
0ac4f893
HW
27{
28 struct ipv6hdr *ip6h;
29 const struct ip6t_HL_info *info = targinfo;
0ac4f893
HW
30 int new_hl;
31
3db05fea 32 if (!skb_make_writable(skb, skb->len))
0ac4f893
HW
33 return NF_DROP;
34
3db05fea 35 ip6h = ipv6_hdr(skb);
0ac4f893
HW
36
37 switch (info->mode) {
38 case IP6T_HL_SET:
39 new_hl = info->hop_limit;
40 break;
41 case IP6T_HL_INC:
42 new_hl = ip6h->hop_limit + info->hop_limit;
43 if (new_hl > 255)
44 new_hl = 255;
45 break;
46 case IP6T_HL_DEC:
47 new_hl = ip6h->hop_limit - info->hop_limit;
48 if (new_hl < 0)
49 new_hl = 0;
50 break;
51 default:
52 new_hl = ip6h->hop_limit;
53 break;
54 }
55
2822b0d9 56 ip6h->hop_limit = new_hl;
0ac4f893 57
6709dbbb 58 return XT_CONTINUE;
0ac4f893
HW
59}
60
e1931b78 61static bool ip6t_hl_checkentry(const char *tablename,
2e4e6a17 62 const void *entry,
c4986734 63 const struct xt_target *target,
0ac4f893 64 void *targinfo,
0ac4f893
HW
65 unsigned int hook_mask)
66{
a47362a2 67 const struct ip6t_HL_info *info = targinfo;
0ac4f893 68
0ac4f893 69 if (info->mode > IP6T_HL_MAXMODE) {
1ab1457c 70 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
0ac4f893 71 info->mode);
e1931b78 72 return false;
0ac4f893 73 }
7c4e36bc 74 if (info->mode != IP6T_HL_SET && info->hop_limit == 0) {
0ac4f893
HW
75 printk(KERN_WARNING "ip6t_HL: increment/decrement doesn't "
76 "make sense with value 0\n");
e1931b78 77 return false;
0ac4f893 78 }
e1931b78 79 return true;
0ac4f893
HW
80}
81
9f15c530 82static struct xt_target ip6t_HL __read_mostly = {
1ab1457c 83 .name = "HL",
6709dbbb 84 .family = AF_INET6,
1ab1457c 85 .target = ip6t_hl_target,
7f939713
PM
86 .targetsize = sizeof(struct ip6t_HL_info),
87 .table = "mangle",
1ab1457c 88 .checkentry = ip6t_hl_checkentry,
0ac4f893
HW
89 .me = THIS_MODULE
90};
91
65b4b4e8 92static int __init ip6t_hl_init(void)
0ac4f893 93{
6709dbbb 94 return xt_register_target(&ip6t_HL);
0ac4f893
HW
95}
96
65b4b4e8 97static void __exit ip6t_hl_fini(void)
0ac4f893 98{
6709dbbb 99 xt_unregister_target(&ip6t_HL);
0ac4f893
HW
100}
101
65b4b4e8
AM
102module_init(ip6t_hl_init);
103module_exit(ip6t_hl_fini);