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

Commit 5b57a98c authored by Simon Horman's avatar Simon Horman
Browse files

IPVS: compact ip_vs_sched_persist()



Compact ip_vs_sched_persist() by setting up parameters
and calling functions once.

Signed-off-by: default avatarSimon Horman <horms@verge.net.au>
Acked-by: default avatarJulian Anastasov <ja@ssi.bg>
parent 001985b2
Loading
Loading
Loading
Loading
+51 −105
Original line number Diff line number Diff line
@@ -193,10 +193,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
	struct ip_vs_iphdr iph;
	struct ip_vs_dest *dest;
	struct ip_vs_conn *ct;
	__be16  dport;			/* destination port to forward */
	int protocol = iph.protocol;
	__be16 dport = 0;		/* destination port to forward */
	__be16 vport = 0;		/* virtual service port */
	unsigned int flags;
	union nf_inet_addr snet;	/* source network of the client,
					   after masking */
	const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
	const union nf_inet_addr *vaddr = &iph.daddr;

	ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);

@@ -227,119 +231,61 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
	 * service, and a template like <caddr, 0, vaddr, vport, daddr, dport>
	 * is created for other persistent services.
	 */
	{
		if (ports[1] == svc->port) {
		/* Check if a template already exists */
		if (svc->port != FTPPORT)
			ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
					     &iph.daddr, ports[1]);
		else
			ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
					     &iph.daddr, 0);

		if (!ct || !ip_vs_check_template(ct)) {
			/*
			 * No template found or the dest of the connection
			 * template is not available.
			 */
			dest = svc->scheduler->schedule(svc, skb);
			if (dest == NULL) {
				IP_VS_DBG(1, "p-schedule: no dest found.\n");
				return NULL;
			}

			/*
			 * Create a template like <protocol,caddr,0,
			 * vaddr,vport,daddr,dport> for non-ftp service,
			 * and <protocol,caddr,0,vaddr,0,daddr,0>
			 * for ftp service.
			/* non-FTP template:
			 * <protocol, caddr, 0, vaddr, vport, daddr, dport>
			 * FTP template:
			 * <protocol, caddr, 0, vaddr, 0, daddr, 0>
			 */
			if (svc->port != FTPPORT)
				ct = ip_vs_conn_new(svc->af, iph.protocol,
						    &snet, 0,
						    &iph.daddr,
						    ports[1],
						    &dest->addr, dest->port,
						    IP_VS_CONN_F_TEMPLATE,
						    dest);
			else
				ct = ip_vs_conn_new(svc->af, iph.protocol,
						    &snet, 0,
						    &iph.daddr, 0,
						    &dest->addr, 0,
						    IP_VS_CONN_F_TEMPLATE,
						    dest);
			if (ct == NULL)
				return NULL;

			ct->timeout = svc->timeout;
		} else {
			/* set destination with the found template */
			dest = ct->dest;
		}
		dport = dest->port;
				vport = ports[1];
		} else {
		/*
		 * Note: persistent fwmark-based services and persistent
		 * port zero service are handled here.
		 * fwmark template: <IPPROTO_IP,caddr,0,fwmark,0,daddr,0>
		 * port zero template: <protocol,caddr,0,vaddr,0,daddr,0>
			/* Note: persistent fwmark-based services and
			 * persistent port zero service are handled here.
			 * fwmark template:
			 * <IPPROTO_IP,caddr,0,fwmark,0,daddr,0>
			 * port zero template:
			 * <protocol,caddr,0,vaddr,0,daddr,0>
			 */
			if (svc->fwmark) {
			union nf_inet_addr fwmark = {
				.ip = htonl(svc->fwmark)
			};
				protocol = IPPROTO_IP;
				vaddr = &fwmark;
			}
		}
	}

			ct = ip_vs_ct_in_get(svc->af, IPPROTO_IP, &snet, 0,
					     &fwmark, 0);
		} else
			ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
					     &iph.daddr, 0);
	/* Check if a template already exists */
	ct = ip_vs_ct_in_get(svc->af, protocol, &snet, 0, vaddr, vport);

	if (!ct || !ip_vs_check_template(ct)) {
			/*
			 * If it is not persistent port zero, return NULL,
			 * otherwise create a connection template.
		/* No template found or the dest of the connection
		 * template is not available.
		 */
			if (svc->port)
				return NULL;

		dest = svc->scheduler->schedule(svc, skb);
			if (dest == NULL) {
		if (!dest) {
			IP_VS_DBG(1, "p-schedule: no dest found.\n");
			return NULL;
		}

			/*
			 * Create a template according to the service
			 */
			if (svc->fwmark) {
				union nf_inet_addr fwmark = {
					.ip = htonl(svc->fwmark)
				};
		if (ports[1] == svc->port && svc->port != FTPPORT)
			dport = dest->port;

				ct = ip_vs_conn_new(svc->af, IPPROTO_IP,
						    &snet, 0,
						    &fwmark, 0,
						    &dest->addr, 0,
						    IP_VS_CONN_F_TEMPLATE,
						    dest);
			} else
				ct = ip_vs_conn_new(svc->af, iph.protocol,
						    &snet, 0,
						    &iph.daddr, 0,
						    &dest->addr, 0,
						    IP_VS_CONN_F_TEMPLATE,
						    dest);
		/* Create a template */
		ct = ip_vs_conn_new(svc->af, protocol, &snet, 0,vaddr, vport,
				    &dest->addr, dport,
				    IP_VS_CONN_F_TEMPLATE, dest);
		if (ct == NULL)
			return NULL;

		ct->timeout = svc->timeout;
		} else {
	} else
		/* set destination with the found template */
		dest = ct->dest;
		}

	dport = ports[1];
	}
	if (dport == svc->port && dest->port)
		dport = dest->port;

	flags = (svc->flags & IP_VS_SVC_F_ONEPACKET
		 && iph.protocol == IPPROTO_UDP)?