diff options
-rw-r--r-- | Documentation/networking/ipvs-sysctl.txt | 7 | ||||
-rw-r--r-- | include/net/ip_vs.h | 12 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_core.c | 12 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ctl.c | 7 |
4 files changed, 34 insertions, 4 deletions
diff --git a/Documentation/networking/ipvs-sysctl.txt b/Documentation/networking/ipvs-sysctl.txt index f2a2488f1bf3..9573d0c48c6e 100644 --- a/Documentation/networking/ipvs-sysctl.txt +++ b/Documentation/networking/ipvs-sysctl.txt | |||
@@ -15,6 +15,13 @@ amemthresh - INTEGER | |||
15 | enabled and the variable is automatically set to 2, otherwise | 15 | enabled and the variable is automatically set to 2, otherwise |
16 | the strategy is disabled and the variable is set to 1. | 16 | the strategy is disabled and the variable is set to 1. |
17 | 17 | ||
18 | backup_only - BOOLEAN | ||
19 | 0 - disabled (default) | ||
20 | not 0 - enabled | ||
21 | |||
22 | If set, disable the director function while the server is | ||
23 | in backup mode to avoid packet loops for DR/TUN methods. | ||
24 | |||
18 | conntrack - BOOLEAN | 25 | conntrack - BOOLEAN |
19 | 0 - disabled (default) | 26 | 0 - disabled (default) |
20 | not 0 - enabled | 27 | not 0 - enabled |
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 68c69d54d392..fce8e6b66d55 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -976,6 +976,7 @@ struct netns_ipvs { | |||
976 | int sysctl_sync_retries; | 976 | int sysctl_sync_retries; |
977 | int sysctl_nat_icmp_send; | 977 | int sysctl_nat_icmp_send; |
978 | int sysctl_pmtu_disc; | 978 | int sysctl_pmtu_disc; |
979 | int sysctl_backup_only; | ||
979 | 980 | ||
980 | /* ip_vs_lblc */ | 981 | /* ip_vs_lblc */ |
981 | int sysctl_lblc_expiration; | 982 | int sysctl_lblc_expiration; |
@@ -1067,6 +1068,12 @@ static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs) | |||
1067 | return ipvs->sysctl_pmtu_disc; | 1068 | return ipvs->sysctl_pmtu_disc; |
1068 | } | 1069 | } |
1069 | 1070 | ||
1071 | static inline int sysctl_backup_only(struct netns_ipvs *ipvs) | ||
1072 | { | ||
1073 | return ipvs->sync_state & IP_VS_STATE_BACKUP && | ||
1074 | ipvs->sysctl_backup_only; | ||
1075 | } | ||
1076 | |||
1070 | #else | 1077 | #else |
1071 | 1078 | ||
1072 | static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) | 1079 | static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) |
@@ -1114,6 +1121,11 @@ static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs) | |||
1114 | return 1; | 1121 | return 1; |
1115 | } | 1122 | } |
1116 | 1123 | ||
1124 | static inline int sysctl_backup_only(struct netns_ipvs *ipvs) | ||
1125 | { | ||
1126 | return 0; | ||
1127 | } | ||
1128 | |||
1117 | #endif | 1129 | #endif |
1118 | 1130 | ||
1119 | /* | 1131 | /* |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 47edf5a40a59..18b4bc55fa3d 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -1577,7 +1577,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1577 | } | 1577 | } |
1578 | /* ipvs enabled in this netns ? */ | 1578 | /* ipvs enabled in this netns ? */ |
1579 | net = skb_net(skb); | 1579 | net = skb_net(skb); |
1580 | if (!net_ipvs(net)->enable) | 1580 | ipvs = net_ipvs(net); |
1581 | if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable)) | ||
1581 | return NF_ACCEPT; | 1582 | return NF_ACCEPT; |
1582 | 1583 | ||
1583 | ip_vs_fill_iph_skb(af, skb, &iph); | 1584 | ip_vs_fill_iph_skb(af, skb, &iph); |
@@ -1654,7 +1655,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1654 | } | 1655 | } |
1655 | 1656 | ||
1656 | IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet"); | 1657 | IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet"); |
1657 | ipvs = net_ipvs(net); | ||
1658 | /* Check the server status */ | 1658 | /* Check the server status */ |
1659 | if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { | 1659 | if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { |
1660 | /* the destination server is not available */ | 1660 | /* the destination server is not available */ |
@@ -1815,13 +1815,15 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb, | |||
1815 | { | 1815 | { |
1816 | int r; | 1816 | int r; |
1817 | struct net *net; | 1817 | struct net *net; |
1818 | struct netns_ipvs *ipvs; | ||
1818 | 1819 | ||
1819 | if (ip_hdr(skb)->protocol != IPPROTO_ICMP) | 1820 | if (ip_hdr(skb)->protocol != IPPROTO_ICMP) |
1820 | return NF_ACCEPT; | 1821 | return NF_ACCEPT; |
1821 | 1822 | ||
1822 | /* ipvs enabled in this netns ? */ | 1823 | /* ipvs enabled in this netns ? */ |
1823 | net = skb_net(skb); | 1824 | net = skb_net(skb); |
1824 | if (!net_ipvs(net)->enable) | 1825 | ipvs = net_ipvs(net); |
1826 | if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable)) | ||
1825 | return NF_ACCEPT; | 1827 | return NF_ACCEPT; |
1826 | 1828 | ||
1827 | return ip_vs_in_icmp(skb, &r, hooknum); | 1829 | return ip_vs_in_icmp(skb, &r, hooknum); |
@@ -1835,6 +1837,7 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb, | |||
1835 | { | 1837 | { |
1836 | int r; | 1838 | int r; |
1837 | struct net *net; | 1839 | struct net *net; |
1840 | struct netns_ipvs *ipvs; | ||
1838 | struct ip_vs_iphdr iphdr; | 1841 | struct ip_vs_iphdr iphdr; |
1839 | 1842 | ||
1840 | ip_vs_fill_iph_skb(AF_INET6, skb, &iphdr); | 1843 | ip_vs_fill_iph_skb(AF_INET6, skb, &iphdr); |
@@ -1843,7 +1846,8 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb, | |||
1843 | 1846 | ||
1844 | /* ipvs enabled in this netns ? */ | 1847 | /* ipvs enabled in this netns ? */ |
1845 | net = skb_net(skb); | 1848 | net = skb_net(skb); |
1846 | if (!net_ipvs(net)->enable) | 1849 | ipvs = net_ipvs(net); |
1850 | if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable)) | ||
1847 | return NF_ACCEPT; | 1851 | return NF_ACCEPT; |
1848 | 1852 | ||
1849 | return ip_vs_in_icmp_v6(skb, &r, hooknum, &iphdr); | 1853 | return ip_vs_in_icmp_v6(skb, &r, hooknum, &iphdr); |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index c68198bf9128..9e2d1cccd1eb 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -1808,6 +1808,12 @@ static struct ctl_table vs_vars[] = { | |||
1808 | .mode = 0644, | 1808 | .mode = 0644, |
1809 | .proc_handler = proc_dointvec, | 1809 | .proc_handler = proc_dointvec, |
1810 | }, | 1810 | }, |
1811 | { | ||
1812 | .procname = "backup_only", | ||
1813 | .maxlen = sizeof(int), | ||
1814 | .mode = 0644, | ||
1815 | .proc_handler = proc_dointvec, | ||
1816 | }, | ||
1811 | #ifdef CONFIG_IP_VS_DEBUG | 1817 | #ifdef CONFIG_IP_VS_DEBUG |
1812 | { | 1818 | { |
1813 | .procname = "debug_level", | 1819 | .procname = "debug_level", |
@@ -3741,6 +3747,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct net *net) | |||
3741 | tbl[idx++].data = &ipvs->sysctl_nat_icmp_send; | 3747 | tbl[idx++].data = &ipvs->sysctl_nat_icmp_send; |
3742 | ipvs->sysctl_pmtu_disc = 1; | 3748 | ipvs->sysctl_pmtu_disc = 1; |
3743 | tbl[idx++].data = &ipvs->sysctl_pmtu_disc; | 3749 | tbl[idx++].data = &ipvs->sysctl_pmtu_disc; |
3750 | tbl[idx++].data = &ipvs->sysctl_backup_only; | ||
3744 | 3751 | ||
3745 | 3752 | ||
3746 | ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl); | 3753 | ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl); |