diff options
author | Rafael Zalamena <rzalamena@cvs.openbsd.org> | 2016-12-05 12:16:56 +0000 |
---|---|---|
committer | Rafael Zalamena <rzalamena@cvs.openbsd.org> | 2016-12-05 12:16:56 +0000 |
commit | 632dacc2a0844412ddc2fa88573801813a4e101f (patch) | |
tree | 3677e1968ca2c03bf0fc02e857b32358619d78f5 /sys | |
parent | d0f40a018c4575dafd5231c1865752d61fbd677f (diff) |
Propagate error type in validation functions that call
swofp_validate_action(), because actions have a different class of errors.
While there update the error type and error variables type to match the
swofp_send_error() prototype.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/switchofp.c | 82 |
1 files changed, 49 insertions, 33 deletions
diff --git a/sys/net/switchofp.c b/sys/net/switchofp.c index aab8239d877..3b1044b47d0 100644 --- a/sys/net/switchofp.c +++ b/sys/net/switchofp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: switchofp.c,v 1.45 2016/12/05 09:46:31 rzalamena Exp $ */ +/* $OpenBSD: switchofp.c,v 1.46 2016/12/05 12:16:55 rzalamena Exp $ */ /* * Copyright (c) 2016 Kazuya GODA <goda@openbsd.org> @@ -193,13 +193,13 @@ int swofp_group_entry_delete(struct switch_softc *, struct swofp_group_entry *); int swofp_group_entry_delete_all(struct switch_softc *); int swofp_validate_buckets(struct switch_softc *, struct mbuf *, uint8_t, - int *); + uint16_t *, uint16_t *); /* * Flow entry */ int swofp_flow_entry_put_instructions(struct mbuf *, - struct swofp_flow_entry *, int *error); + struct swofp_flow_entry *, uint16_t *, uint16_t *); void swofp_flow_entry_instruction_free(struct swofp_flow_entry *); void swofp_flow_entry_free(struct swofp_flow_entry **); void swofp_flow_entry_add(struct switch_softc *, struct swofp_flow_table *, @@ -217,11 +217,11 @@ int swofp_flow_filter_out_port(struct ofp_instruction_actions *, int swofp_flow_filter(struct swofp_flow_entry *, uint64_t, uint64_t, uint32_t, uint32_t); void swofp_flow_timeout(struct switch_softc *); -int swofp_validate_oxm(struct ofp_ox_match *, int *); -int swofp_validate_flow_match(struct ofp_match *, int *); +int swofp_validate_oxm(struct ofp_ox_match *, uint16_t *); +int swofp_validate_flow_match(struct ofp_match *, uint16_t *); int swofp_validate_flow_instruction(struct ofp_instruction *, size_t, - int *); -int swofp_validate_action(struct ofp_action_header *, size_t, int *); + uint16_t *, uint16_t *); +int swofp_validate_action(struct ofp_action_header *, size_t, uint16_t *); /* * OpenFlow protocol compare oxm @@ -1411,7 +1411,7 @@ swofp_group_entry_delete_all(struct switch_softc *sc) int swofp_validate_buckets(struct switch_softc *sc, struct mbuf *m, uint8_t type, - int *error) + uint16_t *etype, uint16_t *error) { struct ofp_group_mod *ogm; struct ofp_bucket *bucket; @@ -1420,6 +1420,8 @@ swofp_validate_buckets(struct switch_softc *sc, struct mbuf *m, uint8_t type, int start, len, off, num; size_t blen; + *etype = OFP_ERRTYPE_GROUP_MOD_FAILED; + ogm = mtod(m, struct ofp_group_mod *); start = offsetof(struct ofp_group_mod, gm_buckets); len = ntohs(ogm->gm_oh.oh_length) - start; @@ -1481,8 +1483,10 @@ swofp_validate_buckets(struct switch_softc *sc, struct mbuf *m, uint8_t type, ah = (struct ofp_action_header *) (mtod(m, caddr_t) + off + sizeof(*bucket)); - if (swofp_validate_action(ah, blen - sizeof(*bucket), error)) + if (swofp_validate_action(ah, blen - sizeof(*bucket), error)) { + *etype = OFP_ERRTYPE_BAD_ACTION; return (-1); + } } return (0); @@ -1882,7 +1886,7 @@ swofp_ox_cmp_ether_addr(struct ofp_ox_match *target, } int -swofp_validate_oxm(struct ofp_ox_match *oxm, int *err) +swofp_validate_oxm(struct ofp_ox_match *oxm, uint16_t *err) { struct ofp_oxm_class *handler; int length, hasmask; @@ -1908,7 +1912,7 @@ swofp_validate_oxm(struct ofp_ox_match *oxm, int *err) } int -swofp_validate_flow_match(struct ofp_match *om, int *err) +swofp_validate_flow_match(struct ofp_match *om, uint16_t *err) { struct ofp_ox_match *oxm; @@ -1930,12 +1934,14 @@ swofp_validate_flow_match(struct ofp_match *om, int *err) int swofp_validate_flow_instruction(struct ofp_instruction *oi, size_t total, - int *err) + uint16_t *etype, uint16_t *err) { struct ofp_action_header *oah; struct ofp_instruction_actions *oia; int ilen; + *etype = OFP_ERRTYPE_BAD_INSTRUCTION; + ilen = ntohs(oi->i_len); /* Check for bigger than packet or smaller than header. */ if (ilen > total || ilen < sizeof(*oi)) { @@ -1976,8 +1982,10 @@ swofp_validate_flow_instruction(struct ofp_instruction *oi, size_t total, /* Validate actions before iterating over them. */ oah = (struct ofp_action_header *) ((uint8_t *)oia + sizeof(*oia)); - if (swofp_validate_action(oah, ilen - sizeof(*oia), err)) + if (swofp_validate_action(oah, ilen - sizeof(*oia), err)) { + *etype = OFP_ERRTYPE_BAD_ACTION; return (-1); + } break; case OFP_INSTRUCTION_T_EXPERIMENTER: @@ -1991,7 +1999,8 @@ swofp_validate_flow_instruction(struct ofp_instruction *oi, size_t total, } int -swofp_validate_action(struct ofp_action_header *ah, size_t ahtotal, int *err) +swofp_validate_action(struct ofp_action_header *ah, size_t ahtotal, + uint16_t *err) { struct ofp_action_handler *oah; struct ofp_ox_match *oxm; @@ -4818,13 +4827,15 @@ swofp_send_flow_removed(struct switch_softc *sc, struct swofp_flow_entry *swfe, */ int swofp_flow_entry_put_instructions(struct mbuf *m, - struct swofp_flow_entry *swfe, int *error) + struct swofp_flow_entry *swfe, uint16_t *etype, uint16_t *error) { struct ofp_flow_mod *ofm; struct ofp_instruction *oi; caddr_t inst; int start, len, off; + *etype = OFP_ERRTYPE_BAD_INSTRUCTION; + ofm = mtod(m, struct ofp_flow_mod *); /* @@ -4840,7 +4851,7 @@ swofp_flow_entry_put_instructions(struct mbuf *m, oi = (struct ofp_instruction *)(mtod(m, caddr_t) + off); if (swofp_validate_flow_instruction(oi, - len - (off - start), error)) + len - (off - start), etype, error)) return (-1); if ((inst = malloc(ntohs(oi->i_len), M_DEVBUF, @@ -4924,9 +4935,10 @@ swofp_flow_mod_cmd_add(struct switch_softc *sc, struct mbuf *m) struct ofp_match *om; struct swofp_flow_entry *swfe, *old_swfe; struct swofp_flow_table *swft; - int error, omlen; - uint16_t etype = OFP_ERRTYPE_FLOW_MOD_FAILED; + int omlen; + uint16_t error, etype; + etype = OFP_ERRTYPE_FLOW_MOD_FAILED; oh = mtod(m, struct ofp_header *); ofm = mtod(m, struct ofp_flow_mod *); om = &ofm->fm_match; @@ -5008,10 +5020,8 @@ swofp_flow_mod_cmd_add(struct switch_softc *sc, struct mbuf *m) if (omlen == sizeof(*om) && swfe->swfe_priority == 0) swfe->swfe_tablemiss = 1; - if (swofp_flow_entry_put_instructions(m, swfe, &error)) { - etype = OFP_ERRTYPE_BAD_INSTRUCTION; + if (swofp_flow_entry_put_instructions(m, swfe, &etype, &error)) goto ofp_error_free_flow; - } if (old_swfe) { if (!(ntohs(ofm->fm_flags) & OFP_FLOWFLAG_RESET_COUNTS)) { @@ -5048,8 +5058,10 @@ swofp_flow_mod_cmd_common_modify(struct switch_softc *sc, struct mbuf *m, struct ofp_match *om; struct swofp_flow_entry *swfe; struct swofp_flow_table *swft; - int error, omlen; - uint16_t etype = OFP_ERRTYPE_FLOW_MOD_FAILED; + int omlen; + uint16_t error, etype; + + etype = OFP_ERRTYPE_FLOW_MOD_FAILED; oh = mtod(m, struct ofp_header *); ofm = mtod(m, struct ofp_flow_mod *); @@ -5102,7 +5114,8 @@ swofp_flow_mod_cmd_common_modify(struct switch_softc *sc, struct mbuf *m, ntohl(ofm->fm_out_group))) continue; - if (swofp_flow_entry_put_instructions(m, swfe, &error)) { + if (swofp_flow_entry_put_instructions(m, swfe, &etype, + &error)) { /* * If error occurs in swofp_flow_entry_put_instructions, * the flow entry might be half-way modified. So the @@ -5149,8 +5162,8 @@ swofp_flow_mod_cmd_common_delete(struct switch_softc *sc, struct mbuf *m, struct ofp_flow_mod *ofm; struct ofp_match *om; struct swofp_flow_table *swft; - int error, omlen; - uint16_t etype = OFP_ERRTYPE_FLOW_MOD_FAILED; + int omlen; + uint16_t error, etype = OFP_ERRTYPE_FLOW_MOD_FAILED; ofm = (struct ofp_flow_mod *)(mtod(m, caddr_t)); om = &ofm->fm_match; @@ -5241,8 +5254,9 @@ swofp_group_mod_add(struct switch_softc *sc, struct mbuf *m) struct swofp_ofs *ofs = sc->sc_ofs; struct ofp_group_mod *ogm; struct swofp_group_entry *swge; - int error; + uint16_t error, etype; + etype = OFP_ERRTYPE_GROUP_MOD_FAILED; ogm = mtod(m, struct ofp_group_mod *); if (ofs->swofs_group_table_num >= ofs->swofs_group_max_table) { @@ -5267,7 +5281,7 @@ swofp_group_mod_add(struct switch_softc *sc, struct mbuf *m) goto failed; } - if (swofp_validate_buckets(sc, m, ogm->gm_type, &error)) + if (swofp_validate_buckets(sc, m, ogm->gm_type, &etype, &error)) goto failed; if ((swge = malloc(sizeof(*swge), M_DEVBUF, M_NOWAIT|M_ZERO)) == NULL) { @@ -5299,7 +5313,7 @@ swofp_group_mod_add(struct switch_softc *sc, struct mbuf *m) return (0); failed: - swofp_send_error(sc, m, OFP_ERRTYPE_GROUP_MOD_FAILED, error); + swofp_send_error(sc, m, etype, error); return (0); } @@ -5308,9 +5322,10 @@ swofp_group_mod_modify(struct switch_softc *sc, struct mbuf *m) { struct ofp_group_mod *ogm; struct swofp_group_entry *swge; - int error; + uint16_t error, etype; uint32_t obucketlen; + etype = OFP_ERRTYPE_GROUP_MOD_FAILED; ogm = mtod(m, struct ofp_group_mod *); if (ogm->gm_type != OFP_GROUP_T_ALL) { @@ -5325,7 +5340,7 @@ swofp_group_mod_modify(struct switch_softc *sc, struct mbuf *m) goto failed; } - if (swofp_validate_buckets(sc, m, ogm->gm_type, &error)) + if (swofp_validate_buckets(sc, m, ogm->gm_type, &etype, &error)) goto failed; swge->swge_type = ogm->gm_type; @@ -5354,7 +5369,7 @@ swofp_group_mod_modify(struct switch_softc *sc, struct mbuf *m) m_freem(m); return (0); failed: - swofp_send_error(sc, m, OFP_ERRTYPE_GROUP_MOD_FAILED, error); + swofp_send_error(sc, m, etype, error); return (0); } @@ -5429,7 +5444,8 @@ swofp_recv_packet_out(struct switch_softc *sc, struct mbuf *m) struct ofp_packet_out *pout; struct ofp_action_header *ah; struct mbuf *mc = NULL, *mcn; - int al_start, al_len, off, error; + int al_start, al_len, off; + uint16_t error; struct switch_flow_classify swfcl = {}; struct swofp_pipline_desc swpld = { .swpld_swfcl = &swfcl }; |