diff options
author | Julius Volz <juliusv@google.com> | 2008-09-02 09:55:36 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2008-09-04 21:17:04 -0400 |
commit | c860c6b1479992440e4962e9c95d258bfdce4fca (patch) | |
tree | 25172dc157cf23f02f1639af5ae6bbd39521f627 /net | |
parent | c842a3ada9ba8f0cca38a70de3fe0effcfab254c (diff) |
IPVS: Add internal versions of sockopt interface structs
Add extended internal versions of struct ip_vs_service_user and struct
ip_vs_dest_user (the originals can't be modified as they are part
of the old sockopt interface). Adjust ip_vs_ctl.c to work with the new
data structures and add some minor AF-awareness.
Signed-off-by: Julius Volz <juliusv@google.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/ipvs/ip_vs_ctl.c | 138 |
1 files changed, 90 insertions, 48 deletions
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c index 3f2277b847db..a0c8b7bb5530 100644 --- a/net/ipv4/ipvs/ip_vs_ctl.c +++ b/net/ipv4/ipvs/ip_vs_ctl.c | |||
@@ -708,7 +708,7 @@ ip_vs_zero_stats(struct ip_vs_stats *stats) | |||
708 | */ | 708 | */ |
709 | static void | 709 | static void |
710 | __ip_vs_update_dest(struct ip_vs_service *svc, | 710 | __ip_vs_update_dest(struct ip_vs_service *svc, |
711 | struct ip_vs_dest *dest, struct ip_vs_dest_user *udest) | 711 | struct ip_vs_dest *dest, struct ip_vs_dest_user_kern *udest) |
712 | { | 712 | { |
713 | int conn_flags; | 713 | int conn_flags; |
714 | 714 | ||
@@ -717,7 +717,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc, | |||
717 | conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE; | 717 | conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE; |
718 | 718 | ||
719 | /* check if local node and update the flags */ | 719 | /* check if local node and update the flags */ |
720 | if (inet_addr_type(&init_net, udest->addr) == RTN_LOCAL) { | 720 | if (inet_addr_type(&init_net, udest->addr.ip) == RTN_LOCAL) { |
721 | conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK) | 721 | conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK) |
722 | | IP_VS_CONN_F_LOCALNODE; | 722 | | IP_VS_CONN_F_LOCALNODE; |
723 | } | 723 | } |
@@ -761,7 +761,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc, | |||
761 | * Create a destination for the given service | 761 | * Create a destination for the given service |
762 | */ | 762 | */ |
763 | static int | 763 | static int |
764 | ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest, | 764 | ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest, |
765 | struct ip_vs_dest **dest_p) | 765 | struct ip_vs_dest **dest_p) |
766 | { | 766 | { |
767 | struct ip_vs_dest *dest; | 767 | struct ip_vs_dest *dest; |
@@ -769,7 +769,7 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest, | |||
769 | 769 | ||
770 | EnterFunction(2); | 770 | EnterFunction(2); |
771 | 771 | ||
772 | atype = inet_addr_type(&init_net, udest->addr); | 772 | atype = inet_addr_type(&init_net, udest->addr.ip); |
773 | if (atype != RTN_LOCAL && atype != RTN_UNICAST) | 773 | if (atype != RTN_LOCAL && atype != RTN_UNICAST) |
774 | return -EINVAL; | 774 | return -EINVAL; |
775 | 775 | ||
@@ -779,11 +779,12 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest, | |||
779 | return -ENOMEM; | 779 | return -ENOMEM; |
780 | } | 780 | } |
781 | 781 | ||
782 | dest->af = svc->af; | ||
782 | dest->protocol = svc->protocol; | 783 | dest->protocol = svc->protocol; |
783 | dest->vaddr.ip = svc->addr.ip; | 784 | dest->vaddr = svc->addr; |
784 | dest->vport = svc->port; | 785 | dest->vport = svc->port; |
785 | dest->vfwmark = svc->fwmark; | 786 | dest->vfwmark = svc->fwmark; |
786 | dest->addr.ip = udest->addr; | 787 | ip_vs_addr_copy(svc->af, &dest->addr, &udest->addr); |
787 | dest->port = udest->port; | 788 | dest->port = udest->port; |
788 | 789 | ||
789 | atomic_set(&dest->activeconns, 0); | 790 | atomic_set(&dest->activeconns, 0); |
@@ -808,10 +809,10 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest, | |||
808 | * Add a destination into an existing service | 809 | * Add a destination into an existing service |
809 | */ | 810 | */ |
810 | static int | 811 | static int |
811 | ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest) | 812 | ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) |
812 | { | 813 | { |
813 | struct ip_vs_dest *dest; | 814 | struct ip_vs_dest *dest; |
814 | __be32 daddr = udest->addr; | 815 | union nf_inet_addr daddr; |
815 | __be16 dport = udest->port; | 816 | __be16 dport = udest->port; |
816 | int ret; | 817 | int ret; |
817 | 818 | ||
@@ -828,10 +829,12 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest) | |||
828 | return -ERANGE; | 829 | return -ERANGE; |
829 | } | 830 | } |
830 | 831 | ||
832 | ip_vs_addr_copy(svc->af, &daddr, &udest->addr); | ||
833 | |||
831 | /* | 834 | /* |
832 | * Check if the dest already exists in the list | 835 | * Check if the dest already exists in the list |
833 | */ | 836 | */ |
834 | dest = ip_vs_lookup_dest(svc, daddr, dport); | 837 | dest = ip_vs_lookup_dest(svc, daddr.ip, dport); |
835 | if (dest != NULL) { | 838 | if (dest != NULL) { |
836 | IP_VS_DBG(1, "ip_vs_add_dest(): dest already exists\n"); | 839 | IP_VS_DBG(1, "ip_vs_add_dest(): dest already exists\n"); |
837 | return -EEXIST; | 840 | return -EEXIST; |
@@ -841,7 +844,7 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest) | |||
841 | * Check if the dest already exists in the trash and | 844 | * Check if the dest already exists in the trash and |
842 | * is from the same service | 845 | * is from the same service |
843 | */ | 846 | */ |
844 | dest = ip_vs_trash_get_dest(svc, daddr, dport); | 847 | dest = ip_vs_trash_get_dest(svc, daddr.ip, dport); |
845 | if (dest != NULL) { | 848 | if (dest != NULL) { |
846 | IP_VS_DBG(3, "Get destination %u.%u.%u.%u:%u from trash, " | 849 | IP_VS_DBG(3, "Get destination %u.%u.%u.%u:%u from trash, " |
847 | "dest->refcnt=%d, service %u/%u.%u.%u.%u:%u\n", | 850 | "dest->refcnt=%d, service %u/%u.%u.%u.%u:%u\n", |
@@ -916,10 +919,10 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest) | |||
916 | * Edit a destination in the given service | 919 | * Edit a destination in the given service |
917 | */ | 920 | */ |
918 | static int | 921 | static int |
919 | ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest) | 922 | ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) |
920 | { | 923 | { |
921 | struct ip_vs_dest *dest; | 924 | struct ip_vs_dest *dest; |
922 | __be32 daddr = udest->addr; | 925 | union nf_inet_addr daddr; |
923 | __be16 dport = udest->port; | 926 | __be16 dport = udest->port; |
924 | 927 | ||
925 | EnterFunction(2); | 928 | EnterFunction(2); |
@@ -935,10 +938,12 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest) | |||
935 | return -ERANGE; | 938 | return -ERANGE; |
936 | } | 939 | } |
937 | 940 | ||
941 | ip_vs_addr_copy(svc->af, &daddr, &udest->addr); | ||
942 | |||
938 | /* | 943 | /* |
939 | * Lookup the destination list | 944 | * Lookup the destination list |
940 | */ | 945 | */ |
941 | dest = ip_vs_lookup_dest(svc, daddr, dport); | 946 | dest = ip_vs_lookup_dest(svc, daddr.ip, dport); |
942 | if (dest == NULL) { | 947 | if (dest == NULL) { |
943 | IP_VS_DBG(1, "ip_vs_edit_dest(): dest doesn't exist\n"); | 948 | IP_VS_DBG(1, "ip_vs_edit_dest(): dest doesn't exist\n"); |
944 | return -ENOENT; | 949 | return -ENOENT; |
@@ -1029,15 +1034,15 @@ static void __ip_vs_unlink_dest(struct ip_vs_service *svc, | |||
1029 | * Delete a destination server in the given service | 1034 | * Delete a destination server in the given service |
1030 | */ | 1035 | */ |
1031 | static int | 1036 | static int |
1032 | ip_vs_del_dest(struct ip_vs_service *svc,struct ip_vs_dest_user *udest) | 1037 | ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) |
1033 | { | 1038 | { |
1034 | struct ip_vs_dest *dest; | 1039 | struct ip_vs_dest *dest; |
1035 | __be32 daddr = udest->addr; | ||
1036 | __be16 dport = udest->port; | 1040 | __be16 dport = udest->port; |
1037 | 1041 | ||
1038 | EnterFunction(2); | 1042 | EnterFunction(2); |
1039 | 1043 | ||
1040 | dest = ip_vs_lookup_dest(svc, daddr, dport); | 1044 | dest = ip_vs_lookup_dest(svc, udest->addr.ip, dport); |
1045 | |||
1041 | if (dest == NULL) { | 1046 | if (dest == NULL) { |
1042 | IP_VS_DBG(1, "ip_vs_del_dest(): destination not found!\n"); | 1047 | IP_VS_DBG(1, "ip_vs_del_dest(): destination not found!\n"); |
1043 | return -ENOENT; | 1048 | return -ENOENT; |
@@ -1072,7 +1077,8 @@ ip_vs_del_dest(struct ip_vs_service *svc,struct ip_vs_dest_user *udest) | |||
1072 | * Add a service into the service hash table | 1077 | * Add a service into the service hash table |
1073 | */ | 1078 | */ |
1074 | static int | 1079 | static int |
1075 | ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p) | 1080 | ip_vs_add_service(struct ip_vs_service_user_kern *u, |
1081 | struct ip_vs_service **svc_p) | ||
1076 | { | 1082 | { |
1077 | int ret = 0; | 1083 | int ret = 0; |
1078 | struct ip_vs_scheduler *sched = NULL; | 1084 | struct ip_vs_scheduler *sched = NULL; |
@@ -1101,8 +1107,9 @@ ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p) | |||
1101 | atomic_set(&svc->usecnt, 1); | 1107 | atomic_set(&svc->usecnt, 1); |
1102 | atomic_set(&svc->refcnt, 0); | 1108 | atomic_set(&svc->refcnt, 0); |
1103 | 1109 | ||
1110 | svc->af = u->af; | ||
1104 | svc->protocol = u->protocol; | 1111 | svc->protocol = u->protocol; |
1105 | svc->addr.ip = u->addr; | 1112 | ip_vs_addr_copy(svc->af, &svc->addr, &u->addr); |
1106 | svc->port = u->port; | 1113 | svc->port = u->port; |
1107 | svc->fwmark = u->fwmark; | 1114 | svc->fwmark = u->fwmark; |
1108 | svc->flags = u->flags; | 1115 | svc->flags = u->flags; |
@@ -1161,7 +1168,7 @@ ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p) | |||
1161 | * Edit a service and bind it with a new scheduler | 1168 | * Edit a service and bind it with a new scheduler |
1162 | */ | 1169 | */ |
1163 | static int | 1170 | static int |
1164 | ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user *u) | 1171 | ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u) |
1165 | { | 1172 | { |
1166 | struct ip_vs_scheduler *sched, *old_sched; | 1173 | struct ip_vs_scheduler *sched, *old_sched; |
1167 | int ret = 0; | 1174 | int ret = 0; |
@@ -1905,14 +1912,44 @@ static const unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = { | |||
1905 | [SET_CMDID(IP_VS_SO_SET_ZERO)] = SERVICE_ARG_LEN, | 1912 | [SET_CMDID(IP_VS_SO_SET_ZERO)] = SERVICE_ARG_LEN, |
1906 | }; | 1913 | }; |
1907 | 1914 | ||
1915 | static void ip_vs_copy_usvc_compat(struct ip_vs_service_user_kern *usvc, | ||
1916 | struct ip_vs_service_user *usvc_compat) | ||
1917 | { | ||
1918 | usvc->af = AF_INET; | ||
1919 | usvc->protocol = usvc_compat->protocol; | ||
1920 | usvc->addr.ip = usvc_compat->addr; | ||
1921 | usvc->port = usvc_compat->port; | ||
1922 | usvc->fwmark = usvc_compat->fwmark; | ||
1923 | |||
1924 | /* Deep copy of sched_name is not needed here */ | ||
1925 | usvc->sched_name = usvc_compat->sched_name; | ||
1926 | |||
1927 | usvc->flags = usvc_compat->flags; | ||
1928 | usvc->timeout = usvc_compat->timeout; | ||
1929 | usvc->netmask = usvc_compat->netmask; | ||
1930 | } | ||
1931 | |||
1932 | static void ip_vs_copy_udest_compat(struct ip_vs_dest_user_kern *udest, | ||
1933 | struct ip_vs_dest_user *udest_compat) | ||
1934 | { | ||
1935 | udest->addr.ip = udest_compat->addr; | ||
1936 | udest->port = udest_compat->port; | ||
1937 | udest->conn_flags = udest_compat->conn_flags; | ||
1938 | udest->weight = udest_compat->weight; | ||
1939 | udest->u_threshold = udest_compat->u_threshold; | ||
1940 | udest->l_threshold = udest_compat->l_threshold; | ||
1941 | } | ||
1942 | |||
1908 | static int | 1943 | static int |
1909 | do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | 1944 | do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) |
1910 | { | 1945 | { |
1911 | int ret; | 1946 | int ret; |
1912 | unsigned char arg[MAX_ARG_LEN]; | 1947 | unsigned char arg[MAX_ARG_LEN]; |
1913 | struct ip_vs_service_user *usvc; | 1948 | struct ip_vs_service_user *usvc_compat; |
1949 | struct ip_vs_service_user_kern usvc; | ||
1914 | struct ip_vs_service *svc; | 1950 | struct ip_vs_service *svc; |
1915 | struct ip_vs_dest_user *udest; | 1951 | struct ip_vs_dest_user *udest_compat; |
1952 | struct ip_vs_dest_user_kern udest; | ||
1916 | 1953 | ||
1917 | if (!capable(CAP_NET_ADMIN)) | 1954 | if (!capable(CAP_NET_ADMIN)) |
1918 | return -EPERM; | 1955 | return -EPERM; |
@@ -1952,35 +1989,40 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | |||
1952 | goto out_unlock; | 1989 | goto out_unlock; |
1953 | } | 1990 | } |
1954 | 1991 | ||
1955 | usvc = (struct ip_vs_service_user *)arg; | 1992 | usvc_compat = (struct ip_vs_service_user *)arg; |
1956 | udest = (struct ip_vs_dest_user *)(usvc + 1); | 1993 | udest_compat = (struct ip_vs_dest_user *)(usvc_compat + 1); |
1994 | |||
1995 | /* We only use the new structs internally, so copy userspace compat | ||
1996 | * structs to extended internal versions */ | ||
1997 | ip_vs_copy_usvc_compat(&usvc, usvc_compat); | ||
1998 | ip_vs_copy_udest_compat(&udest, udest_compat); | ||
1957 | 1999 | ||
1958 | if (cmd == IP_VS_SO_SET_ZERO) { | 2000 | if (cmd == IP_VS_SO_SET_ZERO) { |
1959 | /* if no service address is set, zero counters in all */ | 2001 | /* if no service address is set, zero counters in all */ |
1960 | if (!usvc->fwmark && !usvc->addr && !usvc->port) { | 2002 | if (!usvc.fwmark && !usvc.addr.ip && !usvc.port) { |
1961 | ret = ip_vs_zero_all(); | 2003 | ret = ip_vs_zero_all(); |
1962 | goto out_unlock; | 2004 | goto out_unlock; |
1963 | } | 2005 | } |
1964 | } | 2006 | } |
1965 | 2007 | ||
1966 | /* Check for valid protocol: TCP or UDP, even for fwmark!=0 */ | 2008 | /* Check for valid protocol: TCP or UDP, even for fwmark!=0 */ |
1967 | if (usvc->protocol!=IPPROTO_TCP && usvc->protocol!=IPPROTO_UDP) { | 2009 | if (usvc.protocol != IPPROTO_TCP && usvc.protocol != IPPROTO_UDP) { |
1968 | IP_VS_ERR("set_ctl: invalid protocol: %d %d.%d.%d.%d:%d %s\n", | 2010 | IP_VS_ERR("set_ctl: invalid protocol: %d %d.%d.%d.%d:%d %s\n", |
1969 | usvc->protocol, NIPQUAD(usvc->addr), | 2011 | usvc.protocol, NIPQUAD(usvc.addr.ip), |
1970 | ntohs(usvc->port), usvc->sched_name); | 2012 | ntohs(usvc.port), usvc.sched_name); |
1971 | ret = -EFAULT; | 2013 | ret = -EFAULT; |
1972 | goto out_unlock; | 2014 | goto out_unlock; |
1973 | } | 2015 | } |
1974 | 2016 | ||
1975 | /* Lookup the exact service by <protocol, addr, port> or fwmark */ | 2017 | /* Lookup the exact service by <protocol, addr, port> or fwmark */ |
1976 | if (usvc->fwmark == 0) | 2018 | if (usvc.fwmark == 0) |
1977 | svc = __ip_vs_service_get(usvc->protocol, | 2019 | svc = __ip_vs_service_get(usvc.protocol, |
1978 | usvc->addr, usvc->port); | 2020 | usvc.addr.ip, usvc.port); |
1979 | else | 2021 | else |
1980 | svc = __ip_vs_svc_fwm_get(usvc->fwmark); | 2022 | svc = __ip_vs_svc_fwm_get(usvc.fwmark); |
1981 | 2023 | ||
1982 | if (cmd != IP_VS_SO_SET_ADD | 2024 | if (cmd != IP_VS_SO_SET_ADD |
1983 | && (svc == NULL || svc->protocol != usvc->protocol)) { | 2025 | && (svc == NULL || svc->protocol != usvc.protocol)) { |
1984 | ret = -ESRCH; | 2026 | ret = -ESRCH; |
1985 | goto out_unlock; | 2027 | goto out_unlock; |
1986 | } | 2028 | } |
@@ -1990,10 +2032,10 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | |||
1990 | if (svc != NULL) | 2032 | if (svc != NULL) |
1991 | ret = -EEXIST; | 2033 | ret = -EEXIST; |
1992 | else | 2034 | else |
1993 | ret = ip_vs_add_service(usvc, &svc); | 2035 | ret = ip_vs_add_service(&usvc, &svc); |
1994 | break; | 2036 | break; |
1995 | case IP_VS_SO_SET_EDIT: | 2037 | case IP_VS_SO_SET_EDIT: |
1996 | ret = ip_vs_edit_service(svc, usvc); | 2038 | ret = ip_vs_edit_service(svc, &usvc); |
1997 | break; | 2039 | break; |
1998 | case IP_VS_SO_SET_DEL: | 2040 | case IP_VS_SO_SET_DEL: |
1999 | ret = ip_vs_del_service(svc); | 2041 | ret = ip_vs_del_service(svc); |
@@ -2004,13 +2046,13 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) | |||
2004 | ret = ip_vs_zero_service(svc); | 2046 | ret = ip_vs_zero_service(svc); |
2005 | break; | 2047 | break; |
2006 | case IP_VS_SO_SET_ADDDEST: | 2048 | case IP_VS_SO_SET_ADDDEST: |
2007 | ret = ip_vs_add_dest(svc, udest); | 2049 | ret = ip_vs_add_dest(svc, &udest); |
2008 | break; | 2050 | break; |
2009 | case IP_VS_SO_SET_EDITDEST: | 2051 | case IP_VS_SO_SET_EDITDEST: |
2010 | ret = ip_vs_edit_dest(svc, udest); | 2052 | ret = ip_vs_edit_dest(svc, &udest); |
2011 | break; | 2053 | break; |
2012 | case IP_VS_SO_SET_DELDEST: | 2054 | case IP_VS_SO_SET_DELDEST: |
2013 | ret = ip_vs_del_dest(svc, udest); | 2055 | ret = ip_vs_del_dest(svc, &udest); |
2014 | break; | 2056 | break; |
2015 | default: | 2057 | default: |
2016 | ret = -EINVAL; | 2058 | ret = -EINVAL; |
@@ -2517,7 +2559,7 @@ nla_put_failure: | |||
2517 | return skb->len; | 2559 | return skb->len; |
2518 | } | 2560 | } |
2519 | 2561 | ||
2520 | static int ip_vs_genl_parse_service(struct ip_vs_service_user *usvc, | 2562 | static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc, |
2521 | struct nlattr *nla, int full_entry) | 2563 | struct nlattr *nla, int full_entry) |
2522 | { | 2564 | { |
2523 | struct nlattr *attrs[IPVS_SVC_ATTR_MAX + 1]; | 2565 | struct nlattr *attrs[IPVS_SVC_ATTR_MAX + 1]; |
@@ -2537,6 +2579,7 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user *usvc, | |||
2537 | if (!(nla_af && (nla_fwmark || (nla_port && nla_protocol && nla_addr)))) | 2579 | if (!(nla_af && (nla_fwmark || (nla_port && nla_protocol && nla_addr)))) |
2538 | return -EINVAL; | 2580 | return -EINVAL; |
2539 | 2581 | ||
2582 | usvc->af = nla_get_u16(nla_af); | ||
2540 | /* For now, only support IPv4 */ | 2583 | /* For now, only support IPv4 */ |
2541 | if (nla_get_u16(nla_af) != AF_INET) | 2584 | if (nla_get_u16(nla_af) != AF_INET) |
2542 | return -EAFNOSUPPORT; | 2585 | return -EAFNOSUPPORT; |
@@ -2572,7 +2615,7 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user *usvc, | |||
2572 | if (usvc->fwmark) | 2615 | if (usvc->fwmark) |
2573 | svc = __ip_vs_svc_fwm_get(usvc->fwmark); | 2616 | svc = __ip_vs_svc_fwm_get(usvc->fwmark); |
2574 | else | 2617 | else |
2575 | svc = __ip_vs_service_get(usvc->protocol, usvc->addr, | 2618 | svc = __ip_vs_service_get(usvc->protocol, usvc->addr.ip, |
2576 | usvc->port); | 2619 | usvc->port); |
2577 | if (svc) { | 2620 | if (svc) { |
2578 | usvc->flags = svc->flags; | 2621 | usvc->flags = svc->flags; |
@@ -2583,9 +2626,7 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user *usvc, | |||
2583 | /* set new flags from userland */ | 2626 | /* set new flags from userland */ |
2584 | usvc->flags = (usvc->flags & ~flags.mask) | | 2627 | usvc->flags = (usvc->flags & ~flags.mask) | |
2585 | (flags.flags & flags.mask); | 2628 | (flags.flags & flags.mask); |
2586 | 2629 | usvc->sched_name = nla_data(nla_sched); | |
2587 | strlcpy(usvc->sched_name, nla_data(nla_sched), | ||
2588 | sizeof(usvc->sched_name)); | ||
2589 | usvc->timeout = nla_get_u32(nla_timeout); | 2630 | usvc->timeout = nla_get_u32(nla_timeout); |
2590 | usvc->netmask = nla_get_u32(nla_netmask); | 2631 | usvc->netmask = nla_get_u32(nla_netmask); |
2591 | } | 2632 | } |
@@ -2595,7 +2636,7 @@ static int ip_vs_genl_parse_service(struct ip_vs_service_user *usvc, | |||
2595 | 2636 | ||
2596 | static struct ip_vs_service *ip_vs_genl_find_service(struct nlattr *nla) | 2637 | static struct ip_vs_service *ip_vs_genl_find_service(struct nlattr *nla) |
2597 | { | 2638 | { |
2598 | struct ip_vs_service_user usvc; | 2639 | struct ip_vs_service_user_kern usvc; |
2599 | int ret; | 2640 | int ret; |
2600 | 2641 | ||
2601 | ret = ip_vs_genl_parse_service(&usvc, nla, 0); | 2642 | ret = ip_vs_genl_parse_service(&usvc, nla, 0); |
@@ -2605,7 +2646,7 @@ static struct ip_vs_service *ip_vs_genl_find_service(struct nlattr *nla) | |||
2605 | if (usvc.fwmark) | 2646 | if (usvc.fwmark) |
2606 | return __ip_vs_svc_fwm_get(usvc.fwmark); | 2647 | return __ip_vs_svc_fwm_get(usvc.fwmark); |
2607 | else | 2648 | else |
2608 | return __ip_vs_service_get(usvc.protocol, usvc.addr, | 2649 | return __ip_vs_service_get(usvc.protocol, usvc.addr.ip, |
2609 | usvc.port); | 2650 | usvc.port); |
2610 | } | 2651 | } |
2611 | 2652 | ||
@@ -2705,7 +2746,7 @@ out_err: | |||
2705 | return skb->len; | 2746 | return skb->len; |
2706 | } | 2747 | } |
2707 | 2748 | ||
2708 | static int ip_vs_genl_parse_dest(struct ip_vs_dest_user *udest, | 2749 | static int ip_vs_genl_parse_dest(struct ip_vs_dest_user_kern *udest, |
2709 | struct nlattr *nla, int full_entry) | 2750 | struct nlattr *nla, int full_entry) |
2710 | { | 2751 | { |
2711 | struct nlattr *attrs[IPVS_DEST_ATTR_MAX + 1]; | 2752 | struct nlattr *attrs[IPVS_DEST_ATTR_MAX + 1]; |
@@ -2861,8 +2902,8 @@ static int ip_vs_genl_set_config(struct nlattr **attrs) | |||
2861 | static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) | 2902 | static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) |
2862 | { | 2903 | { |
2863 | struct ip_vs_service *svc = NULL; | 2904 | struct ip_vs_service *svc = NULL; |
2864 | struct ip_vs_service_user usvc; | 2905 | struct ip_vs_service_user_kern usvc; |
2865 | struct ip_vs_dest_user udest; | 2906 | struct ip_vs_dest_user_kern udest; |
2866 | int ret = 0, cmd; | 2907 | int ret = 0, cmd; |
2867 | int need_full_svc = 0, need_full_dest = 0; | 2908 | int need_full_svc = 0, need_full_dest = 0; |
2868 | 2909 | ||
@@ -2914,7 +2955,8 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) | |||
2914 | 2955 | ||
2915 | /* Lookup the exact service by <protocol, addr, port> or fwmark */ | 2956 | /* Lookup the exact service by <protocol, addr, port> or fwmark */ |
2916 | if (usvc.fwmark == 0) | 2957 | if (usvc.fwmark == 0) |
2917 | svc = __ip_vs_service_get(usvc.protocol, usvc.addr, usvc.port); | 2958 | svc = __ip_vs_service_get(usvc.protocol, usvc.addr.ip, |
2959 | usvc.port); | ||
2918 | else | 2960 | else |
2919 | svc = __ip_vs_svc_fwm_get(usvc.fwmark); | 2961 | svc = __ip_vs_svc_fwm_get(usvc.fwmark); |
2920 | 2962 | ||