Skip to content

Commit

Permalink
OS-4683 Using the allowed-ips property prevents using dynamic addresses
Browse files Browse the repository at this point in the history
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Dan McDonald <danmcd@joyent.com>
Approved by: Dan McDonald <danmcd@joyent.com>
  • Loading branch information
melloc committed Jun 8, 2018
1 parent c6b0ac1 commit 12a82dd
Show file tree
Hide file tree
Showing 14 changed files with 424 additions and 148 deletions.
40 changes: 37 additions & 3 deletions usr/src/lib/libdladm/common/libdladm.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, Joyent, Inc.
* Copyright 2017, Joyent, Inc.
*/

#include <unistd.h>
Expand Down Expand Up @@ -99,6 +99,18 @@ static link_protect_t link_protect_types[] = {
};
#define LPTYPES (sizeof (link_protect_types) / sizeof (link_protect_t))

typedef struct {
uint32_t ld_type;
char *ld_name;
} link_dynamic_t;

static link_dynamic_t link_dynamic_types[] = {
{ MPT_DYN_DHCPV4, "dhcpv4" },
{ MPT_DYN_DHCPV6, "dhcpv6" },
{ MPT_DYN_SLAAC, "slaac" },
};
#define DYNTYPES (sizeof (link_dynamic_types) / sizeof (link_dynamic_t))

dladm_status_t
dladm_open(dladm_handle_t *handle)
{
Expand Down Expand Up @@ -951,6 +963,28 @@ dladm_protect2str(uint32_t ptype, char *buf)
return (buf);
}


/*
* Convert dynamic address method value to a string.
*/
const char *
dladm_dynamic2str(uint32_t dtype, char *buf, size_t size)
{
const char *s = "--";
link_dynamic_t *ld;
int i;

for (i = 0; i < DYNTYPES; i++) {
ld = &link_dynamic_types[i];
if (ld->ld_type == dtype) {
s = ld->ld_name;
break;
}
}
(void) snprintf(buf, size, "%s", dgettext(TEXT_DOMAIN, s));
return (buf);
}

/*
* Convert an IPv4 address to/from a string.
*/
Expand Down Expand Up @@ -1092,8 +1126,8 @@ dladm_parse_args(char *str, dladm_arg_list_t **listp, boolean_t novalues)
* is allocated here but should be freed by the caller.
*/
dladm_status_t
dladm_strs2range(char **prop_val, uint_t val_cnt, mac_propval_type_t type,
mac_propval_range_t **range)
dladm_strs2range(char **prop_val, uint_t val_cnt,
mac_propval_type_t type, mac_propval_range_t **range)
{
int i;
char *endp;
Expand Down
3 changes: 2 additions & 1 deletion usr/src/lib/libdladm/common/libdladm.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2015, Joyent, Inc.
* Copyright 2017, Joyent, Inc.
*/

#ifndef _LIBDLADM_H
Expand Down Expand Up @@ -265,6 +265,7 @@ extern dladm_status_t dladm_str2pri(char *, mac_priority_level_t *);
extern const char *dladm_pri2str(mac_priority_level_t, char *);
extern dladm_status_t dladm_str2protect(char *, uint32_t *);
extern const char *dladm_protect2str(uint32_t, char *);
extern const char *dladm_dynamic2str(uint32_t, char *, size_t);
extern dladm_status_t dladm_str2ipv4addr(char *, void *);
extern const char *dladm_ipv4addr2str(void *, char *);
extern dladm_status_t dladm_str2ipv6addr(char *, void *);
Expand Down
2 changes: 1 addition & 1 deletion usr/src/lib/libdladm/common/libdladm_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ extern dladm_status_t dladm_flow_proplist_extract(dladm_arg_list_t *,
* by the pd_check function.
*/
typedef dladm_status_t rp_extractf_t(val_desc_t *, uint_t, void *);
extern rp_extractf_t extract_priority, extract_cpus,
extern rp_extractf_t extract_dynamic_methods, extract_priority, extract_cpus,
extract_protection, extract_allowallcids, extract_pool,
extract_allowedips, extract_allowedcids, extract_maxbw,
extract_rxrings, extract_txrings;
Expand Down
59 changes: 58 additions & 1 deletion usr/src/lib/libdladm/common/linkprop.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ static pd_getf_t get_zone, get_autopush, get_rate_mod, get_rate,
get_txrings, get_cntavail, get_secondary_macs,
get_allowallcids, get_allowedips, get_allowedcids,
get_pool, get_rings_range, get_linkmode_prop,
get_promisc_filtered;
get_promisc_filtered, get_dynamic_methods;

static pd_setf_t set_zone, set_rate, set_powermode, set_radio,
set_public_prop, set_resource, set_stp_prop,
Expand Down Expand Up @@ -451,6 +451,13 @@ static val_desc_t link_protect_vals[] = {
{ "dhcp-nospoof", MPT_DHCPNOSPOOF },
};

static val_desc_t link_dynamic_method_vals[] = {
{ "dhcpv4", MPT_DYN_DHCPV4 },
{ "dhcpv6", MPT_DYN_DHCPV6 },
{ "slaac", MPT_DYN_SLAAC },
{ "addrconf", (MPT_DYN_SLAAC | MPT_DYN_DHCPV6) },
};

static val_desc_t dladm_bool_vals[] = {
{ "false", MPT_FALSE },
{ "true", MPT_TRUE },
Expand Down Expand Up @@ -797,6 +804,11 @@ static prop_desc_t prop_table[] = {
set_resource, NULL, get_protection, check_prop, 0,
DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE },

{ "dynamic-methods", { "--", RESET_VAL },
link_dynamic_method_vals, VALCNT(link_dynamic_method_vals),
set_resource, NULL, get_dynamic_methods, check_prop, 0,
DATALINK_CLASS_ALL, DATALINK_ANY_MEDIATYPE },

{ "promisc-filtered", { "on", 1 },
link_promisc_filtered_vals, VALCNT(link_promisc_filtered_vals),
set_promisc_filtered, NULL, get_promisc_filtered, check_prop, 0,
Expand Down Expand Up @@ -864,6 +876,7 @@ static resource_prop_t rsrc_prop_table[] = {
{"pool", extract_pool},
{"pool-effective", extract_pool},
{"protection", extract_protection},
{"dynamic-methods", extract_dynamic_methods},
{"allowed-ips", extract_allowedips},
{"allowed-dhcp-cids", extract_allowedcids},
{"allow-all-dhcp-cids", extract_allowallcids},
Expand Down Expand Up @@ -2927,6 +2940,50 @@ dladm_str2cid(char *buf, mac_dhcpcid_t *cid)
return (DLADM_STATUS_OK);
}

/* ARGSUSED */
static dladm_status_t
get_dynamic_methods(dladm_handle_t handle, prop_desc_t *pdp,
datalink_id_t linkid, char **prop_val, uint_t *val_cnt,
datalink_media_t media, uint_t flags, uint_t *perm_flags)
{
mac_resource_props_t mrp;
mac_protect_t *p;
dladm_status_t status;
uint32_t i, cnt = 0, setbits[32];

status = i_dladm_get_public_prop(handle, linkid, "resource", flags,
perm_flags, &mrp, sizeof (mrp));
if (status != DLADM_STATUS_OK)
return (status);

p = &mrp.mrp_protect;
dladm_find_setbits32(p->mp_dynamic, setbits, &cnt);
if (cnt > *val_cnt)
return (DLADM_STATUS_BADVALCNT);

for (i = 0; i < cnt; i++)
(void) dladm_dynamic2str(
setbits[i], prop_val[i], DLADM_STRSIZE);

*val_cnt = cnt;
return (DLADM_STATUS_OK);
}

dladm_status_t
extract_dynamic_methods(val_desc_t *vdp, uint_t cnt, void *arg)
{
mac_resource_props_t *mrp = arg;
uint32_t methods = 0;
int i;

for (i = 0; i < cnt; i++)
methods |= (uint32_t)vdp[i].vd_val;

mrp->mrp_protect.mp_dynamic = methods;
mrp->mrp_mask |= MRP_PROTECT;
return (DLADM_STATUS_OK);
}

/* ARGSUSED */
static dladm_status_t
get_allowallcids(dladm_handle_t handle, prop_desc_t *pdp,
Expand Down
18 changes: 18 additions & 0 deletions usr/src/man/man1m/dladm.1m
Original file line number Diff line number Diff line change
Expand Up @@ -4988,6 +4988,24 @@ The default is no CPU binding, which is to say that the processing of packets
is not bound to any specific processor or processor set.
.RE

.sp
.ne 2
.na
\fB\fBdynamic-methods\fR\fR
.ad
.sp .6
.RS 4n
When using IP spoofing protection (see \fBprotection\fR), addresses can be
learned dynamically by monitoring certain network traffic, like DHCP
transactions or IPv6 Stateless Address Autoconfiguration (SLAAC). By default,
all learning methods are permitted, but if \fBallowed-ips\fR contains any
addresses, then all methods are disabled, and any packets sent from addresses
previously learned will be dropped. This property allows selecting which ones
are re-enabled, where valid options are \fBdhcpv4\fR, \fBdhcpv6\fR, and
\fBslaac\fR. \fBaddrconf\fR is available as an alias for enabling both
\fBdhcpv6\fR and \fBslaac\fR.
.RE

.sp
.ne 2
.na
Expand Down
45 changes: 45 additions & 0 deletions usr/src/test/util-tests/tests/dladm/dynamic-methods.ksh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/bin/ksh
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#

#
# Copyright 2017 Joyent, Inc.
#

source ./common.ksh

property="dynamic-methods"

setup

# All valid values on their own
epass slaac
epass dhcpv4
epass dhcpv6
epass addrconf

# Combinations of values
epass slaac,dhcpv4
epass slaac,dhcpv6
epass dhcpv4,dhcpv6
epass dhcpv4,addrconf
epass dhcpv4,dhcpv6,slaac

# Illegal values
efail dhcpv8
efail slaac,dhcpv8
efail slack
efail ipv6
efail dhcp
efail dhcpv

cleanup
printf "TEST PASS: $ai_arg0\n"
19 changes: 18 additions & 1 deletion usr/src/uts/common/inet/ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
/*
* Copyright (c) 1990 Mentat Inc.
* Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
* Copyright 2017, Joyent, Inc. All rights reserved.
* Copyright 2017 Nexenta Systems, Inc.
* Copyright 2017 OmniTI Computer Consulting, Inc. All rights reserved.
*/
Expand Down Expand Up @@ -1415,6 +1415,7 @@ typedef union ill_g_head_u {
#define ILL_CAPAB_DLD 0x20 /* DLD capabilities */
#define ILL_CAPAB_DLD_POLL 0x40 /* Polling */
#define ILL_CAPAB_DLD_DIRECT 0x80 /* Direct function call */
#define ILL_CAPAB_DLD_IPCHECK 0x100 /* Check if IPs are permitted */

/*
* Per-ill Hardware Checksumming capbilities.
Expand Down Expand Up @@ -1728,6 +1729,8 @@ typedef struct ill_s {
* Capabilities related fields.
*/
uint_t ill_dlpi_capab_state; /* State of capability query, IDCS_* */
kcondvar_t ill_dlpi_capab_cv; /* CV for broadcasting state changes */
kmutex_t ill_dlpi_capab_lock; /* Lock for accessing above Cond Var */
uint_t ill_capab_pending_cnt;
uint64_t ill_capabilities; /* Enabled capabilities, ILL_CAPAB_* */
ill_hcksum_capab_t *ill_hcksum_capab; /* H/W cksumming capabilities */
Expand Down Expand Up @@ -1769,6 +1772,10 @@ typedef struct ill_s {
* Used to save errors that occur during plumbing
*/
uint_t ill_ifname_pending_err;
/*
* Used to save errors that occur during binding
*/
uint_t ill_dl_bind_err;
avl_node_t ill_avl_byppa; /* avl node based on ppa */
list_t ill_nce; /* pointer to nce_s list */
uint_t ill_refcnt; /* active refcnt by threads */
Expand Down Expand Up @@ -1934,6 +1941,7 @@ typedef struct ill_s {
* ill_nd_lla_len ipsq + down ill only when ill is up
* ill_phys_addr_pend ipsq + down ill only when ill is up
* ill_ifname_pending_err ipsq ipsq
* ill_dl_bind_err ipsq ipsq
* ill_avl_byppa ipsq, ill_g_lock write once
*
* ill_fastpath_list ill_lock ill_lock
Expand Down Expand Up @@ -3575,6 +3583,8 @@ typedef void (*ip_flow_enable_t)(void *, ip_mac_tx_cookie_t);
typedef void *(*ip_dld_callb_t)(void *,
ip_flow_enable_t, void *);
typedef boolean_t (*ip_dld_fctl_t)(void *, ip_mac_tx_cookie_t);
typedef boolean_t (*ip_mac_ipcheck_t)(void *, boolean_t,
in6_addr_t *);
typedef int (*ip_capab_func_t)(void *, uint_t,
void *, uint_t);

Expand Down Expand Up @@ -3627,6 +3637,12 @@ typedef struct ill_dld_direct_s { /* DLD provided driver Tx */
void *idd_tx_fctl_dh; /* mac_client_handle */
} ill_dld_direct_t;

/* IP - DLD direct function call to check if an IP is allowed */
typedef struct ill_dld_ipcheck_s {
ip_mac_ipcheck_t idi_allowed_df;
void *idi_allowed_dh;
} ill_dld_ipcheck_t;

/* IP - DLD polling capability */
typedef struct ill_dld_poll_s {
ill_rx_ring_t idp_ring_tbl[ILL_MAX_RINGS];
Expand All @@ -3638,6 +3654,7 @@ struct ill_dld_capab_s {
void *idc_capab_dh; /* dld_str_t *dsp */
ill_dld_direct_t idc_direct;
ill_dld_poll_t idc_poll;
ill_dld_ipcheck_t idc_ipcheck;
};

/*
Expand Down

0 comments on commit 12a82dd

Please sign in to comment.