/* * IPVS main scheduling function * It selects a server according to the virtual service, and * creates a connection entry. */ static struct ip_vs_conn * ip_vs_schedule(struct ip_vs_service *svc, struct iphdr *iph) { struct ip_vs_conn *cp = NULL; struct ip_vs_dest *dest; const __u16 *portp; /* * Persistent service */ if (svc->flags & IP_VS_SVC_F_PERSISTENT) return ip_vs_sched_persist(svc, iph); /* * Non-persistent service */ portp = (__u16 *)&(((char *)iph)[iph->ihl*4]); if (!svc->fwmark && portp[1] != svc->port) { if (!svc->port) IP_VS_ERR("Schedule: port zero only supported " "in persistent services, " "check your ipvs configuration\n"); return NULL; } dest = svc->scheduler->schedule(svc, iph); if (dest == NULL) { IP_VS_DBG(1, "Schedule: no dest found.\n"); return NULL; } /* * Create a connection entry. */ cp = ip_vs_conn_new(iph->protocol, iph->saddr, portp[0], iph->daddr, portp[1], dest->addr, dest->port?dest->port:portp[1], 0, dest); if (cp == NULL) return NULL; /* * Increase the inactive connection counter because it is in * Syn-Received state (inactive) when the connection is created. */ atomic_inc(&dest->inactconns); IP_VS_DBG(6, "Schedule fwd:%c s:%s c:%u.%u.%u.%u:%u v:%u.%u.%u.%u:%u " "d:%u.%u.%u.%u:%u flg:%X cnt:%d\n", ip_vs_fwd_tag(cp), ip_vs_state_name(cp->state), NIPQUAD(cp->caddr), ntohs(cp->cport), NIPQUAD(cp->vaddr), ntohs(cp->vport), NIPQUAD(cp->daddr), ntohs(cp->dport), cp->flags, atomic_read(&cp->refcnt)); return cp; }
#ifdef CONFIG_IP_VS_IPV6 if (cp->af == AF_INET6) seq_printf(seq, "%-3s %pI6 %04X %pI6 %04X %pI6 %04X %-11s %-6s %7lu\n", ip_vs_proto_name(cp->protocol), &cp->caddr.in6, ntohs(cp->cport), &cp->vaddr.in6, ntohs(cp->vport), &cp->daddr.in6, ntohs(cp->dport), ip_vs_state_name(cp->protocol, cp->state), ip_vs_origin_name(cp->flags), (cp->timer.expires-jiffies)/HZ); else #endif seq_printf(seq, "%-3s %08X %04X %08X %04X " "%08X %04X %-11s %-6s %7lu\n", ip_vs_proto_name(cp->protocol), ntohl(cp->caddr.ip), ntohs(cp->cport), ntohl(cp->vaddr.ip), ntohs(cp->vport), ntohl(cp->daddr.ip), ntohs(cp->dport), ip_vs_state_name(cp->protocol, cp->state), ip_vs_origin_name(cp->flags), (cp->timer.expires-jiffies)/HZ);