Module Name: src Committed By: martin Date: Tue Mar 13 15:29:45 UTC 2018
Modified Files: src/sys/net [netbsd-8]: if_ipsec.c src/sys/netipsec [netbsd-8]: ipsecif.c Log Message: Pull up following revision(s) (requested by knakahara in ticket #620): sys/netipsec/ipsecif.c: revision 1.4 sys/net/if_ipsec.c: revision 1.4 sys/net/if_ipsec.c: revision 1.5 sys/net/if_ipsec.c: revision 1.6 NAT-T src and dst port in ipsec_variant should be network byte order. Fix missing sadb_x_ipsecrequest informations for PF_KEY message. Functionalize duplicated code. No functional changes. Fix ipsec(4) I/F esp_frag support. To generate a diff of this commit: cvs rdiff -u -r1.3.2.2 -r1.3.2.3 src/sys/net/if_ipsec.c cvs rdiff -u -r1.1.2.3 -r1.1.2.4 src/sys/netipsec/ipsecif.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/if_ipsec.c diff -u src/sys/net/if_ipsec.c:1.3.2.2 src/sys/net/if_ipsec.c:1.3.2.3 --- src/sys/net/if_ipsec.c:1.3.2.2 Sun Feb 11 21:17:34 2018 +++ src/sys/net/if_ipsec.c Tue Mar 13 15:29:45 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: if_ipsec.c,v 1.3.2.2 2018/02/11 21:17:34 snj Exp $ */ +/* $NetBSD: if_ipsec.c,v 1.3.2.3 2018/03/13 15:29:45 martin Exp $ */ /* * Copyright (c) 2017 Internet Initiative Japan Inc. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.3.2.2 2018/02/11 21:17:34 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.3.2.3 2018/03/13 15:29:45 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -109,7 +109,8 @@ static inline size_t if_ipsec_set_sadb_s static inline size_t if_ipsec_set_sadb_dst(struct sadb_address *, struct sockaddr *, int); static inline size_t if_ipsec_set_sadb_x_policy(struct sadb_x_policy *, - struct sadb_x_ipsecrequest *, uint16_t, uint8_t, uint32_t, uint8_t); + struct sadb_x_ipsecrequest *, uint16_t, uint8_t, uint32_t, uint8_t, + struct sockaddr *, struct sockaddr *); static inline void if_ipsec_set_sadb_msg(struct sadb_msg *, uint16_t, uint8_t); static inline void if_ipsec_set_sadb_msg_add(struct sadb_msg *, uint16_t); static inline void if_ipsec_set_sadb_msg_del(struct sadb_msg *, uint16_t); @@ -892,7 +893,7 @@ if_ipsec_set_tunnel(struct ifnet *ifp, switch(nsrc->sa_family) { #ifdef INET case AF_INET: - nsport = ntohs(satosin(src)->sin_port); + nsport = satosin(src)->sin_port; /* * avoid confuse SP when NAT-T disabled, * e.g. @@ -900,15 +901,15 @@ if_ipsec_set_tunnel(struct ifnet *ifp, * confuse : 10.0.1.2[600] 10.0.1.1[600] 4(ipv4) */ satosin(nsrc)->sin_port = 0; - ndport = ntohs(satosin(dst)->sin_port); + ndport = satosin(dst)->sin_port; satosin(ndst)->sin_port = 0; break; #endif /* INET */ #ifdef INET6 case AF_INET6: - nsport = ntohs(satosin6(src)->sin6_port); + nsport = satosin6(src)->sin6_port; satosin6(nsrc)->sin6_port = 0; - ndport = ntohs(satosin6(dst)->sin6_port); + ndport = satosin6(dst)->sin6_port; satosin6(ndst)->sin6_port = 0; break; #endif /* INET6 */ @@ -1320,6 +1321,20 @@ if_ipsec_add_mbuf(struct mbuf *m0, void } static inline void +if_ipsec_add_mbuf_addr_port(struct mbuf *m0, struct sockaddr *addr, in_port_t port) +{ + + if (port == 0) { + if_ipsec_add_mbuf(m0, addr, addr->sa_len); + } else { + struct sockaddr addrport; + + if_ipsec_set_addr_port(&addrport, addr, port); + if_ipsec_add_mbuf(m0, &addrport, addrport.sa_len); + } +} + +static inline void if_ipsec_add_pad(struct mbuf *m0, size_t len) { struct mbuf *m; @@ -1388,7 +1403,7 @@ if_ipsec_set_sadb_dst(struct sadb_addres static inline size_t if_ipsec_set_sadb_x_policy(struct sadb_x_policy *xpl, struct sadb_x_ipsecrequest *xisr, uint16_t policy, uint8_t dir, uint32_t id, - uint8_t level) + uint8_t level, struct sockaddr *src, struct sockaddr *dst) { size_t size; @@ -1397,6 +1412,10 @@ if_ipsec_set_sadb_x_policy(struct sadb_x size = sizeof(*xpl); if (policy == IPSEC_POLICY_IPSEC) { size += PFKEY_ALIGN8(sizeof(*xisr)); + if (src != NULL) + size += PFKEY_ALIGN8(src->sa_len); + if (dst != NULL) + size += PFKEY_ALIGN8(dst->sa_len); } xpl->sadb_x_policy_len = PFKEY_UNIT64(size); xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY; @@ -1408,6 +1427,10 @@ if_ipsec_set_sadb_x_policy(struct sadb_x if (policy == IPSEC_POLICY_IPSEC) { xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(sizeof(*xisr)); + if (src != NULL) + xisr->sadb_x_ipsecrequest_len += PFKEY_ALIGN8(src->sa_len); + if (dst != NULL) + xisr->sadb_x_ipsecrequest_len += PFKEY_ALIGN8(dst->sa_len); xisr->sadb_x_ipsecrequest_proto = IPPROTO_ESP; xisr->sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT; xisr->sadb_x_ipsecrequest_level = level; @@ -1459,14 +1482,14 @@ if_ipsec_set_addr_port(struct sockaddr * #ifdef INET case AF_INET: { struct sockaddr_in *sin = satosin(addrport); - sin->sin_port = htons(port); + sin->sin_port = port; break; } #endif /* INET */ #ifdef INET6 case AF_INET6: { struct sockaddr_in6 *sin6 = satosin6(addrport); - sin6->sin6_port = htons(port); + sin6->sin6_port = port; break; } #endif /* INET6 */ @@ -1506,7 +1529,7 @@ if_ipsec_add_sp0(struct sockaddr *src, i ext_msg_len += PFKEY_UNIT64(size); size = if_ipsec_set_sadb_dst(&xdst, dst, proto); ext_msg_len += PFKEY_UNIT64(size); - size = if_ipsec_set_sadb_x_policy(&xpl, &xisr, policy, dir, 0, level); + size = if_ipsec_set_sadb_x_policy(&xpl, &xisr, policy, dir, 0, level, src, dst); ext_msg_len += PFKEY_UNIT64(size); if_ipsec_set_sadb_msg_add(&msg, ext_msg_len); @@ -1516,34 +1539,29 @@ if_ipsec_add_sp0(struct sockaddr *src, i m_copyback(m, 0, sizeof(msg), &msg); if_ipsec_add_mbuf(m, &xsrc, sizeof(xsrc)); - if (sport == 0) { - if_ipsec_add_mbuf(m, src, src->sa_len); - } else { - struct sockaddr addrport; - - if_ipsec_set_addr_port(&addrport, src, sport); - if_ipsec_add_mbuf(m, &addrport, addrport.sa_len); - } + if_ipsec_add_mbuf_addr_port(m, src, sport); padlen = PFKEY_UNUNIT64(xsrc.sadb_address_len) - (sizeof(xsrc) + PFKEY_ALIGN8(src->sa_len)); if_ipsec_add_pad(m, padlen); if_ipsec_add_mbuf(m, &xdst, sizeof(xdst)); - if (dport == 0) { - if_ipsec_add_mbuf(m, dst, dst->sa_len); - } else { - struct sockaddr addrport; - - if_ipsec_set_addr_port(&addrport, dst, dport); - if_ipsec_add_mbuf(m, &addrport, addrport.sa_len); - } + if_ipsec_add_mbuf_addr_port(m, dst, dport); padlen = PFKEY_UNUNIT64(xdst.sadb_address_len) - (sizeof(xdst) + PFKEY_ALIGN8(dst->sa_len)); if_ipsec_add_pad(m, padlen); if_ipsec_add_mbuf(m, &xpl, sizeof(xpl)); - if (policy == IPSEC_POLICY_IPSEC) + if (policy == IPSEC_POLICY_IPSEC) { if_ipsec_add_mbuf(m, &xisr, sizeof(xisr)); + if_ipsec_add_mbuf_addr_port(m, src, sport); + if_ipsec_add_mbuf_addr_port(m, dst, dport); + } + padlen = PFKEY_UNUNIT64(xpl.sadb_x_policy_len) - sizeof(xpl); + if (src != NULL) + padlen -= PFKEY_ALIGN8(src->sa_len); + if (dst != NULL) + padlen -= PFKEY_ALIGN8(dst->sa_len); + if_ipsec_add_pad(m, padlen); /* key_kpi_spdadd() has already done KEY_SP_REF(). */ return key_kpi_spdadd(m); @@ -1636,7 +1654,7 @@ if_ipsec_del_sp0(struct secpolicy *sp) MGETHDR(m, M_WAITOK, MT_DATA); - size = if_ipsec_set_sadb_x_policy(&xpl, NULL, 0, 0, sp->id, 0); + size = if_ipsec_set_sadb_x_policy(&xpl, NULL, 0, 0, sp->id, 0, NULL, NULL); ext_msg_len += PFKEY_UNIT64(size); if_ipsec_set_sadb_msg_del(&msg, ext_msg_len); Index: src/sys/netipsec/ipsecif.c diff -u src/sys/netipsec/ipsecif.c:1.1.2.3 src/sys/netipsec/ipsecif.c:1.1.2.4 --- src/sys/netipsec/ipsecif.c:1.1.2.3 Tue Mar 6 11:17:55 2018 +++ src/sys/netipsec/ipsecif.c Tue Mar 13 15:29:45 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ipsecif.c,v 1.1.2.3 2018/03/06 11:17:55 martin Exp $ */ +/* $NetBSD: ipsecif.c,v 1.1.2.4 2018/03/13 15:29:45 martin Exp $ */ /* * Copyright (c) 2017 Internet Initiative Japan Inc. @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.1.2.3 2018/03/06 11:17:55 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.1.2.4 2018/03/13 15:29:45 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -260,7 +260,13 @@ ipsecif4_fragout(struct ipsec_variant *v if (mtag) m_tag_delete(m, mtag); - error = ip_fragment(m, ifp, mtu); + /* consider new IP header prepended in ipsecif4_output() */ + if (mtu <= sizeof(struct ip)) { + m_freem(m); + return ENETUNREACH; + } + m->m_pkthdr.csum_flags |= M_CSUM_IPv4; + error = ip_fragment(m, ifp, mtu - sizeof(struct ip)); if (error) return error; @@ -397,7 +403,7 @@ ipsecif4_output(struct ipsec_variant *va * frangmentation is already done in ipsecif4_fragout(), * so ipsec4_process_packet() must not do fragmentation here. */ - KASSERT(error != 0 || sa_mtu == 0); + KASSERT(sa_mtu == 0); done: return error;