This diff teaches switchd(8) how to send the set_config message for
OpenFlow 1.3.5. We need this to set the default miss_send_len to
a value greater than zero so we can receive packets from the switch(4)
with the payload.

ok?


Index: ofp13.c
===================================================================
RCS file: /home/obsdcvs/src/usr.sbin/switchd/ofp13.c,v
retrieving revision 1.19
diff -u -p -r1.19 ofp13.c
--- ofp13.c     7 Oct 2016 08:49:53 -0000       1.19
+++ ofp13.c     12 Oct 2016 12:47:40 -0000
@@ -99,6 +99,12 @@ struct ofp_group_mod *
 struct ofp_bucket *
            ofp13_bucket(struct ibuf *, uint16_t, uint32_t, uint32_t);
 
+int     ofp13_setconfig_validate(struct switchd *,
+           struct sockaddr_storage *, struct sockaddr_storage *,
+           struct ofp_header *, struct ibuf *);
+int     ofp13_setconfig(struct switchd *, struct switch_connection *,
+           uint16_t, uint16_t);
+
 struct ofp_callback ofp13_callbacks[] = {
        { OFP_T_HELLO,                  ofp13_hello, NULL },
        { OFP_T_ERROR,                  NULL, ofp13_validate_error },
@@ -109,7 +115,7 @@ struct ofp_callback ofp13_callbacks[] = 
        { OFP_T_FEATURES_REPLY,         NULL, NULL },
        { OFP_T_GET_CONFIG_REQUEST,     NULL, NULL },
        { OFP_T_GET_CONFIG_REPLY,       NULL, NULL },
-       { OFP_T_SET_CONFIG,             NULL, NULL },
+       { OFP_T_SET_CONFIG,             NULL, ofp13_setconfig_validate },
        { OFP_T_PACKET_IN,              ofp13_packet_in,
                                        ofp13_validate_packet_in },
        { OFP_T_FLOW_REMOVED,           ofp13_flow_removed, NULL },
@@ -585,6 +591,8 @@ ofp13_hello(struct switchd *sc, struct s
            OFP_TABLE_ID_ALL);
        ofp13_table_features(sc, con, 0);
        ofp13_desc(sc, con);
+       ofp13_setconfig(sc, con, OFP_CONFIG_FRAG_REASM,
+           OFP_CONTROLLER_MAXLEN_NO_BUFFER);
 
        return (0);
 }
@@ -1461,4 +1469,48 @@ ofp13_bucket(struct ibuf *ibuf, uint16_t
        b->b_watch_port = htonl(watchport);
        b->b_watch_group = htonl(watchgroup);
        return (b);
+}
+
+int
+ofp13_setconfig_validate(struct switchd *sc,
+    struct sockaddr_storage *src, struct sockaddr_storage *dst,
+    struct ofp_header *oh, struct ibuf *ibuf)
+{
+       struct ofp_switch_config        *cfg;
+
+       if ((cfg = ibuf_seek(ibuf, 0, sizeof(*cfg))) == NULL)
+               return (-1);
+
+       log_debug("\tflags %#04x miss_send_len %d",
+           ntohs(cfg->cfg_flags), ntohs(cfg->cfg_miss_send_len));
+       return (0);
+}
+
+int
+ofp13_setconfig(struct switchd *sc, struct switch_connection *con,
+     uint16_t flags, uint16_t misslen)
+{
+       struct ibuf                     *ibuf;
+       struct ofp_switch_config        *cfg;
+       struct ofp_header               *oh;
+       int                              rv;
+
+       if ((ibuf = ibuf_static()) == NULL ||
+           (cfg = ibuf_advance(ibuf, sizeof(*cfg))) == NULL)
+               return (-1);
+
+       cfg->cfg_flags = htons(flags);
+       cfg->cfg_miss_send_len = htons(misslen);
+
+       oh = &cfg->cfg_oh;
+       oh->oh_version = OFP_V_1_3;
+       oh->oh_type = OFP_T_SET_CONFIG;
+       oh->oh_length = htons(ibuf_length(ibuf));
+       oh->oh_xid = htonl(con->con_xidnxt++);
+       if (ofp13_validate(sc, &con->con_local, &con->con_peer, oh, ibuf) != 0)
+               return (-1);
+
+       rv = ofp_output(con, NULL, ibuf);
+       ibuf_free(ibuf);
+       return (rv);
 }

Reply via email to