netfilter: nf_conntrack: support conntrack templates
[linux-2.6.git] / include / net / ip_vs.h
index 3d3b699..a816c37 100644 (file)
 
 #include <net/checksum.h>
 #include <linux/netfilter.h>           /* for union nf_inet_addr */
+#include <linux/ip.h>
 #include <linux/ipv6.h>                        /* for struct ipv6hdr */
 #include <net/ipv6.h>                  /* for ipv6_addr_copy */
 
+
+/* Connections' size value needed by ip_vs_ctl.c */
+extern int ip_vs_conn_tab_size;
+
+
 struct ip_vs_iphdr {
        int len;
        __u8 protocol;
@@ -86,59 +92,59 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
        int len;
 #ifdef CONFIG_IP_VS_IPV6
        if (af == AF_INET6)
-               len = snprintf(&buf[*idx], buf_len - *idx, "[" NIP6_FMT "]",
-                              NIP6(addr->in6)) + 1;
+               len = snprintf(&buf[*idx], buf_len - *idx, "[%pI6]",
+                              &addr->in6) + 1;
        else
 #endif
-               len = snprintf(&buf[*idx], buf_len - *idx, NIPQUAD_FMT,
-                              NIPQUAD(addr->ip)) + 1;
+               len = snprintf(&buf[*idx], buf_len - *idx, "%pI4",
+                              &addr->ip) + 1;
 
        *idx += len;
        BUG_ON(*idx > buf_len + 1);
        return &buf[*idx - len];
 }
 
-#define IP_VS_DBG_BUF(level, msg...)                   \
-    do {                                               \
-           char ip_vs_dbg_buf[160];                    \
-           int ip_vs_dbg_idx = 0;                      \
-           if (level <= ip_vs_get_debug_level())       \
-                   printk(KERN_DEBUG "IPVS: " msg);    \
-    } while (0)
-#define IP_VS_ERR_BUF(msg...)                          \
-    do {                                               \
-           char ip_vs_dbg_buf[160];                    \
-           int ip_vs_dbg_idx = 0;                      \
-           printk(KERN_ERR "IPVS: " msg);              \
-    } while (0)
+#define IP_VS_DBG_BUF(level, msg, ...)                                 \
+       do {                                                            \
+               char ip_vs_dbg_buf[160];                                \
+               int ip_vs_dbg_idx = 0;                                  \
+               if (level <= ip_vs_get_debug_level())                   \
+                       printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);  \
+       } while (0)
+#define IP_VS_ERR_BUF(msg...)                                          \
+       do {                                                            \
+               char ip_vs_dbg_buf[160];                                \
+               int ip_vs_dbg_idx = 0;                                  \
+               pr_err(msg);                                            \
+       } while (0)
 
 /* Only use from within IP_VS_DBG_BUF() or IP_VS_ERR_BUF macros */
-#define IP_VS_DBG_ADDR(af, addr)                       \
-    ip_vs_dbg_addr(af, ip_vs_dbg_buf,                  \
-                  sizeof(ip_vs_dbg_buf), addr,         \
-                  &ip_vs_dbg_idx)
-
-#define IP_VS_DBG(level, msg...)                       \
-    do {                                               \
-           if (level <= ip_vs_get_debug_level())       \
-                   printk(KERN_DEBUG "IPVS: " msg);    \
-    } while (0)
-#define IP_VS_DBG_RL(msg...)                           \
-    do {                                               \
-           if (net_ratelimit())                        \
-                   printk(KERN_DEBUG "IPVS: " msg);    \
-    } while (0)
-#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg)                \
-    do {                                               \
-           if (level <= ip_vs_get_debug_level())       \
-               pp->debug_packet(pp, skb, ofs, msg);    \
-    } while (0)
-#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg)     \
-    do {                                               \
-           if (level <= ip_vs_get_debug_level() &&     \
-               net_ratelimit())                        \
-               pp->debug_packet(pp, skb, ofs, msg);    \
-    } while (0)
+#define IP_VS_DBG_ADDR(af, addr)                                       \
+       ip_vs_dbg_addr(af, ip_vs_dbg_buf,                               \
+                      sizeof(ip_vs_dbg_buf), addr,                     \
+                      &ip_vs_dbg_idx)
+
+#define IP_VS_DBG(level, msg, ...)                                     \
+       do {                                                            \
+               if (level <= ip_vs_get_debug_level())                   \
+                       printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);  \
+       } while (0)
+#define IP_VS_DBG_RL(msg, ...)                                         \
+       do {                                                            \
+               if (net_ratelimit())                                    \
+                       printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);  \
+       } while (0)
+#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg)                                \
+       do {                                                            \
+               if (level <= ip_vs_get_debug_level())                   \
+                       pp->debug_packet(pp, skb, ofs, msg);            \
+       } while (0)
+#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg)                     \
+       do {                                                            \
+               if (level <= ip_vs_get_debug_level() &&                 \
+                   net_ratelimit())                                    \
+                       pp->debug_packet(pp, skb, ofs, msg);            \
+       } while (0)
 #else  /* NO DEBUGGING at ALL */
 #define IP_VS_DBG_BUF(level, msg...)  do {} while (0)
 #define IP_VS_ERR_BUF(msg...)  do {} while (0)
