key: Share common code path to fill sockaddr{}.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
This commit is contained in:
parent
9e8b4ed8bb
commit
e5b56652c1
462
net/key/af_key.c
462
net/key/af_key.c
|
@ -691,6 +691,36 @@ static inline int pfkey_mode_to_xfrm(int mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned int pfkey_sockaddr_fill(xfrm_address_t *xaddr, __be16 port,
|
||||||
|
struct sockaddr *sa,
|
||||||
|
unsigned short family)
|
||||||
|
{
|
||||||
|
switch (family) {
|
||||||
|
case AF_INET:
|
||||||
|
{
|
||||||
|
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
|
||||||
|
sin->sin_family = AF_INET;
|
||||||
|
sin->sin_port = port;
|
||||||
|
sin->sin_addr.s_addr = xaddr->a4;
|
||||||
|
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
||||||
|
return 32;
|
||||||
|
}
|
||||||
|
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
||||||
|
case AF_INET6:
|
||||||
|
{
|
||||||
|
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sa;
|
||||||
|
sin6->sin6_family = AF_INET6;
|
||||||
|
sin6->sin6_port = port;
|
||||||
|
sin6->sin6_flowinfo = 0;
|
||||||
|
ipv6_addr_copy(&sin6->sin6_addr, (struct in6_addr *)xaddr->a6);
|
||||||
|
sin6->sin6_scope_id = 0;
|
||||||
|
return 128;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
|
static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
|
||||||
int add_keys, int hsc)
|
int add_keys, int hsc)
|
||||||
{
|
{
|
||||||
|
@ -701,13 +731,9 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
|
||||||
struct sadb_address *addr;
|
struct sadb_address *addr;
|
||||||
struct sadb_key *key;
|
struct sadb_key *key;
|
||||||
struct sadb_x_sa2 *sa2;
|
struct sadb_x_sa2 *sa2;
|
||||||
struct sockaddr_in *sin;
|
|
||||||
struct sadb_x_sec_ctx *sec_ctx;
|
struct sadb_x_sec_ctx *sec_ctx;
|
||||||
struct xfrm_sec_ctx *xfrm_ctx;
|
struct xfrm_sec_ctx *xfrm_ctx;
|
||||||
int ctx_size = 0;
|
int ctx_size = 0;
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
struct sockaddr_in6 *sin6;
|
|
||||||
#endif
|
|
||||||
int size;
|
int size;
|
||||||
int auth_key_size = 0;
|
int auth_key_size = 0;
|
||||||
int encrypt_key_size = 0;
|
int encrypt_key_size = 0;
|
||||||
|
@ -865,29 +891,12 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
|
||||||
protocol's number." - RFC2367 */
|
protocol's number." - RFC2367 */
|
||||||
addr->sadb_address_proto = 0;
|
addr->sadb_address_proto = 0;
|
||||||
addr->sadb_address_reserved = 0;
|
addr->sadb_address_reserved = 0;
|
||||||
if (x->props.family == AF_INET) {
|
|
||||||
addr->sadb_address_prefixlen = 32;
|
|
||||||
|
|
||||||
sin = (struct sockaddr_in *) (addr + 1);
|
addr->sadb_address_prefixlen =
|
||||||
sin->sin_family = AF_INET;
|
pfkey_sockaddr_fill(&x->props.saddr, 0,
|
||||||
sin->sin_addr.s_addr = x->props.saddr.a4;
|
(struct sockaddr *) (addr + 1),
|
||||||
sin->sin_port = 0;
|
x->props.family);
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
if (!addr->sadb_address_prefixlen)
|
||||||
}
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
else if (x->props.family == AF_INET6) {
|
|
||||||
addr->sadb_address_prefixlen = 128;
|
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *) (addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
memcpy(&sin6->sin6_addr, x->props.saddr.a6,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
/* dst address */
|
/* dst address */
|
||||||
|
@ -898,71 +907,33 @@ static struct sk_buff *__pfkey_xfrm_state2msg(struct xfrm_state *x,
|
||||||
sizeof(uint64_t);
|
sizeof(uint64_t);
|
||||||
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
|
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
|
||||||
addr->sadb_address_proto = 0;
|
addr->sadb_address_proto = 0;
|
||||||
addr->sadb_address_prefixlen = 32; /* XXX */
|
|
||||||
addr->sadb_address_reserved = 0;
|
addr->sadb_address_reserved = 0;
|
||||||
if (x->props.family == AF_INET) {
|
|
||||||
sin = (struct sockaddr_in *) (addr + 1);
|
|
||||||
sin->sin_family = AF_INET;
|
|
||||||
sin->sin_addr.s_addr = x->id.daddr.a4;
|
|
||||||
sin->sin_port = 0;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
|
|
||||||
if (x->sel.saddr.a4 != x->props.saddr.a4) {
|
addr->sadb_address_prefixlen =
|
||||||
addr = (struct sadb_address*) skb_put(skb,
|
pfkey_sockaddr_fill(&x->id.daddr, 0,
|
||||||
sizeof(struct sadb_address)+sockaddr_size);
|
(struct sockaddr *) (addr + 1),
|
||||||
addr->sadb_address_len =
|
x->props.family);
|
||||||
(sizeof(struct sadb_address)+sockaddr_size)/
|
if (!addr->sadb_address_prefixlen)
|
||||||
sizeof(uint64_t);
|
|
||||||
addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
|
|
||||||
addr->sadb_address_proto =
|
|
||||||
pfkey_proto_from_xfrm(x->sel.proto);
|
|
||||||
addr->sadb_address_prefixlen = x->sel.prefixlen_s;
|
|
||||||
addr->sadb_address_reserved = 0;
|
|
||||||
|
|
||||||
sin = (struct sockaddr_in *) (addr + 1);
|
|
||||||
sin->sin_family = AF_INET;
|
|
||||||
sin->sin_addr.s_addr = x->sel.saddr.a4;
|
|
||||||
sin->sin_port = x->sel.sport;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
else if (x->props.family == AF_INET6) {
|
|
||||||
addr->sadb_address_prefixlen = 128;
|
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *) (addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
memcpy(&sin6->sin6_addr, x->id.daddr.a6, sizeof(struct in6_addr));
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
|
|
||||||
if (memcmp (x->sel.saddr.a6, x->props.saddr.a6,
|
|
||||||
sizeof(struct in6_addr))) {
|
|
||||||
addr = (struct sadb_address *) skb_put(skb,
|
|
||||||
sizeof(struct sadb_address)+sockaddr_size);
|
|
||||||
addr->sadb_address_len =
|
|
||||||
(sizeof(struct sadb_address)+sockaddr_size)/
|
|
||||||
sizeof(uint64_t);
|
|
||||||
addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
|
|
||||||
addr->sadb_address_proto =
|
|
||||||
pfkey_proto_from_xfrm(x->sel.proto);
|
|
||||||
addr->sadb_address_prefixlen = x->sel.prefixlen_s;
|
|
||||||
addr->sadb_address_reserved = 0;
|
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *) (addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = x->sel.sport;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
memcpy(&sin6->sin6_addr, x->sel.saddr.a6,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
|
if (xfrm_addr_cmp(&x->sel.saddr, &x->props.saddr,
|
||||||
|
x->props.family)) {
|
||||||
|
addr = (struct sadb_address*) skb_put(skb,
|
||||||
|
sizeof(struct sadb_address)+sockaddr_size);
|
||||||
|
addr->sadb_address_len =
|
||||||
|
(sizeof(struct sadb_address)+sockaddr_size)/
|
||||||
|
sizeof(uint64_t);
|
||||||
|
addr->sadb_address_exttype = SADB_EXT_ADDRESS_PROXY;
|
||||||
|
addr->sadb_address_proto =
|
||||||
|
pfkey_proto_from_xfrm(x->sel.proto);
|
||||||
|
addr->sadb_address_prefixlen = x->sel.prefixlen_s;
|
||||||
|
addr->sadb_address_reserved = 0;
|
||||||
|
|
||||||
|
pfkey_sockaddr_fill(&x->sel.saddr, x->sel.sport,
|
||||||
|
(struct sockaddr *) (addr + 1),
|
||||||
|
x->props.family);
|
||||||
|
}
|
||||||
|
|
||||||
/* auth key */
|
/* auth key */
|
||||||
if (add_keys && auth_key_size) {
|
if (add_keys && auth_key_size) {
|
||||||
key = (struct sadb_key *) skb_put(skb,
|
key = (struct sadb_key *) skb_put(skb,
|
||||||
|
@ -1989,12 +1960,8 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
|
||||||
struct sadb_address *addr;
|
struct sadb_address *addr;
|
||||||
struct sadb_lifetime *lifetime;
|
struct sadb_lifetime *lifetime;
|
||||||
struct sadb_x_policy *pol;
|
struct sadb_x_policy *pol;
|
||||||
struct sockaddr_in *sin;
|
|
||||||
struct sadb_x_sec_ctx *sec_ctx;
|
struct sadb_x_sec_ctx *sec_ctx;
|
||||||
struct xfrm_sec_ctx *xfrm_ctx;
|
struct xfrm_sec_ctx *xfrm_ctx;
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
struct sockaddr_in6 *sin6;
|
|
||||||
#endif
|
|
||||||
int i;
|
int i;
|
||||||
int size;
|
int size;
|
||||||
int sockaddr_size = pfkey_sockaddr_size(xp->family);
|
int sockaddr_size = pfkey_sockaddr_size(xp->family);
|
||||||
|
@ -2016,26 +1983,10 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
|
||||||
addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
|
addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
|
||||||
addr->sadb_address_prefixlen = xp->selector.prefixlen_s;
|
addr->sadb_address_prefixlen = xp->selector.prefixlen_s;
|
||||||
addr->sadb_address_reserved = 0;
|
addr->sadb_address_reserved = 0;
|
||||||
/* src address */
|
if (!pfkey_sockaddr_fill(&xp->selector.saddr,
|
||||||
if (xp->family == AF_INET) {
|
xp->selector.sport,
|
||||||
sin = (struct sockaddr_in *) (addr + 1);
|
(struct sockaddr *) (addr + 1),
|
||||||
sin->sin_family = AF_INET;
|
xp->family))
|
||||||
sin->sin_addr.s_addr = xp->selector.saddr.a4;
|
|
||||||
sin->sin_port = xp->selector.sport;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
}
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
else if (xp->family == AF_INET6) {
|
|
||||||
sin6 = (struct sockaddr_in6 *) (addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = xp->selector.sport;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
memcpy(&sin6->sin6_addr, xp->selector.saddr.a6,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
/* dst address */
|
/* dst address */
|
||||||
|
@ -2048,26 +1999,10 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
|
||||||
addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
|
addr->sadb_address_proto = pfkey_proto_from_xfrm(xp->selector.proto);
|
||||||
addr->sadb_address_prefixlen = xp->selector.prefixlen_d;
|
addr->sadb_address_prefixlen = xp->selector.prefixlen_d;
|
||||||
addr->sadb_address_reserved = 0;
|
addr->sadb_address_reserved = 0;
|
||||||
if (xp->family == AF_INET) {
|
|
||||||
sin = (struct sockaddr_in *) (addr + 1);
|
pfkey_sockaddr_fill(&xp->selector.daddr, xp->selector.dport,
|
||||||
sin->sin_family = AF_INET;
|
(struct sockaddr *) (addr + 1),
|
||||||
sin->sin_addr.s_addr = xp->selector.daddr.a4;
|
xp->family);
|
||||||
sin->sin_port = xp->selector.dport;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
}
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
else if (xp->family == AF_INET6) {
|
|
||||||
sin6 = (struct sockaddr_in6 *) (addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = xp->selector.dport;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
memcpy(&sin6->sin6_addr, xp->selector.daddr.a6,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
|
|
||||||
/* hard time */
|
/* hard time */
|
||||||
lifetime = (struct sadb_lifetime *) skb_put(skb,
|
lifetime = (struct sadb_lifetime *) skb_put(skb,
|
||||||
|
@ -2121,10 +2056,13 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
|
||||||
int mode;
|
int mode;
|
||||||
|
|
||||||
req_size = sizeof(struct sadb_x_ipsecrequest);
|
req_size = sizeof(struct sadb_x_ipsecrequest);
|
||||||
if (t->mode == XFRM_MODE_TUNNEL)
|
if (t->mode == XFRM_MODE_TUNNEL) {
|
||||||
req_size += pfkey_sockaddr_len(t->encap_family) * 2;
|
socklen = pfkey_sockaddr_len(t->encap_family);
|
||||||
else
|
req_size += socklen * 2;
|
||||||
|
} else {
|
||||||
size -= 2*socklen;
|
size -= 2*socklen;
|
||||||
|
socklen = 0;
|
||||||
|
}
|
||||||
rq = (void*)skb_put(skb, req_size);
|
rq = (void*)skb_put(skb, req_size);
|
||||||
pol->sadb_x_policy_len += req_size/8;
|
pol->sadb_x_policy_len += req_size/8;
|
||||||
memset(rq, 0, sizeof(*rq));
|
memset(rq, 0, sizeof(*rq));
|
||||||
|
@ -2139,42 +2077,15 @@ static int pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, in
|
||||||
if (t->optional)
|
if (t->optional)
|
||||||
rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
|
rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
|
||||||
rq->sadb_x_ipsecrequest_reqid = t->reqid;
|
rq->sadb_x_ipsecrequest_reqid = t->reqid;
|
||||||
if (t->mode == XFRM_MODE_TUNNEL) {
|
|
||||||
switch (t->encap_family) {
|
|
||||||
case AF_INET:
|
|
||||||
sin = (void*)(rq+1);
|
|
||||||
sin->sin_family = AF_INET;
|
|
||||||
sin->sin_addr.s_addr = t->saddr.a4;
|
|
||||||
sin->sin_port = 0;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
sin++;
|
|
||||||
sin->sin_family = AF_INET;
|
|
||||||
sin->sin_addr.s_addr = t->id.daddr.a4;
|
|
||||||
sin->sin_port = 0;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
break;
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
case AF_INET6:
|
|
||||||
sin6 = (void*)(rq+1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
memcpy(&sin6->sin6_addr, t->saddr.a6,
|
|
||||||
sizeof(struct in6_addr));
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
|
|
||||||
sin6++;
|
if (t->mode == XFRM_MODE_TUNNEL) {
|
||||||
sin6->sin6_family = AF_INET6;
|
u8 *sa = (void *)(rq + 1);
|
||||||
sin6->sin6_port = 0;
|
pfkey_sockaddr_fill(&t->saddr, 0,
|
||||||
sin6->sin6_flowinfo = 0;
|
(struct sockaddr *)sa,
|
||||||
memcpy(&sin6->sin6_addr, t->id.daddr.a6,
|
t->encap_family);
|
||||||
sizeof(struct in6_addr));
|
pfkey_sockaddr_fill(&t->id.daddr, 0,
|
||||||
sin6->sin6_scope_id = 0;
|
(struct sockaddr *) (sa + socklen),
|
||||||
break;
|
t->encap_family);
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3079,10 +2990,6 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
|
||||||
struct sadb_msg *hdr;
|
struct sadb_msg *hdr;
|
||||||
struct sadb_address *addr;
|
struct sadb_address *addr;
|
||||||
struct sadb_x_policy *pol;
|
struct sadb_x_policy *pol;
|
||||||
struct sockaddr_in *sin;
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
struct sockaddr_in6 *sin6;
|
|
||||||
#endif
|
|
||||||
int sockaddr_size;
|
int sockaddr_size;
|
||||||
int size;
|
int size;
|
||||||
struct sadb_x_sec_ctx *sec_ctx;
|
struct sadb_x_sec_ctx *sec_ctx;
|
||||||
|
@ -3131,29 +3038,11 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
|
||||||
addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
|
addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
|
||||||
addr->sadb_address_proto = 0;
|
addr->sadb_address_proto = 0;
|
||||||
addr->sadb_address_reserved = 0;
|
addr->sadb_address_reserved = 0;
|
||||||
if (x->props.family == AF_INET) {
|
addr->sadb_address_prefixlen =
|
||||||
addr->sadb_address_prefixlen = 32;
|
pfkey_sockaddr_fill(&x->props.saddr, 0,
|
||||||
|
(struct sockaddr *) (addr + 1),
|
||||||
sin = (struct sockaddr_in *) (addr + 1);
|
x->props.family);
|
||||||
sin->sin_family = AF_INET;
|
if (!addr->sadb_address_prefixlen)
|
||||||
sin->sin_addr.s_addr = x->props.saddr.a4;
|
|
||||||
sin->sin_port = 0;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
}
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
else if (x->props.family == AF_INET6) {
|
|
||||||
addr->sadb_address_prefixlen = 128;
|
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *) (addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
memcpy(&sin6->sin6_addr,
|
|
||||||
x->props.saddr.a6, sizeof(struct in6_addr));
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
/* dst address */
|
/* dst address */
|
||||||
|
@ -3165,29 +3054,11 @@ static int pfkey_send_acquire(struct xfrm_state *x, struct xfrm_tmpl *t, struct
|
||||||
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
|
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
|
||||||
addr->sadb_address_proto = 0;
|
addr->sadb_address_proto = 0;
|
||||||
addr->sadb_address_reserved = 0;
|
addr->sadb_address_reserved = 0;
|
||||||
if (x->props.family == AF_INET) {
|
addr->sadb_address_prefixlen =
|
||||||
addr->sadb_address_prefixlen = 32;
|
pfkey_sockaddr_fill(&x->id.daddr, 0,
|
||||||
|
(struct sockaddr *) (addr + 1),
|
||||||
sin = (struct sockaddr_in *) (addr + 1);
|
x->props.family);
|
||||||
sin->sin_family = AF_INET;
|
if (!addr->sadb_address_prefixlen)
|
||||||
sin->sin_addr.s_addr = x->id.daddr.a4;
|
|
||||||
sin->sin_port = 0;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
}
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
else if (x->props.family == AF_INET6) {
|
|
||||||
addr->sadb_address_prefixlen = 128;
|
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *) (addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
memcpy(&sin6->sin6_addr,
|
|
||||||
x->id.daddr.a6, sizeof(struct in6_addr));
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy));
|
pol = (struct sadb_x_policy *) skb_put(skb, sizeof(struct sadb_x_policy));
|
||||||
|
@ -3313,10 +3184,6 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
|
||||||
struct sadb_sa *sa;
|
struct sadb_sa *sa;
|
||||||
struct sadb_address *addr;
|
struct sadb_address *addr;
|
||||||
struct sadb_x_nat_t_port *n_port;
|
struct sadb_x_nat_t_port *n_port;
|
||||||
struct sockaddr_in *sin;
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
struct sockaddr_in6 *sin6;
|
|
||||||
#endif
|
|
||||||
int sockaddr_size;
|
int sockaddr_size;
|
||||||
int size;
|
int size;
|
||||||
__u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0);
|
__u8 satype = (x->id.proto == IPPROTO_ESP ? SADB_SATYPE_ESP : 0);
|
||||||
|
@ -3380,29 +3247,11 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
|
||||||
addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
|
addr->sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
|
||||||
addr->sadb_address_proto = 0;
|
addr->sadb_address_proto = 0;
|
||||||
addr->sadb_address_reserved = 0;
|
addr->sadb_address_reserved = 0;
|
||||||
if (x->props.family == AF_INET) {
|
addr->sadb_address_prefixlen =
|
||||||
addr->sadb_address_prefixlen = 32;
|
pfkey_sockaddr_fill(&x->props.saddr, 0,
|
||||||
|
(struct sockaddr *) (addr + 1),
|
||||||
sin = (struct sockaddr_in *) (addr + 1);
|
x->props.family);
|
||||||
sin->sin_family = AF_INET;
|
if (!addr->sadb_address_prefixlen)
|
||||||
sin->sin_addr.s_addr = x->props.saddr.a4;
|
|
||||||
sin->sin_port = 0;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
}
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
else if (x->props.family == AF_INET6) {
|
|
||||||
addr->sadb_address_prefixlen = 128;
|
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *) (addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
memcpy(&sin6->sin6_addr,
|
|
||||||
x->props.saddr.a6, sizeof(struct in6_addr));
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
/* NAT_T_SPORT (old port) */
|
/* NAT_T_SPORT (old port) */
|
||||||
|
@ -3421,28 +3270,11 @@ static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr,
|
||||||
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
|
addr->sadb_address_exttype = SADB_EXT_ADDRESS_DST;
|
||||||
addr->sadb_address_proto = 0;
|
addr->sadb_address_proto = 0;
|
||||||
addr->sadb_address_reserved = 0;
|
addr->sadb_address_reserved = 0;
|
||||||
if (x->props.family == AF_INET) {
|
addr->sadb_address_prefixlen =
|
||||||
addr->sadb_address_prefixlen = 32;
|
pfkey_sockaddr_fill(ipaddr, 0,
|
||||||
|
(struct sockaddr *) (addr + 1),
|
||||||
sin = (struct sockaddr_in *) (addr + 1);
|
x->props.family);
|
||||||
sin->sin_family = AF_INET;
|
if (!addr->sadb_address_prefixlen)
|
||||||
sin->sin_addr.s_addr = ipaddr->a4;
|
|
||||||
sin->sin_port = 0;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
}
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
else if (x->props.family == AF_INET6) {
|
|
||||||
addr->sadb_address_prefixlen = 128;
|
|
||||||
|
|
||||||
sin6 = (struct sockaddr_in6 *) (addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
memcpy(&sin6->sin6_addr, &ipaddr->a6, sizeof(struct in6_addr));
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
BUG();
|
BUG();
|
||||||
|
|
||||||
/* NAT_T_DPORT (new port) */
|
/* NAT_T_DPORT (new port) */
|
||||||
|
@ -3460,10 +3292,6 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
|
||||||
struct xfrm_selector *sel)
|
struct xfrm_selector *sel)
|
||||||
{
|
{
|
||||||
struct sadb_address *addr;
|
struct sadb_address *addr;
|
||||||
struct sockaddr_in *sin;
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
struct sockaddr_in6 *sin6;
|
|
||||||
#endif
|
|
||||||
addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize);
|
addr = (struct sadb_address *)skb_put(skb, sizeof(struct sadb_address) + sasize);
|
||||||
addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8;
|
addr->sadb_address_len = (sizeof(struct sadb_address) + sasize)/8;
|
||||||
addr->sadb_address_exttype = type;
|
addr->sadb_address_exttype = type;
|
||||||
|
@ -3472,50 +3300,16 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SADB_EXT_ADDRESS_SRC:
|
case SADB_EXT_ADDRESS_SRC:
|
||||||
if (sel->family == AF_INET) {
|
addr->sadb_address_prefixlen = sel->prefixlen_s;
|
||||||
addr->sadb_address_prefixlen = sel->prefixlen_s;
|
pfkey_sockaddr_fill(&sel->saddr, 0,
|
||||||
sin = (struct sockaddr_in *)(addr + 1);
|
(struct sockaddr *)(addr + 1),
|
||||||
sin->sin_family = AF_INET;
|
sel->family);
|
||||||
memcpy(&sin->sin_addr.s_addr, &sel->saddr,
|
|
||||||
sizeof(sin->sin_addr.s_addr));
|
|
||||||
sin->sin_port = 0;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
}
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
else if (sel->family == AF_INET6) {
|
|
||||||
addr->sadb_address_prefixlen = sel->prefixlen_s;
|
|
||||||
sin6 = (struct sockaddr_in6 *)(addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
memcpy(&sin6->sin6_addr.s6_addr, &sel->saddr,
|
|
||||||
sizeof(sin6->sin6_addr.s6_addr));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case SADB_EXT_ADDRESS_DST:
|
case SADB_EXT_ADDRESS_DST:
|
||||||
if (sel->family == AF_INET) {
|
addr->sadb_address_prefixlen = sel->prefixlen_d;
|
||||||
addr->sadb_address_prefixlen = sel->prefixlen_d;
|
pfkey_sockaddr_fill(&sel->daddr, 0,
|
||||||
sin = (struct sockaddr_in *)(addr + 1);
|
(struct sockaddr *)(addr + 1),
|
||||||
sin->sin_family = AF_INET;
|
sel->family);
|
||||||
memcpy(&sin->sin_addr.s_addr, &sel->daddr,
|
|
||||||
sizeof(sin->sin_addr.s_addr));
|
|
||||||
sin->sin_port = 0;
|
|
||||||
memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
|
|
||||||
}
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
else if (sel->family == AF_INET6) {
|
|
||||||
addr->sadb_address_prefixlen = sel->prefixlen_d;
|
|
||||||
sin6 = (struct sockaddr_in6 *)(addr + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
memcpy(&sin6->sin6_addr.s6_addr, &sel->daddr,
|
|
||||||
sizeof(sin6->sin6_addr.s6_addr));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -3530,10 +3324,8 @@ static int set_ipsecrequest(struct sk_buff *skb,
|
||||||
xfrm_address_t *src, xfrm_address_t *dst)
|
xfrm_address_t *src, xfrm_address_t *dst)
|
||||||
{
|
{
|
||||||
struct sadb_x_ipsecrequest *rq;
|
struct sadb_x_ipsecrequest *rq;
|
||||||
struct sockaddr_in *sin;
|
u8 *sa;
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
int socklen = pfkey_sockaddr_len(family);
|
||||||
struct sockaddr_in6 *sin6;
|
|
||||||
#endif
|
|
||||||
int size_req;
|
int size_req;
|
||||||
|
|
||||||
size_req = sizeof(struct sadb_x_ipsecrequest) +
|
size_req = sizeof(struct sadb_x_ipsecrequest) +
|
||||||
|
@ -3547,38 +3339,10 @@ static int set_ipsecrequest(struct sk_buff *skb,
|
||||||
rq->sadb_x_ipsecrequest_level = level;
|
rq->sadb_x_ipsecrequest_level = level;
|
||||||
rq->sadb_x_ipsecrequest_reqid = reqid;
|
rq->sadb_x_ipsecrequest_reqid = reqid;
|
||||||
|
|
||||||
switch (family) {
|
sa = (u8 *) (rq + 1);
|
||||||
case AF_INET:
|
if (!pfkey_sockaddr_fill(src, 0, (struct sockaddr *)sa, family) ||
|
||||||
sin = (struct sockaddr_in *)(rq + 1);
|
!pfkey_sockaddr_fill(dst, 0, (struct sockaddr *)(sa + socklen), family))
|
||||||
sin->sin_family = AF_INET;
|
|
||||||
memcpy(&sin->sin_addr.s_addr, src,
|
|
||||||
sizeof(sin->sin_addr.s_addr));
|
|
||||||
sin++;
|
|
||||||
sin->sin_family = AF_INET;
|
|
||||||
memcpy(&sin->sin_addr.s_addr, dst,
|
|
||||||
sizeof(sin->sin_addr.s_addr));
|
|
||||||
break;
|
|
||||||
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
|
|
||||||
case AF_INET6:
|
|
||||||
sin6 = (struct sockaddr_in6 *)(rq + 1);
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
memcpy(&sin6->sin6_addr.s6_addr, src,
|
|
||||||
sizeof(sin6->sin6_addr.s6_addr));
|
|
||||||
sin6++;
|
|
||||||
sin6->sin6_family = AF_INET6;
|
|
||||||
sin6->sin6_port = 0;
|
|
||||||
sin6->sin6_flowinfo = 0;
|
|
||||||
sin6->sin6_scope_id = 0;
|
|
||||||
memcpy(&sin6->sin6_addr.s6_addr, dst,
|
|
||||||
sizeof(sin6->sin6_addr.s6_addr));
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue