diff options
author | akoshibe <akoshibe@cvs.openbsd.org> | 2019-11-27 17:37:33 +0000 |
---|---|---|
committer | akoshibe <akoshibe@cvs.openbsd.org> | 2019-11-27 17:37:33 +0000 |
commit | 009ad2bc01a6adf57f7d7db01a16a67babc5485a (patch) | |
tree | 22086f40f1127536cc6bfd5aba220bccd53247a2 /sys/net | |
parent | ef9bd43e529c1cca474c19812253e58b17eef098 (diff) |
OpenFlow 1.3 defines packet header patterns of interest using TLVs (OXMs)
that represent various header fields. One place where OXMs are used is in
the sef_field action, which contains one OXM representing the header field
to set, followed by padding to align the action in the OpenFlow message to
64 bits. Currently, we assume that a set_field action can contain multiple
OXMs and that they do not need to be padded.
This matches the way we handle OpenFlow messages that contain set_field
actions so that we follow the specs.
OK ori claudio
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/switchofp.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/sys/net/switchofp.c b/sys/net/switchofp.c index f2a34be7add..587a9c99d38 100644 --- a/sys/net/switchofp.c +++ b/sys/net/switchofp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: switchofp.c,v 1.75 2019/11/21 17:24:15 akoshibe Exp $ */ +/* $OpenBSD: switchofp.c,v 1.76 2019/11/27 17:37:32 akoshibe Exp $ */ /* * Copyright (c) 2016 Kazuya GODA <goda@openbsd.org> @@ -2174,7 +2174,8 @@ swofp_validate_action(struct switch_softc *sc, struct ofp_action_header *ah, } break; case OFP_ACTION_SET_FIELD: - if (ahlen < sizeof(struct ofp_action_set_field)) { + if (ahlen < sizeof(struct ofp_action_set_field) || + ahlen != OFP_ALIGN(ahlen)) { *err = OFP_ERRACTION_LEN; return (-1); } @@ -2189,22 +2190,37 @@ swofp_validate_action(struct switch_softc *sc, struct ofp_action_header *ah, dptr = (uint8_t *)ah; dptr += sizeof(struct ofp_action_set_field) - offsetof(struct ofp_action_set_field, asf_field); - while (oxmlen > 0) { - oxm = (struct ofp_ox_match *)dptr; - if (swofp_validate_oxm(oxm, err)) { - if (*err == OFP_ERRMATCH_BAD_LEN) - *err = OFP_ERRACTION_SET_LEN; - else - *err = OFP_ERRACTION_SET_TYPE; + oxm = (struct ofp_ox_match *)dptr; + oxmlen -= sizeof(struct ofp_ox_match); + if (oxmlen < oxm->oxm_length) { + *err = OFP_ERRACTION_SET_LEN; + return (-1); + } + /* Remainder is padding. */ + oxmlen -= oxm->oxm_length; + if (oxmlen >= OFP_ALIGNMENT) { + *err = OFP_ERRACTION_SET_LEN; + return (-1); + } + if (swofp_validate_oxm(oxm, err)) { + if (*err == OFP_ERRMATCH_BAD_LEN) + *err = OFP_ERRACTION_SET_LEN; + else + *err = OFP_ERRACTION_SET_TYPE; + return (-1); + } + + dptr += sizeof(struct ofp_ox_match) + oxm->oxm_length; + while (oxmlen > 0) { + if (*dptr != 0) { + *err = OFP_ERRACTION_SET_ARGUMENT; return (-1); } - - dptr += sizeof(*oxm) + oxm->oxm_length; - oxmlen -= sizeof(*oxm) + oxm->oxm_length; + oxmlen--; + dptr++; } break; - default: /* Unknown/unsupported action. */ *err = OFP_ERRACTION_TYPE; |