summaryrefslogtreecommitdiff
path: root/usr.sbin/switchd
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@cvs.openbsd.org>2016-11-22 22:05:21 +0000
committerRafael Zalamena <rzalamena@cvs.openbsd.org>2016-11-22 22:05:21 +0000
commit60f489309783075082411f5548d78aa037e341a7 (patch)
tree5ef3d81103692ef3d18e367b1d1881b9ad22206e /usr.sbin/switchd
parentf8a68c8b40eefe73a7d123ebc7602228d772edc9 (diff)
Add "features request" support and reply validation.
ok reyk@
Diffstat (limited to 'usr.sbin/switchd')
-rw-r--r--usr.sbin/switchd/ofp10.c79
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);
}