* Potentially decap ESP in UDP frame. Check for an ESP header. * If present, strip the UDP header and push the result through IPSec. * * Returns error if mbuf consumed and/or processed, otherwise 0. */
| 113 | * Returns error if mbuf consumed and/or processed, otherwise 0. |
| 114 | */ |
| 115 | int |
| 116 | udp_ipsec_input(struct mbuf *m, int off, int af) |
| 117 | { |
| 118 | union sockaddr_union dst; |
| 119 | struct secasvar *sav; |
| 120 | struct udphdr *udp; |
| 121 | struct ip *ip; |
| 122 | uint32_t spi; |
| 123 | int hlen; |
| 124 | |
| 125 | /* |
| 126 | * Just return if packet doesn't have enough data. |
| 127 | * We need at least [IP header + UDP header + ESP header]. |
| 128 | * NAT-Keepalive packet has only one byte of payload, so it |
| 129 | * by default will not be processed. |
| 130 | */ |
| 131 | if (m->m_pkthdr.len < off + sizeof(struct esp)) |
| 132 | return (0); |
| 133 | |
| 134 | m_copydata(m, off, sizeof(uint32_t), (caddr_t)&spi); |
| 135 | if (spi == 0) /* Non-ESP marker. */ |
| 136 | return (0); |
| 137 | |
| 138 | /* |
| 139 | * Find SA and check that it is configured for UDP |
| 140 | * encapsulation. |
| 141 | */ |
| 142 | bzero(&dst, sizeof(dst)); |
| 143 | dst.sa.sa_family = af; |
| 144 | switch (af) { |
| 145 | #ifdef INET |
| 146 | case AF_INET: |
| 147 | dst.sin.sin_len = sizeof(struct sockaddr_in); |
| 148 | ip = mtod(m, struct ip *); |
| 149 | ip->ip_p = IPPROTO_ESP; |
| 150 | off = offsetof(struct ip, ip_p); |
| 151 | hlen = ip->ip_hl << 2; |
| 152 | dst.sin.sin_addr = ip->ip_dst; |
| 153 | break; |
| 154 | #endif |
| 155 | #ifdef INET6 |
| 156 | case AF_INET6: |
| 157 | /* Not yet */ |
| 158 | /* FALLTHROUGH */ |
| 159 | #endif |
| 160 | default: |
| 161 | ESPSTAT_INC(esps_nopf); |
| 162 | m_freem(m); |
| 163 | return (EPFNOSUPPORT); |
| 164 | } |
| 165 | |
| 166 | sav = key_allocsa(&dst, IPPROTO_ESP, spi); |
| 167 | if (sav == NULL) { |
| 168 | ESPSTAT_INC(esps_notdb); |
| 169 | m_freem(m); |
| 170 | return (ENOENT); |
| 171 | } |
| 172 | udp = mtodo(m, hlen); |
nothing calls this directly
no test coverage detected