return 1;
}
+static int
+cmd_bondslave_srcmac_type(struct lldpctl_conn_t *conn, struct writer *w,
+ struct cmd_env *env, void *arg)
+{
+ char *value_str;
+ int m = 0, value = -1;
+
+ log_debug("lldpctl", "bond slave src mac");
+
+ lldpctl_atom_t *config = lldpctl_get_configuration(conn);
+ if (config == NULL) {
+ log_warnx("lldpctl",
+ "unable to get configuration from lldpd. %s",
+ lldpctl_last_strerror(conn));
+ return 0;
+ }
+
+ value_str = arg;
+ for (lldpctl_map_t *b_map =
+ lldpctl_key_get_map(lldpctl_k_config_bond_slave_src_mac_type);
+ b_map->string; b_map++) {
+ if (!strcmp(b_map->string, value_str)) {
+ value = b_map->value;
+ break;
+ }
+ }
+
+ if (value == -1) {
+ log_warnx("lldpctl", "invalid value");
+ return 0;
+ }
+
+ if (lldpctl_atom_set_int(config,
+ lldpctl_k_config_bond_slave_src_mac_type, value) == NULL) {
+ log_warnx("lldpctl", "unable to set bond slave src mac type."
+ " %s", lldpctl_last_strerror(conn));
+ lldpctl_atom_dec_ref(config);
+ return 0;
+ }
+
+ log_info("lldpctl", "bond slave src mac set to new value : %s", arg);
+ lldpctl_atom_dec_ref(config);
+
+ return 1;
+}
+
/**
* Register `configure system` commands.
*
NEWLINE, "Set active interface pattern",
NULL, cmd_iface_pattern, NULL);
+ struct cmd_node *bond_slave_src_mac_type =
+ commands_new(configure_system,
+ "bond-slave-src-mac-type",
+ "Set LLDP bond slave src mac type",
+ NULL, NULL, NULL);
+
+ for (lldpctl_map_t *b_map =
+ lldpctl_key_get_map(lldpctl_k_config_bond_slave_src_mac_type);
+ b_map->string; b_map++) {
+ /* XXX: Would have been nice to encode the "Help" string in
+ * the map. Need to enhance the map struct for that
+ */
+ if (!strcmp(b_map->string, "real")) {
+ commands_new(
+ commands_new(bond_slave_src_mac_type,
+ b_map->string, "Real mac",
+ NULL, NULL, NULL),
+ NEWLINE, NULL,
+ NULL, cmd_bondslave_srcmac_type,
+ b_map->string);
+ } else if (!strcmp(b_map->string, "zero")) {
+ commands_new(
+ commands_new(bond_slave_src_mac_type,
+ b_map->string, "All zero mac",
+ NULL, NULL, NULL),
+ NEWLINE, NULL,
+ NULL, cmd_bondslave_srcmac_type,
+ b_map->string);
+ } else if (!strcmp(b_map->string, "local")) {
+ commands_new(
+ commands_new(bond_slave_src_mac_type,
+ b_map->string, "Real Mac with locally "
+ "administered bit set",
+ NULL, NULL, NULL),
+ NEWLINE, NULL,
+ NULL, cmd_bondslave_srcmac_type,
+ b_map->string);
+ }
+ }
+
commands_new(
commands_new(configure_interface,
"description", "Update interface descriptions with neighbor name",
"no":"yes");
tag_datatag(w, "lldpmed-faststart-interval", "LLDP-MED fast start interval",
N(lldpctl_atom_get_str(configuration, lldpctl_k_config_fast_start_interval)));
+ tag_datatag(w, "bond-slave-src-mac-type",
+ "Src mac for lldp frames on bond slaves",
+ lldpctl_atom_get_str(configuration,
+ lldpctl_k_config_bond_slave_src_mac_type));
tag_end(w);
tag_end(w);
the default TTL is 120 seconds.
.Ed
+.Cd configure
+.Cd system bond-slave-src-mac-type Ar value
+.Bd -ragged -offset XXXXXX
+Set the type of src mac in lldp frames sent on bond slaves
+
+Valid types are:
+.Bl -tag -width "XXX." -compact -offset XX
+.It Sy real
+Slave real mac
+.It Sy zero
+All zero mac
+.It Sy local
+Real mac with locally administered bit set. If the real mac already
+has the locally administered bit set, default to zero mac.
+.El
+.Pp
+Default value for
+.Nm bond-slave-src-mac-type
+is
+.Nm local
+.Ed
+
.Cd configure med fast-start
.Cd enable | tx-interval Ar interval
.Bd -ragged -offset XXXXXX
cfg->g_config.c_set_ifdescr = config->c_set_ifdescr;
levent_update_now(cfg);
}
+ if (config->c_bond_slave_src_mac_type >
+ LLDP_BOND_SLAVE_SRC_MAC_TYPE_UNKNOWN &&
+ config->c_bond_slave_src_mac_type <=
+ LLDP_BOND_SLAVE_SRC_MAC_TYPE_MAX) {
+ log_debug("rpc", "change bond src mac type to %d",
+ config->c_bond_slave_src_mac_type);
+ cfg->g_config.c_bond_slave_src_mac_type =
+ config->c_bond_slave_src_mac_type;
+ } else {
+ log_info("rpc", "Invalid bond slave src mac type: %d\n",
+ config->c_bond_slave_src_mac_type);
+ }
lldpd_config_cleanup(config);
free(config);
* already set to 1, use an unused MAC address instead.
*/
static void
-iface_mangle_mac(char *buffer)
+iface_mangle_mac(struct lldpd *cfg, char *src_mac)
{
+#define MAC_UL_ADMINISTERED_BIT_MASK 0x02
+
+ if (cfg->g_config.c_bond_slave_src_mac_type ==
+ LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED) {
+ if (*src_mac & MAC_UL_ADMINISTERED_BIT_MASK)
+ /* If locally administered bit already set,
+ * use zero mac
+ */
+ memset(src_mac, 0, ETHER_ADDR_LEN);
+ else
+ *src_mac |= MAC_UL_ADMINISTERED_BIT_MASK;
+ } else if (cfg->g_config.c_bond_slave_src_mac_type ==
+ LLDP_BOND_SLAVE_SRC_MAC_TYPE_ZERO) {
+ memset(src_mac, 0, ETHER_ADDR_LEN);
+ }
+ /* If cfg->g_config.c_bond_slave_src_mac_type is
+ * LLDP_BOND_SLAVE_SRC_MAC_TYPE_UNKNOWN or
+ * LLDP_BOND_SLAVE_SRC_MAC_TYPE_REAL, dont change mac
+ */
+
+#if 0
if (buffer[0] & 2) {
/* Already a locally administered MAC address, use a fixed MAC
* address (an old 3c905 MAC address of a card that I own). */
return;
}
buffer[0] |= 2;
+#endif
}
static int
hardware->h_ifname);
return 0;
}
- iface_mangle_mac(buffer + ETHER_ADDR_LEN);
+ iface_mangle_mac(cfg, buffer + ETHER_ADDR_LEN);
return write(hardware->h_sendfd,
buffer, size);
}
cfg->g_snmp = snmp;
cfg->g_snmp_agentx = agentx;
#endif /* USE_SNMP */
+ cfg->g_config.c_bond_slave_src_mac_type = \
+ LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED;
/* Get ioctl socket */
log_debug("main", "get an ioctl socket");
static lldpctl_map_t *port_med_pow_priority_map = port_dot3_power_priority_map;
#endif
+static lldpctl_map_t bond_slave_src_mac_map[] = {
+ { LLDP_BOND_SLAVE_SRC_MAC_TYPE_REAL, "real"},
+ { LLDP_BOND_SLAVE_SRC_MAC_TYPE_ZERO, "zero"},
+ { LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED, "local" },
+ { LLDP_BOND_SLAVE_SRC_MAC_TYPE_UNKNOWN, NULL},
+};
+
static const char*
map_lookup(lldpctl_map_t *list, int n)
{
case lldpctl_k_dot3_power_priority:
return port_dot3_power_priority_map;
#endif
+ case lldpctl_k_config_bond_slave_src_mac_type:
+ return bond_slave_src_mac_map;
default: return empty_map;
}
}
res = c->config->c_description; break;
case lldpctl_k_config_platform:
res = c->config->c_platform; break;
+ case lldpctl_k_config_bond_slave_src_mac_type:
+ return map_lookup(bond_slave_src_mac_map,
+ c->config->c_bond_slave_src_mac_type);
default:
SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
return NULL;
config.c_tx_hold = value;
if (value > 0) c->config->c_tx_hold = value;
break;
+ case lldpctl_k_config_bond_slave_src_mac_type:
+ config.c_bond_slave_src_mac_type = value;
+ c->config->c_bond_slave_src_mac_type = value;
+ break;
default:
SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST);
return NULL;
lldpctl_k_insert_cnt, /**< `(I)` insert cnt. Only works for a local port. */
lldpctl_k_delete_cnt, /**< `(I)` delete cnt. Only works for a local port. */
lldpctl_k_config_tx_hold, /**< `(I,WO)` Transmit hold interval. */
+ lldpctl_k_config_bond_slave_src_mac_type, /**< `(I,WO)` bond slave src mac type. */
} lldpctl_key_t;
/**
#define LLDPD_MODE_MAX LLDPD_MODE_FDP
+/* Bond slave src mac type constants */
+#define LLDP_BOND_SLAVE_SRC_MAC_TYPE_UNKNOWN 0
+#define LLDP_BOND_SLAVE_SRC_MAC_TYPE_REAL 1
+#define LLDP_BOND_SLAVE_SRC_MAC_TYPE_ZERO 2
+#define LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED 3
+#define LLDP_BOND_SLAVE_SRC_MAC_TYPE_MAX LLDP_BOND_SLAVE_SRC_MAC_TYPE_LOCALLY_ADMINISTERED
+
#endif /* _LLDP_H */
int c_tx_fast_interval; /* Time intr between sends during fast start */
#endif
int c_tx_hold; /* Transmit hold */
+ int c_bond_slave_src_mac_type; /* Src mac type in lldp frames over bond
+ slaves */
};
MARSHAL_BEGIN(lldpd_config)
MARSHAL_STR(lldpd_config, c_mgmt_pattern)