diff options
author | Ethan Jackson <ethan@nicira.com> | 2011-04-05 12:37:52 -0700 |
---|---|---|
committer | Ethan Jackson <ethan@nicira.com> | 2011-04-11 15:56:20 -0700 |
commit | 3b6a2571f07e153e850a9bf2044699d8d4434ef0 (patch) | |
tree | f7d918e850be52bafff360cceddcd683971ec8c1 /lib | |
parent | 141d9ce465b9722fb9321c3d102238dd33507d79 (diff) |
autopath: Create the autopath action.
The newly created autopath action will be the way OpenFlow
interacts with the existing bonding infrastructure.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/automake.mk | 2 | ||||
-rw-r--r-- | lib/autopath.c | 110 | ||||
-rw-r--r-- | lib/autopath.h | 34 | ||||
-rw-r--r-- | lib/ofp-parse.c | 5 | ||||
-rw-r--r-- | lib/ofp-print.c | 11 | ||||
-rw-r--r-- | lib/ofp-util.c | 9 |
6 files changed, 171 insertions, 0 deletions
diff --git a/lib/automake.mk b/lib/automake.mk index ffebefa5..802cc992 100644 --- a/lib/automake.mk +++ b/lib/automake.mk @@ -10,6 +10,8 @@ noinst_LIBRARIES += lib/libopenvswitch.a lib_libopenvswitch_a_SOURCES = \ lib/aes128.c \ lib/aes128.h \ + lib/autopath.c \ + lib/autopath.h \ lib/backtrace.c \ lib/backtrace.h \ lib/bitmap.c \ diff --git a/lib/autopath.c b/lib/autopath.c new file mode 100644 index 00000000..889b037b --- /dev/null +++ b/lib/autopath.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011 Nicira Networks. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <config.h> + +#include "autopath.h" + +#include <inttypes.h> +#include <stdlib.h> + +#include "flow.h" +#include "nx-match.h" +#include "ofp-util.h" +#include "openflow/nicira-ext.h" +#include "vlog.h" + +VLOG_DEFINE_THIS_MODULE(autopath); + +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + +/* Loads 'ofp_port' into the appropriate register in accordance with the + * autopath action. */ +void +autopath_execute(const struct nx_action_autopath *ap, struct flow *flow, + uint16_t ofp_port) +{ + uint32_t *reg = &flow->regs[NXM_NX_REG_IDX(ntohl(ap->dst))]; + int ofs = nxm_decode_ofs(ap->ofs_nbits); + int n_bits = nxm_decode_n_bits(ap->ofs_nbits); + uint32_t mask = n_bits == 32 ? UINT32_MAX : (UINT32_C(1) << n_bits) - 1; + *reg = (*reg & ~(mask << ofs)) | ((ofp_port & mask) << ofs); +} + +void +autopath_parse(struct nx_action_autopath *ap, const char *s_) +{ + char *s; + uint32_t reg; + int id_int, ofs, n_bits; + char *id_str, *dst, *save_ptr; + + s = xstrdup(s_); + save_ptr = NULL; + id_str = strtok_r(s, ", ", &save_ptr); + dst = strtok_r(NULL, ", ", &save_ptr); + + if (!dst) { + ovs_fatal(0, "%s: not enough arguments to autopath action", s_); + } + + id_int = atoi(id_str); + if (id_int < 1 || id_int > UINT32_MAX) { + ovs_fatal(0, "%s: autopath id %d is not in valid range " + "1 to %"PRIu32, s_, id_int, UINT32_MAX); + } + + nxm_parse_field_bits(dst, ®, &ofs, &n_bits); + if (!NXM_IS_NX_REG(reg) || NXM_NX_REG_IDX(reg) >= FLOW_N_REGS) { + ovs_fatal(0, "%s: destination field must be a register", s_); + } + + if (n_bits < 16) { + ovs_fatal(0, "%s: %d-bit destination field has %u possible values, " + "less than required 65536", s_, n_bits, 1u << n_bits); + } + + memset(ap, 0, sizeof *ap); + ap->type = htons(OFPAT_VENDOR); + ap->len = htons(sizeof *ap); + ap->vendor = htonl(NX_VENDOR_ID); + ap->subtype = htons(NXAST_AUTOPATH); + ap->id = htonl(id_int); + ap->ofs_nbits = nxm_encode_ofs_nbits(ofs, n_bits); + ap->dst = htonl(reg); + + free(s); +} + +int +autopath_check(const struct nx_action_autopath *ap) +{ + uint32_t dst = ntohl(ap->dst); + int ofs = nxm_decode_ofs(ap->ofs_nbits); + int n_bits = nxm_decode_n_bits(ap->ofs_nbits); + + if (!NXM_IS_NX_REG(dst) || NXM_NX_REG_IDX(dst) >= FLOW_N_REGS) { + VLOG_WARN_RL(&rl, "unsupported destination field %#"PRIx32, dst); + } else if (ofs + n_bits > nxm_field_bits(dst)) { + VLOG_WARN_RL(&rl, "destination overflows output field"); + } else if (n_bits < 16) { + VLOG_WARN_RL(&rl, "minimum of 16 bits required in output field"); + } else { + return 0; + } + + return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_BAD_ARGUMENT); +} diff --git a/lib/autopath.h b/lib/autopath.h new file mode 100644 index 00000000..ba55f90d --- /dev/null +++ b/lib/autopath.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2011 Nicira Networks. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AUTOPATH_H +#define AUTOPATH_H 1 + +#include <stdint.h> + +struct flow; +struct nx_action_autopath; + +/* NXAST_AUTOPATH helper functions. + * + * See include/openflow/nicira-ext.h for NXAST_AUTOPATH specification. */ + +void autopath_execute(const struct nx_action_autopath *, struct flow *, + uint16_t ofp_port); +void autopath_parse(struct nx_action_autopath *, const char *); +int autopath_check(const struct nx_action_autopath *); + +#endif /* autopath.h */ diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index de7cd9c7..4c4811b6 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -22,6 +22,7 @@ #include <errno.h> #include <stdlib.h> +#include "autopath.h" #include "byte-order.h" #include "dynamic-string.h" #include "netdev.h" @@ -453,6 +454,10 @@ str_to_action(char *str, struct ofpbuf *b) struct nx_action_multipath *nam; nam = ofpbuf_put_uninit(b, sizeof *nam); multipath_parse(nam, arg); + } else if (!strcasecmp(act, "autopath")) { + struct nx_action_autopath *naa; + naa = ofpbuf_put_uninit(b, sizeof *naa); + autopath_parse(naa, arg); } else if (!strcasecmp(act, "output")) { put_output_action(b, str_to_u32(arg)); } else if (!strcasecmp(act, "enqueue")) { diff --git a/lib/ofp-print.c b/lib/ofp-print.c index 1cd94626..f5eb9ad0 100644 --- a/lib/ofp-print.c +++ b/lib/ofp-print.c @@ -219,6 +219,7 @@ nx_action_len(enum nx_action_subtype subtype) case NXAST_NOTE: return -1; case NXAST_SET_TUNNEL64: return sizeof(struct nx_action_set_tunnel64); case NXAST_MULTIPATH: return sizeof(struct nx_action_multipath); + case NXAST_AUTOPATH: return sizeof (struct nx_action_autopath); default: return -1; } } @@ -244,6 +245,7 @@ ofp_print_nx_action(struct ds *string, const struct nx_action_header *nah) const struct nx_action_reg_move *move; const struct nx_action_reg_load *load; const struct nx_action_multipath *nam; + const struct nx_action_autopath *naa; switch ((enum nx_action_subtype) subtype) { case NXAST_RESUBMIT: @@ -295,6 +297,15 @@ ofp_print_nx_action(struct ds *string, const struct nx_action_header *nah) multipath_format(nam, string); return; + case NXAST_AUTOPATH: + naa = (const struct nx_action_autopath *)nah; + ds_put_format(string, "autopath(%u,", ntohl(naa->id)); + nxm_format_field_bits(string, ntohl(naa->dst), + nxm_decode_ofs(naa->ofs_nbits), + nxm_decode_n_bits(naa->ofs_nbits)); + ds_put_char(string, ')'); + return; + case NXAST_SNAT__OBSOLETE: default: break; diff --git a/lib/ofp-util.c b/lib/ofp-util.c index cc448bcd..c49b0798 100644 --- a/lib/ofp-util.c +++ b/lib/ofp-util.c @@ -19,6 +19,7 @@ #include <errno.h> #include <inttypes.h> #include <stdlib.h> +#include "autopath.h" #include "byte-order.h" #include "classifier.h" #include "dynamic-string.h" @@ -2014,6 +2015,14 @@ check_nicira_action(const union ofp_action *a, unsigned int len, } return multipath_check((const struct nx_action_multipath *) a); + case NXAST_AUTOPATH: + error = check_nx_action_exact_len( + nah, len, sizeof(struct nx_action_autopath)); + if (error) { + return error; + } + return autopath_check((const struct nx_action_autopath *) a); + case NXAST_SNAT__OBSOLETE: default: VLOG_WARN_RL(&bad_ofmsg_rl, |