diff options
author | Jamal Hadi Salim <hadi@cyberus.ca> | 2006-03-20 22:16:40 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2006-03-20 22:16:40 -0500 |
commit | 980ebd25794f0f87ac32844e2c73e9e81f0a72ba (patch) | |
tree | da52df6e31bd4b2527c223ca2585e0d792bf3ea2 | |
parent | d51d081d65048a7a6f9956a7809c3bb504f3b95d (diff) |
[IPSEC]: Sync series - acquire insert
This introduces a feature similar to the one described in RFC 2367:
"
... the application needing an SA sends a PF_KEY
SADB_ACQUIRE message down to the Key Engine, which then either
returns an error or sends a similar SADB_ACQUIRE message up to one or
more key management applications capable of creating such SAs.
...
...
The third is where an application-layer consumer of security
associations (e.g. an OSPFv2 or RIPv2 daemon) needs a security
association.
Send an SADB_ACQUIRE message from a user process to the kernel.
<base, address(SD), (address(P),) (identity(SD),) (sensitivity,)
proposal>
The kernel returns an SADB_ACQUIRE message to registered
sockets.
<base, address(SD), (address(P),) (identity(SD),) (sensitivity,)
proposal>
The user-level consumer waits for an SADB_UPDATE or SADB_ADD
message for its particular type, and then can use that
association by using SADB_GET messages.
"
An app such as OSPF could then use ipsec KM to get keys
Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/xfrm.h | 2 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 5 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 54 |
3 files changed, 58 insertions, 3 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index bc005e62e434..30a940b147b0 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -214,10 +214,10 @@ extern int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo); | |||
214 | extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo); | 214 | extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo); |
215 | extern void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c); | 215 | extern void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c); |
216 | extern void km_state_notify(struct xfrm_state *x, struct km_event *c); | 216 | extern void km_state_notify(struct xfrm_state *x, struct km_event *c); |
217 | |||
218 | #define XFRM_ACQ_EXPIRES 30 | 217 | #define XFRM_ACQ_EXPIRES 30 |
219 | 218 | ||
220 | struct xfrm_tmpl; | 219 | struct xfrm_tmpl; |
220 | extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); | ||
221 | struct xfrm_state_afinfo { | 221 | struct xfrm_state_afinfo { |
222 | unsigned short family; | 222 | unsigned short family; |
223 | rwlock_t lock; | 223 | rwlock_t lock; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 8eaee499cad5..a613b5c7d409 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -57,7 +57,7 @@ static int __xfrm_state_delete(struct xfrm_state *x); | |||
57 | static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family); | 57 | static struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned short family); |
58 | static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); | 58 | static void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo); |
59 | 59 | ||
60 | static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); | 60 | int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); |
61 | static void km_state_expired(struct xfrm_state *x, int hard); | 61 | static void km_state_expired(struct xfrm_state *x, int hard); |
62 | 62 | ||
63 | static void xfrm_state_gc_destroy(struct xfrm_state *x) | 63 | static void xfrm_state_gc_destroy(struct xfrm_state *x) |
@@ -925,7 +925,7 @@ void km_state_expired(struct xfrm_state *x, int hard) | |||
925 | * We send to all registered managers regardless of failure | 925 | * We send to all registered managers regardless of failure |
926 | * We are happy with one success | 926 | * We are happy with one success |
927 | */ | 927 | */ |
928 | static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol) | 928 | int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol) |
929 | { | 929 | { |
930 | int err = -EINVAL, acqret; | 930 | int err = -EINVAL, acqret; |
931 | struct xfrm_mgr *km; | 931 | struct xfrm_mgr *km; |
@@ -939,6 +939,7 @@ static int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_polic | |||
939 | read_unlock(&xfrm_km_lock); | 939 | read_unlock(&xfrm_km_lock); |
940 | return err; | 940 | return err; |
941 | } | 941 | } |
942 | EXPORT_SYMBOL(km_query); | ||
942 | 943 | ||
943 | int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport) | 944 | int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport) |
944 | { | 945 | { |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index e230ba5328d3..d6e6527fd8d7 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1232,6 +1232,58 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x | |||
1232 | return 0; | 1232 | return 0; |
1233 | } | 1233 | } |
1234 | 1234 | ||
1235 | static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | ||
1236 | { | ||
1237 | struct xfrm_policy *xp; | ||
1238 | struct xfrm_user_tmpl *ut; | ||
1239 | int i; | ||
1240 | struct rtattr *rt = xfrma[XFRMA_TMPL-1]; | ||
1241 | |||
1242 | struct xfrm_user_acquire *ua = NLMSG_DATA(nlh); | ||
1243 | struct xfrm_state *x = xfrm_state_alloc(); | ||
1244 | int err = -ENOMEM; | ||
1245 | |||
1246 | if (!x) | ||
1247 | return err; | ||
1248 | |||
1249 | err = verify_newpolicy_info(&ua->policy); | ||
1250 | if (err) { | ||
1251 | printk("BAD policy passed\n"); | ||
1252 | kfree(x); | ||
1253 | return err; | ||
1254 | } | ||
1255 | |||
1256 | /* build an XP */ | ||
1257 | xp = xfrm_policy_construct(&ua->policy, (struct rtattr **) xfrma, &err); if (!xp) { | ||
1258 | kfree(x); | ||
1259 | return err; | ||
1260 | } | ||
1261 | |||
1262 | memcpy(&x->id, &ua->id, sizeof(ua->id)); | ||
1263 | memcpy(&x->props.saddr, &ua->saddr, sizeof(ua->saddr)); | ||
1264 | memcpy(&x->sel, &ua->sel, sizeof(ua->sel)); | ||
1265 | |||
1266 | ut = RTA_DATA(rt); | ||
1267 | /* extract the templates and for each call km_key */ | ||
1268 | for (i = 0; i < xp->xfrm_nr; i++, ut++) { | ||
1269 | struct xfrm_tmpl *t = &xp->xfrm_vec[i]; | ||
1270 | memcpy(&x->id, &t->id, sizeof(x->id)); | ||
1271 | x->props.mode = t->mode; | ||
1272 | x->props.reqid = t->reqid; | ||
1273 | x->props.family = ut->family; | ||
1274 | t->aalgos = ua->aalgos; | ||
1275 | t->ealgos = ua->ealgos; | ||
1276 | t->calgos = ua->calgos; | ||
1277 | err = km_query(x, t, xp); | ||
1278 | |||
1279 | } | ||
1280 | |||
1281 | kfree(x); | ||
1282 | kfree(xp); | ||
1283 | |||
1284 | return 0; | ||
1285 | } | ||
1286 | |||
1235 | 1287 | ||
1236 | #define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type)) | 1288 | #define XMSGSIZE(type) NLMSG_LENGTH(sizeof(struct type)) |
1237 | 1289 | ||
@@ -1243,6 +1295,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = { | |||
1243 | [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), | 1295 | [XFRM_MSG_DELPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), |
1244 | [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), | 1296 | [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_id), |
1245 | [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info), | 1297 | [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userspi_info), |
1298 | [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = XMSGSIZE(xfrm_user_acquire), | ||
1246 | [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), | 1299 | [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = XMSGSIZE(xfrm_userpolicy_info), |
1247 | [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), | 1300 | [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_info), |
1248 | [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), | 1301 | [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = XMSGSIZE(xfrm_usersa_flush), |
@@ -1266,6 +1319,7 @@ static struct xfrm_link { | |||
1266 | [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, | 1319 | [XFRM_MSG_GETPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_get_policy, |
1267 | .dump = xfrm_dump_policy }, | 1320 | .dump = xfrm_dump_policy }, |
1268 | [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, | 1321 | [XFRM_MSG_ALLOCSPI - XFRM_MSG_BASE] = { .doit = xfrm_alloc_userspi }, |
1322 | [XFRM_MSG_ACQUIRE - XFRM_MSG_BASE] = { .doit = xfrm_add_acquire }, | ||
1269 | [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, | 1323 | [XFRM_MSG_UPDPOLICY - XFRM_MSG_BASE] = { .doit = xfrm_add_policy }, |
1270 | [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, | 1324 | [XFRM_MSG_UPDSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, |
1271 | [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa }, | 1325 | [XFRM_MSG_FLUSHSA - XFRM_MSG_BASE] = { .doit = xfrm_flush_sa }, |