@@ -149,29 +155,27 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
 #endif
 
 #define IP_VS_BUG() BUG()
-#define IP_VS_ERR(msg...) printk(KERN_ERR "IPVS: " msg)
-#define IP_VS_INFO(msg...) printk(KERN_INFO "IPVS: " msg)
-#define IP_VS_WARNING(msg...) \
-       printk(KERN_WARNING "IPVS: " msg)
-#define IP_VS_ERR_RL(msg...)                           \
-    do {                                               \
-           if (net_ratelimit())                        \
-                   printk(KERN_ERR "IPVS: " msg);      \
-    } while (0)
+#define IP_VS_ERR_RL(msg, ...)                                         \
+       do {                                                            \
+               if (net_ratelimit())                                    \
+                       pr_err(msg, ##__VA_ARGS__);                     \
+       } while (0)
 
 #ifdef CONFIG_IP_VS_DEBUG
 #define EnterFunction(level)                                           \
-    do {                                                               \
-           if (level <= ip_vs_get_debug_level())                       \
-                   printk(KERN_DEBUG "Enter: %s, %s line %i\n",        \
-                          __FUNCTION__, __FILE__, __LINE__);           \
-    } while (0)
-#define LeaveFunction(level)                                            \
-    do {                                                                \
-           if (level <= ip_vs_get_debug_level())                       \
-                       printk(KERN_DEBUG "Leave: %s, %s line %i\n",    \
-                              __FUNCTION__, __FILE__, __LINE__);       \
-    } while (0)
+       do {                                                            \
+               if (level <= ip_vs_get_debug_level())                   \
+                       printk(KERN_DEBUG                               \
+                              pr_fmt("Enter: %s, %s line %i\n"),       \
+                              __func__, __FILE__, __LINE__);           \
+       } while (0)
+#define LeaveFunction(level)                                           \
+       do {                                                            \
+               if (level <= ip_vs_get_debug_level())                   \
+                       printk(KERN_DEBUG                               \
+                              pr_fmt("Leave: %s, %s line %i\n"),       \
+                              __func__, __FILE__, __LINE__);           \
+       } while (0)
 #else
 #define EnterFunction(level)   do {} while (0)
 #define LeaveFunction(level)   do {} while (0)
@@ -183,8 +187,8 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
 /*
  *      The port number of FTP service (in network order).
  */
-#define FTPPORT  __constant_htons(21)
-#define FTPDATA  __constant_htons(20)
+#define FTPPORT  cpu_to_be16(21)
+#define FTPDATA  cpu_to_be16(20)
 
 /*
  *      TCP State Values
@@ -252,29 +256,11 @@ struct ip_vs_estimator {
        u32                     outbps;
 };
 
-struct ip_vs_stats
-{
-       __u32                   conns;          /* connections scheduled */
-       __u32                   inpkts;         /* incoming packets */
-       __u32                   outpkts;        /* outgoing packets */
-       __u64                   inbytes;        /* incoming bytes */
-       __u64                   outbytes;       /* outgoing bytes */
-
-       __u32                   cps;            /* current connection rate */
-       __u32                   inpps;          /* current in packet rate */
-       __u32                   outpps;         /* current out packet rate */
-       __u32                   inbps;          /* current in byte rate */
-       __u32                   outbps;         /* current out byte rate */
-
-       /*
-        * Don't add anything before the lock, because we use memcpy() to copy
-        * the members before the lock to struct ip_vs_stats_user in
-        * ip_vs_ctl.c.
-        */
+struct ip_vs_stats {
+       struct ip_vs_stats_user ustats;         /* statistics */
+       struct ip_vs_estimator  est;            /* estimator */
 
        spinlock_t              lock;           /* spin lock */
-
-       struct ip_vs_estimator  est;            /* estimator */
 };
 
 struct dst_entry;
@@ -296,21 +282,23 @@ struct ip_vs_protocol {
 
        void (*exit)(struct ip_vs_protocol *pp);
 
-       int (*conn_schedule)(struct sk_buff *skb,
+       int (*conn_schedule)(int af, struct sk_buff *skb,
                             struct ip_vs_protocol *pp,
                             int *verdict, struct ip_vs_conn **cpp);
 
        struct ip_vs_conn *
-       (*conn_in_get)(const struct sk_buff *skb,
+       (*conn_in_get)(int af,
+                      const struct sk_buff *skb,
                       struct ip_vs_protocol *pp,
-                      const struct iphdr *iph,
+                      const struct ip_vs_iphdr *iph,
                       unsigned int proto_off,
                       int inverse);
 
        struct ip_vs_conn *
-       (*conn_out_get)(const struct sk_buff *skb,
+       (*conn_out_get)(int af,
+                       const struct sk_buff *skb,
                        struct ip_vs_protocol *pp,
-                       const struct iphdr *iph,
+                       const struct ip_vs_iphdr *iph,
                        unsigned int proto_off,
                        int inverse);
 
@@ -320,7 +308,8 @@ struct ip_vs_protocol {
        int (*dnat_handler)(struct sk_buff *skb,
                            struct ip_vs_protocol *pp, struct ip_vs_conn *cp);
 
-       int (*csum_check)(struct sk_buff *skb, struct ip_vs_protocol *pp);
+       int (*csum_check)(int af, struct sk_buff *skb,
+                         struct ip_vs_protocol *pp);
 
        const char *(*state_name)(int state);
 
@@ -516,9 +505,6 @@ struct ip_vs_scheduler {
        char                    *name;          /* scheduler name */
        atomic_t                refcnt;         /* reference counter */
        struct module           *module;        /* THIS_MODULE/NULL */
-#ifdef CONFIG_IP_VS_IPV6
-       int                     supports_ipv6;  /* scheduler has IPv6 support */
-#endif
 
        /* scheduler initializing service */
        int (*init_service)(struct ip_vs_service *svc);
@@ -536,8 +522,7 @@ struct ip_vs_scheduler {
 /*
  *     The application module object (a.k.a. app incarnation)
  */
-struct ip_vs_app
-{
+struct ip_vs_app {
        struct list_head        a_list;         /* member in app list */
        int                     type;           /* IP_VS_APP_TYPE_xxx */
        char                    *name;          /* application module name */
@@ -612,25 +597,6 @@ extern void ip_vs_init_hash_table(struct list_head *table, int rows);
  *     (from ip_vs_conn.c)
  */
 
-/*
- *     IPVS connection entry hash table
- */
-#ifndef CONFIG_IP_VS_TAB_BITS
-#define CONFIG_IP_VS_TAB_BITS   12
-#endif
-/* make sure that IP_VS_CONN_TAB_BITS is located in [8, 20] */
-#if CONFIG_IP_VS_TAB_BITS < 8
-#define IP_VS_CONN_TAB_BITS    8
-#endif
-#if CONFIG_IP_VS_TAB_BITS > 20
-#define IP_VS_CONN_TAB_BITS    20
-#endif
-#if 8 <= CONFIG_IP_VS_TAB_BITS && CONFIG_IP_VS_TAB_BITS <= 20
-#define IP_VS_CONN_TAB_BITS    CONFIG_IP_VS_TAB_BITS
-#endif
-#define IP_VS_CONN_TAB_SIZE     (1 << IP_VS_CONN_TAB_BITS)
-#define IP_VS_CONN_TAB_MASK     (IP_VS_CONN_TAB_SIZE - 1)
-
 enum {
        IP_VS_DIR_INPUT = 0,
        IP_VS_DIR_OUTPUT,
@@ -639,11 +605,16 @@ enum {
 };
 
 extern struct ip_vs_conn *ip_vs_conn_in_get
-(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port);
+(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
+ const union nf_inet_addr *d_addr, __be16 d_port);
+
 extern struct ip_vs_conn *ip_vs_ct_in_get
-(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port);
+(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
+ const union nf_inet_addr *d_addr, __be16 d_port);
+
 extern struct ip_vs_conn *ip_vs_conn_out_get
-(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port);
+(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
+ const union nf_inet_addr *d_addr, __be16 d_port);
 
 /* put back the conn without restarting its timer */
 static inline void __ip_vs_conn_put(struct ip_vs_conn *cp)
@@ -654,8 +625,9 @@ extern void ip_vs_conn_put(struct ip_vs_conn *cp);
 extern void ip_vs_conn_fill_cport(struct ip_vs_conn *cp, __be16 cport);
 
 extern struct ip_vs_conn *
-ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport,
-              __be32 daddr, __be16 dport, unsigned flags,
+ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,
+              const union nf_inet_addr *vaddr, __be16 vport,
+              const union nf_inet_addr *daddr, __be16 dport, unsigned flags,
               struct ip_vs_dest *dest);
 extern void ip_vs_conn_expire_now(struct ip_vs_conn *cp);
 
@@ -671,24 +643,32 @@ static inline void ip_vs_control_del(struct ip_vs_conn *cp)
 {
        struct ip_vs_conn *ctl_cp = cp->control;
        if (!ctl_cp) {
-               IP_VS_ERR("request control DEL for uncontrolled: "
-                         "%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",
-                         NIPQUAD(cp->caddr),ntohs(cp->cport),
-                         NIPQUAD(cp->vaddr),ntohs(cp->vport));
+               IP_VS_ERR_BUF("request control DEL for uncontrolled: "
+                             "%s:%d to %s:%d\n",
+                             IP_VS_DBG_ADDR(cp->af, &cp->caddr),
+                             ntohs(cp->cport),
+                             IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
+                             ntohs(cp->vport));
+
                return;
        }
 
-       IP_VS_DBG(7, "DELeting control for: "
-                 "cp.dst=%d.%d.%d.%d:%d ctl_cp.dst=%d.%d.%d.%d:%d\n",
-                 NIPQUAD(cp->caddr),ntohs(cp->cport),
-                 NIPQUAD(ctl_cp->caddr),ntohs(ctl_cp->cport));
+       IP_VS_DBG_BUF(7, "DELeting control for: "
+                     "cp.dst=%s:%d ctl_cp.dst=%s:%d\n",
+                     IP_VS_DBG_ADDR(cp->af, &cp->caddr),
+                     ntohs(cp->cport),
+                     IP_VS_DBG_ADDR(cp->af, &ctl_cp->caddr),
+                     ntohs(ctl_cp->cport));
 
        cp->control = NULL;
        if (atomic_read(&ctl_cp->n_control) == 0) {
-               IP_VS_ERR("BUG control DEL with n=0 : "
-                         "%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",
-                         NIPQUAD(cp->caddr),ntohs(cp->cport),
-                         NIPQUAD(cp->vaddr),ntohs(cp->vport));
+               IP_VS_ERR_BUF("BUG control DEL with n=0 : "
+                             "%s:%d to %s:%d\n",
+                             IP_VS_DBG_ADDR(cp->af, &cp->caddr),
+                             ntohs(cp->cport),
+                             IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
+                             ntohs(cp->vport));
+
                return;
        }
        atomic_dec(&ctl_cp->n_control);
@@ -698,17 +678,22 @@ static inline void
 ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp)
 {
        if (cp->control) {
-               IP_VS_ERR("request control ADD for already controlled: "
-                         "%d.%d.%d.%d:%d to %d.%d.%d.%d:%d\n",
-                         NIPQUAD(cp->caddr),ntohs(cp->cport),
-                         NIPQUAD(cp->vaddr),ntohs(cp->vport));
+               IP_VS_ERR_BUF("request control ADD for already controlled: "
+                             "%s:%d to %s:%d\n",
+                             IP_VS_DBG_ADDR(cp->af, &cp->caddr),
+                             ntohs(cp->cport),
+                             IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
+                             ntohs(cp->vport));
+
                ip_vs_control_del(cp);
        }
 
-       IP_VS_DBG(7, "ADDing control for: "
-                 "cp.dst=%d.%d.%d.%d:%d ctl_cp.dst=%d.%d.%d.%d:%d\n",
-                 NIPQUAD(cp->caddr),ntohs(cp->cport),
-                 NIPQUAD(ctl_cp->caddr),ntohs(ctl_cp->cport));
+       IP_VS_DBG_BUF(7, "ADDing control for: "
+                     "cp.dst=%s:%d ctl_cp.dst=%s:%d\n",
+                     IP_VS_DBG_ADDR(cp->af, &cp->caddr),
+                     ntohs(cp->cport),
+                     IP_VS_DBG_ADDR(cp->af, &ctl_cp->caddr),
+                     ntohs(ctl_cp->cport));
 
        cp->control = ctl_cp;
        atomic_inc(&ctl_cp->n_control);
@@ -745,7 +730,8 @@ extern void ip_vs_protocol_cleanup(void);
 extern void ip_vs_protocol_timeout_change(int flags);
 extern int *ip_vs_create_timeout_table(int *table, int size);
 extern int
-ip_vs_set_state_timeout(int *table, int num, char **names, char *name, int to);
+ip_vs_set_state_timeout(int *table, int num, const char *const *names,
+                       const char *name, int to);
 extern void
 ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
                          int offset, const char *msg);
@@ -795,14 +781,16 @@ static inline void ip_vs_service_put(struct ip_vs_service *svc)
 }
 
 extern struct ip_vs_dest *
-ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, __be16 dport);
+ip_vs_lookup_real_service(int af, __u16 protocol,
+                         const union nf_inet_addr *daddr, __be16 dport);
+
 extern int ip_vs_use_count_inc(void);
 extern void ip_vs_use_count_dec(void);
 extern int ip_vs_control_init(void);
 extern void ip_vs_control_cleanup(void);
 extern struct ip_vs_dest *
-ip_vs_find_dest(__be32 daddr, __be16 dport,
-                __be32 vaddr, __be16 vport, __u16 protocol);
+ip_vs_find_dest(int af, const union nf_inet_addr *daddr, __be16 dport,
+               const union nf_inet_addr *vaddr, __be16 vport, __u16 protocol);
 extern struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp);
 
 
@@ -846,6 +834,19 @@ extern int ip_vs_icmp_xmit
 (struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp, int offset);
 extern void ip_vs_dst_reset(struct ip_vs_dest *dest);
 
+#ifdef CONFIG_IP_VS_IPV6
+extern int ip_vs_bypass_xmit_v6
+(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
+extern int ip_vs_nat_xmit_v6
+(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
+extern int ip_vs_tunnel_xmit_v6
+(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
+extern int ip_vs_dr_xmit_v6
+(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp);
+extern int ip_vs_icmp_xmit_v6
+(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp,
+ int offset);
+#endif
 
 /*
  *     This is a simple mechanism to ignore packets when
@@ -890,7 +891,12 @@ static inline char ip_vs_fwd_tag(struct ip_vs_conn *cp)
 }
 
 extern void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
-               struct ip_vs_conn *cp, int dir);
+                          struct ip_vs_conn *cp, int dir);
+
+#ifdef CONFIG_IP_VS_IPV6
+extern void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
+                             struct ip_vs_conn *cp, int dir);
+#endif
 
 extern __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset);
 
@@ -898,14 +904,25 @@ static inline __wsum ip_vs_check_diff4(__be32 old, __be32 new, __wsum oldsum)
 {
        __be32 diff[2] = { ~old, new };
 
-       return csum_partial((char *) diff, sizeof(diff), oldsum);
+       return csum_partial(diff, sizeof(diff), oldsum);
 }
 
+#ifdef CONFIG_IP_VS_IPV6
+static inline __wsum ip_vs_check_diff16(const __be32 *old, const __be32 *new,
+                                       __wsum oldsum)
+{
+       __be32 diff[8] = { ~old[3], ~old[2], ~old[1], ~old[0],
+                           new[3],  new[2],  new[1],  new[0] };
+
+       return csum_partial(diff, sizeof(diff), oldsum);
+}
+#endif
+
 static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
 {
        __be16 diff[2] = { ~old, new };
 
-       return csum_partial((char *) diff, sizeof(diff), oldsum);
+       return csum_partial(diff, sizeof(diff), oldsum);
 }
 
 #endif /* __KERNEL__ */