These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / net / netfilter / ipvs / ip_vs_proto_ah_esp.c
1 /*
2  * ip_vs_proto_ah_esp.c:        AH/ESP IPSec load balancing support for IPVS
3  *
4  * Authors:     Julian Anastasov <ja@ssi.bg>, February 2002
5  *              Wensong Zhang <wensong@linuxvirtualserver.org>
6  *
7  *              This program is free software; you can redistribute it and/or
8  *              modify it under the terms of the GNU General Public License
9  *              version 2 as published by the Free Software Foundation;
10  *
11  */
12
13 #define KMSG_COMPONENT "IPVS"
14 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
15
16 #include <linux/in.h>
17 #include <linux/ip.h>
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/netfilter.h>
21 #include <linux/netfilter_ipv4.h>
22
23 #include <net/ip_vs.h>
24
25
26 /* TODO:
27
28 struct isakmp_hdr {
29         __u8            icookie[8];
30         __u8            rcookie[8];
31         __u8            np;
32         __u8            version;
33         __u8            xchgtype;
34         __u8            flags;
35         __u32           msgid;
36         __u32           length;
37 };
38
39 */
40
41 #define PORT_ISAKMP     500
42
43 static void
44 ah_esp_conn_fill_param_proto(struct netns_ipvs *ipvs, int af,
45                              const struct ip_vs_iphdr *iph,
46                              struct ip_vs_conn_param *p)
47 {
48         if (likely(!ip_vs_iph_inverse(iph)))
49                 ip_vs_conn_fill_param(ipvs, af, IPPROTO_UDP,
50                                       &iph->saddr, htons(PORT_ISAKMP),
51                                       &iph->daddr, htons(PORT_ISAKMP), p);
52         else
53                 ip_vs_conn_fill_param(ipvs, af, IPPROTO_UDP,
54                                       &iph->daddr, htons(PORT_ISAKMP),
55                                       &iph->saddr, htons(PORT_ISAKMP), p);
56 }
57
58 static struct ip_vs_conn *
59 ah_esp_conn_in_get(struct netns_ipvs *ipvs, int af, const struct sk_buff *skb,
60                    const struct ip_vs_iphdr *iph)
61 {
62         struct ip_vs_conn *cp;
63         struct ip_vs_conn_param p;
64
65         ah_esp_conn_fill_param_proto(ipvs, af, iph, &p);
66         cp = ip_vs_conn_in_get(&p);
67         if (!cp) {
68                 /*
69                  * We are not sure if the packet is from our
70                  * service, so our conn_schedule hook should return NF_ACCEPT
71                  */
72                 IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for outin packet "
73                               "%s%s %s->%s\n",
74                               ip_vs_iph_icmp(iph) ? "ICMP+" : "",
75                               ip_vs_proto_get(iph->protocol)->name,
76                               IP_VS_DBG_ADDR(af, &iph->saddr),
77                               IP_VS_DBG_ADDR(af, &iph->daddr));
78         }
79
80         return cp;
81 }
82
83
84 static struct ip_vs_conn *
85 ah_esp_conn_out_get(struct netns_ipvs *ipvs, int af, const struct sk_buff *skb,
86                     const struct ip_vs_iphdr *iph)
87 {
88         struct ip_vs_conn *cp;
89         struct ip_vs_conn_param p;
90
91         ah_esp_conn_fill_param_proto(ipvs, af, iph, &p);
92         cp = ip_vs_conn_out_get(&p);
93         if (!cp) {
94                 IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet "
95                               "%s%s %s->%s\n",
96                               ip_vs_iph_icmp(iph) ? "ICMP+" : "",
97                               ip_vs_proto_get(iph->protocol)->name,
98                               IP_VS_DBG_ADDR(af, &iph->saddr),
99                               IP_VS_DBG_ADDR(af, &iph->daddr));
100         }
101
102         return cp;
103 }
104
105
106 static int
107 ah_esp_conn_schedule(struct netns_ipvs *ipvs, int af, struct sk_buff *skb,
108                      struct ip_vs_proto_data *pd,
109                      int *verdict, struct ip_vs_conn **cpp,
110                      struct ip_vs_iphdr *iph)
111 {
112         /*
113          * AH/ESP is only related traffic. Pass the packet to IP stack.
114          */
115         *verdict = NF_ACCEPT;
116         return 0;
117 }
118
119 #ifdef CONFIG_IP_VS_PROTO_AH
120 struct ip_vs_protocol ip_vs_protocol_ah = {
121         .name =                 "AH",
122         .protocol =             IPPROTO_AH,
123         .num_states =           1,
124         .dont_defrag =          1,
125         .init =                 NULL,
126         .exit =                 NULL,
127         .conn_schedule =        ah_esp_conn_schedule,
128         .conn_in_get =          ah_esp_conn_in_get,
129         .conn_out_get =         ah_esp_conn_out_get,
130         .snat_handler =         NULL,
131         .dnat_handler =         NULL,
132         .csum_check =           NULL,
133         .state_transition =     NULL,
134         .register_app =         NULL,
135         .unregister_app =       NULL,
136         .app_conn_bind =        NULL,
137         .debug_packet =         ip_vs_tcpudp_debug_packet,
138         .timeout_change =       NULL,           /* ISAKMP */
139 };
140 #endif
141
142 #ifdef CONFIG_IP_VS_PROTO_ESP
143 struct ip_vs_protocol ip_vs_protocol_esp = {
144         .name =                 "ESP",
145         .protocol =             IPPROTO_ESP,
146         .num_states =           1,
147         .dont_defrag =          1,
148         .init =                 NULL,
149         .exit =                 NULL,
150         .conn_schedule =        ah_esp_conn_schedule,
151         .conn_in_get =          ah_esp_conn_in_get,
152         .conn_out_get =         ah_esp_conn_out_get,
153         .snat_handler =         NULL,
154         .dnat_handler =         NULL,
155         .csum_check =           NULL,
156         .state_transition =     NULL,
157         .register_app =         NULL,
158         .unregister_app =       NULL,
159         .app_conn_bind =        NULL,
160         .debug_packet =         ip_vs_tcpudp_debug_packet,
161         .timeout_change =       NULL,           /* ISAKMP */
162 };
163 #endif