diff options
author | Rafael Zalamena <rzalamena@cvs.openbsd.org> | 2016-11-22 22:05:21 +0000 |
---|---|---|
committer | Rafael Zalamena <rzalamena@cvs.openbsd.org> | 2016-11-22 22:05:21 +0000 |
commit | 60f489309783075082411f5548d78aa037e341a7 (patch) | |
tree | 5ef3d81103692ef3d18e367b1d1881b9ad22206e /usr.sbin/switchd | |
parent | f8a68c8b40eefe73a7d123ebc7602228d772edc9 (diff) |
Add "features request" support and reply validation.
ok reyk@
Diffstat (limited to 'usr.sbin/switchd')
-rw-r--r-- | usr.sbin/switchd/ofp10.c | 79 |
1 files changed, 66 insertions, 13 deletions
diff --git a/usr.sbin/switchd/ofp10.c b/usr.sbin/switchd/ofp10.c index c990442f596..1db598d69a1 100644 --- a/usr.sbin/switchd/ofp10.c +++ b/usr.sbin/switchd/ofp10.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofp10.c,v 1.17 2016/11/22 17:21:56 rzalamena Exp $ */ +/* $OpenBSD: ofp10.c,v 1.18 2016/11/22 22:05:20 rzalamena Exp $ */ /* * Copyright (c) 2013-2016 Reyk Floeter <reyk@openbsd.org> @@ -43,6 +43,11 @@ int ofp10_packet_match(struct packet *, struct ofp10_match *, unsigned int); +int ofp10_features_reply(struct switchd *, struct switch_connection *, + struct ofp_header *, struct ibuf *); +int ofp10_validate_features_reply(struct switchd *, + struct sockaddr_storage *, struct sockaddr_storage *, + struct ofp_header *, struct ibuf *); int ofp10_echo_request(struct switchd *, struct switch_connection *, struct ofp_header *, struct ibuf *); int ofp10_validate_error(struct switchd *, @@ -66,7 +71,8 @@ struct ofp_callback ofp10_callbacks[] = { { OFP10_T_ECHO_REPLY, NULL, NULL }, { OFP10_T_EXPERIMENTER, NULL, NULL }, { OFP10_T_FEATURES_REQUEST, NULL, NULL }, - { OFP10_T_FEATURES_REPLY, NULL, NULL }, + { OFP10_T_FEATURES_REPLY, ofp10_features_reply, + ofp10_validate_features_reply }, { OFP10_T_GET_CONFIG_REQUEST, NULL, NULL }, { OFP10_T_GET_CONFIG_REPLY, NULL, NULL }, { OFP10_T_SET_CONFIG, NULL, NULL }, @@ -265,17 +271,64 @@ ofp10_hello(struct switchd *sc, struct switch_connection *con, if (ofp_recv_hello(sc, con, oh, ibuf) == -1) return (-1); -#if 0 - (void)write(fd, &oh, sizeof(oh)); - ofd_debug(sc, &sname, &con->con_ss, &oh, buf, len); - oh.oh_xid = htonl(1); - oh.oh_type = OFP10_T_FEATURES_REQUEST; - (void)write(fd, &oh, sizeof(oh)); - ofd_debug(sc, &sname, &con->con_ss, &oh, buf, len); - oh.oh_xid = htonl(2); - oh.oh_type = OFP10_T_GET_CONFIG_REQUEST; - (void)write(fd, &oh, sizeof(oh)); -#endif + oh->oh_type = OFP10_T_FEATURES_REQUEST; + oh->oh_length = htons(sizeof(*oh)); + oh->oh_xid = htonl(con->con_xidnxt++); + if (ofp10_validate(sc, &con->con_local, &con->con_peer, oh, NULL) != 0) + return (-1); + + return (ofp_output(con, oh, NULL)); +} + +int +ofp10_features_reply(struct switchd *sc, struct switch_connection *con, + struct ofp_header *oh, struct ibuf *ibuf) +{ + /* Nothing yet. */ + return (0); +} + +int +ofp10_validate_features_reply(struct switchd *sc, + struct sockaddr_storage *src, struct sockaddr_storage *dst, + struct ofp_header *oh, struct ibuf *ibuf) +{ + struct ofp_switch_features *swf; + struct ofp10_phy_port *swp; + off_t poff; + int portslen; + char *mac; + + if ((swf = ibuf_seek(ibuf, 0, sizeof(*swf))) == NULL) + return (-1); + + log_debug("\tdatapath_id %#016llx nbuffers %u ntables %d " + "capabilities %#08x actions %#08x", + be64toh(swf->swf_datapath_id), ntohl(swf->swf_nbuffers), + swf->swf_ntables, ntohl(swf->swf_capabilities), + ntohl(swf->swf_actions)); + + poff = sizeof(*swf); + portslen = ntohs(oh->oh_length) - sizeof(*swf); + if (portslen <= 0) + return (0); + + while (portslen > 0) { + if ((swp = ibuf_seek(ibuf, poff, sizeof(*swp))) == NULL) + return (-1); + + mac = ether_ntoa((void *)swp->swp_macaddr); + log_debug("no %s macaddr %s name %s config %#08x state %#08x " + "cur %#08x advertised %#08x supported %#08x peer %#08x", + print_map(ntohs(swp->swp_number), ofp10_port_map), mac, + swp->swp_name, swp->swp_config, swp->swp_state, + swp->swp_cur, swp->swp_advertised, swp->swp_supported, + swp->swp_peer); + + portslen -= sizeof(*swp); + poff += sizeof(*swp); + } + return (0); } |