diff options
-rw-r--r-- | usr/src/lib/libdladm/common/linkprop.c | 70 | ||||
-rw-r--r-- | usr/src/man/man1m/dladm.1m | 16 | ||||
-rw-r--r-- | usr/src/uts/common/io/mac/mac_protect.c | 19 | ||||
-rw-r--r-- | usr/src/uts/common/sys/mac_flow.h | 2 |
4 files changed, 101 insertions, 6 deletions
diff --git a/usr/src/lib/libdladm/common/linkprop.c b/usr/src/lib/libdladm/common/linkprop.c index d46054e686..8c0a5daf9f 100644 --- a/usr/src/lib/libdladm/common/linkprop.c +++ b/usr/src/lib/libdladm/common/linkprop.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <stdlib.h> @@ -2333,6 +2333,33 @@ get_protection(dladm_handle_t handle, prop_desc_t *pdp, return (DLADM_STATUS_OK); } +static uint32_t +nbits_to_mask(int nbits) +{ + int i; + uint_t mask = 0; + + for (i = 0; i < nbits; i++) { + mask >>= 1; + mask |= 0x80000000; + } + + return (mask); +} + +static uint32_t +mask_to_nbits(uint32_t mask) +{ + uint_t nbits = 0; + + while (mask != 0) { + nbits++; + mask <<= 1; + } + + return (nbits); +} + /* ARGSUSED */ static dladm_status_t get_allowedips(dladm_handle_t handle, prop_desc_t *pdp, @@ -2360,9 +2387,16 @@ get_allowedips(dladm_handle_t handle, prop_desc_t *pdp, for (i = 0; i < p->mp_ipaddrcnt; i++) { if (p->mp_ipaddrs[i].ip_version == IPV4_VERSION) { ipaddr_t v4addr; + uint32_t mask; v4addr = V4_PART_OF_V6(p->mp_ipaddrs[i].ip_addr); + mask = p->mp_ipaddrs[i].ip_v4netmask; (void) dladm_ipv4addr2str(&v4addr, prop_val[i]); + if (mask != 0) { + int len = strlen(prop_val[i]); + (void)sprintf(prop_val[i] + len, "/%d", + mask_to_nbits(mask)); + } } else { (void) dladm_ipv6addr2str(&p->mp_ipaddrs[i].ip_addr, prop_val[i]); @@ -2414,6 +2448,28 @@ check_single_ip(char *buf, mac_ipaddr_t *addr) ipaddr_t v4addr; in6_addr_t v6addr; boolean_t isv4 = B_TRUE; + char *p; + uint32_t mask; + + /* + * If the IP address is in CIDR format, parse the bits component + * seperately. An address in this style will be used to indicate an + * entire subnet, so it must be a network number with no host address. + */ + if ((p = strchr(buf, '/')) != NULL) { + char *end = NULL; + long msk; + + *p++ = '\0'; + if (!isdigit(*p)) + return (DLADM_STATUS_INVALID_IP); + msk = strtol(p, &end, 10); + if (end != NULL && *end != '\0') + return (DLADM_STATUS_INVALID_IP); + if (msk > 32 || msk < 1) + return (DLADM_STATUS_INVALID_IP); + mask = nbits_to_mask((int)msk); + } status = dladm_str2ipv4addr(buf, &v4addr); if (status == DLADM_STATUS_INVALID_IP) { @@ -2430,10 +2486,22 @@ check_single_ip(char *buf, mac_ipaddr_t *addr) IN6_IPADDR_TO_V4MAPPED(v4addr, &addr->ip_addr); addr->ip_version = IPV4_VERSION; + if (p != NULL) { + /* + * We have a CIDR style address, confirm that only the + * network number is set. + */ + if (htonl(v4addr) & ~mask) + return (DLADM_STATUS_INVALID_IP); + addr->ip_v4netmask = mask; + } } else { if (IN6_IS_ADDR_UNSPECIFIED(&v6addr)) return (DLADM_STATUS_INVALID_IP); + if (p != NULL) + return (DLADM_STATUS_INVALID_IP); + addr->ip_addr = v6addr; addr->ip_version = IPV6_VERSION; } diff --git a/usr/src/man/man1m/dladm.1m b/usr/src/man/man1m/dladm.1m index a2050328b7..cc4ba921db 100644 --- a/usr/src/man/man1m/dladm.1m +++ b/usr/src/man/man1m/dladm.1m @@ -1,6 +1,6 @@ '\" te .\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved -.\" Copyright (c) 2011, Joyent, Inc. All Rights Reserved +.\" Copyright (c) 2013, Joyent, Inc. All Rights Reserved .\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at http://www.opengroup.org/bookstore/. .\" The Institute of Electrical and Electronics Engineers and The Open Group, have given us permission to reprint portions of their documentation. In the following statement, the phrase "this text" refers to portions of the system documentation. Portions of this text .\" are reprinted and reproduced in electronic form in the Sun OS Reference Manual, from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of Electrical @@ -4432,6 +4432,20 @@ The following general link properties are supported: .sp .ne 2 .na +\fB\fBallowed-ips\fR\fR +.ad +.sp .6 +.RS 4n +A comma-seperated list of IP addresses that are allowed on the interface. +.sp +An address in CIDR format with no host address specified is used to indicate +that any address on that subnet is allowed (e.g. 192.168.10.0/24 means any +address in the range 192.168.10.0 - 192.168.10.255 is allowed). +.RE + +.sp +.ne 2 +.na \fB\fBautopush\fR\fR .ad .sp .6 diff --git a/usr/src/uts/common/io/mac/mac_protect.c b/usr/src/uts/common/io/mac/mac_protect.c index 4d5201a994..5016cc2665 100644 --- a/usr/src/uts/common/io/mac/mac_protect.c +++ b/usr/src/uts/common/io/mac/mac_protect.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2012, Joyent, Inc. All rights reserved. + * Copyright (c) 2013, Joyent, Inc. All rights reserved. */ #include <sys/strsun.h> @@ -1533,9 +1533,20 @@ ipnospoof_check_v4(mac_client_impl_t *mcip, mac_protect_t *protect, for (i = 0; i < protect->mp_ipaddrcnt; i++) { mac_ipaddr_t *v4addr = &protect->mp_ipaddrs[i]; - if (v4addr->ip_version == IPV4_VERSION && - V4_PART_OF_V6(v4addr->ip_addr) == *addr) - return (B_TRUE); + if (v4addr->ip_version == IPV4_VERSION) { + if (v4addr->ip_v4netmask != 0) { + /* + * Since we have a netmask we know this entry + * signifies the entire subnet. Check if the + * given address is on the subnet. + */ + if (htonl(V4_PART_OF_V6(v4addr->ip_addr)) == + (htonl(*addr) & v4addr->ip_v4netmask)) + return (B_TRUE); + } else if (V4_PART_OF_V6(v4addr->ip_addr) == *addr) { + return (B_TRUE); + } + } } return (protect->mp_ipaddrcnt == 0 ? check_dhcpv4_dyn_ip(mcip, *addr) : B_FALSE); diff --git a/usr/src/uts/common/sys/mac_flow.h b/usr/src/uts/common/sys/mac_flow.h index 9f9902fc29..4d7905de18 100644 --- a/usr/src/uts/common/sys/mac_flow.h +++ b/usr/src/uts/common/sys/mac_flow.h @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2013 Joyent, Inc. All rights reserved. */ #ifndef _MAC_FLOW_H @@ -157,6 +158,7 @@ typedef enum { typedef struct mac_ipaddr_s { uint32_t ip_version; in6_addr_t ip_addr; + uint32_t ip_v4netmask; } mac_ipaddr_t; typedef enum { |