Hi, This is an updated version of Julian's One Packet Scheduler patch. It is based on http://marc.info/?l=linux-virtual-server&m=112800257026121&w=2 with all issues raised in previous discussions addressed. Index: net-2.6/include/linux/ip_vs.h =================================================================== --- net-2.6.orig/include/linux/ip_vs.h +++ net-2.6/include/linux/ip_vs.h @@ -19,6 +19,7 @@ */ #define IP_VS_SVC_F_PERSISTENT 0x0001 /* persistent port */ #define IP_VS_SVC_F_HASHED 0x0002 /* hashed entry */ +#define IP_VS_SVC_F_ONEPACKET 0x0004 /* one-packet scheduling */ /* * Destination Server Flags @@ -85,6 +86,7 @@ #define IP_VS_CONN_F_SEQ_MASK 0x0600 /* in/out sequence mask */ #define IP_VS_CONN_F_NO_CPORT 0x0800 /* no client port set yet */ #define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */ +#define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */ #define IP_VS_SCHEDNAME_MAXLEN 16 #define IP_VS_IFNAME_MAXLEN 16 Index: net-2.6/net/netfilter/ipvs/ip_vs_conn.c =================================================================== --- net-2.6.orig/net/netfilter/ipvs/ip_vs_conn.c +++ net-2.6/net/netfilter/ipvs/ip_vs_conn.c @@ -158,6 +158,9 @@ static inline int ip_vs_conn_hash(struct unsigned hash; int ret; + if (cp->flags & IP_VS_CONN_F_ONE_PACKET) + return 0; + /* Hash by protocol, client address and port */ hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport); @@ -359,8 +362,13 @@ struct ip_vs_conn *ip_vs_conn_out_get */ void ip_vs_conn_put(struct ip_vs_conn *cp) { + unsigned long timeout = cp->timeout; + + if (cp->flags & IP_VS_CONN_F_ONE_PACKET) + timeout = 0; + /* reset it expire in its timeout */ - mod_timer(&cp->timer, jiffies+cp->timeout); + mod_timer(&cp->timer, jiffies+timeout); __ip_vs_conn_put(cp); } @@ -653,7 +661,7 @@ static void ip_vs_conn_expire(unsigned l /* * unhash it if it is hashed in the conn table */ - if (!ip_vs_conn_unhash(cp)) + if (!ip_vs_conn_unhash(cp) && !(cp->flags & IP_VS_CONN_F_ONE_PACKET)) goto expire_later; /* Index: net-2.6/net/netfilter/ipvs/ip_vs_core.c =================================================================== --- net-2.6.orig/net/netfilter/ipvs/ip_vs_core.c +++ net-2.6/net/netfilter/ipvs/ip_vs_core.c @@ -176,6 +176,13 @@ ip_vs_set_state(struct ip_vs_conn *cp, i return pp->state_transition(cp, direction, skb, pp); } +static inline __u16 +ip_vs_onepacket_enabled(struct ip_vs_service *svc, struct ip_vs_iphdr *iph) +{ + return (svc->flags & IP_VS_SVC_F_ONEPACKET + && iph->protocol == IPPROTO_UDP) + ? IP_VS_CONN_F_ONE_PACKET : 0; +} /* * IPVS persistent scheduling function @@ -347,7 +354,7 @@ ip_vs_sched_persist(struct ip_vs_service &iph.saddr, ports[0], &iph.daddr, ports[1], &dest->addr, dport, - 0, + ip_vs_onepacket_enabled(svc, &iph), dest); if (cp == NULL) { ip_vs_conn_put(ct); @@ -414,7 +421,7 @@ ip_vs_schedule(struct ip_vs_service *svc &iph.saddr, pptr[0], &iph.daddr, pptr[1], &dest->addr, dest->port ? dest->port : pptr[1], - 0, + ip_vs_onepacket_enabled(svc, &iph), dest); if (cp == NULL) return NULL; @@ -474,7 +481,8 @@ int ip_vs_leave(struct ip_vs_service *sv &iph.saddr, pptr[0], &iph.daddr, pptr[1], &daddr, 0, - IP_VS_CONN_F_BYPASS, + IP_VS_CONN_F_BYPASS | + ip_vs_onepacket_enabled(svc, &iph), NULL); if (cp == NULL) return NF_DROP; Index: net-2.6/net/netfilter/ipvs/ip_vs_ctl.c =================================================================== --- net-2.6.orig/net/netfilter/ipvs/ip_vs_ctl.c +++ net-2.6/net/netfilter/ipvs/ip_vs_ctl.c @@ -1857,21 +1857,27 @@ static int ip_vs_info_seq_show(struct se if (iter->table == ip_vs_svc_table) { #ifdef CONFIG_IP_VS_IPV6 if (svc->af == AF_INET6) - seq_printf(seq, "%s [%pI6]:%04X %s ", + seq_printf(seq, "%s [%pI6]:%04X %s%s ", ip_vs_proto_name(svc->protocol), &svc->addr.in6, ntohs(svc->port), - svc->scheduler->name); + svc->scheduler->name, + (svc->flags & IP_VS_SVC_F_ONEPACKET)? + " ops":""); else #endif - seq_printf(seq, "%s %08X:%04X %s ", + seq_printf(seq, "%s %08X:%04X %s%s ", ip_vs_proto_name(svc->protocol), ntohl(svc->addr.ip), ntohs(svc->port), - svc->scheduler->name); + svc->scheduler->name, + (svc->flags & IP_VS_SVC_F_ONEPACKET)? + " ops":""); } else { - seq_printf(seq, "FWM %08X %s ", - svc->fwmark, svc->scheduler->name); + seq_printf(seq, "FWM %08X %s%s ", + svc->fwmark, svc->scheduler->name, + (svc->flags & IP_VS_SVC_F_ONEPACKET)? + " ops":""); } if (svc->flags & IP_VS_SVC_F_PERSISTENT) -- To unsubscribe from this list: send the line "unsubscribe lvs-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html