From owner-svn-src-stable-11@freebsd.org Thu Apr 27 12:17:00 2017 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 00193D50D40; Thu, 27 Apr 2017 12:16:59 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id CF584FE9; Thu, 27 Apr 2017 12:16:59 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v3RCGwgK047871; Thu, 27 Apr 2017 12:16:58 GMT (envelope-from ae@FreeBSD.org) Received: (from ae@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v3RCGwB9047867; Thu, 27 Apr 2017 12:16:58 GMT (envelope-from ae@FreeBSD.org) Message-Id: <201704271216.v3RCGwB9047867@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ae set sender to ae@FreeBSD.org using -f From: "Andrey V. Elsukov" Date: Thu, 27 Apr 2017 12:16:58 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r317502 - in stable/11: lib/libipsec sbin/setkey sys/netipsec X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 27 Apr 2017 12:17:00 -0000 Author: ae Date: Thu Apr 27 12:16:58 2017 New Revision: 317502 URL: https://svnweb.freebsd.org/changeset/base/317502 Log: MFC r316759: Add large replay widow support to setkey(8) and libipsec. When the replay window size is large than UINT8_MAX, add to the request the SADB_X_EXT_SA_REPLAY extension header that was added in r309144. Also add support of SADB_X_EXT_NAT_T_TYPE, SADB_X_EXT_NAT_T_SPORT, SADB_X_EXT_NAT_T_DPORT, SADB_X_EXT_NAT_T_OAI, SADB_X_EXT_NAT_T_OAR, SADB_X_EXT_SA_REPLAY, SADB_X_EXT_NEW_ADDRESS_SRC, SADB_X_EXT_NEW_ADDRESS_DST extension headers to the key_debug that is used by `setkey -x`. Modify kdebug_sockaddr() to use inet_ntop() for IP addresses formatting. And modify kdebug_sadb_x_policy() to show policy scope and priority. Reviewed by: gnn, Emeric Poupon Differential Revision: https://reviews.freebsd.org/D10375 Modified: stable/11/lib/libipsec/pfkey.c stable/11/sbin/setkey/Makefile stable/11/sbin/setkey/parse.y stable/11/sys/netipsec/key_debug.c Directory Properties: stable/11/ (props changed) Modified: stable/11/lib/libipsec/pfkey.c ============================================================================== --- stable/11/lib/libipsec/pfkey.c Thu Apr 27 12:15:15 2017 (r317501) +++ stable/11/lib/libipsec/pfkey.c Thu Apr 27 12:16:58 2017 (r317502) @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -69,6 +70,7 @@ static caddr_t pfkey_setsadbmsg(caddr_t, u_int, u_int32_t, pid_t); static caddr_t pfkey_setsadbsa(caddr_t, caddr_t, u_int32_t, u_int, u_int, u_int, u_int32_t); +static caddr_t pfkey_setsadbxreplay(caddr_t, caddr_t, uint32_t); static caddr_t pfkey_setsadbaddr(caddr_t, caddr_t, u_int, struct sockaddr *, u_int, u_int); static caddr_t pfkey_setsadbkey(caddr_t, caddr_t, u_int, caddr_t, u_int); @@ -1196,6 +1198,13 @@ pfkey_send_x1(so, type, satype, mode, sr + sizeof(struct sadb_lifetime) + sizeof(struct sadb_lifetime); + if (wsize > UINT8_MAX) { + if (wsize > (UINT32_MAX - 32) >> 3) { + __ipsec_errcode = EIPSEC_INVAL_ARGUMENT; + return (-1); + } + len += sizeof(struct sadb_x_sa_replay); + } if (e_type != SADB_EALG_NONE) len += (sizeof(struct sadb_key) + PFKEY_ALIGN8(e_keylen)); if (a_type != SADB_AALG_NONE) @@ -1223,6 +1232,13 @@ pfkey_send_x1(so, type, satype, mode, sr free(newmsg); return -1; } + if (wsize > UINT8_MAX) { + p = pfkey_setsadbxreplay(p, ep, wsize); + if (!p) { + free(newmsg); + return (-1); + } + } p = pfkey_setsadbaddr(p, ep, SADB_EXT_ADDRESS_SRC, src, plen, IPSEC_ULPROTO_ANY); if (!p) { @@ -1982,7 +1998,7 @@ pfkey_setsadbsa(buf, lim, spi, wsize, au p->sadb_sa_len = PFKEY_UNIT64(len); p->sadb_sa_exttype = SADB_EXT_SA; p->sadb_sa_spi = spi; - p->sadb_sa_replay = wsize; + p->sadb_sa_replay = wsize > UINT8_MAX ? UINT8_MAX: wsize; p->sadb_sa_state = SADB_SASTATE_LARVAL; p->sadb_sa_auth = auth; p->sadb_sa_encrypt = enc; @@ -1992,6 +2008,31 @@ pfkey_setsadbsa(buf, lim, spi, wsize, au } /* + * Set data into sadb_x_sa_replay. + * `buf' must has been allocated sufficiently. + */ +static caddr_t +pfkey_setsadbxreplay(caddr_t buf, caddr_t lim, uint32_t wsize) +{ + struct sadb_x_sa_replay *p; + u_int len; + + p = (struct sadb_x_sa_replay *)buf; + len = sizeof(struct sadb_x_sa_replay); + + if (buf + len > lim) + return (NULL); + + memset(p, 0, len); + p->sadb_x_sa_replay_len = PFKEY_UNIT64(len); + p->sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY; + /* Convert wsize from bytes to number of packets. */ + p->sadb_x_sa_replay_replay = wsize << 3; + + return (buf + len); +} + +/* * set data into sadb_address. * `buf' must has been allocated sufficiently. * prefixlen is in bits. Modified: stable/11/sbin/setkey/Makefile ============================================================================== --- stable/11/sbin/setkey/Makefile Thu Apr 27 12:15:15 2017 (r317501) +++ stable/11/sbin/setkey/Makefile Thu Apr 27 12:16:58 2017 (r317502) @@ -51,6 +51,9 @@ CFLAGS+= -I${.CURDIR}/../../lib/libipsec SRCS+= y.tab.h y.tab.h: parse.y CFLAGS+= -DIPSEC_DEBUG -DYY_NO_UNPUT +.if ${MK_INET_SUPPORT} != "no" +CFLAGS+= -DINET +.endif .if ${MK_INET6_SUPPORT} != "no" CFLAGS+= -DINET6 .endif Modified: stable/11/sbin/setkey/parse.y ============================================================================== --- stable/11/sbin/setkey/parse.y Thu Apr 27 12:15:15 2017 (r317501) +++ stable/11/sbin/setkey/parse.y Thu Apr 27 12:16:58 2017 (r317502) @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -513,6 +514,8 @@ extension return -1; } p_replay = $2; + if (p_replay > (UINT32_MAX - 32) >> 3) + yyerror("replay window is too large"); } | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } @@ -899,6 +902,7 @@ setkeymsg_addr(type, satype, srcs, dsts, int l, l0, len; struct sadb_sa m_sa; struct sadb_x_sa2 m_sa2; + struct sadb_x_sa_replay m_replay; struct sadb_address m_addr; struct addrinfo *s, *d; int n; @@ -920,7 +924,8 @@ setkeymsg_addr(type, satype, srcs, dsts, m_sa.sadb_sa_len = PFKEY_UNIT64(len); m_sa.sadb_sa_exttype = SADB_EXT_SA; m_sa.sadb_sa_spi = htonl(p_spi); - m_sa.sadb_sa_replay = p_replay; + m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX: + p_replay; m_sa.sadb_sa_state = 0; m_sa.sadb_sa_auth = p_alg_auth; m_sa.sadb_sa_encrypt = p_alg_enc; @@ -937,6 +942,17 @@ setkeymsg_addr(type, satype, srcs, dsts, memcpy(buf + l, &m_sa2, len); l += len; + + if (p_replay > UINT8_MAX) { + len = sizeof(struct sadb_x_sa_replay); + m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len); + m_replay.sadb_x_sa_replay_exttype = + SADB_X_EXT_SA_REPLAY; + m_replay.sadb_x_sa_replay_replay = p_replay << 3; + + memcpy(buf + l, &m_replay, len); + l += len; + } } l0 = l; @@ -1017,6 +1033,7 @@ setkeymsg_add(type, satype, srcs, dsts) struct sadb_sa m_sa; struct sadb_x_sa2 m_sa2; struct sadb_address m_addr; + struct sadb_x_sa_replay m_replay; struct addrinfo *s, *d; int n; int plen; @@ -1100,7 +1117,7 @@ setkeymsg_add(type, satype, srcs, dsts) m_sa.sadb_sa_len = PFKEY_UNIT64(len); m_sa.sadb_sa_exttype = SADB_EXT_SA; m_sa.sadb_sa_spi = htonl(p_spi); - m_sa.sadb_sa_replay = p_replay; + m_sa.sadb_sa_replay = p_replay > UINT8_MAX ? UINT8_MAX: p_replay; m_sa.sadb_sa_state = 0; m_sa.sadb_sa_auth = p_alg_auth; m_sa.sadb_sa_encrypt = p_alg_enc; @@ -1118,6 +1135,15 @@ setkeymsg_add(type, satype, srcs, dsts) memcpy(buf + l, &m_sa2, len); l += len; + if (p_replay > UINT8_MAX) { + len = sizeof(struct sadb_x_sa_replay); + m_replay.sadb_x_sa_replay_len = PFKEY_UNIT64(len); + m_replay.sadb_x_sa_replay_exttype = SADB_X_EXT_SA_REPLAY; + m_replay.sadb_x_sa_replay_replay = p_replay << 3; + + memcpy(buf + l, &m_replay, len); + l += len; + } l0 = l; n = 0; Modified: stable/11/sys/netipsec/key_debug.c ============================================================================== --- stable/11/sys/netipsec/key_debug.c Thu Apr 27 12:15:15 2017 (r317501) +++ stable/11/sys/netipsec/key_debug.c Thu Apr 27 12:16:58 2017 (r317502) @@ -63,6 +63,7 @@ #include #include #include +#include #endif /* !_KERNEL */ static void kdebug_sadb_prop(struct sadb_ext *); @@ -73,6 +74,8 @@ static void kdebug_sadb_sa(struct sadb_e static void kdebug_sadb_address(struct sadb_ext *); static void kdebug_sadb_key(struct sadb_ext *); static void kdebug_sadb_x_sa2(struct sadb_ext *); +static void kdebug_sadb_x_sa_replay(struct sadb_ext *); +static void kdebug_sadb_x_natt(struct sadb_ext *); #ifdef _KERNEL static void kdebug_secreplay(struct secreplay *); @@ -131,6 +134,10 @@ kdebug_sadb(struct sadb_msg *base) case SADB_EXT_ADDRESS_SRC: case SADB_EXT_ADDRESS_DST: case SADB_EXT_ADDRESS_PROXY: + case SADB_X_EXT_NAT_T_OAI: + case SADB_X_EXT_NAT_T_OAR: + case SADB_X_EXT_NEW_ADDRESS_SRC: + case SADB_X_EXT_NEW_ADDRESS_DST: kdebug_sadb_address(ext); break; case SADB_EXT_KEY_AUTH: @@ -159,6 +166,14 @@ kdebug_sadb(struct sadb_msg *base) case SADB_X_EXT_SA2: kdebug_sadb_x_sa2(ext); break; + case SADB_X_EXT_SA_REPLAY: + kdebug_sadb_x_sa_replay(ext); + break; + case SADB_X_EXT_NAT_T_TYPE: + case SADB_X_EXT_NAT_T_SPORT: + case SADB_X_EXT_NAT_T_DPORT: + kdebug_sadb_x_natt(ext); + break; default: printf("%s: invalid ext_type %u\n", __func__, ext->sadb_ext_type); @@ -342,8 +357,6 @@ kdebug_sadb_address(struct sadb_ext *ext ((u_char *)&addr->sadb_address_reserved)[1]); kdebug_sockaddr((struct sockaddr *)((caddr_t)ext + sizeof(*addr))); - - return; } static void @@ -392,6 +405,41 @@ kdebug_sadb_x_sa2(struct sadb_ext *ext) return; } +static void +kdebug_sadb_x_sa_replay(struct sadb_ext *ext) +{ + struct sadb_x_sa_replay *replay; + + /* sanity check */ + if (ext == NULL) + panic("%s: NULL pointer was passed.\n", __func__); + + replay = (struct sadb_x_sa_replay *)ext; + printf("sadb_x_sa_replay{ replay=%u }\n", + replay->sadb_x_sa_replay_replay); +} + +static void +kdebug_sadb_x_natt(struct sadb_ext *ext) +{ + struct sadb_x_nat_t_type *type; + struct sadb_x_nat_t_port *port; + + /* sanity check */ + if (ext == NULL) + panic("%s: NULL pointer was passed.\n", __func__); + + if (ext->sadb_ext_type == SADB_X_EXT_NAT_T_TYPE) { + type = (struct sadb_x_nat_t_type *)ext; + printf("sadb_x_nat_t_type{ type=%u }\n", + type->sadb_x_nat_t_type_type); + } else { + port = (struct sadb_x_nat_t_port *)ext; + printf("sadb_x_nat_t_port{ port=%u }\n", + ntohs(port->sadb_x_nat_t_port_port)); + } +} + void kdebug_sadb_x_policy(struct sadb_ext *ext) { @@ -402,9 +450,11 @@ kdebug_sadb_x_policy(struct sadb_ext *ex if (ext == NULL) panic("%s: NULL pointer was passed.\n", __func__); - printf("sadb_x_policy{ type=%u dir=%u id=%x }\n", + printf("sadb_x_policy{ type=%u dir=%u id=%x scope=%u %s=%u }\n", xpl->sadb_x_policy_type, xpl->sadb_x_policy_dir, - xpl->sadb_x_policy_id); + xpl->sadb_x_policy_id, xpl->sadb_x_policy_scope, + xpl->sadb_x_policy_scope == IPSEC_POLICYSCOPE_IFNET ? + "ifindex": "priority", xpl->sadb_x_policy_priority); if (xpl->sadb_x_policy_type == IPSEC_POLICY_IPSEC) { int tlen; @@ -850,39 +900,42 @@ ipsec_sa2str(struct secasvar *sav, char void kdebug_sockaddr(struct sockaddr *addr) { - struct sockaddr_in *sin4; -#ifdef INET6 - struct sockaddr_in6 *sin6; -#endif + char buf[IPSEC_ADDRSTRLEN]; /* sanity check */ if (addr == NULL) panic("%s: NULL pointer was passed.\n", __func__); - /* NOTE: We deal with port number as host byte order. */ - printf("sockaddr{ len=%u family=%u", addr->sa_len, addr->sa_family); - switch (addr->sa_family) { - case AF_INET: - sin4 = (struct sockaddr_in *)addr; - printf(" port=%u\n", ntohs(sin4->sin_port)); - ipsec_hexdump((caddr_t)&sin4->sin_addr, sizeof(sin4->sin_addr)); +#ifdef INET + case AF_INET: { + struct sockaddr_in *sin; + + sin = (struct sockaddr_in *)addr; + inet_ntop(AF_INET, &sin->sin_addr, buf, sizeof(buf)); break; + } +#endif #ifdef INET6 - case AF_INET6: + case AF_INET6: { + struct sockaddr_in6 *sin6; + sin6 = (struct sockaddr_in6 *)addr; - printf(" port=%u\n", ntohs(sin6->sin6_port)); - printf(" flowinfo=0x%08x, scope_id=0x%08x\n", - sin6->sin6_flowinfo, sin6->sin6_scope_id); - ipsec_hexdump((caddr_t)&sin6->sin6_addr, - sizeof(sin6->sin6_addr)); + if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + snprintf(buf, sizeof(buf), "%s%%%u", + inet_ntop(AF_INET6, &sin6->sin6_addr, buf, + sizeof(buf)), sin6->sin6_scope_id); + } else + inet_ntop(AF_INET6, &sin6->sin6_addr, buf, + sizeof(buf)); break; + } #endif + default: + sprintf(buf, "unknown"); } - - printf(" }\n"); - - return; + printf("sockaddr{ len=%u family=%u addr=%s }\n", addr->sa_len, + addr->sa_family, buf); } void