add sad_process_auth() to bc_event() to check for authentication tlvs on incoming messages. This processing happens after msg_post_recv(). However, if security is active, a duplicate message is allocated and kept in network byte order to be used for icv calculation.
The standard proposes a security parameters database (SPD) to specify policy limiting attributes as to which messages should authenticated but this is a lot of overhead for a something that isn't too helpful. For this patch, the only policy limiting attribute is the port. That is to say, you can specify a spp (and corresponding Security Association) for each port. When spp is set to -1 (default), no security processing is done. Signed-off-by: Clay Kaiser <clay.kai...@ibm.com> --- config.c | 1 + msg.c | 4 ++++ msg.h | 3 ++- port.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- port_private.h | 1 + 5 files changed, 57 insertions(+), 2 deletions(-) diff --git a/config.c b/config.c index 8150dc7..c483920 100644 --- a/config.c +++ b/config.c @@ -364,6 +364,7 @@ struct config_item config_tab[] = { GLOB_ITEM_INT("utc_offset", CURRENT_UTC_OFFSET, 0, INT_MAX), GLOB_ITEM_INT("verbose", 0, 0, 1), GLOB_ITEM_INT("write_phase_mode", 0, 0, 1), + PORT_ITEM_INT("spp", -1, -1, UINT8_MAX), GLOB_ITEM_STR("sa_file", NULL), }; diff --git a/msg.c b/msg.c index ab841f0..c82a5cb 100644 --- a/msg.c +++ b/msg.c @@ -307,6 +307,10 @@ struct ptp_message *msg_duplicate(struct ptp_message *msg, int cnt) dup->refcnt = 1; TAILQ_INIT(&dup->tlv_list); + if (!cnt) { + return dup; + } + err = msg_post_recv(dup, cnt); if (err) { switch (err) { diff --git a/msg.h b/msg.h index 484435d..044b92b 100644 --- a/msg.h +++ b/msg.h @@ -366,7 +366,8 @@ void msg_cleanup(void); * @param msg A message obtained using @ref msg_allocate(). * The passed message must be in network byte order, not * having been passed to @ref msg_post_recv(). - * + * @param cnt The size of 'msg' in bytes. set to zero when + * @ref msg_post_recv() is not required (icv calculation) * @return Pointer to a message on success, NULL otherwise. * The returned message will be in host byte order, having * been passed to @ref msg_post_recv(). diff --git a/port.c b/port.c index 5803cd3..82ef73f 100644 --- a/port.c +++ b/port.c @@ -36,6 +36,7 @@ #include "port_private.h" #include "print.h" #include "rtnl.h" +#include "sad.h" #include "sk.h" #include "tc.h" #include "tlv.h" @@ -57,6 +58,7 @@ enum syfu_event { static int port_is_ieee8021as(struct port *p); static int port_is_uds(struct port *p); +static int port_has_security(struct port *p); static void port_nrate_initialize(struct port *p); static int announce_compare(struct ptp_message *m1, struct ptp_message *m2) @@ -862,6 +864,11 @@ static int port_is_uds(struct port *p) return transport_type(p->trp) == TRANS_UDS; } +static int port_has_security(struct port *p) +{ + return p->spp < 0 ? 0 : 1; +} + static void port_management_send_error(struct port *p, struct port *ingress, struct ptp_message *msg, int error_id) { @@ -2844,7 +2851,7 @@ enum fsm_event port_event(struct port *p, int fd_index) static enum fsm_event bc_event(struct port *p, int fd_index) { enum fsm_event event = EV_NONE; - struct ptp_message *msg; + struct ptp_message *msg, *dup = NULL; int cnt, fd = p->fda.fd[fd_index], err; switch (fd_index) { @@ -2961,6 +2968,13 @@ static enum fsm_event bc_event(struct port *p, int fd_index) msg_put(msg); return EV_FAULT_DETECTED; } + if (port_has_security(p)) { + dup = msg_duplicate(msg, 0); + if (!dup) { + msg_put(msg); + return EV_NONE; + } + } err = msg_post_recv(msg, cnt); if (err) { switch (err) { @@ -2972,11 +2986,17 @@ static enum fsm_event bc_event(struct port *p, int fd_index) break; } msg_put(msg); + if (dup) { + msg_put(dup); + } return EV_NONE; } port_stats_inc_rx(p, msg); if (port_ignore(p, msg)) { msg_put(msg); + if (dup) { + msg_put(dup); + } return EV_NONE; } if (msg_sots_missing(msg) && @@ -2984,6 +3004,25 @@ static enum fsm_event bc_event(struct port *p, int fd_index) pr_err("%s: received %s without timestamp", p->log_name, msg_type_string(msg_type(msg))); msg_put(msg); + if (dup) { + msg_put(dup); + } + return EV_NONE; + } + err = sad_process_auth(clock_config(p->clock), p->spp, msg, dup); + if (err) { + switch (err) { + case -EBADMSG: + pr_err("%s: bad message", p->log_name); + break; + case -EPROTO: + pr_debug("%s: ignoring message", p->log_name); + break; + } + msg_put(msg); + if (dup) { + msg_put(dup); + } return EV_NONE; } if (msg_sots_valid(msg)) { @@ -3035,6 +3074,9 @@ static enum fsm_event bc_event(struct port *p, int fd_index) } msg_put(msg); + if (dup) { + msg_put(dup); + } return event; } @@ -3405,6 +3447,7 @@ struct port *port_open(const char *phc_device, p->pwr.totalTimeInaccuracy = config_get_int(cfg, p->name, "power_profile.2017.totalTimeInaccuracy"); p->slave_event_monitor = clock_slave_monitor(clock); + p->spp = config_get_int(cfg, p->name, "spp"); if (!port_is_uds(p) && unicast_client_initialize(p)) { goto err_transport; @@ -3434,6 +3477,11 @@ struct port *port_open(const char *phc_device, if (p->net_sync_monitor && !p->hybrid_e2e) { pr_warning("%s: net_sync_monitor needs hybrid_e2e", p->log_name); } + if (port_has_security(p) && (p->timestamping == TS_ONESTEP || + p->timestamping == TS_P2P1STEP)) { + pr_err("%s: spp not supported on one step ports", p->log_name); + p->spp = -1; + } /* Set fault timeouts to a default value */ for (i = 0; i < FT_CNT; i++) { diff --git a/port_private.h b/port_private.h index 3b02d2f..8ef9593 100644 --- a/port_private.h +++ b/port_private.h @@ -164,6 +164,7 @@ struct port { /* slave event monitoring */ struct monitor *slave_event_monitor; bool unicast_state_dirty; + int spp; }; #define portnum(p) (p->portIdentity.portNumber) -- 2.42.1 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel