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 net *net, int af,
  45                             const struct ip_vs_iphdr *iph, int inverse,
  46                             struct ip_vs_conn_param *p)
  47{
  48        if (likely(!inverse))
  49                ip_vs_conn_fill_param(net, af, IPPROTO_UDP,
  50                                      &iph->saddr, htons(PORT_ISAKMP),
  51                                      &iph->daddr, htons(PORT_ISAKMP), p);
  52        else
  53                ip_vs_conn_fill_param(net, 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(int af, const struct sk_buff *skb,
  60                   const struct ip_vs_iphdr *iph,
  61                   int inverse)
  62{
  63        struct ip_vs_conn *cp;
  64        struct ip_vs_conn_param p;
  65        struct net *net = skb_net(skb);
  66
  67        ah_esp_conn_fill_param_proto(net, af, iph, inverse, &p);
  68        cp = ip_vs_conn_in_get(&p);
  69        if (!cp) {
  70                /*
  71                 * We are not sure if the packet is from our
  72                 * service, so our conn_schedule hook should return NF_ACCEPT
  73                 */
  74                IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for outin packet "
  75                              "%s%s %s->%s\n",
  76                              inverse ? "ICMP+" : "",
  77                              ip_vs_proto_get(iph->protocol)->name,
  78                              IP_VS_DBG_ADDR(af, &iph->saddr),
  79                              IP_VS_DBG_ADDR(af, &iph->daddr));
  80        }
  81
  82        return cp;
  83}
  84
  85
  86static struct ip_vs_conn *
  87ah_esp_conn_out_get(int af, const struct sk_buff *skb,
  88                    const struct ip_vs_iphdr *iph, int inverse)
  89{
  90        struct ip_vs_conn *cp;
  91        struct ip_vs_conn_param p;
  92        struct net *net = skb_net(skb);
  93
  94        ah_esp_conn_fill_param_proto(net, af, iph, inverse, &p);
  95        cp = ip_vs_conn_out_get(&p);
  96        if (!cp) {
  97                IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet "
  98                              "%s%s %s->%s\n",
  99                              inverse ? "ICMP+" : "",
 100                              ip_vs_proto_get(iph->protocol)->name,
 101                              IP_VS_DBG_ADDR(af, &iph->saddr),
 102                              IP_VS_DBG_ADDR(af, &iph->daddr));
 103        }
 104
 105        return cp;
 106}
 107
 108
 109static int
 110ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_proto_data *pd,
 111                     int *verdict, struct ip_vs_conn **cpp,
 112                     struct ip_vs_iphdr *iph)
 113{
 114        /*
 115         * AH/ESP is only related traffic. Pass the packet to IP stack.
 116         */
 117        *verdict = NF_ACCEPT;
 118        return 0;
 119}
 120
 121#ifdef CONFIG_IP_VS_PROTO_AH
 122struct ip_vs_protocol ip_vs_protocol_ah = {
 123        .name =                 "AH",
 124        .protocol =             IPPROTO_AH,
 125        .num_states =           1,
 126        .dont_defrag =          1,
 127        .init =                 NULL,
 128        .exit =                 NULL,
 129        .conn_schedule =        ah_esp_conn_schedule,
 130        .conn_in_get =          ah_esp_conn_in_get,
 131        .conn_out_get =         ah_esp_conn_out_get,
 132        .snat_handler =         NULL,
 133        .dnat_handler =         NULL,
 134        .csum_check =           NULL,
 135        .state_transition =     NULL,
 136        .register_app =         NULL,
 137        .unregister_app =       NULL,
 138        .app_conn_bind =        NULL,
 139        .debug_packet =         ip_vs_tcpudp_debug_packet,
 140        .timeout_change =       NULL,           /* ISAKMP */
 141};
 142#endif
 143
 144#ifdef CONFIG_IP_VS_PROTO_ESP
 145struct ip_vs_protocol ip_vs_protocol_esp = {
 146        .name =                 "ESP",
 147        .protocol =             IPPROTO_ESP,
 148        .num_states =           1,
 149        .dont_defrag =          1,
 150        .init =                 NULL,
 151        .exit =                 NULL,
 152        .conn_schedule =        ah_esp_conn_schedule,
 153        .conn_in_get =          ah_esp_conn_in_get,
 154        .conn_out_get =         ah_esp_conn_out_get,
 155        .snat_handler =         NULL,
 156        .dnat_handler =         NULL,
 157        .csum_check =           NULL,
 158        .state_transition =     NULL,
 159        .register_app =         NULL,
 160        .unregister_app =       NULL,
 161        .app_conn_bind =        NULL,
 162        .debug_packet =         ip_vs_tcpudp_debug_packet,
 163        .timeout_change =       NULL,           /* ISAKMP */
 164};
 165#endif
 166