aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipvs/ip_vs_ctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ipvs/ip_vs_ctl.c')
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index 6dbc527285fa..7f89c588e588 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -1177,6 +1177,19 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
1177 goto out_mod_dec; 1177 goto out_mod_dec;
1178 } 1178 }
1179 1179
1180#ifdef CONFIG_IP_VS_IPV6
1181 if (u->af == AF_INET6) {
1182 if (!sched->supports_ipv6) {
1183 ret = -EAFNOSUPPORT;
1184 goto out_err;
1185 }
1186 if ((u->netmask < 1) || (u->netmask > 128)) {
1187 ret = -EINVAL;
1188 goto out_err;
1189 }
1190 }
1191#endif
1192
1180 svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC); 1193 svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC);
1181 if (svc == NULL) { 1194 if (svc == NULL) {
1182 IP_VS_DBG(1, "ip_vs_add_service: kmalloc failed.\n"); 1195 IP_VS_DBG(1, "ip_vs_add_service: kmalloc failed.\n");
@@ -1214,7 +1227,10 @@ ip_vs_add_service(struct ip_vs_service_user_kern *u,
1214 atomic_inc(&ip_vs_nullsvc_counter); 1227 atomic_inc(&ip_vs_nullsvc_counter);
1215 1228
1216 ip_vs_new_estimator(&svc->stats); 1229 ip_vs_new_estimator(&svc->stats);
1217 ip_vs_num_services++; 1230
1231 /* Count only IPv4 services for old get/setsockopt interface */
1232 if (svc->af == AF_INET)
1233 ip_vs_num_services++;
1218 1234
1219 /* Hash the service into the service table */ 1235 /* Hash the service into the service table */
1220 write_lock_bh(&__ip_vs_svc_lock); 1236 write_lock_bh(&__ip_vs_svc_lock);
@@ -1265,6 +1281,19 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)
1265 } 1281 }
1266 old_sched = sched; 1282 old_sched = sched;
1267 1283
1284#ifdef CONFIG_IP_VS_IPV6
1285 if (u->af == AF_INET6) {
1286 if (!sched->supports_ipv6) {
1287 ret = EAFNOSUPPORT;
1288 goto out;
1289 }
1290 if ((u->netmask < 1) || (u->netmask > 128)) {
1291 ret = EINVAL;
1292 goto out;
1293 }
1294 }
1295#endif
1296
1268 write_lock_bh(&__ip_vs_svc_lock); 1297 write_lock_bh(&__ip_vs_svc_lock);
1269 1298
1270 /* 1299 /*
@@ -1329,7 +1358,10 @@ static void __ip_vs_del_service(struct ip_vs_service *svc)
1329 struct ip_vs_dest *dest, *nxt; 1358 struct ip_vs_dest *dest, *nxt;
1330 struct ip_vs_scheduler *old_sched; 1359 struct ip_vs_scheduler *old_sched;
1331 1360
1332 ip_vs_num_services--; 1361 /* Count only IPv4 services for old get/setsockopt interface */
1362 if (svc->af == AF_INET)
1363 ip_vs_num_services--;
1364
1333 ip_vs_kill_estimator(&svc->stats); 1365 ip_vs_kill_estimator(&svc->stats);
1334 1366
1335 /* Unbind scheduler */ 1367 /* Unbind scheduler */
@@ -2212,6 +2244,10 @@ __ip_vs_get_service_entries(const struct ip_vs_get_services *get,
2212 2244
2213 for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { 2245 for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
2214 list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) { 2246 list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
2247 /* Only expose IPv4 entries to old interface */
2248 if (svc->af != AF_INET)
2249 continue;
2250
2215 if (count >= get->num_services) 2251 if (count >= get->num_services)
2216 goto out; 2252 goto out;
2217 memset(&entry, 0, sizeof(entry)); 2253 memset(&entry, 0, sizeof(entry));
@@ -2227,6 +2263,10 @@ __ip_vs_get_service_entries(const struct ip_vs_get_services *get,
2227 2263
2228 for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { 2264 for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
2229 list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) { 2265 list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
2266 /* Only expose IPv4 entries to old interface */
2267 if (svc->af != AF_INET)
2268 continue;
2269
2230 if (count >= get->num_services) 2270 if (count >= get->num_services)
2231 goto out; 2271 goto out;
2232 memset(&entry, 0, sizeof(entry)); 2272 memset(&entry, 0, sizeof(entry));
@@ -2584,7 +2624,7 @@ static int ip_vs_genl_fill_service(struct sk_buff *skb,
2584 if (!nl_service) 2624 if (!nl_service)
2585 return -EMSGSIZE; 2625 return -EMSGSIZE;
2586 2626
2587 NLA_PUT_U16(skb, IPVS_SVC_ATTR_AF, AF_INET); 2627 NLA_PUT_U16(skb, IPVS_SVC_ATTR_AF, svc->af);
2588 2628
2589 if (svc->fwmark) { 2629 if (svc->fwmark) {
2590 NLA_PUT_U32(skb, IPVS_SVC_ATTR_FWMARK, svc->fwmark); 2630 NLA_PUT_U32(skb, IPVS_SVC_ATTR_FWMARK, svc->fwmark);
@@ -2691,8 +2731,11 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc,
2691 return -EINVAL; 2731 return -EINVAL;
2692 2732
2693 usvc->af = nla_get_u16(nla_af); 2733 usvc->af = nla_get_u16(nla_af);
2694 /* For now, only support IPv4 */ 2734#ifdef CONFIG_IP_VS_IPV6
2695 if (nla_get_u16(nla_af) != AF_INET) 2735 if (usvc->af != AF_INET && usvc->af != AF_INET6)
2736#else
2737 if (usvc->af != AF_INET)
2738#endif
2696 return -EAFNOSUPPORT; 2739 return -EAFNOSUPPORT;
2697 2740
2698 if (nla_fwmark) { 2741 if (nla_fwmark) {