Print this page
fixup .text where possible
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/mac/plugins/mac_ipv6.c
+++ new/usr/src/uts/common/io/mac/plugins/mac_ipv6.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * DL_IPV6 MAC Type plugin for the Nemo mac module
28 28 */
29 29
30 30 #include <sys/types.h>
31 31 #include <sys/modctl.h>
32 32 #include <sys/dlpi.h>
33 33 #include <sys/mac.h>
34 34 #include <sys/mac_ipv6.h>
35 35 #include <sys/mac_ipv4_impl.h>
36 36 #include <sys/byteorder.h>
37 37 #include <sys/strsun.h>
38 38 #include <netinet/ip6.h>
39 39 #include <inet/common.h>
40 40 #include <inet/mib2.h>
41 41 #include <inet/ip.h>
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
42 42 #include <inet/ip6.h>
43 43 #include <inet/iptun.h>
44 44
45 45 static struct modlmisc mac_ipv6_modlmisc = {
46 46 &mod_miscops,
47 47 "IPv6 tunneling MAC plugin"
48 48 };
49 49
50 50 static struct modlinkage mac_ipv6_modlinkage = {
51 51 MODREV_1,
52 - &mac_ipv6_modlmisc,
53 - NULL
52 + { &mac_ipv6_modlmisc,
53 + NULL }
54 54 };
55 55
56 56 static mactype_ops_t mac_ipv6_type_ops;
57 57
58 58 int
59 59 _init(void)
60 60 {
61 61 mactype_register_t *mtrp;
62 62 int err;
63 63
64 64 if ((mtrp = mactype_alloc(MACTYPE_VERSION)) == NULL)
65 65 return (EINVAL);
66 66 mtrp->mtr_ident = MAC_PLUGIN_IDENT_IPV6;
67 67 mtrp->mtr_ops = &mac_ipv6_type_ops;
68 68 mtrp->mtr_mactype = DL_IPV6;
69 69 mtrp->mtr_nativetype = DL_IPV6;
70 70 mtrp->mtr_addrlen = sizeof (in6_addr_t);
71 71 if ((err = mactype_register(mtrp)) == 0) {
72 72 if ((err = mod_install(&mac_ipv6_modlinkage)) != 0)
73 73 (void) mactype_unregister(MAC_PLUGIN_IDENT_IPV6);
74 74 }
75 75 mactype_free(mtrp);
76 76 return (err);
77 77 }
78 78
79 79 int
80 80 _fini(void)
81 81 {
82 82 int err;
83 83 if ((err = mactype_unregister(MAC_PLUGIN_IDENT_IPV6)) != 0)
84 84 return (err);
85 85 return (mod_remove(&mac_ipv6_modlinkage));
86 86 }
87 87
88 88 int
89 89 _info(struct modinfo *modinfop)
90 90 {
91 91 return (mod_info(&mac_ipv6_modlinkage, modinfop));
92 92 }
93 93
94 94
95 95 /*
96 96 * MAC Type plugin operations
97 97 */
98 98
99 99 /* ARGSUSED */
100 100 int
101 101 mac_ipv6_unicst_verify(const void *addr, void *pdata)
102 102 {
103 103 const in6_addr_t *in6addr = addr;
104 104 if (IN6_IS_ADDR_UNSPECIFIED(in6addr) ||
105 105 IN6_IS_ADDR_LOOPBACK(in6addr) ||
106 106 IN6_IS_ADDR_MULTICAST(in6addr) ||
107 107 IN6_IS_ADDR_V4MAPPED(in6addr) ||
108 108 IN6_IS_ADDR_V4COMPAT(in6addr)) {
109 109 return (EINVAL);
110 110 }
111 111 return (0);
112 112 }
113 113
114 114 /*
115 115 * Build an IPv6 link-layer header for tunneling. If provided, the
116 116 * template header provided by the driver supplies the traffic class, flow
117 117 * label, hop limit, and potential options. The template's payload length
118 118 * must either be 0 if there are no extension headers, or reflect the size
119 119 * of the extension headers if present. The template's next header value
120 120 * must either be IPPROTO_NONE if no extension headers are present, or
121 121 * reflect the type of extension header that follows (the same is true for
122 122 * the field values of the extension headers themselves.)
123 123 */
124 124 /* ARGSUSED */
125 125 mblk_t *
126 126 mac_ipv6_header(const void *saddr, const void *daddr, uint32_t sap, void *pdata,
127 127 mblk_t *payload, size_t extra_len)
128 128 {
129 129 ip6_t *ip6hp;
130 130 ip6_t *tmpl_ip6hp = pdata;
131 131 mblk_t *mp;
132 132 size_t hdr_len = sizeof (ip6_t);
133 133 uint8_t *nxt_proto;
134 134
135 135 if (!mac_ipv4_sap_verify(sap, NULL, NULL))
136 136 return (NULL);
137 137
138 138 if (tmpl_ip6hp != NULL)
139 139 hdr_len = sizeof (ip6_t) + tmpl_ip6hp->ip6_plen;
140 140
141 141 if ((mp = allocb(hdr_len + extra_len, BPRI_HI)) == NULL)
142 142 return (NULL);
143 143
144 144 ip6hp = (ip6_t *)mp->b_rptr;
145 145
146 146 bzero(ip6hp, hdr_len + extra_len);
147 147 if (tmpl_ip6hp != NULL) {
148 148 bcopy(tmpl_ip6hp, ip6hp, hdr_len);
149 149 } else {
150 150 ip6hp->ip6_nxt = IPPROTO_NONE;
151 151 ip6hp->ip6_hlim = IPTUN_DEFAULT_HOPLIMIT;
152 152 }
153 153
154 154 ip6hp->ip6_vcf = IPV6_DEFAULT_VERS_AND_FLOW;
155 155 ip6hp->ip6_plen = 0;
156 156
157 157 nxt_proto = &ip6hp->ip6_nxt;
158 158 if (*nxt_proto != IPPROTO_NONE) {
159 159 ip6_dest_t *hdrptr = (ip6_dest_t *)(ip6hp + 1);
160 160 nxt_proto = &hdrptr->ip6d_nxt;
161 161 while (*nxt_proto != IPPROTO_NONE) {
162 162 hdrptr = (ip6_dest_t *)((uint8_t *)hdrptr +
163 163 (8 * (hdrptr->ip6d_len + 1)));
164 164 nxt_proto = &hdrptr->ip6d_nxt;
165 165 }
166 166 }
167 167 *nxt_proto = (uint8_t)sap;
168 168 bcopy(saddr, &(ip6hp->ip6_src), sizeof (in6_addr_t));
169 169 bcopy(daddr, &(ip6hp->ip6_dst), sizeof (in6_addr_t));
170 170
171 171 mp->b_wptr += hdr_len;
172 172 return (mp);
173 173 }
174 174
175 175 /* ARGSUSED */
176 176 int
177 177 mac_ipv6_header_info(mblk_t *mp, void *pdata, mac_header_info_t *hdr_info)
178 178 {
179 179 ip6_t *ip6hp;
180 180 uint8_t *whereptr, *endptr;
181 181 uint8_t nexthdr;
182 182
183 183 if (MBLKL(mp) < sizeof (ip6_t))
184 184 return (EINVAL);
185 185
186 186 ip6hp = (ip6_t *)mp->b_rptr;
187 187
188 188 /*
189 189 * IPv6 tunnels don't have a concept of link-layer multicast since
190 190 * they have fixed unicast endpoints.
191 191 */
192 192 if (mac_ipv6_unicst_verify(&ip6hp->ip6_dst, NULL) != 0)
193 193 return (EINVAL);
194 194
195 195 nexthdr = ip6hp->ip6_nxt;
196 196 whereptr = (uint8_t *)(ip6hp + 1);
197 197 endptr = mp->b_wptr;
198 198 while (nexthdr != IPPROTO_ENCAP && nexthdr != IPPROTO_IPV6) {
199 199 ip6_dest_t *exthdrptr = (ip6_dest_t *)whereptr;
200 200
201 201 if (whereptr + sizeof (ip6_dest_t) >= endptr)
202 202 return (EINVAL);
203 203
204 204 nexthdr = exthdrptr->ip6d_nxt;
205 205 whereptr += 8 * (exthdrptr->ip6d_len + 1);
206 206
207 207 if (whereptr > endptr)
208 208 return (EINVAL);
209 209 }
210 210
211 211 hdr_info->mhi_hdrsize = whereptr - mp->b_rptr;
212 212 hdr_info->mhi_pktsize = 0;
213 213 hdr_info->mhi_daddr = (const uint8_t *)&(ip6hp->ip6_dst);
214 214 hdr_info->mhi_saddr = (const uint8_t *)&(ip6hp->ip6_src);
215 215 hdr_info->mhi_bindsap = hdr_info->mhi_origsap = nexthdr;
216 216 hdr_info->mhi_dsttype = MAC_ADDRTYPE_UNICAST;
217 217 return (0);
218 218 }
219 219
220 220 /*
221 221 * This plugin's MAC plugin data is a template IPv6 header followed by
222 222 * optional extension headers. The chain of headers must be terminated by
223 223 * a header with a next header value of IPPROTO_NONE. The payload length
224 224 * of the IPv6 header must be 0 if there are no extension headers, or must
225 225 * reflect the total size of extension headers present.
226 226 */
227 227 boolean_t
228 228 mac_ipv6_pdata_verify(void *pdata, size_t pdata_size)
229 229 {
230 230 ip6_t *ip6hp = pdata;
231 231 uint8_t *whereptr, *endptr;
232 232 uint8_t nexthdr;
233 233
234 234 /*
235 235 * Since the plugin does not require plugin data, it is acceptable
236 236 * for drivers to pass in NULL plugin data as long as the plugin
237 237 * data size is consistent.
238 238 */
239 239 if (pdata == NULL)
240 240 return (pdata_size == 0);
241 241
242 242 /* First verify that we have enough data to hold an IPv6 header. */
243 243 if (pdata_size < sizeof (ip6_t))
244 244 return (B_FALSE);
245 245 /* Make sure that pdata_size is consistent with the payload length. */
246 246 if (pdata_size != sizeof (ip6_t) + ip6hp->ip6_plen)
247 247 return (B_FALSE);
248 248
249 249 /*
250 250 * Make sure that the header chain is terminated by a header with a
251 251 * next header value of IPPROTO_NONE.
252 252 */
253 253 nexthdr = ip6hp->ip6_nxt;
254 254 if (nexthdr == IPPROTO_NONE)
255 255 return (ip6hp->ip6_plen == 0);
256 256 whereptr = (uint8_t *)(ip6hp + 1);
257 257 endptr = (uint8_t *)pdata + pdata_size;
258 258
259 259 while (nexthdr != IPPROTO_NONE && whereptr < endptr) {
260 260 ip6_dest_t *hdrptr = (ip6_dest_t *)whereptr;
261 261
262 262 /* make sure we're pointing at a complete header */
263 263 if (whereptr + sizeof (ip6_dest_t) > endptr)
264 264 break;
265 265 nexthdr = hdrptr->ip6d_nxt;
266 266 whereptr += 8 * (hdrptr->ip6d_len + 1);
267 267 }
268 268
269 269 return (nexthdr == IPPROTO_NONE && whereptr == endptr);
270 270 }
271 271
272 272 static mactype_ops_t mac_ipv6_type_ops = {
273 273 MTOPS_PDATA_VERIFY,
274 274 mac_ipv6_unicst_verify,
275 275 mac_ipv4_multicst_verify, /* neither plugin supports multicast */
276 276 mac_ipv4_sap_verify, /* same set of legal SAP values */
277 277 mac_ipv6_header,
278 278 mac_ipv6_header_info,
279 279 mac_ipv6_pdata_verify,
280 280 NULL,
281 281 NULL,
282 282 NULL
283 283 };
↓ open down ↓ |
220 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX