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 <netipsec/ipsec.h>
 
 #include <stdlib.h>
+#include <stdint.h>
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
@@ -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 <string.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <stdint.h>
 #include <netdb.h>
 #include <ctype.h>
 #include <errno.h>
@@ -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 <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <arpa/inet.h>
 #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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to