linux/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
<<
>>
Prefs
   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
  28struct 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
  43static void
  44ah_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
  58static struct ip_vs_conn *
  59ah_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
  84static struct ip_vs_conn *
  85ah_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
 106static int
 107ah_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
 120struct 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
 143struct 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
 164