unicast: Enable sharing master tables between ports.
Don't require each port to have its own master table specified in the config. Instead of ports claming configured tables, clone the table in each port, so different ports don't interfere with each other. Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>master
parent
581a6bd59b
commit
ee6930a884
17
port.c
17
port.c
|
@ -2311,6 +2311,7 @@ void port_close(struct port *p)
|
|||
rtnl_close(p->fda.fd[FD_RTNL]);
|
||||
}
|
||||
|
||||
unicast_client_cleanup(p);
|
||||
unicast_service_cleanup(p);
|
||||
transport_destroy(p->trp);
|
||||
tsproc_destroy(p->tsproc);
|
||||
|
@ -3039,25 +3040,25 @@ struct port *port_open(const char *phc_device,
|
|||
p->delayMechanism = config_get_int(cfg, p->name, "delay_mechanism");
|
||||
p->versionNumber = PTP_VERSION;
|
||||
|
||||
if (number && unicast_client_claim_table(p)) {
|
||||
if (number && unicast_client_initialize(p)) {
|
||||
goto err_transport;
|
||||
}
|
||||
if (unicast_client_enabled(p) &&
|
||||
config_set_section_int(cfg, p->name, "hybrid_e2e", 1)) {
|
||||
goto err_transport;
|
||||
goto err_uc_client;
|
||||
}
|
||||
if (number && unicast_service_initialize(p)) {
|
||||
goto err_transport;
|
||||
goto err_uc_client;
|
||||
}
|
||||
p->hybrid_e2e = config_get_int(cfg, p->name, "hybrid_e2e");
|
||||
|
||||
if (number && type == CLOCK_TYPE_P2P && p->delayMechanism != DM_P2P) {
|
||||
pr_err("port %d: P2P TC needs P2P ports", number);
|
||||
goto err_transport;
|
||||
goto err_uc_service;
|
||||
}
|
||||
if (number && type == CLOCK_TYPE_E2E && p->delayMechanism != DM_E2E) {
|
||||
pr_err("port %d: E2E TC needs E2E ports", number);
|
||||
goto err_transport;
|
||||
goto err_uc_service;
|
||||
}
|
||||
if (p->hybrid_e2e && p->delayMechanism != DM_E2E) {
|
||||
pr_warning("port %d: hybrid_e2e only works with E2E", number);
|
||||
|
@ -3083,7 +3084,7 @@ struct port *port_open(const char *phc_device,
|
|||
config_get_int(cfg, p->name, "delay_filter_length"));
|
||||
if (!p->tsproc) {
|
||||
pr_err("Failed to create time stamp processor");
|
||||
goto err_transport;
|
||||
goto err_uc_service;
|
||||
}
|
||||
p->nrate.ratio = 1.0;
|
||||
|
||||
|
@ -3100,6 +3101,10 @@ struct port *port_open(const char *phc_device,
|
|||
|
||||
err_tsproc:
|
||||
tsproc_destroy(p->tsproc);
|
||||
err_uc_service:
|
||||
unicast_service_cleanup(p);
|
||||
err_uc_client:
|
||||
unicast_client_cleanup(p);
|
||||
err_transport:
|
||||
transport_destroy(p->trp);
|
||||
err_port:
|
||||
|
|
4
ptp4l.8
4
ptp4l.8
|
@ -275,9 +275,7 @@ The default is 0 (disabled).
|
|||
When set to a positive integer, this option specifies the table id to
|
||||
be used for unicast discovery. Each table lives in its own section
|
||||
and has a unique, positive numerical ID. Entries in the table are a
|
||||
pair of transport type and protocol address. Tables may not be shared
|
||||
between ports, but nothing prevents table entries from appearing in
|
||||
more than table.
|
||||
pair of transport type and protocol address.
|
||||
The default is 0 (unicast discovery disabled).
|
||||
.TP
|
||||
.B unicast_req_duration
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "port.h"
|
||||
#include "port_private.h"
|
||||
#include "print.h"
|
||||
|
@ -250,6 +252,45 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
static void free_master_table(struct unicast_master_table *table)
|
||||
{
|
||||
struct unicast_master_address *address;
|
||||
|
||||
while ((address = STAILQ_FIRST(&table->addrs))) {
|
||||
STAILQ_REMOVE_HEAD(&table->addrs, list);
|
||||
free(address);
|
||||
}
|
||||
free(table->peer_name);
|
||||
free(table);
|
||||
}
|
||||
|
||||
static struct unicast_master_table *
|
||||
clone_master_table(struct unicast_master_table *table)
|
||||
{
|
||||
struct unicast_master_address *address, *cloned_address;
|
||||
struct unicast_master_table *cloned_table;
|
||||
|
||||
cloned_table = malloc(sizeof(*cloned_table));
|
||||
if (!cloned_table)
|
||||
return NULL;
|
||||
*cloned_table = *table;
|
||||
STAILQ_INIT(&cloned_table->addrs);
|
||||
memset(&cloned_table->list, 0, sizeof(cloned_table->list));
|
||||
if (table->peer_name)
|
||||
cloned_table->peer_name = strdup(table->peer_name);
|
||||
|
||||
STAILQ_FOREACH(address, &table->addrs, list) {
|
||||
cloned_address = malloc(sizeof(*cloned_address));
|
||||
if (!cloned_address) {
|
||||
free_master_table(cloned_table);
|
||||
return NULL;
|
||||
}
|
||||
*cloned_address = *address;
|
||||
STAILQ_INSERT_TAIL(&cloned_table->addrs, cloned_address, list);
|
||||
}
|
||||
return cloned_table;
|
||||
}
|
||||
|
||||
/* public methods */
|
||||
|
||||
int unicast_client_cancel(struct port *p, struct ptp_message *m,
|
||||
|
@ -302,7 +343,7 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
int unicast_client_claim_table(struct port *p)
|
||||
int unicast_client_initialize(struct port *p)
|
||||
{
|
||||
struct unicast_master_address *master, *peer;
|
||||
struct config *cfg = clock_config(p->clock);
|
||||
|
@ -322,9 +363,9 @@ int unicast_client_claim_table(struct port *p)
|
|||
pr_err("port %d: no table with id %d", portnum(p), table_id);
|
||||
return -1;
|
||||
}
|
||||
if (table->port) {
|
||||
pr_err("port %d: table %d already claimed by port %d",
|
||||
portnum(p), table_id, table->port);
|
||||
table = clone_master_table(table);
|
||||
if (!table) {
|
||||
pr_err("low memory");
|
||||
return -1;
|
||||
}
|
||||
peer = &table->peer_addr;
|
||||
|
@ -332,6 +373,7 @@ int unicast_client_claim_table(struct port *p)
|
|||
table->peer_name, &peer->address)) {
|
||||
pr_err("port %d: bad peer address: %s",
|
||||
portnum(p), table->peer_name);
|
||||
free_master_table(table);
|
||||
return -1;
|
||||
}
|
||||
STAILQ_FOREACH(master, &table->addrs, list) {
|
||||
|
@ -352,6 +394,12 @@ int unicast_client_claim_table(struct port *p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void unicast_client_cleanup(struct port *p)
|
||||
{
|
||||
if (p->unicast_master_table)
|
||||
free_master_table(p->unicast_master_table);
|
||||
}
|
||||
|
||||
int unicast_client_enabled(struct port *p)
|
||||
{
|
||||
return p->unicast_master_table ? 1 : 0;
|
||||
|
|
|
@ -37,7 +37,13 @@ int unicast_client_cancel(struct port *p, struct ptp_message *m,
|
|||
* @param port The port in question.
|
||||
* @return Zero on success, non-zero otherwise.
|
||||
*/
|
||||
int unicast_client_claim_table(struct port *port);
|
||||
int unicast_client_initialize(struct port *port);
|
||||
|
||||
/**
|
||||
* Frees all of the resources associated with a port's unicast client.
|
||||
* @param p The port in question.
|
||||
*/
|
||||
void unicast_client_cleanup(struct port *p);
|
||||
|
||||
/**
|
||||
* Tests whether a unicast master table is associated with a given port.
|
||||
|
|
Loading…
Reference in New Issue