Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b1a1ce6 authored by Patrick McHardy's avatar Patrick McHardy
Browse files
parents cc6eb433 b0aeef30
Loading
Loading
Loading
Loading
+41 −12
Original line number Original line Diff line number Diff line
@@ -25,7 +25,7 @@
#include <linux/ip.h>
#include <linux/ip.h>
#include <linux/ipv6.h>			/* for struct ipv6hdr */
#include <linux/ipv6.h>			/* for struct ipv6hdr */
#include <net/ipv6.h>			/* for ipv6_addr_copy */
#include <net/ipv6.h>			/* for ipv6_addr_copy */
#ifdef CONFIG_IP_VS_NFCT
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack.h>
#endif
#endif


@@ -136,24 +136,24 @@ static inline const char *ip_vs_dbg_addr(int af, char *buf, size_t buf_len,
		if (net_ratelimit())					\
		if (net_ratelimit())					\
			printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);	\
			printk(KERN_DEBUG pr_fmt(msg), ##__VA_ARGS__);	\
	} while (0)
	} while (0)
#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg)				\
#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg)			\
	do {								\
	do {								\
		if (level <= ip_vs_get_debug_level())			\
		if (level <= ip_vs_get_debug_level())			\
			pp->debug_packet(pp, skb, ofs, msg);		\
			pp->debug_packet(af, pp, skb, ofs, msg);	\
	} while (0)
	} while (0)
#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg)			\
#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg)			\
	do {								\
	do {								\
		if (level <= ip_vs_get_debug_level() &&			\
		if (level <= ip_vs_get_debug_level() &&			\
		    net_ratelimit())					\
		    net_ratelimit())					\
			pp->debug_packet(pp, skb, ofs, msg);		\
			pp->debug_packet(af, pp, skb, ofs, msg);	\
	} while (0)
	} while (0)
#else	/* NO DEBUGGING at ALL */
#else	/* NO DEBUGGING at ALL */
#define IP_VS_DBG_BUF(level, msg...)  do {} while (0)
#define IP_VS_DBG_BUF(level, msg...)  do {} while (0)
#define IP_VS_ERR_BUF(msg...)  do {} while (0)
#define IP_VS_ERR_BUF(msg...)  do {} while (0)
#define IP_VS_DBG(level, msg...)  do {} while (0)
#define IP_VS_DBG(level, msg...)  do {} while (0)
#define IP_VS_DBG_RL(msg...)  do {} while (0)
#define IP_VS_DBG_RL(msg...)  do {} while (0)
#define IP_VS_DBG_PKT(level, pp, skb, ofs, msg)		do {} while (0)
#define IP_VS_DBG_PKT(level, af, pp, skb, ofs, msg)	do {} while (0)
#define IP_VS_DBG_RL_PKT(level, pp, skb, ofs, msg)	do {} while (0)
#define IP_VS_DBG_RL_PKT(level, af, pp, skb, ofs, msg)	do {} while (0)
#endif
#endif


#define IP_VS_BUG() BUG()
#define IP_VS_BUG() BUG()
@@ -345,7 +345,7 @@ struct ip_vs_protocol {


	int (*app_conn_bind)(struct ip_vs_conn *cp);
	int (*app_conn_bind)(struct ip_vs_conn *cp);


	void (*debug_packet)(struct ip_vs_protocol *pp,
	void (*debug_packet)(int af, struct ip_vs_protocol *pp,
			     const struct sk_buff *skb,
			     const struct sk_buff *skb,
			     int offset,
			     int offset,
			     const char *msg);
			     const char *msg);
@@ -409,6 +409,7 @@ struct ip_vs_conn {
	/* packet transmitter for different forwarding methods.  If it
	/* packet transmitter for different forwarding methods.  If it
	   mangles the packet, it must return NF_DROP or better NF_STOLEN,
	   mangles the packet, it must return NF_DROP or better NF_STOLEN,
	   otherwise this must be changed to a sk_buff **.
	   otherwise this must be changed to a sk_buff **.
	   NF_ACCEPT can be returned when destination is local.
	 */
	 */
	int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp,
	int (*packet_xmit)(struct sk_buff *skb, struct ip_vs_conn *cp,
			   struct ip_vs_protocol *pp);
			   struct ip_vs_protocol *pp);
@@ -597,11 +598,19 @@ struct ip_vs_app {
	__be16			port;		/* port number in net order */
	__be16			port;		/* port number in net order */
	atomic_t		usecnt;		/* usage counter */
	atomic_t		usecnt;		/* usage counter */


	/* output hook: return false if can't linearize. diff set for TCP.  */
	/*
	 * output hook: Process packet in inout direction, diff set for TCP.
	 * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok,
	 *	   2=Mangled but checksum was not updated
	 */
	int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *,
	int (*pkt_out)(struct ip_vs_app *, struct ip_vs_conn *,
		       struct sk_buff *, int *diff);
		       struct sk_buff *, int *diff);


	/* input hook: return false if can't linearize. diff set for TCP. */
	/*
	 * input hook: Process packet in outin direction, diff set for TCP.
	 * Return: 0=Error, 1=Payload Not Mangled/Mangled but checksum is ok,
	 *	   2=Mangled but checksum was not updated
	 */
	int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *,
	int (*pkt_in)(struct ip_vs_app *, struct ip_vs_conn *,
		      struct sk_buff *, int *diff);
		      struct sk_buff *, int *diff);


@@ -819,7 +828,8 @@ extern int
ip_vs_set_state_timeout(int *table, int num, const char *const *names,
ip_vs_set_state_timeout(int *table, int num, const char *const *names,
			const char *name, int to);
			const char *name, int to);
extern void
extern void
ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
ip_vs_tcpudp_debug_packet(int af, struct ip_vs_protocol *pp,
			  const struct sk_buff *skb,
			  int offset, const char *msg);
			  int offset, const char *msg);


extern struct ip_vs_protocol ip_vs_protocol_tcp;
extern struct ip_vs_protocol ip_vs_protocol_tcp;
@@ -841,7 +851,8 @@ extern int ip_vs_unbind_scheduler(struct ip_vs_service *svc);
extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name);
extern struct ip_vs_scheduler *ip_vs_scheduler_get(const char *sched_name);
extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler);
extern void ip_vs_scheduler_put(struct ip_vs_scheduler *scheduler);
extern struct ip_vs_conn *
extern struct ip_vs_conn *
ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb);
ip_vs_schedule(struct ip_vs_service *svc, struct sk_buff *skb,
	       struct ip_vs_protocol *pp, int *ignored);
extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
extern int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
			struct ip_vs_protocol *pp);
			struct ip_vs_protocol *pp);


@@ -1013,6 +1024,24 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum)
	return csum_partial(diff, sizeof(diff), oldsum);
	return csum_partial(diff, sizeof(diff), oldsum);
}
}


/*
 * Forget current conntrack (unconfirmed) and attach notrack entry
 */
static inline void ip_vs_notrack(struct sk_buff *skb)
{
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
	enum ip_conntrack_info ctinfo;
	struct nf_conn *ct = ct = nf_ct_get(skb, &ctinfo);

	if (!ct || !nf_ct_is_untracked(ct)) {
		nf_reset(skb);
		skb->nfct = &nf_ct_untracked_get()->ct_general;
		skb->nfctinfo = IP_CT_NEW;
		nf_conntrack_get(skb->nfct);
	}
#endif
}

#ifdef CONFIG_IP_VS_NFCT
#ifdef CONFIG_IP_VS_NFCT
/*
/*
 *      Netfilter connection tracking
 *      Netfilter connection tracking
+15 −14
Original line number Original line Diff line number Diff line
@@ -462,6 +462,18 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,
			return 0;
			return 0;
	}
	}


	if (manip == IP_NAT_MANIP_SRC)
		statusbit = IPS_SRC_NAT;
	else
		statusbit = IPS_DST_NAT;

	/* Invert if this is reply dir. */
	if (dir == IP_CT_DIR_REPLY)
		statusbit ^= IPS_NAT_MASK;

	if (!(ct->status & statusbit))
		return 1;

	pr_debug("icmp_reply_translation: translating error %p manip %u "
	pr_debug("icmp_reply_translation: translating error %p manip %u "
		 "dir %s\n", skb, manip,
		 "dir %s\n", skb, manip,
		 dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
		 dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
@@ -496,20 +508,9 @@ int nf_nat_icmp_reply_translation(struct nf_conn *ct,


	/* Change outer to look the reply to an incoming packet
	/* Change outer to look the reply to an incoming packet
	 * (proto 0 means don't invert per-proto part). */
	 * (proto 0 means don't invert per-proto part). */
	if (manip == IP_NAT_MANIP_SRC)
		statusbit = IPS_SRC_NAT;
	else
		statusbit = IPS_DST_NAT;

	/* Invert if this is reply dir. */
	if (dir == IP_CT_DIR_REPLY)
		statusbit ^= IPS_NAT_MASK;

	if (ct->status & statusbit) {
	nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
	nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
	if (!manip_pkt(0, skb, 0, &target, manip))
	if (!manip_pkt(0, skb, 0, &target, manip))
		return 0;
		return 0;
	}


	return 1;
	return 1;
}
}
+2 −0
Original line number Original line Diff line number Diff line
@@ -563,6 +563,8 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
		 */
		 */
		if (!(cp->flags & IP_VS_CONN_F_TEMPLATE))
		if (!(cp->flags & IP_VS_CONN_F_TEMPLATE))
			conn_flags &= ~IP_VS_CONN_F_INACTIVE;
			conn_flags &= ~IP_VS_CONN_F_INACTIVE;
		/* connections inherit forwarding method from dest */
		cp->flags &= ~IP_VS_CONN_F_FWD_MASK;
	}
	}
	cp->flags |= conn_flags;
	cp->flags |= conn_flags;
	cp->dest = dest;
	cp->dest = dest;
+413 −173

File changed.

Preview size limit exceeded, changes collapsed.

+4 −14
Original line number Original line Diff line number Diff line
@@ -777,20 +777,6 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
	conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK;
	conn_flags = udest->conn_flags & IP_VS_CONN_F_DEST_MASK;
	conn_flags |= IP_VS_CONN_F_INACTIVE;
	conn_flags |= IP_VS_CONN_F_INACTIVE;


	/* check if local node and update the flags */
#ifdef CONFIG_IP_VS_IPV6
	if (svc->af == AF_INET6) {
		if (__ip_vs_addr_is_local_v6(&udest->addr.in6)) {
			conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
				| IP_VS_CONN_F_LOCALNODE;
		}
	} else
#endif
		if (inet_addr_type(&init_net, udest->addr.ip) == RTN_LOCAL) {
			conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
				| IP_VS_CONN_F_LOCALNODE;
		}

	/* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */
	/* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */
	if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != IP_VS_CONN_F_MASQ) {
	if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != IP_VS_CONN_F_MASQ) {
		conn_flags |= IP_VS_CONN_F_NOOUTPUT;
		conn_flags |= IP_VS_CONN_F_NOOUTPUT;
@@ -824,6 +810,10 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest,
	dest->u_threshold = udest->u_threshold;
	dest->u_threshold = udest->u_threshold;
	dest->l_threshold = udest->l_threshold;
	dest->l_threshold = udest->l_threshold;


	spin_lock(&dest->dst_lock);
	ip_vs_dst_reset(dest);
	spin_unlock(&dest->dst_lock);

	if (add)
	if (add)
		ip_vs_new_estimator(&dest->stats);
		ip_vs_new_estimator(&dest->stats);


Loading