9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /*
26 * This file contains routines that are used to modify/retrieve protocol or
27 * interface property values. It also holds all the supported properties for
28 * both IP interface and protocols in `ipadm_prop_desc_t'. Following protocols
29 * are supported: IP, IPv4, IPv6, TCP, SCTP, UDP and ICMP.
30 *
31 * This file also contains walkers, which walks through the property table and
32 * calls the callback function, of the form `ipadm_prop_wfunc_t' , for every
33 * property in the table.
34 */
35
36 #include <unistd.h>
37 #include <errno.h>
38 #include <ctype.h>
39 #include <fcntl.h>
40 #include <strings.h>
41 #include <stdlib.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h>
44 #include <sys/sockio.h>
45 #include <assert.h>
46 #include <libdllink.h>
47 #include <zone.h>
48 #include "libipadm_impl.h"
49 #include <inet/tunables.h>
65 */
66 static ipadm_pd_getf_t i_ipadm_get_prop, i_ipadm_get_ifprop_flags,
67 i_ipadm_get_mtu, i_ipadm_get_metric,
68 i_ipadm_get_usesrc, i_ipadm_get_forwarding,
69 i_ipadm_get_ecnsack, i_ipadm_get_hostmodel;
70
71 /*
72 * Callback function to set property values. These functions translate the
73 * values to a format suitable for kernel consumption, allocates the necessary
74 * ioctl buffers and then invokes ioctl().
75 */
76 static ipadm_pd_setf_t i_ipadm_set_prop, i_ipadm_set_mtu,
77 i_ipadm_set_ifprop_flags,
78 i_ipadm_set_metric, i_ipadm_set_usesrc,
79 i_ipadm_set_forwarding, i_ipadm_set_eprivport,
80 i_ipadm_set_ecnsack, i_ipadm_set_hostmodel;
81
82 /* array of protocols we support */
83 static int protocols[] = { MOD_PROTO_IP, MOD_PROTO_RAWIP,
84 MOD_PROTO_TCP, MOD_PROTO_UDP,
85 MOD_PROTO_SCTP };
86
87 /*
88 * Supported IP protocol properties.
89 */
90 static ipadm_prop_desc_t ipadm_ip_prop_table[] = {
91 { "arp", IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
92 i_ipadm_set_ifprop_flags, i_ipadm_get_onoff,
93 i_ipadm_get_ifprop_flags },
94
95 { "forwarding", IPADMPROP_CLASS_MODIF, MOD_PROTO_IPV4, 0,
96 i_ipadm_set_forwarding, i_ipadm_get_onoff,
97 i_ipadm_get_forwarding },
98
99 { "metric", IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
100 i_ipadm_set_metric, NULL, i_ipadm_get_metric },
101
102 { "mtu", IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
103 i_ipadm_set_mtu, i_ipadm_get_mtu, i_ipadm_get_mtu },
104
105 { "exchange_routes", IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
222 { "smallest_anon_port", IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 0,
223 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
224
225 { "smallest_nonpriv_port", IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 0,
226 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
227
228 { NULL, 0, 0, 0, NULL, NULL, NULL }
229 };
230
231 /* Supported ICMP protocol properties */
232 static ipadm_prop_desc_t ipadm_icmp_prop_table[] = {
233 { "recv_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_RAWIP, 0,
234 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
235
236 { "send_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_RAWIP, 0,
237 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
238
239 { NULL, 0, 0, 0, NULL, NULL, NULL }
240 };
241
242 /*
243 * A dummy private property structure, used while handling private
244 * protocol properties (properties not yet supported by libipadm).
245 */
246 static ipadm_prop_desc_t ipadm_privprop =\
247 { NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_NONE, 0,
248 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop };
249
250 /*
251 * Returns the property description table, for the given protocol
252 */
253 static ipadm_prop_desc_t *
254 i_ipadm_get_propdesc_table(uint_t proto)
255 {
256 switch (proto) {
257 case MOD_PROTO_IP:
258 case MOD_PROTO_IPV4:
259 case MOD_PROTO_IPV6:
260 return (ipadm_ip_prop_table);
261 case MOD_PROTO_RAWIP:
262 return (ipadm_icmp_prop_table);
263 case MOD_PROTO_TCP:
264 return (ipadm_tcp_prop_table);
265 case MOD_PROTO_UDP:
266 return (ipadm_udp_prop_table);
267 case MOD_PROTO_SCTP:
268 return (ipadm_sctp_prop_table);
269 }
270
271 return (NULL);
272 }
273
274 static ipadm_prop_desc_t *
275 i_ipadm_get_prop_desc(const char *pname, uint_t proto, int *errp)
276 {
277 int err = 0;
278 boolean_t matched_name = B_FALSE;
279 ipadm_prop_desc_t *ipdp = NULL, *ipdtbl;
280
281 if ((ipdtbl = i_ipadm_get_propdesc_table(proto)) == NULL) {
282 err = EINVAL;
283 goto ret;
284 }
285 for (ipdp = ipdtbl; ipdp->ipd_name != NULL; ipdp++) {
286 if (strcmp(pname, ipdp->ipd_name) == 0) {
287 matched_name = B_TRUE;
288 if (ipdp->ipd_proto == proto)
303 }
304
305 char *
306 ipadm_proto2str(uint_t proto)
307 {
308 switch (proto) {
309 case MOD_PROTO_IP:
310 return ("ip");
311 case MOD_PROTO_IPV4:
312 return ("ipv4");
313 case MOD_PROTO_IPV6:
314 return ("ipv6");
315 case MOD_PROTO_RAWIP:
316 return ("icmp");
317 case MOD_PROTO_TCP:
318 return ("tcp");
319 case MOD_PROTO_UDP:
320 return ("udp");
321 case MOD_PROTO_SCTP:
322 return ("sctp");
323 }
324
325 return (NULL);
326 }
327
328 uint_t
329 ipadm_str2proto(const char *protostr)
330 {
331 if (protostr == NULL)
332 return (MOD_PROTO_NONE);
333 if (strcmp(protostr, "tcp") == 0)
334 return (MOD_PROTO_TCP);
335 else if (strcmp(protostr, "udp") == 0)
336 return (MOD_PROTO_UDP);
337 else if (strcmp(protostr, "ip") == 0)
338 return (MOD_PROTO_IP);
339 else if (strcmp(protostr, "ipv4") == 0)
340 return (MOD_PROTO_IPV4);
341 else if (strcmp(protostr, "ipv6") == 0)
342 return (MOD_PROTO_IPV6);
343 else if (strcmp(protostr, "icmp") == 0)
344 return (MOD_PROTO_RAWIP);
345 else if (strcmp(protostr, "sctp") == 0)
346 return (MOD_PROTO_SCTP);
347 else if (strcmp(protostr, "arp") == 0)
348 return (MOD_PROTO_IP);
349
350 return (MOD_PROTO_NONE);
351 }
352
353 /* ARGSUSED */
354 static ipadm_status_t
355 i_ipadm_set_mtu(ipadm_handle_t iph, const void *arg,
356 ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags)
357 {
358 struct lifreq lifr;
359 char *endp;
360 uint_t mtu;
361 int s;
362 const char *ifname = arg;
363 char val[MAXPROPVALLEN];
364
365 /* to reset MTU first retrieve the default MTU and then set it */
366 if (flags & IPADM_OPT_DEFAULT) {
367 ipadm_status_t status;
368 uint_t size = MAXPROPVALLEN;
|
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /*
26 * This file contains routines that are used to modify/retrieve protocol or
27 * interface property values. It also holds all the supported properties for
28 * both IP interface and protocols in `ipadm_prop_desc_t'. Following protocols
29 * are supported: IP, IPv4, IPv6, TCP, SCTP, UDP, ICMP and DCCP.
30 *
31 * This file also contains walkers, which walks through the property table and
32 * calls the callback function, of the form `ipadm_prop_wfunc_t' , for every
33 * property in the table.
34 */
35
36 #include <unistd.h>
37 #include <errno.h>
38 #include <ctype.h>
39 #include <fcntl.h>
40 #include <strings.h>
41 #include <stdlib.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h>
44 #include <sys/sockio.h>
45 #include <assert.h>
46 #include <libdllink.h>
47 #include <zone.h>
48 #include "libipadm_impl.h"
49 #include <inet/tunables.h>
65 */
66 static ipadm_pd_getf_t i_ipadm_get_prop, i_ipadm_get_ifprop_flags,
67 i_ipadm_get_mtu, i_ipadm_get_metric,
68 i_ipadm_get_usesrc, i_ipadm_get_forwarding,
69 i_ipadm_get_ecnsack, i_ipadm_get_hostmodel;
70
71 /*
72 * Callback function to set property values. These functions translate the
73 * values to a format suitable for kernel consumption, allocates the necessary
74 * ioctl buffers and then invokes ioctl().
75 */
76 static ipadm_pd_setf_t i_ipadm_set_prop, i_ipadm_set_mtu,
77 i_ipadm_set_ifprop_flags,
78 i_ipadm_set_metric, i_ipadm_set_usesrc,
79 i_ipadm_set_forwarding, i_ipadm_set_eprivport,
80 i_ipadm_set_ecnsack, i_ipadm_set_hostmodel;
81
82 /* array of protocols we support */
83 static int protocols[] = { MOD_PROTO_IP, MOD_PROTO_RAWIP,
84 MOD_PROTO_TCP, MOD_PROTO_UDP,
85 MOD_PROTO_SCTP, MOD_PROTO_DCCP };
86
87 /*
88 * Supported IP protocol properties.
89 */
90 static ipadm_prop_desc_t ipadm_ip_prop_table[] = {
91 { "arp", IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
92 i_ipadm_set_ifprop_flags, i_ipadm_get_onoff,
93 i_ipadm_get_ifprop_flags },
94
95 { "forwarding", IPADMPROP_CLASS_MODIF, MOD_PROTO_IPV4, 0,
96 i_ipadm_set_forwarding, i_ipadm_get_onoff,
97 i_ipadm_get_forwarding },
98
99 { "metric", IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
100 i_ipadm_set_metric, NULL, i_ipadm_get_metric },
101
102 { "mtu", IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
103 i_ipadm_set_mtu, i_ipadm_get_mtu, i_ipadm_get_mtu },
104
105 { "exchange_routes", IPADMPROP_CLASS_IF, MOD_PROTO_IPV4, 0,
222 { "smallest_anon_port", IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 0,
223 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
224
225 { "smallest_nonpriv_port", IPADMPROP_CLASS_MODULE, MOD_PROTO_SCTP, 0,
226 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
227
228 { NULL, 0, 0, 0, NULL, NULL, NULL }
229 };
230
231 /* Supported ICMP protocol properties */
232 static ipadm_prop_desc_t ipadm_icmp_prop_table[] = {
233 { "recv_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_RAWIP, 0,
234 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
235
236 { "send_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_RAWIP, 0,
237 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
238
239 { NULL, 0, 0, 0, NULL, NULL, NULL }
240 };
241
242 /* Supported DCCP protocol properties */
243 static ipadm_prop_desc_t ipadm_dccp_prop_table[] = {
244 { "extra_priv_ports", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP,
245 IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop,
246 i_ipadm_get_prop },
247
248 { "largest_anon_port", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP, 0,
249 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
250
251 { "recv_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP, 0,
252 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
253
254 { "send_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP, 0,
255 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
256
257 { "smallest_anon_port", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP, 0,
258 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
259
260 { "smallest_nonpriv_port", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP, 0,
261 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
262
263 { NULL, 0, 0, 0, NULL, NULL, NULL }
264 };
265
266 /*
267 * A dummy private property structure, used while handling private
268 * protocol properties (properties not yet supported by libipadm).
269 */
270 static ipadm_prop_desc_t ipadm_privprop =\
271 { NULL, IPADMPROP_CLASS_MODULE, MOD_PROTO_NONE, 0,
272 i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop };
273
274 /*
275 * Returns the property description table, for the given protocol
276 */
277 static ipadm_prop_desc_t *
278 i_ipadm_get_propdesc_table(uint_t proto)
279 {
280 switch (proto) {
281 case MOD_PROTO_IP:
282 case MOD_PROTO_IPV4:
283 case MOD_PROTO_IPV6:
284 return (ipadm_ip_prop_table);
285 case MOD_PROTO_RAWIP:
286 return (ipadm_icmp_prop_table);
287 case MOD_PROTO_TCP:
288 return (ipadm_tcp_prop_table);
289 case MOD_PROTO_UDP:
290 return (ipadm_udp_prop_table);
291 case MOD_PROTO_SCTP:
292 return (ipadm_sctp_prop_table);
293 case MOD_PROTO_DCCP:
294 return (ipadm_dccp_prop_table);
295 }
296
297 return (NULL);
298 }
299
300 static ipadm_prop_desc_t *
301 i_ipadm_get_prop_desc(const char *pname, uint_t proto, int *errp)
302 {
303 int err = 0;
304 boolean_t matched_name = B_FALSE;
305 ipadm_prop_desc_t *ipdp = NULL, *ipdtbl;
306
307 if ((ipdtbl = i_ipadm_get_propdesc_table(proto)) == NULL) {
308 err = EINVAL;
309 goto ret;
310 }
311 for (ipdp = ipdtbl; ipdp->ipd_name != NULL; ipdp++) {
312 if (strcmp(pname, ipdp->ipd_name) == 0) {
313 matched_name = B_TRUE;
314 if (ipdp->ipd_proto == proto)
329 }
330
331 char *
332 ipadm_proto2str(uint_t proto)
333 {
334 switch (proto) {
335 case MOD_PROTO_IP:
336 return ("ip");
337 case MOD_PROTO_IPV4:
338 return ("ipv4");
339 case MOD_PROTO_IPV6:
340 return ("ipv6");
341 case MOD_PROTO_RAWIP:
342 return ("icmp");
343 case MOD_PROTO_TCP:
344 return ("tcp");
345 case MOD_PROTO_UDP:
346 return ("udp");
347 case MOD_PROTO_SCTP:
348 return ("sctp");
349 case MOD_PROTO_DCCP:
350 return ("dccp");
351 }
352
353 return (NULL);
354 }
355
356 uint_t
357 ipadm_str2proto(const char *protostr)
358 {
359 if (protostr == NULL)
360 return (MOD_PROTO_NONE);
361 if (strcmp(protostr, "tcp") == 0)
362 return (MOD_PROTO_TCP);
363 else if (strcmp(protostr, "udp") == 0)
364 return (MOD_PROTO_UDP);
365 else if (strcmp(protostr, "ip") == 0)
366 return (MOD_PROTO_IP);
367 else if (strcmp(protostr, "ipv4") == 0)
368 return (MOD_PROTO_IPV4);
369 else if (strcmp(protostr, "ipv6") == 0)
370 return (MOD_PROTO_IPV6);
371 else if (strcmp(protostr, "icmp") == 0)
372 return (MOD_PROTO_RAWIP);
373 else if (strcmp(protostr, "sctp") == 0)
374 return (MOD_PROTO_SCTP);
375 else if (strcmp(protostr, "arp") == 0)
376 return (MOD_PROTO_IP);
377 else if (strcmp(protostr, "dccp") == 0)
378 return (MOD_PROTO_DCCP);
379
380 return (MOD_PROTO_NONE);
381 }
382
383 /* ARGSUSED */
384 static ipadm_status_t
385 i_ipadm_set_mtu(ipadm_handle_t iph, const void *arg,
386 ipadm_prop_desc_t *pdp, const void *pval, uint_t proto, uint_t flags)
387 {
388 struct lifreq lifr;
389 char *endp;
390 uint_t mtu;
391 int s;
392 const char *ifname = arg;
393 char val[MAXPROPVALLEN];
394
395 /* to reset MTU first retrieve the default MTU and then set it */
396 if (flags & IPADM_OPT_DEFAULT) {
397 ipadm_status_t status;
398 uint_t size = MAXPROPVALLEN;
|