aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
authorMasahide NAKAMURA <nakam@linux-ipv6.org>2006-08-24 01:49:28 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 18:08:35 -0400
commitf7b6983f0feeefcd2a594138adcffe640593d8de (patch)
tree41878fad9f0f0306718fa832eac7dfa76f51222d /net/xfrm/xfrm_user.c
parent41a49cc3c02ace59d4dddae91ea211c330970ee3 (diff)
[XFRM] POLICY: Support netlink socket interface for sub policy.
Sub policy can be used through netlink socket. PF_KEY uses main only and it is TODO to support sub. Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c134
1 files changed, 121 insertions, 13 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 7303b820bea4..c59a78d2923a 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -786,6 +786,22 @@ static int verify_policy_dir(__u8 dir)
786 return 0; 786 return 0;
787} 787}
788 788
789static int verify_policy_type(__u8 type)
790{
791 switch (type) {
792 case XFRM_POLICY_TYPE_MAIN:
793#ifdef CONFIG_XFRM_SUB_POLICY
794 case XFRM_POLICY_TYPE_SUB:
795#endif
796 break;
797
798 default:
799 return -EINVAL;
800 };
801
802 return 0;
803}
804
789static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) 805static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
790{ 806{
791 switch (p->share) { 807 switch (p->share) {
@@ -879,6 +895,29 @@ static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma)
879 return 0; 895 return 0;
880} 896}
881 897
898static int copy_from_user_policy_type(u8 *tp, struct rtattr **xfrma)
899{
900 struct rtattr *rt = xfrma[XFRMA_POLICY_TYPE-1];
901 struct xfrm_userpolicy_type *upt;
902 __u8 type = XFRM_POLICY_TYPE_MAIN;
903 int err;
904
905 if (rt) {
906 if (rt->rta_len < sizeof(*upt))
907 return -EINVAL;
908
909 upt = RTA_DATA(rt);
910 type = upt->type;
911 }
912
913 err = verify_policy_type(type);
914 if (err)
915 return err;
916
917 *tp = type;
918 return 0;
919}
920
882static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p) 921static void copy_from_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_info *p)
883{ 922{
884 xp->priority = p->priority; 923 xp->priority = p->priority;
@@ -917,16 +956,20 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
917 956
918 copy_from_user_policy(xp, p); 957 copy_from_user_policy(xp, p);
919 958
959 err = copy_from_user_policy_type(&xp->type, xfrma);
960 if (err)
961 goto error;
962
920 if (!(err = copy_from_user_tmpl(xp, xfrma))) 963 if (!(err = copy_from_user_tmpl(xp, xfrma)))
921 err = copy_from_user_sec_ctx(xp, xfrma); 964 err = copy_from_user_sec_ctx(xp, xfrma);
922 965 if (err)
923 if (err) { 966 goto error;
924 *errp = err;
925 kfree(xp);
926 xp = NULL;
927 }
928 967
929 return xp; 968 return xp;
969 error:
970 *errp = err;
971 kfree(xp);
972 return NULL;
930} 973}
931 974
932static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 975static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
@@ -1037,6 +1080,29 @@ static inline int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *s
1037 return 0; 1080 return 0;
1038} 1081}
1039 1082
1083#ifdef CONFIG_XFRM_SUB_POLICY
1084static int copy_to_user_policy_type(struct xfrm_policy *xp, struct sk_buff *skb)
1085{
1086 struct xfrm_userpolicy_type upt;
1087
1088 memset(&upt, 0, sizeof(upt));
1089 upt.type = xp->type;
1090
1091 RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
1092
1093 return 0;
1094
1095rtattr_failure:
1096 return -1;
1097}
1098
1099#else
1100static inline int copy_to_user_policy_type(struct xfrm_policy *xp, struct sk_buff *skb)
1101{
1102 return 0;
1103}
1104#endif
1105
1040static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr) 1106static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr)
1041{ 1107{
1042 struct xfrm_dump_info *sp = ptr; 1108 struct xfrm_dump_info *sp = ptr;
@@ -1060,6 +1126,8 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
1060 goto nlmsg_failure; 1126 goto nlmsg_failure;
1061 if (copy_to_user_sec_ctx(xp, skb)) 1127 if (copy_to_user_sec_ctx(xp, skb))
1062 goto nlmsg_failure; 1128 goto nlmsg_failure;
1129 if (copy_to_user_policy_type(xp, skb) < 0)
1130 goto nlmsg_failure;
1063 1131
1064 nlh->nlmsg_len = skb->tail - b; 1132 nlh->nlmsg_len = skb->tail - b;
1065out: 1133out:
@@ -1081,7 +1149,10 @@ static int xfrm_dump_policy(struct sk_buff *skb, struct netlink_callback *cb)
1081 info.nlmsg_flags = NLM_F_MULTI; 1149 info.nlmsg_flags = NLM_F_MULTI;
1082 info.this_idx = 0; 1150 info.this_idx = 0;
1083 info.start_idx = cb->args[0]; 1151 info.start_idx = cb->args[0];
1084 (void) xfrm_policy_walk(dump_one_policy, &info); 1152 (void) xfrm_policy_walk(XFRM_POLICY_TYPE_MAIN, dump_one_policy, &info);
1153#ifdef CONFIG_XFRM_SUB_POLICY
1154 (void) xfrm_policy_walk(XFRM_POLICY_TYPE_SUB, dump_one_policy, &info);
1155#endif
1085 cb->args[0] = info.this_idx; 1156 cb->args[0] = info.this_idx;
1086 1157
1087 return skb->len; 1158 return skb->len;
@@ -1117,6 +1188,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
1117{ 1188{
1118 struct xfrm_policy *xp; 1189 struct xfrm_policy *xp;
1119 struct xfrm_userpolicy_id *p; 1190 struct xfrm_userpolicy_id *p;
1191 __u8 type = XFRM_POLICY_TYPE_MAIN;
1120 int err; 1192 int err;
1121 struct km_event c; 1193 struct km_event c;
1122 int delete; 1194 int delete;
@@ -1124,12 +1196,16 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
1124 p = NLMSG_DATA(nlh); 1196 p = NLMSG_DATA(nlh);
1125 delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY; 1197 delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
1126 1198
1199 err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
1200 if (err)
1201 return err;
1202
1127 err = verify_policy_dir(p->dir); 1203 err = verify_policy_dir(p->dir);
1128 if (err) 1204 if (err)
1129 return err; 1205 return err;
1130 1206
1131 if (p->index) 1207 if (p->index)
1132 xp = xfrm_policy_byid(p->dir, p->index, delete); 1208 xp = xfrm_policy_byid(type, p->dir, p->index, delete);
1133 else { 1209 else {
1134 struct rtattr **rtattrs = (struct rtattr **)xfrma; 1210 struct rtattr **rtattrs = (struct rtattr **)xfrma;
1135 struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1]; 1211 struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
@@ -1146,7 +1222,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
1146 if ((err = security_xfrm_policy_alloc(&tmp, uctx))) 1222 if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
1147 return err; 1223 return err;
1148 } 1224 }
1149 xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, delete); 1225 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete);
1150 security_xfrm_policy_free(&tmp); 1226 security_xfrm_policy_free(&tmp);
1151 } 1227 }
1152 if (xp == NULL) 1228 if (xp == NULL)
@@ -1329,9 +1405,16 @@ out:
1329 1405
1330static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1406static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
1331{ 1407{
1332struct km_event c; 1408 struct km_event c;
1409 __u8 type = XFRM_POLICY_TYPE_MAIN;
1410 int err;
1411
1412 err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
1413 if (err)
1414 return err;
1333 1415
1334 xfrm_policy_flush(); 1416 xfrm_policy_flush(type);
1417 c.data.type = type;
1335 c.event = nlh->nlmsg_type; 1418 c.event = nlh->nlmsg_type;
1336 c.seq = nlh->nlmsg_seq; 1419 c.seq = nlh->nlmsg_seq;
1337 c.pid = nlh->nlmsg_pid; 1420 c.pid = nlh->nlmsg_pid;
@@ -1344,10 +1427,15 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void *
1344 struct xfrm_policy *xp; 1427 struct xfrm_policy *xp;
1345 struct xfrm_user_polexpire *up = NLMSG_DATA(nlh); 1428 struct xfrm_user_polexpire *up = NLMSG_DATA(nlh);
1346 struct xfrm_userpolicy_info *p = &up->pol; 1429 struct xfrm_userpolicy_info *p = &up->pol;
1430 __u8 type = XFRM_POLICY_TYPE_MAIN;
1347 int err = -ENOENT; 1431 int err = -ENOENT;
1348 1432
1433 err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
1434 if (err)
1435 return err;
1436
1349 if (p->index) 1437 if (p->index)
1350 xp = xfrm_policy_byid(p->dir, p->index, 0); 1438 xp = xfrm_policy_byid(type, p->dir, p->index, 0);
1351 else { 1439 else {
1352 struct rtattr **rtattrs = (struct rtattr **)xfrma; 1440 struct rtattr **rtattrs = (struct rtattr **)xfrma;
1353 struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1]; 1441 struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
@@ -1364,7 +1452,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void *
1364 if ((err = security_xfrm_policy_alloc(&tmp, uctx))) 1452 if ((err = security_xfrm_policy_alloc(&tmp, uctx)))
1365 return err; 1453 return err;
1366 } 1454 }
1367 xp = xfrm_policy_bysel_ctx(p->dir, &p->sel, tmp.security, 0); 1455 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, 0);
1368 security_xfrm_policy_free(&tmp); 1456 security_xfrm_policy_free(&tmp);
1369 } 1457 }
1370 1458
@@ -1818,6 +1906,8 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
1818 goto nlmsg_failure; 1906 goto nlmsg_failure;
1819 if (copy_to_user_state_sec_ctx(x, skb)) 1907 if (copy_to_user_state_sec_ctx(x, skb))
1820 goto nlmsg_failure; 1908 goto nlmsg_failure;
1909 if (copy_to_user_policy_type(xp, skb) < 0)
1910 goto nlmsg_failure;
1821 1911
1822 nlh->nlmsg_len = skb->tail - b; 1912 nlh->nlmsg_len = skb->tail - b;
1823 return skb->len; 1913 return skb->len;
@@ -1898,6 +1988,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
1898 } 1988 }
1899 1989
1900 copy_from_user_policy(xp, p); 1990 copy_from_user_policy(xp, p);
1991 xp->type = XFRM_POLICY_TYPE_MAIN;
1901 copy_templates(xp, ut, nr); 1992 copy_templates(xp, ut, nr);
1902 1993
1903 if (!xp->security) { 1994 if (!xp->security) {
@@ -1931,6 +2022,8 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
1931 goto nlmsg_failure; 2022 goto nlmsg_failure;
1932 if (copy_to_user_sec_ctx(xp, skb)) 2023 if (copy_to_user_sec_ctx(xp, skb))
1933 goto nlmsg_failure; 2024 goto nlmsg_failure;
2025 if (copy_to_user_policy_type(xp, skb) < 0)
2026 goto nlmsg_failure;
1934 upe->hard = !!hard; 2027 upe->hard = !!hard;
1935 2028
1936 nlh->nlmsg_len = skb->tail - b; 2029 nlh->nlmsg_len = skb->tail - b;
@@ -2002,6 +2095,8 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
2002 copy_to_user_policy(xp, p, dir); 2095 copy_to_user_policy(xp, p, dir);
2003 if (copy_to_user_tmpl(xp, skb) < 0) 2096 if (copy_to_user_tmpl(xp, skb) < 0)
2004 goto nlmsg_failure; 2097 goto nlmsg_failure;
2098 if (copy_to_user_policy_type(xp, skb) < 0)
2099 goto nlmsg_failure;
2005 2100
2006 nlh->nlmsg_len = skb->tail - b; 2101 nlh->nlmsg_len = skb->tail - b;
2007 2102
@@ -2019,6 +2114,9 @@ static int xfrm_notify_policy_flush(struct km_event *c)
2019 struct nlmsghdr *nlh; 2114 struct nlmsghdr *nlh;
2020 struct sk_buff *skb; 2115 struct sk_buff *skb;
2021 unsigned char *b; 2116 unsigned char *b;
2117#ifdef CONFIG_XFRM_SUB_POLICY
2118 struct xfrm_userpolicy_type upt;
2119#endif
2022 int len = NLMSG_LENGTH(0); 2120 int len = NLMSG_LENGTH(0);
2023 2121
2024 skb = alloc_skb(len, GFP_ATOMIC); 2122 skb = alloc_skb(len, GFP_ATOMIC);
@@ -2028,6 +2126,13 @@ static int xfrm_notify_policy_flush(struct km_event *c)
2028 2126
2029 2127
2030 nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0); 2128 nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0);
2129 nlh->nlmsg_flags = 0;
2130
2131#ifdef CONFIG_XFRM_SUB_POLICY
2132 memset(&upt, 0, sizeof(upt));
2133 upt.type = c->data.type;
2134 RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
2135#endif
2031 2136
2032 nlh->nlmsg_len = skb->tail - b; 2137 nlh->nlmsg_len = skb->tail - b;
2033 2138
@@ -2035,6 +2140,9 @@ static int xfrm_notify_policy_flush(struct km_event *c)
2035 return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); 2140 return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
2036 2141
2037nlmsg_failure: 2142nlmsg_failure:
2143#ifdef CONFIG_XFRM_SUB_POLICY
2144rtattr_failure:
2145#endif
2038 kfree_skb(skb); 2146 kfree_skb(skb);
2039 return -1; 2147 return -1;
2040} 2148}