aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c39
1 files changed, 36 insertions, 3 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2f7ddc3a59b4..51398ae6cda8 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -137,7 +137,8 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
137 if (!rt) 137 if (!rt)
138 return 0; 138 return 0;
139 139
140 if (p->id.proto != IPPROTO_ESP) 140 /* As only ESP and AH support ESN feature. */
141 if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH))
141 return -EINVAL; 142 return -EINVAL;
142 143
143 if (p->replay_window != 0) 144 if (p->replay_window != 0)
@@ -881,6 +882,7 @@ static int xfrm_dump_sa_done(struct netlink_callback *cb)
881 return 0; 882 return 0;
882} 883}
883 884
885static const struct nla_policy xfrma_policy[XFRMA_MAX+1];
884static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb) 886static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
885{ 887{
886 struct net *net = sock_net(skb->sk); 888 struct net *net = sock_net(skb->sk);
@@ -896,8 +898,31 @@ static int xfrm_dump_sa(struct sk_buff *skb, struct netlink_callback *cb)
896 info.nlmsg_flags = NLM_F_MULTI; 898 info.nlmsg_flags = NLM_F_MULTI;
897 899
898 if (!cb->args[0]) { 900 if (!cb->args[0]) {
901 struct nlattr *attrs[XFRMA_MAX+1];
902 struct xfrm_address_filter *filter = NULL;
903 u8 proto = 0;
904 int err;
905
899 cb->args[0] = 1; 906 cb->args[0] = 1;
900 xfrm_state_walk_init(walk, 0); 907
908 err = nlmsg_parse(cb->nlh, 0, attrs, XFRMA_MAX,
909 xfrma_policy);
910 if (err < 0)
911 return err;
912
913 if (attrs[XFRMA_ADDRESS_FILTER]) {
914 filter = kmalloc(sizeof(*filter), GFP_KERNEL);
915 if (filter == NULL)
916 return -ENOMEM;
917
918 memcpy(filter, nla_data(attrs[XFRMA_ADDRESS_FILTER]),
919 sizeof(*filter));
920 }
921
922 if (attrs[XFRMA_PROTO])
923 proto = nla_get_u8(attrs[XFRMA_PROTO]);
924
925 xfrm_state_walk_init(walk, proto, filter);
901 } 926 }
902 927
903 (void) xfrm_state_walk(net, walk, dump_one_state, &info); 928 (void) xfrm_state_walk(net, walk, dump_one_state, &info);
@@ -2303,6 +2328,8 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
2303 [XFRMA_TFCPAD] = { .type = NLA_U32 }, 2328 [XFRMA_TFCPAD] = { .type = NLA_U32 },
2304 [XFRMA_REPLAY_ESN_VAL] = { .len = sizeof(struct xfrm_replay_state_esn) }, 2329 [XFRMA_REPLAY_ESN_VAL] = { .len = sizeof(struct xfrm_replay_state_esn) },
2305 [XFRMA_SA_EXTRA_FLAGS] = { .type = NLA_U32 }, 2330 [XFRMA_SA_EXTRA_FLAGS] = { .type = NLA_U32 },
2331 [XFRMA_PROTO] = { .type = NLA_U8 },
2332 [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) },
2306}; 2333};
2307 2334
2308static const struct xfrm_link { 2335static const struct xfrm_link {
@@ -2350,7 +2377,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
2350 link = &xfrm_dispatch[type]; 2377 link = &xfrm_dispatch[type];
2351 2378
2352 /* All operations require privileges, even GET */ 2379 /* All operations require privileges, even GET */
2353 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 2380 if (!netlink_net_capable(skb, CAP_NET_ADMIN))
2354 return -EPERM; 2381 return -EPERM;
2355 2382
2356 if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || 2383 if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
@@ -2976,6 +3003,11 @@ static int xfrm_send_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
2976 return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_MAPPING, GFP_ATOMIC); 3003 return nlmsg_multicast(net->xfrm.nlsk, skb, 0, XFRMNLGRP_MAPPING, GFP_ATOMIC);
2977} 3004}
2978 3005
3006static bool xfrm_is_alive(const struct km_event *c)
3007{
3008 return (bool)xfrm_acquire_is_on(c->net);
3009}
3010
2979static struct xfrm_mgr netlink_mgr = { 3011static struct xfrm_mgr netlink_mgr = {
2980 .id = "netlink", 3012 .id = "netlink",
2981 .notify = xfrm_send_state_notify, 3013 .notify = xfrm_send_state_notify,
@@ -2985,6 +3017,7 @@ static struct xfrm_mgr netlink_mgr = {
2985 .report = xfrm_send_report, 3017 .report = xfrm_send_report,
2986 .migrate = xfrm_send_migrate, 3018 .migrate = xfrm_send_migrate,
2987 .new_mapping = xfrm_send_mapping, 3019 .new_mapping = xfrm_send_mapping,
3020 .is_alive = xfrm_is_alive,
2988}; 3021};
2989 3022
2990static int __net_init xfrm_user_net_init(struct net *net) 3023static int __net_init xfrm_user_net_init(struct net *net)