Print this page
%B


   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;