[ovs-dev] [PATCH v2.42 5/5] datapath: Add basic MPLS support to kernel
Allow datapath to recognize and extract MPLS labels into flow keys and execute actions which push, pop, and set labels on packets. Based heavily on work by Leo Alterman, Ravi K, Isaku Yamahata and Joe Stringer. Cc: Ravi K Cc: Leo Alterman Cc: Isaku Yamahata Cc: Joe Stringer Signed-off-by: Simon Horman --- v2.42 * Rebase for: + 0585f7a ("datapath: Simplify mega-flow APIs.") + a097c0b ("datapath: Restructure datapath.c and flow.c") * As suggested by Jesse Gross + Take into account that push_mpls() will have freed the skb on error + Remove dubious !eth_p_mpls(skb->protocol) condition from push_mpls The !eth_p_mpls(skb->protocol) condition on setting inner_protocol has no effect. Its motivation was to ensure that inner_protocol was only set the first time that mpls_push occured. However this is already ensured by the !ovs_skb_get_inner_protocol(skb) condition. + Return -EINVAL instead of -ENOMEM from pop_mpls() if the skb is too short + Do not add @inner_protocol to kernel doc for struct ovs_skb_cb. The patch no longer adds an inner_protocol member to struct ovs_skb_cb + Do not add and set otherwise unsued inner_protocol variable in rpl_dev_queue_xmit() * As suggested by Pravin Shelar + Implement compatibility code in existing rpl_skb_gso_segment rather than introducing to use rpl___skb_gso_segment v2.41 * No change v2.40 * Rebase for: + New dev_queue_xmit compat code + Updated put_vlan() * As suggested by Jesse Gross + Remove bogus mac_len update from push_mpls() + Slightly simplify push_mpls() by using eth_hdr() + Remove dubious condition !eth_p_mpls(inner_protocol) on an skb being considered to be MPLS in netdev_send() + Only use compatibility code for MPLS GSO segmentation on kernels older than 3.11 + Revamp setting of inner_protocol 1. Do not unconditionally set inner_protocol to the value of skb->protocol in ovs_execute_actions(). 2. Initialise inner_protocol it to zero only if compatibility code is in use. In the case where compatibility code is not in use it will either be zero due since the allocation of the skb or some other value set by some other user. 3. Conditionally set the inner_protocol in push_mpls() to the value of skb->protocol when entering push_mpls(). The condition is that inner_protocol is zero and the value of skb->protocol is not an MPLS ethernet type. - This new scheme: + Pushes logic to set inner_protocol closer to the case where it is needed. + Avoids over-writing values set by other users. * As suggested by Pravin Shelar + Only set and restore skb->protocol in rpl___skb_gso_segment() in the case of MPLS + Add inner_protocol field to struct ovs_gso_cb instead of ovs_skb_cb. This moves compatibility code closer to where it is used and creates fewer differences with mainline. * Update comment on mac_len updates in datapath/actions.c * Remove HAVE_INNER_PROCOTOL and instead just check against kernel version 3.11 directly. HAVE_INNER_PROCOTOL is a hang-over from work done prior to the merge of inner_protocol into the kernel. * Remove dubious condition !eth_p_mpls(inner_protocol) on using inner_protocol as the type in rpl_skb_network_protocol() * Do not update type of features in rpl_dev_queue_xmit. Though arguably correct this is not an inherent part of the changes made by this patch. * Use skb_cow_head() in push_mpls() + Call skb_cow_head(skb, MPLS_HLEN) instead of make_writable(skb, skb->mac_len) to ensure that there is enough head room to push an MPLS LSE regardless of whether the skb is cloned or not. + This is consistent with the behaviour of rpl__vlan_put_tag(). + This is a fix for crashes reported when performing mpls_push with headroom less than 4. This problem was introduced in v3.36. * Skip popping in mpls_pop if the skb is too short to contain an MPLS LSE v2.39 * Rebase for removal of vlan, checksum and skb->mark compat code v2.38 * Rebase for SCTP support * Refactor validate_tp_port() to iterate over eth_types rather than open-coding the loop. With the addition of SCTP this logic is now used three times. v2.36 - v2.37 * Rebase * Do not add set_ethertype() to datapath/actions.c. As this patch has evolved this function had devolved into to sets of functionality wrapped into a single function with only one line of common code. Refactor things to simply open-code setting the ether type in the two locations where set_ethertype() was previously used. The aim here is to improve readability. * Update setting skb->ethertype after mpls push and pop. - In the case of push_mpls it should be set unconditionally as in v2.35 the behaviour of this function to always push an MPLS LSE before any VLAN tags. - In the case of mpls_pop eth_p_mpls(skb->protocol) is a better test than skb->protocol != htons(ETH_P_8021Q) as it will give the correct behav
[ovs-dev] [PATCH v2.42 2/5] ofp-actions: Add separate OpenFlow 1.3 action parser
From: Joe Stringer This patch adds new ofpact_from_openflow13() and ofpacts_from_openflow13() functions parallel to the existing ofpact handling code. In the OpenFlow 1.3 version, push_mpls is handled differently, but all other actions are handled by the existing code. In the case of push_mpls for OpenFlow 1.3 the new mpls_before_vlan field of struct ofpact_push_mpls is set to true. This will be used by a subsequent patch to allow allow the correct VLAN+MPLS datapath behaviour to be determined at odp translation time. Signed-off-by: Joe Stringer Signed-off-by: Simon Horman --- v2.41 [Simon Horman] * As suggested by Ben Pfaff + Expand struct ofpact_reg_load to include a mpls_before_vlan field rather than using the compat field of the ofpact field of struct ofpact_reg_load. + Pass version to ofpacts_pull_openflow11_actions and ofpacts_pull_openflow11_instructions. This removes the invalid assumption that that these functions are passed a full message and are thus able to deduce the OpenFlow version. v2.36 - v2.40 * No change v2.35 [Joe Stringer] * First post --- lib/ofp-actions.c | 68 --- lib/ofp-actions.h | 9 +++ lib/ofp-print.c | 2 +- lib/ofp-util.c| 24 ++ lib/ofp-util.h| 2 +- utilities/ovs-ofctl.c | 8 +++--- 6 files changed, 93 insertions(+), 20 deletions(-) diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 65430f3..434d020 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -881,6 +881,40 @@ ofpacts_from_openflow11(const union ofp_action *in, size_t n_in, return ofpacts_from_openflow(in, n_in, out, ofpact_from_openflow11); } +static enum ofperr +ofpact_from_openflow13(const union ofp_action *a, struct ofpbuf *out) +{ +enum ofputil_action_code code; +enum ofperr error; + +error = decode_openflow11_action(a, &code); +if (error) { +return error; +} + +if (code == OFPUTIL_OFPAT11_PUSH_MPLS) { +struct ofpact_push_mpls *oam; +struct ofp11_action_push *oap = (struct ofp11_action_push *)a; +if (!eth_type_mpls(oap->ethertype)) { +return OFPERR_OFPBAC_BAD_ARGUMENT; +} +oam = ofpact_put_PUSH_MPLS(out); +oam->ethertype = oap->ethertype; +oam->mpls_before_vlan = true; +} else { +return ofpact_from_openflow11(a, out); +} + +return error; +} + +static enum ofperr +ofpacts_from_openflow13(const union ofp_action *in, size_t n_in, +struct ofpbuf *out) +{ +return ofpacts_from_openflow(in, n_in, out, ofpact_from_openflow13); +} + /* OpenFlow 1.1 instructions. */ #define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) \ @@ -1085,11 +1119,14 @@ get_actions_from_instruction(const struct ofp11_instruction *inst, *n_actions = (ntohs(inst->len) - sizeof *inst) / OFP11_INSTRUCTION_ALIGN; } -/* Attempts to convert 'actions_len' bytes of OpenFlow 1.1 actions from the +/* Attempts to convert 'actions_len' bytes of OpenFlow actions from the * front of 'openflow' into ofpacts. On success, replaces any existing content * in 'ofpacts' by the converted ofpacts; on failure, clears 'ofpacts'. * Returns 0 if successful, otherwise an OpenFlow error. * + * Actions are processed according to their OpenFlow version which + * is provided in the 'version' parameter. + * * In most places in OpenFlow 1.1 and 1.2, actions appear encapsulated in * instructions, so you should call ofpacts_pull_openflow11_instructions() * instead of this function. @@ -1101,15 +1138,27 @@ get_actions_from_instruction(const struct ofp11_instruction *inst, * valid in a specific context. */ enum ofperr ofpacts_pull_openflow11_actions(struct ofpbuf *openflow, +enum ofp_version version, unsigned int actions_len, struct ofpbuf *ofpacts) { -return ofpacts_pull_actions(openflow, actions_len, ofpacts, -ofpacts_from_openflow11); +switch (version) { +case OFP10_VERSION: +case OFP11_VERSION: +case OFP12_VERSION: +return ofpacts_pull_actions(openflow, actions_len, ofpacts, +ofpacts_from_openflow11); +case OFP13_VERSION: +return ofpacts_pull_actions(openflow, actions_len, ofpacts, +ofpacts_from_openflow13); +default: +NOT_REACHED(); +} } enum ofperr ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow, + enum ofp_version version, unsigned int instructions_len, struct ofpbuf *ofpacts) { @@ -1160,7 +1209,18 @@ ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow, get_actions_from_instruction(insts[OVSINST_OFPIT11_APPLY_ACTIONS],
[ovs-dev] [PATCH v2.42 1/5] odp: Allow VLAN actions after MPLS actions
From: Joe Stringer OpenFlow 1.1 and 1.2, and 1.3 differ in their handling of MPLS actions in the presence of VLAN tags. To allow correct behaviour to be committed in each situation, this patch adds a second round of VLAN tag action handling to commit_odp_actions(), which occurs after MPLS actions. This is implemented with a new field in 'struct xlate_in' called 'vlan_tci'. When an push_mpls action is composed, the flow's current VLAN state is stored into xin->vlan_tci, and flow->vlan_tci is set to 0 (pop_vlan). If a VLAN tag is present, it is stripped; if not, then there is no change. Any later modifications to the VLAN state is written to xin->vlan_tci. When committing the actions, flow->vlan_tci is used before MPLS actions, and xin->vlan_tci is used afterwards. This retains the current datapath behaviour, but allows VLAN actions to be applied in a more flexible manner. Both before and after this patch MPLS LSEs are pushed onto a packet after any VLAN tags that may be present. This is the behaviour described in OpenFlow 1.1 and 1.2. OpenFlow 1.3 specifies that MPLS LSEs should be pushed onto a packet before any VLAN tags that are present. Support for this will be added by a subsequent patch that makes use of the infrastructure added by this patch. Signed-off-by: Joe Stringer Signed-off-by: Simon Horman --- v2.41 * Rework comments to make things a little clearer v2.40 * Rebase for removal of mpls_depth from struct flow v2.38 - v2.39 * No change v2.37 * Rebase v2.36 * No change v2.5 * First post --- lib/odp-util.c | 9 +- lib/odp-util.h | 2 +- ofproto/ofproto-dpif-xlate.c | 101 - ofproto/ofproto-dpif-xlate.h | 5 ++ tests/ofproto-dpif.at| 209 +++ 5 files changed, 303 insertions(+), 23 deletions(-) diff --git a/lib/odp-util.c b/lib/odp-util.c index 5c7ccfb..4028167 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -3600,11 +3600,15 @@ commit_set_pkt_mark_action(const struct flow *flow, struct flow *base, * key from 'base' into 'flow', and then changes 'base' the same way. Does not * commit set_tunnel actions. Users should call commit_odp_tunnel_action() * in addition to this function if needed. Sets fields in 'wc' that are - * used as part of the action. */ + * used as part of the action. + * + * VLAN actions may be committed twice; If vlan_tci in 'flow' differs from the + * one in 'base', then it is committed before MPLS actions. If 'final_vlan_tci' + * differs from 'flow->vlan_tci', it is committed afterwards. */ void commit_odp_actions(const struct flow *flow, struct flow *base, struct ofpbuf *odp_actions, struct flow_wildcards *wc, - int *mpls_depth_delta) + int *mpls_depth_delta, ovs_be16 final_vlan_tci) { commit_set_ether_addr_action(flow, base, odp_actions, wc); commit_vlan_action(flow->vlan_tci, base, odp_actions, wc); @@ -3615,6 +3619,7 @@ commit_odp_actions(const struct flow *flow, struct flow *base, * that it is no longer IP and thus nw and port actions are no longer valid. */ commit_mpls_action(flow, base, odp_actions, wc, mpls_depth_delta); +commit_vlan_action(final_vlan_tci, base, odp_actions, wc); commit_set_priority_action(flow, base, odp_actions, wc); commit_set_pkt_mark_action(flow, base, odp_actions, wc); } diff --git a/lib/odp-util.h b/lib/odp-util.h index 2712cb0..a7bca43 100644 --- a/lib/odp-util.h +++ b/lib/odp-util.h @@ -143,7 +143,7 @@ void commit_odp_tunnel_action(const struct flow *, struct flow *base, struct ofpbuf *odp_actions); void commit_odp_actions(const struct flow *, struct flow *base, struct ofpbuf *odp_actions, struct flow_wildcards *wc, -int *mpls_depth_delta); +int *mpls_depth_delta, ovs_be16 final_vlan_tci); /* ofproto-dpif interface. * diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index cced7cc..6757933 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -982,10 +982,11 @@ static void output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle, uint16_t vlan) { -ovs_be16 *flow_tci = &ctx->xin->flow.vlan_tci; +ovs_be16 *flow_tci = &ctx->xin->vlan_tci; uint16_t vid; ovs_be16 tci, old_tci; struct xport *xport; +bool flow_tci_equal_to_xin = (*flow_tci == ctx->xin->flow.vlan_tci); vid = output_vlan_to_vid(out_xbundle, vlan); if (list_is_empty(&out_xbundle->xports)) { @@ -1016,9 +1017,15 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle, } } *flow_tci = tci; +if (flow_tci_equal_to_xin) { +ctx->xin->flow.vlan_tci = tci; +} compose_output_action(ctx, xport->ofp_port); *flow_tci = old_tci; +if (flow_tci_equal_to_xin) { +ctx->xin->flo
[ovs-dev] [PATCH v2.42 0/5] MPLS actions and matches
Hi, This series implements MPLS actions and matches based on work by Ravi K, Leo Alterman, Yamahata-san and Joe Stringer. This series provides two changes * Patches 1 - 3 Provide user-space support for the VLAN/MPLS tag insertion order up to and including OpenFlow 1.2, and the different ordering specified from OpenFlow 1.3. In a nutshell the datapath always uses the OpenFlow 1.3 ordering, which is to always insert tags immediately after the L2 header, regardless of the presence of other tags. And ovs-vswtichd provides compatibility for the behaviour up to OpenFlow 1.2, which is that MPLS tags should follow VLAN tags if present. These patches have been updated since v2.40. Ben, these are for you to review. * Patches 4 and 5 Adding basic MPLS action and match support to the kernel datapath These patches have not been updated since v2.40. Jesse, these are for you to review. Differences between v2.42 and v2.41: v2.42 * Rebase for: + 0585f7a ("datapath: Simplify mega-flow APIs.") + a097c0b ("datapath: Restructure datapath.c and flow.c") * As suggested by Jesse Gross + Take into account that push_mpls() will have freed the skb on error + Remove dubious !eth_p_mpls(skb->protocol) condition from push_mpls The !eth_p_mpls(skb->protocol) condition on setting inner_protocol has no effect. Its motivation was to ensure that inner_protocol was only set the first time that mpls_push occured. However this is already ensured by the !ovs_skb_get_inner_protocol(skb) condition. + Return -EINVAL instead of -ENOMEM from pop_mpls() if the skb is too short + Do not add @inner_protocol to kernel doc for struct ovs_skb_cb. The patch no longer adds an inner_protocol member to struct ovs_skb_cb + Do not add and set otherwise unsued inner_protocol variable in rpl_dev_queue_xmit() * As suggested by Pravin Shelar + Implement compatibility code in existing rpl_skb_gso_segment rather than introducing to use rpl___skb_gso_segment Differences between v2.41 and v2.40: * As suggested by Ben Pfaff + Expand struct ofpact_reg_load to include a mpls_before_vlan field rather than using the compat field of the ofpact field of struct ofpact_reg_load. + Pass version to ofpacts_pull_openflow11_actions and ofpacts_pull_openflow11_instructions. This removes the invalid assumption that that these functions are passed a full message and are thus able to deduce the OpenFlow version. Differences between v2.40 and v2.39: * Rebase for: + New dev_queue_xmit compat code + Updated put_vlan() + Removal of mpls_depth field from struct flow * As suggested by Jesse Gross + Remove bogus mac_len update from push_mpls() + Slightly simplify push_mpls() by using eth_hdr() + Remove dubious condition !eth_p_mpls(inner_protocol) on an skb being considered to be MPLS in netdev_send() + Only use compatibility code for MPLS GSO segmentation on kernels older than 3.11 + Revamp setting of inner_protocol 1. Do not unconditionally set inner_protocol to the value of skb->protocol in ovs_execute_actions(). 2. Initialise inner_protocol it to zero only if compatibility code is in use. In the case where compatibility code is not in use it will either be zero due since the allocation of the skb or some other value set by some other user. 3. Conditionally set the inner_protocol in push_mpls() to the value of skb->protocol when entering push_mpls(). The condition is that inner_protocol is zero and the value of skb->protocol is not an MPLS ethernet type. - This new scheme: + Pushes logic to set inner_protocol closer to the case where it is needed. + Avoids over-writing values set by other users. * As suggested by Pravin Shelar + Only set and restore skb->protocol in rpl___skb_gso_segment() in the case of MPLS + Add inner_protocol field to struct ovs_gso_cb instead of ovs_skb_cb. This moves compatibility code closer to where it is used and creates fewer differences with mainline. * Update comment on mac_len updates in datapath/actions.c * Remove HAVE_INNER_PROCOTOL and instead just check against kernel version 3.11 directly. HAVE_INNER_PROCOTOL is a hang-over from work done prior to the merge of inner_protocol into the kernel. * Remove dubious condition !eth_p_mpls(inner_protocol) on using inner_protocol as the type in rpl_skb_network_protocol() * Do not update type of features in rpl_dev_queue_xmit. Though arguably correct this is not an inherent part of the changes made by this patch. * Use skb_cow_head() in push_mpls() + Call skb_cow_head(skb, MPLS_HLEN) instead of make_writable(skb, skb->mac_len) to ensure that there is enough head room to push an MPLS LSE regardless of whether the skb is cloned or not. + This is consistent with the behaviour of rpl__vlan_put_tag(). + This is a fix for crashes reported when performing mpls_pu
[ovs-dev] [PATCH v2.42 4/5] datapath: Break out deacceleration portion of vlan_push
Break out deacceleration portion of vlan_push into vlan_put so that it may be re-used by mpls_push. For both vlan_push and mpls_push if there is an accelerated VLAN tag present then it should be deaccelerated, adding it to the data of the skb, before the new tag is added. Signed-off-by: Simon Horman --- v2.40 * As suggested by Jesse Gross + Simplify vlan_push by returning an error code rather than an error code encoded as a struct xkb_buff * v2.39 * First post --- datapath/actions.c | 29 +++-- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/datapath/actions.c b/datapath/actions.c index 30ea1d2..d961e5d 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -105,22 +105,31 @@ static int pop_vlan(struct sk_buff *skb) return 0; } -static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vlan) +/* push down current VLAN tag */ +static int put_vlan(struct sk_buff *skb) { - if (unlikely(vlan_tx_tag_present(skb))) { - u16 current_tag; + u16 current_tag = vlan_tx_tag_get(skb); - /* push down current VLAN tag */ - current_tag = vlan_tx_tag_get(skb); + if (!__vlan_put_tag(skb, skb->vlan_proto, current_tag)) + return -ENOMEM; - if (!__vlan_put_tag(skb, skb->vlan_proto, current_tag)) - return -ENOMEM; + if (skb->ip_summed == CHECKSUM_COMPLETE) + skb->csum = csum_add(skb->csum, csum_partial(skb->data + + (2 * ETH_ALEN), VLAN_HLEN, 0)); - if (skb->ip_summed == CHECKSUM_COMPLETE) - skb->csum = csum_add(skb->csum, csum_partial(skb->data - + (2 * ETH_ALEN), VLAN_HLEN, 0)); + return 0; +} +static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vlan) +{ + if (unlikely(vlan_tx_tag_present(skb))) { + int err; + + err = put_vlan(skb); + if (unlikely(err)) + return err; } + __vlan_hwaccel_put_tag(skb, vlan->vlan_tpid, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT); return 0; } -- 1.8.4 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [PATCH v2.42 3/5] lib: Support pushing of MPLS LSE before or after VLAN tag
From: Joe Stringer This patch modifies the push_mpls behaviour to allow pushing of an MPLS LSE either before any VLAN tag that may be present. Pushing the MPLS LSE before any VLAN tag that is present is the behaviour specified in OpenFlow 1.3. Pushing the MPLS LSE after the any VLAN tag that is present is the behaviour specified in OpenFlow 1.1 and 1.2. This is the only behaviour that was supported prior to this patch. When an push_mpls action has been inserted using OpenFlow 1.2 or earlier the behaviour of pushing the MPLS LSE before any VLAN tag that may be present is implemented by by inserting VLAN actions around the MPLS push action during odp translation; Pop VLAN tags before committing MPLS actions, and push the expected VLAN tag afterwards. The trigger condition for the two different behaviours is the value of the mpls_before_vlan field of struct ofpact_push_mpls. This field is set when parsing OpenFlow actions. Signed-off-by: Joe Stringer Signed-off-by: Simon Horman --- v2.41 [Simon Horman] * Use mpls_before_vlan field of struct ofpact_reg_load. * Reword changelog to describe the difference in behaviour between different Open Flow versions. v2.40 [Simon Horman] * Trivial rebase for removal of set_ethertype() v2.36 - v2.39 * No change v2.35 [Joe Stringer] * First post --- lib/flow.c | 2 +- lib/packets.c| 10 +- lib/packets.h| 2 +- ofproto/ofproto-dpif-xlate.c | 27 ++--- tests/ofproto-dpif.at| 237 +++ 5 files changed, 259 insertions(+), 19 deletions(-) diff --git a/lib/flow.c b/lib/flow.c index 0678c6f..6242ef9 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -1061,7 +1061,7 @@ flow_compose(struct ofpbuf *b, const struct flow *flow) } if (eth_type_mpls(flow->dl_type)) { -b->l2_5 = b->l3; +b->l2_5 = (char*)b->l2 + ETH_HEADER_LEN; push_mpls(b, flow->dl_type, flow->mpls_lse); } } diff --git a/lib/packets.c b/lib/packets.c index 922c5db..f8a58b6 100644 --- a/lib/packets.c +++ b/lib/packets.c @@ -220,11 +220,11 @@ eth_pop_vlan(struct ofpbuf *packet) /* Set ethertype of the packet. */ void -set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type) +set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type, bool inner) { struct eth_header *eh = packet->data; -if (eh->eth_type == htons(ETH_TYPE_VLAN)) { +if (inner && eh->eth_type == htons(ETH_TYPE_VLAN)) { ovs_be16 *p; p = ALIGNED_CAST(ovs_be16 *, (char *)(packet->l2_5 ? packet->l2_5 : packet->l3) - 2); @@ -332,8 +332,8 @@ push_mpls(struct ofpbuf *packet, ovs_be16 ethtype, ovs_be32 lse) if (!is_mpls(packet)) { /* Set ethtype and MPLS label stack entry. */ -set_ethertype(packet, ethtype); -packet->l2_5 = packet->l3; +set_ethertype(packet, ethtype, false); +packet->l2_5 = (char*)packet->l2 + ETH_HEADER_LEN; } /* Push new MPLS shim header onto packet. */ @@ -354,7 +354,7 @@ pop_mpls(struct ofpbuf *packet, ovs_be16 ethtype) size_t len; mh = packet->l2_5; len = (char*)packet->l2_5 - (char*)packet->l2; -set_ethertype(packet, ethtype); +set_ethertype(packet, ethtype, true); if (mh->mpls_lse & htonl(MPLS_BOS_MASK)) { packet->l2_5 = NULL; } else { diff --git a/lib/packets.h b/lib/packets.h index 7388152..38fec70 100644 --- a/lib/packets.h +++ b/lib/packets.h @@ -143,7 +143,7 @@ void compose_rarp(struct ofpbuf *, const uint8_t eth_src[ETH_ADDR_LEN]); void eth_push_vlan(struct ofpbuf *, ovs_be16 tci); void eth_pop_vlan(struct ofpbuf *); -void set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type); +void set_ethertype(struct ofpbuf *packet, ovs_be16 eth_type, bool inner); const char *eth_from_hex(const char *hex, struct ofpbuf **packetp); void eth_format_masked(const uint8_t eth[ETH_ADDR_LEN], diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 6757933..2afd760 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -2419,24 +2419,27 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, break; } -case OFPACT_PUSH_MPLS: -if (compose_mpls_push_action(ctx, - ofpact_get_PUSH_MPLS(a)->ethertype)) { +case OFPACT_PUSH_MPLS: { +struct ofpact_push_mpls *oam = ofpact_get_PUSH_MPLS(a); + +if (compose_mpls_push_action(ctx, oam->ethertype)) { return; } -/* Save and pop any existing VLAN tags. They will be pushed - * back onto the packet after pushing the MPLS LSE. The overall - * effect is to push the MPLS LSE after any VLAN tags that may - * be present. This is the behaviour described for OpenFlow 1.1 - * and 1.2. This code needs to be enhanced to make this
[ovs-dev] [PATCH] datapath: add linux/flow_{table, netlink}.c to .gitignore
Signed-off-by: Lorand Jakab --- datapath/linux/.gitignore |2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/datapath/linux/.gitignore b/datapath/linux/.gitignore index d74ad3c..32b1770 100644 --- a/datapath/linux/.gitignore +++ b/datapath/linux/.gitignore @@ -15,6 +15,8 @@ /flex_array.c /flow.c /flow_dissector.c +/flow_netlink.c +/flow_table.c /genetlink-openvswitch.c /genl_exec.c /gre.c -- 1.7.7.5 (Apple Git-26) ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 1/8] nsh: datapath support for network service headers
On Oct 3, 2013, at 2:31 PM, Jesse Gross wrote: > On Thu, Oct 3, 2013 at 9:46 AM, Kyle Mestery (kmestery) > wrote: >> So, we realize the need to add the NSH code upstream into the kernel. >> But in parallel to this work, we're wondering if it would be ok to add a new >> vport-nsh in the data path code. This would allow for stacking NSH headers >> on whatever tunnel is required, per the RFC, by using flows to direct traffic >> between ports. In parallel, we're going to work to get the NSH code upstream >> into the Linux kernel and the iproute2 package for configuration using a CLI. >> >> Does this approach sound ok? > > Since we've been pushing hard to make the out-of-tree code closely > track upstream, I would be very hesitant to apply anything that isn't > ready to go upstream. > Makes sense. Is the eventual goal to remove the need for the out of tree kernel module completely? > Ready for upstream doesn't necessarily mean that configuration has to > available through iproute2 but it should be in an essentially final > form and make sense purely in the context of what's there plus the new > OVS code. > Got it. We'll make sure to finalize all the interfaces as well. I guess the goal for now would be to push the NSH encap/decap upstream into the kernel, but rely on the out of tree kernel for previous kernel support. > I'm not sure if that's true of what you're proposing or would this be > more temporary? Well, I see the out of tree kernel module as a way to support older kernels with features which are upstream in newer kernels, correct me if I'm wrong here. But overall, I think we're both on the same page here. Thanks, Kyle ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [RFC L3 1/4] ofproto-dpif: add support for layer 3 ports
Add member is_layer3 to struct ofport_dpif to mark layer 3 ports. Set it to "true" for the only layer 3 port we support for now: lisp. Additionally, prevent flooding to layer 3 ports. A later patch will also prevent MAC learning. This patch could be applied even without the rest of the layer 3 patches, since flooding packets to lisp ports shouldn't happen anyway. It currently breaks tests 2 and 669, not sure why. Signed-off-by: Lorand Jakab --- lib/netdev-vport.c |8 lib/netdev-vport.h |1 + ofproto/ofproto-dpif.c |5 + 3 files changed, 14 insertions(+), 0 deletions(-) diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index 0374ae3..608fb6d 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -108,6 +108,14 @@ netdev_vport_is_patch(const struct netdev *netdev) return class->get_config == get_patch_config; } +bool +netdev_vport_is_layer3(const struct netdev *dev) +{ +const char *type = netdev_get_type(dev); + +return (!strcmp("lisp", type)); +} + static bool netdev_vport_needs_dst_port(const struct netdev *dev) { diff --git a/lib/netdev-vport.h b/lib/netdev-vport.h index dc49097..eaeb386 100644 --- a/lib/netdev-vport.h +++ b/lib/netdev-vport.h @@ -30,6 +30,7 @@ void netdev_vport_tunnel_register(void); void netdev_vport_patch_register(void); bool netdev_vport_is_patch(const struct netdev *); +bool netdev_vport_is_layer3(const struct netdev *); char *netdev_vport_patch_peer(const struct netdev *netdev); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 80e97e0..58bdd2f 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -309,6 +309,7 @@ struct ofport_dpif { struct bfd *bfd;/* BFD, if any. */ bool may_enable;/* May be enabled in bonds. */ bool is_tunnel; /* This port is a tunnel. */ +bool is_layer3; /* This is a layer 3 port. */ long long int carrier_seq; /* Carrier status changes. */ struct ofport_dpif *peer; /* Peer if patch port. */ @@ -1710,6 +1711,8 @@ port_construct(struct ofport *port_) return 0; } +port->is_layer3 = netdev_vport_is_layer3(netdev); + error = dpif_port_query_by_name(ofproto->backer->dpif, netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf), @@ -2288,6 +2291,7 @@ bundle_update(struct ofbundle *bundle) bundle->floodable = true; LIST_FOR_EACH (port, bundle_node, &bundle->ports) { if (port->up.pp.config & OFPUTIL_PC_NO_FLOOD +|| port->is_layer3 || !stp_forward_in_state(port->stp_state)) { bundle->floodable = false; break; @@ -2335,6 +2339,7 @@ bundle_add_port(struct ofbundle *bundle, ofp_port_t ofp_port, port->bundle = bundle; list_push_back(&bundle->ports, &port->bundle_node); if (port->up.pp.config & OFPUTIL_PC_NO_FLOOD +|| port->is_layer3 || !stp_forward_in_state(port->stp_state)) { bundle->floodable = false; } -- 1.7.7.5 (Apple Git-26) ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [RFC L3 2/4] userspace: add support for pop_eth and push_eth actions
These actions will allow L2->L3 and L3->L2 switching Signed-off-by: Lorand Jakab --- include/linux/openvswitch.h | 12 lib/odp-execute.c | 12 lib/odp-util.c | 61 +++ lib/odp-util.h |6 lib/packets.c | 15 ++ lib/packets.h |4 +++ 6 files changed, 110 insertions(+), 0 deletions(-) diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h index 09c26b5..cee2204 100644 --- a/include/linux/openvswitch.h +++ b/include/linux/openvswitch.h @@ -507,6 +507,16 @@ struct ovs_action_push_vlan { }; /** + * struct ovs_action_push_eth - %OVS_ACTION_ATTR_PUSH_ETH action argument. + * @addresses: Source and destination MAC addresses. + * @eth_type: Ethernet type + */ +struct ovs_action_push_eth { + struct ovs_key_ethernet addresses; + __be16 eth_type; +}; + +/** * enum ovs_action_attr - Action types. * * @OVS_ACTION_ATTR_OUTPUT: Output packet to port. @@ -545,6 +555,8 @@ enum ovs_action_attr { OVS_ACTION_ATTR_SAMPLE, /* Nested OVS_SAMPLE_ATTR_*. */ OVS_ACTION_ATTR_PUSH_MPLS,/* struct ovs_action_push_mpls. */ OVS_ACTION_ATTR_POP_MPLS, /* __be16 ethertype. */ + OVS_ACTION_ATTR_PUSH_ETH, /* struct ovs_action_push_eth. */ + OVS_ACTION_ATTR_POP_ETH, /* No argument. */ __OVS_ACTION_ATTR_MAX }; diff --git a/lib/odp-execute.c b/lib/odp-execute.c index c91cc4a..935b66b 100644 --- a/lib/odp-execute.c +++ b/lib/odp-execute.c @@ -190,6 +190,18 @@ odp_execute_actions(void *dp, struct ofpbuf *packet, struct flow *key, break; } +case OVS_ACTION_ATTR_PUSH_ETH: { +const struct ovs_action_push_eth *eth = nl_attr_get(a); +push_eth(packet, eth->addresses.eth_dst, eth->addresses.eth_src, + eth->eth_type); +break; +} + +case OVS_ACTION_ATTR_POP_ETH: { +pop_eth(packet); +break; +} + case OVS_ACTION_ATTR_PUSH_VLAN: { const struct ovs_action_push_vlan *vlan = nl_attr_get(a); eth_push_vlan(packet, vlan->vlan_tci); diff --git a/lib/odp-util.c b/lib/odp-util.c index 5c7ccfb..eda679e 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -74,6 +74,8 @@ odp_action_len(uint16_t type) switch ((enum ovs_action_attr) type) { case OVS_ACTION_ATTR_OUTPUT: return sizeof(uint32_t); case OVS_ACTION_ATTR_USERSPACE: return -2; +case OVS_ACTION_ATTR_PUSH_ETH: return sizeof(struct ovs_action_push_eth); +case OVS_ACTION_ATTR_POP_ETH: return 0; case OVS_ACTION_ATTR_PUSH_VLAN: return sizeof(struct ovs_action_push_vlan); case OVS_ACTION_ATTR_POP_VLAN: return 0; case OVS_ACTION_ATTR_PUSH_MPLS: return sizeof(struct ovs_action_push_mpls); @@ -383,6 +385,7 @@ format_odp_action(struct ds *ds, const struct nlattr *a) { int expected_len; enum ovs_action_attr type = nl_attr_type(a); +const struct ovs_action_push_eth *eth; const struct ovs_action_push_vlan *vlan; expected_len = odp_action_len(nl_attr_type(a)); @@ -405,6 +408,17 @@ format_odp_action(struct ds *ds, const struct nlattr *a) format_odp_key_attr(nl_attr_get(a), NULL, NULL, ds, true); ds_put_cstr(ds, ")"); break; +case OVS_ACTION_ATTR_PUSH_ETH: +eth = nl_attr_get(a); +ds_put_format(ds, "push_eth(src="ETH_ADDR_FMT",dst="ETH_ADDR_FMT + ",type=0x%04"PRIx16")", + ETH_ADDR_ARGS(eth->addresses.eth_src), + ETH_ADDR_ARGS(eth->addresses.eth_dst), + ntohs(eth->eth_type)); +break; +case OVS_ACTION_ATTR_POP_ETH: +ds_put_cstr(ds, "pop_eth"); +break; case OVS_ACTION_ATTR_PUSH_VLAN: vlan = nl_attr_get(a); ds_put_cstr(ds, "push_vlan("); @@ -616,6 +630,31 @@ parse_odp_action(const char *s, const struct simap *port_names, } { +struct ovs_action_push_eth push; +int eth_type = 0; +int n = -1; + +if (sscanf(s, "push_eth(src="ETH_ADDR_SCAN_FMT"," + "dst="ETH_ADDR_SCAN_FMT",type=%i)%n", + ETH_ADDR_SCAN_ARGS(push.addresses.eth_src), + ETH_ADDR_SCAN_ARGS(push.addresses.eth_dst), + ð_type, &n) > 0 && n > 0) { + +push.eth_type = htons(eth_type); + +nl_msg_put_unspec(actions, OVS_ACTION_ATTR_PUSH_ETH, + &push, sizeof push); + +return n; +} +} + +if (!strncmp(s, "pop_eth", 7)) { +nl_msg_put_flag(actions, OVS_ACTION_ATTR_POP_ETH); +return 7; +} + +{ struct ovs_action_push_vlan push; int tpid = ETH_TYPE_VLAN; int vid, pcp; @@ -3296,6 +3335,28 @@ odp_put_userspace_action(uint32_t pid, } void +odp_put_pop_eth_action(struct ofpbuf *odp_
[ovs-dev] [RFC L3 0/4] Looking for further guidance on layer 3 support
This is a second RFC on the layer 3 support design, based a feedback received from Jesse and Ben. It is still not a formal patch, since the code is incomplete, but I would like to check at this point if you agree with the implementation decisions I had taken so far. Lorand Jakab (4): ofproto-dpif: add support for layer 3 ports userspace: add support for pop_eth and push_eth actions userspace: add layer 3 flow and switching support datapath: add layer 3 flow/port support datapath/actions.c | 32 +++ datapath/datapath.h |1 + datapath/flow.c | 43 ++--- datapath/flow.h |1 + datapath/flow_netlink.c | 18 ++- datapath/vport-gre.c |1 + datapath/vport-lisp.c| 17 ++ datapath/vport-netdev.c |1 + datapath/vport-vxlan.c |1 + include/linux/openvswitch.h | 12 +++ lib/dpif-linux.c |7 lib/dpif.c |6 ++- lib/flow.c | 38 --- lib/flow.h |7 ++-- lib/match.c | 11 -- lib/netdev-vport.c |8 + lib/netdev-vport.h |1 + lib/nx-match.c |2 +- lib/odp-execute.c| 12 +++ lib/odp-util.c | 69 ++--- lib/odp-util.h |6 lib/ofp-print.c | 14 ++-- lib/ofp-print.h |3 +- lib/ofp-util.c |2 +- lib/packets.c| 15 + lib/packets.h|4 ++ ofproto/ofproto-dpif-xlate.c | 21 +++-- ofproto/ofproto-dpif-xlate.h |2 +- ofproto/ofproto-dpif.c |9 - 29 files changed, 297 insertions(+), 67 deletions(-) -- 1.7.7.5 (Apple Git-26) ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [RFC L3 3/4] userspace: add layer 3 flow and switching support
This commit relexes the assumption that all packets have an Ethernet header, and add support for layer 3 flows. For each packet received on the linux kernel datapath the l2 and l3 members of struct ofpbuf are intialized appropriately, and some functions now expect this, in order to differentiate between layer 2 and layer 3 packets. struct flow has now a new 'noeth' member, because we cannot assume that eth_src and eth_dst being 0 the flow has no Ethernet header. For layer 3 packets, the protocol type is still stored in the eth_type member. Switching L2->L3 and L3->L2 is also implemented, by adding the pop_eth and push_eth actions respectively when a transition is detected. The push_eth action has hardcoded addresses for now, pending ARP resolution implementation. Signed-off-by: Lorand Jakab --- lib/dpif-linux.c |7 +++ lib/dpif.c |6 -- lib/flow.c | 38 +- lib/flow.h |7 --- lib/match.c | 11 +++ lib/nx-match.c |2 +- lib/odp-util.c |8 +++- lib/ofp-print.c | 14 ++ lib/ofp-print.h |3 ++- lib/ofp-util.c |2 +- ofproto/ofproto-dpif-xlate.c | 21 ++--- ofproto/ofproto-dpif-xlate.h |2 +- ofproto/ofproto-dpif.c |4 ++-- 13 files changed, 93 insertions(+), 32 deletions(-) diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c index 6f75f57..f0b9d9b 100644 --- a/lib/dpif-linux.c +++ b/lib/dpif-linux.c @@ -1379,6 +1379,13 @@ parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall, upcall->key = CONST_CAST(struct nlattr *, nl_attr_get(a[OVS_PACKET_ATTR_KEY])); upcall->key_len = nl_attr_get_size(a[OVS_PACKET_ATTR_KEY]); +if (nl_attr_find__(upcall->key, upcall->key_len, OVS_KEY_ATTR_ETHERNET)) { +upcall->packet->l2 = upcall->packet->data; +upcall->packet->l3 = NULL; +} else { +upcall->packet->l2 = NULL; +upcall->packet->l3 = upcall->packet->data; +} upcall->userdata = a[OVS_PACKET_ATTR_USERDATA]; *dp_ifindex = ovs_header->dp_ifindex; diff --git a/lib/dpif.c b/lib/dpif.c index b66e3bc..92c8cae 100644 --- a/lib/dpif.c +++ b/lib/dpif.c @@ -1204,7 +1204,8 @@ dpif_recv(struct dpif *dpif, struct dpif_upcall *upcall, struct ofpbuf *buf) char *packet; packet = ofp_packet_to_string(upcall->packet->data, - upcall->packet->size); + upcall->packet->size, + upcall->packet->l3); ds_init(&flow); odp_flow_key_format(upcall->key, upcall->key_len, &flow); @@ -1406,7 +1407,8 @@ log_execute_message(struct dpif *dpif, const struct dpif_execute *execute, char *packet; packet = ofp_packet_to_string(execute->packet->data, - execute->packet->size); + execute->packet->size, + execute->packet->l3); ds_put_format(&ds, "%s: execute ", dpif_name(dpif)); format_odp_actions(&ds, execute->actions, execute->actions_len); if (error) { diff --git a/lib/flow.c b/lib/flow.c index 0678c6f..491daec 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -40,6 +40,21 @@ COVERAGE_DEFINE(flow_extract); COVERAGE_DEFINE(miniflow_malloc); +static ovs_be16 +get_l3_eth_type(struct ofpbuf *packet) +{ +struct ip_header *ip = packet->l3; +int ip_ver = IP_VER(ip->ip_ihl_ver); +switch (ip_ver) { +case 4: +return htons(ETH_TYPE_IP); +case 6: +return htons(ETH_TYPE_IPV6); +default: +return 0; +} +} + static struct arp_eth_header * pull_arp(struct ofpbuf *packet) { @@ -381,6 +396,8 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark, COVERAGE_INC(flow_extract); +ovs_assert(packet->l2 != NULL || packet->l3 != NULL); + memset(flow, 0, sizeof *flow); if (tnl) { @@ -393,11 +410,21 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark, flow->skb_priority = skb_priority; flow->pkt_mark = pkt_mark; -packet->l2 = b.data; -packet->l2_5 = NULL; -packet->l3 = NULL; -packet->l4 = NULL; packet->l7 = NULL; +packet->l4 = NULL; + +if (packet->l3) { +packet->l2_5 = NULL; +packet->l2 = NULL; +flow->noeth = true; +/* We assume L3 packets are either IPv4 or IPv6 */ +flow->dl_type = get_l3_eth_type(packet); +goto layer3; +} + +packet->l3 = NULL; +packet->l2_5 = NULL; +packet->l2 = b.data; if (b.size < sizeof *eth) { return; @@ -423,6 +450,7 @@ flow_extract(struct ofpbuf *packet, uint32_t skb_priority, uint32_t pkt_mark, /* Netw
[ovs-dev] [RFC L3 4/4] datapath: add layer 3 flow/port support
Implementation of the pop_eth and push_eth actions in the kernel, also layer 3 flow support. Jesse Gross provided feedback on a previous version of this RFC patch, all of those comments are resolved here. Signed-off-by: Lorand Jakab --- datapath/actions.c | 32 datapath/datapath.h |1 + datapath/flow.c | 43 --- datapath/flow.h |1 + datapath/flow_netlink.c | 18 -- datapath/vport-gre.c|1 + datapath/vport-lisp.c | 17 +++-- datapath/vport-netdev.c |1 + datapath/vport-vxlan.c |1 + 9 files changed, 80 insertions(+), 35 deletions(-) diff --git a/datapath/actions.c b/datapath/actions.c index 30ea1d2..b90e715 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -143,6 +143,30 @@ static int set_eth_addr(struct sk_buff *skb, return 0; } +static int pop_eth(struct sk_buff *skb) +{ + skb_pull(skb, skb_network_offset(skb)); + return 0; +} + +static int push_eth(struct sk_buff *skb, const struct ovs_action_push_eth *ethh) +{ + int err; + + skb_push(skb, ETH_HLEN); + skb_reset_mac_header(skb); + + err = set_eth_addr(skb, ðh->addresses); + if (unlikely(err)) + return err; + + eth_hdr(skb)->h_proto = ethh->eth_type; + + ovs_skb_postpush_rcsum(skb, skb->data, ETH_HLEN); + + return 0; +} + static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh, __be32 *addr, __be32 new_addr) { @@ -546,6 +570,14 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, err = pop_vlan(skb); break; + case OVS_ACTION_ATTR_PUSH_ETH: + err = push_eth(skb, nla_data(a)); + break; + + case OVS_ACTION_ATTR_POP_ETH: + err = pop_eth(skb); + break; + case OVS_ACTION_ATTR_SET: err = execute_set_action(skb, nla_data(a)); break; diff --git a/datapath/datapath.h b/datapath/datapath.h index 64920de..08fae82 100644 --- a/datapath/datapath.h +++ b/datapath/datapath.h @@ -99,6 +99,7 @@ struct ovs_skb_cb { struct sw_flow *flow; struct sw_flow_key *pkt_key; struct ovs_key_ipv4_tunnel *tun_key; + bool is_layer3; }; #define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb) diff --git a/datapath/flow.c b/datapath/flow.c index faa4e15..c98a0fa 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -369,26 +369,31 @@ int ovs_flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key) skb_reset_mac_header(skb); - /* Link layer. We are guaranteed to have at least the 14 byte Ethernet -* header in the linear data area. -*/ - eth = eth_hdr(skb); - memcpy(key->eth.src, eth->h_source, ETH_ALEN); - memcpy(key->eth.dst, eth->h_dest, ETH_ALEN); - - __skb_pull(skb, 2 * ETH_ALEN); - /* We are going to push all headers that we pull, so no need to -* update skb->csum here. */ - - if (vlan_tx_tag_present(skb)) - key->eth.tci = htons(vlan_get_tci(skb)); - else if (eth->h_proto == htons(ETH_P_8021Q)) - if (unlikely(parse_vlan(skb, key))) + /* Link layer. */ + if (OVS_CB(skb)->is_layer3) { + /* The receiving L3 vport should set the inner packet protocol +* on the skb. We use that here to set eth.type */ + key->noeth = true; + key->eth.type = skb->protocol; + } else { + eth = eth_hdr(skb); + memcpy(key->eth.src, eth->h_source, ETH_ALEN); + memcpy(key->eth.dst, eth->h_dest, ETH_ALEN); + + /* We are going to push all headers that we pull, so no need to +* update skb->csum here. */ + __skb_pull(skb, 2 * ETH_ALEN); + + if (vlan_tx_tag_present(skb)) + key->eth.tci = htons(vlan_get_tci(skb)); + else if (eth->h_proto == htons(ETH_P_8021Q)) + if (unlikely(parse_vlan(skb, key))) + return -ENOMEM; + + key->eth.type = parse_ethertype(skb); + if (unlikely(key->eth.type == htons(0))) return -ENOMEM; - - key->eth.type = parse_ethertype(skb); - if (unlikely(key->eth.type == htons(0))) - return -ENOMEM; + } skb_reset_network_header(skb); __skb_push(skb, skb->data - skb_mac_header(skb)); diff --git a/datapath/flow.h b/datapath/flow.h index 91a3022..134e535 100644 --- a/datapath/flow.h +++ b/datapath/flow.h @@ -68,6 +68,7 @@ static inline void ovs_flow_tun_key_init(struct ovs_key_ipv4_tunnel *tun_key, struct sw_flow_key { s
Re: [ovs-dev] [PATCH] datapath: add linux/flow_{table, netlink}.c to .gitignore
On Oct 4, 2013, at 6:07 AM, Lorand Jakab wrote: > Signed-off-by: Lorand Jakab Looks fine to me Lori. Acked-by: Kyle Mestery ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH] ofproto-dpif-xlate: Limit actions, stack use to 64 kB at resubmit time.
On Thu, Oct 03, 2013 at 05:15:33PM -0700, Justin Pettit wrote: > > On Aug 23, 2013, at 10:04 AM, Ben Pfaff wrote: > > > @@ -1667,7 +1674,18 @@ static void > > xlate_table_action(struct xlate_ctx *ctx, > >ofp_port_t in_port, uint8_t table_id, bool may_packet_in) > > { > > -if (ctx->recurse < MAX_RESUBMIT_RECURSION) { > > +static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); > > + > > +if (ctx->recurse >= MAX_RESUBMIT_RECURSION) { > > +VLOG_ERR_RL(&rl, "resubmit actions recursed over %d times", > > +MAX_RESUBMIT_RECURSION); > > +} else if (ctx->resubmits >= MAX_RESUBMITS) { > > +VLOG_ERR_RL(&rl, "over %d resubmit actions", MAX_RESUBMITS); > > +} else if (ctx->xout->odp_actions.size >= 65536) { > > In other parts of the code, the max action size is UINT16_MAX. It > might be nice to be consistent. OK, I changed >= 65536 to > UINT16_MAX. > Acked-by: Justin Pettit Thanks. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH] ofproto-dpif-xlate: Suppress oversize datapath actions.
On Thu, Oct 03, 2013 at 05:18:00PM -0700, Justin Pettit wrote: > On Aug 23, 2013, at 10:44 AM, Ben Pfaff wrote: > > > --- a/ofproto/ofproto-dpif-xlate.c > > +++ b/ofproto/ofproto-dpif-xlate.c > > @@ -2706,6 +2706,15 @@ xlate_actions(struct xlate_in *xin, struct xlate_out > > *xout) > > } > > } > > > > +if (nl_attr_oversized(ctx.xout->odp_actions.size)) { > > +/* It is impossible to these datapath actions into a Netlink > > attribute, > > "to *put* these"? Yes, fixed. > Otherwise: > > Acked-by: Justin Pettit Thanks. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH] ovsdb-server: Document that --remote may be used multiple times.
Acked-by: Justin Pettit --Justin On Oct 4, 2013, at 8:56 AM, Ben Pfaff wrote: > Reported-by: Vasiliy Tolstov > Signed-off-by: Ben Pfaff > --- > ovsdb/ovsdb-server.1.in |4 > 1 file changed, 4 insertions(+) > > diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in > index 4628b59..f86e8f3 100644 > --- a/ovsdb/ovsdb-server.1.in > +++ b/ovsdb/ovsdb-server.1.in > @@ -73,6 +73,10 @@ client before sending an inactivity probe message. > It is an error for \fIcolumn\fR to have another type. > .RE > . > +.IP > +To connect or listen on multiple connection methods, use multiple > +\fB\-\-remote\fR options. > +. > .IP "\fB\-\-run=\fIcommand\fR]" > Ordinarily \fBovsdb\-server\fR runs forever, or until it is told to > exit (see \fBRUNTIME MANAGEMENT COMMANDS\fR below). With this option, > -- > 1.7.10.4 > > ___ > dev mailing list > dev@openvswitch.org > http://openvswitch.org/mailman/listinfo/dev ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH] ovsdb-server: Document that --remote may be used multiple times.
Thanks, applied. On Fri, Oct 04, 2013 at 08:57:35AM -0700, Justin Pettit wrote: > Acked-by: Justin Pettit > > --Justin > > > On Oct 4, 2013, at 8:56 AM, Ben Pfaff wrote: > > > Reported-by: Vasiliy Tolstov > > Signed-off-by: Ben Pfaff > > --- > > ovsdb/ovsdb-server.1.in |4 > > 1 file changed, 4 insertions(+) > > > > diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in > > index 4628b59..f86e8f3 100644 > > --- a/ovsdb/ovsdb-server.1.in > > +++ b/ovsdb/ovsdb-server.1.in > > @@ -73,6 +73,10 @@ client before sending an inactivity probe message. > > It is an error for \fIcolumn\fR to have another type. > > .RE > > . > > +.IP > > +To connect or listen on multiple connection methods, use multiple > > +\fB\-\-remote\fR options. > > +. > > .IP "\fB\-\-run=\fIcommand\fR]" > > Ordinarily \fBovsdb\-server\fR runs forever, or until it is told to > > exit (see \fBRUNTIME MANAGEMENT COMMANDS\fR below). With this option, > > -- > > 1.7.10.4 > > > > ___ > > dev mailing list > > dev@openvswitch.org > > http://openvswitch.org/mailman/listinfo/dev > ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [PATCH] ovsdb-server: Document that --remote may be used multiple times.
Reported-by: Vasiliy Tolstov Signed-off-by: Ben Pfaff --- ovsdb/ovsdb-server.1.in |4 1 file changed, 4 insertions(+) diff --git a/ovsdb/ovsdb-server.1.in b/ovsdb/ovsdb-server.1.in index 4628b59..f86e8f3 100644 --- a/ovsdb/ovsdb-server.1.in +++ b/ovsdb/ovsdb-server.1.in @@ -73,6 +73,10 @@ client before sending an inactivity probe message. It is an error for \fIcolumn\fR to have another type. .RE . +.IP +To connect or listen on multiple connection methods, use multiple +\fB\-\-remote\fR options. +. .IP "\fB\-\-run=\fIcommand\fR]" Ordinarily \fBovsdb\-server\fR runs forever, or until it is told to exit (see \fBRUNTIME MANAGEMENT COMMANDS\fR below). With this option, -- 1.7.10.4 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH v2.42 1/5] odp: Allow VLAN actions after MPLS actions
On Fri, Oct 04, 2013 at 05:09:56PM +0900, Simon Horman wrote: > From: Joe Stringer > > OpenFlow 1.1 and 1.2, and 1.3 differ in their handling of MPLS actions in the > presence of VLAN tags. To allow correct behaviour to be committed in > each situation, this patch adds a second round of VLAN tag action > handling to commit_odp_actions(), which occurs after MPLS actions. This > is implemented with a new field in 'struct xlate_in' called 'vlan_tci'. > > When an push_mpls action is composed, the flow's current VLAN state is > stored into xin->vlan_tci, and flow->vlan_tci is set to 0 (pop_vlan). If > a VLAN tag is present, it is stripped; if not, then there is no change. > Any later modifications to the VLAN state is written to xin->vlan_tci. > When committing the actions, flow->vlan_tci is used before MPLS actions, > and xin->vlan_tci is used afterwards. This retains the current datapath > behaviour, but allows VLAN actions to be applied in a more flexible > manner. > > Both before and after this patch MPLS LSEs are pushed onto a packet after > any VLAN tags that may be present. This is the behaviour described in > OpenFlow 1.1 and 1.2. OpenFlow 1.3 specifies that MPLS LSEs should be > pushed onto a packet before any VLAN tags that are present. Support > for this will be added by a subsequent patch that makes use of > the infrastructure added by this patch. > > Signed-off-by: Joe Stringer > Signed-off-by: Simon Horman I noticed a couple more minor points. First, it seems to me that the "vlan_tci" member that this adds to xlate_in could go in xlate_ctx just as well. I would prefer that, because (as far as I can tell) there is no reason for the client to use any value other than flow->vlan_tci here, and putting it in xlate_ctx hides it from the client. Thanks for rearranging the code and updating the comment in do_xlate_actions(). It makes the operation clearer. But now that it's clear I have an additional question. Does it really make sense to have 'vlan_tci' as only a local variable in do_xlate_actions()? Presumably, MPLS and VLANs should interact the same way regardless of whether they are separated by resubmits or goto_tables. That is, I suspect that this is xlate_ctx state, not local state. Thanks, Ben. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH v2.42 2/5] ofp-actions: Add separate OpenFlow 1.3 action parser
On Fri, Oct 04, 2013 at 05:09:57PM +0900, Simon Horman wrote: > From: Joe Stringer > > This patch adds new ofpact_from_openflow13() and > ofpacts_from_openflow13() functions parallel to the existing ofpact > handling code. In the OpenFlow 1.3 version, push_mpls is handled > differently, but all other actions are handled by the existing code. > > In the case of push_mpls for OpenFlow 1.3 the new mpls_before_vlan field of > struct ofpact_push_mpls is set to true. This will be used by a subsequent > patch to allow allow the correct VLAN+MPLS datapath behaviour to be > determined at odp translation time. > > Signed-off-by: Joe Stringer > Signed-off-by: Simon Horman The need for a huge comment on mpls_before_vlan suggests to me that breaking it out as a separate type would be helpful. How about this: /* The position in the packet at which to insert an MPLS header. * * Used NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */ enum ofpact_mpls_position { /* Add the MPLS LSE after the Ethernet header but before any VLAN tags. * OpenFlow 1.3+ requires this behavior. */ OFPACT_MPLS_BEFORE_VLAN, /* Add the MPLS LSE after the Ethernet header and any VLAN tags. * OpenFlow 1.1 and 1.2 require this behavior. */ OFPACT_MPLS_AFTER_VLAN }; /* OFPACT_PUSH_VLAN/MPLS/PBB * * Used for NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */ struct ofpact_push_mpls { struct ofpact ofpact; ovs_be16 ethertype; enum ofpact_mpls_position position; }; Thanks, Ben. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH v2.42 3/5] lib: Support pushing of MPLS LSE before or after VLAN tag
On Fri, Oct 04, 2013 at 05:09:58PM +0900, Simon Horman wrote: > From: Joe Stringer > > This patch modifies the push_mpls behaviour to allow > pushing of an MPLS LSE either before any VLAN tag that may be present. > > Pushing the MPLS LSE before any VLAN tag that is present is the > behaviour specified in OpenFlow 1.3. > > Pushing the MPLS LSE after the any VLAN tag that is present is the > behaviour specified in OpenFlow 1.1 and 1.2. This is the only behaviour > that was supported prior to this patch. > > When an push_mpls action has been inserted using OpenFlow 1.2 or earlier > the behaviour of pushing the MPLS LSE before any VLAN tag that may be > present is implemented by by inserting VLAN actions around the MPLS push > action during odp translation; Pop VLAN tags before committing MPLS > actions, and push the expected VLAN tag afterwards. > > The trigger condition for the two different behaviours is the value of the > mpls_before_vlan field of struct ofpact_push_mpls. This field is set when > parsing OpenFlow actions. > > Signed-off-by: Joe Stringer > Signed-off-by: Simon Horman I'm happy with this, I think. It will need a trivial update if you take my suggestion on patch 2. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] ovsdb implementation
You've mentioned that you're working on an ovsdb implementation. If part of this is client bindings for another language (e.g. Java, ...), then I'd like to invite you to consider contributing it to the Open vSwitch project. We'd be happy to include more OVSDB language bindings. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH] datapath: add linux/flow_{table, netlink}.c to .gitignore
On Fri, Oct 4, 2013 at 6:31 AM, Kyle Mestery (kmestery) wrote: > On Oct 4, 2013, at 6:07 AM, Lorand Jakab wrote: >> Signed-off-by: Lorand Jakab > > > Looks fine to me Lori. > > Acked-by: Kyle Mestery Applied, thanks guys. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH 1/8] nsh: datapath support for network service headers
On Fri, Oct 4, 2013 at 6:30 AM, Kyle Mestery (kmestery) wrote: > On Oct 3, 2013, at 2:31 PM, Jesse Gross wrote: >> On Thu, Oct 3, 2013 at 9:46 AM, Kyle Mestery (kmestery) >> wrote: >>> So, we realize the need to add the NSH code upstream into the kernel. >>> But in parallel to this work, we're wondering if it would be ok to add a new >>> vport-nsh in the data path code. This would allow for stacking NSH headers >>> on whatever tunnel is required, per the RFC, by using flows to direct >>> traffic >>> between ports. In parallel, we're going to work to get the NSH code upstream >>> into the Linux kernel and the iproute2 package for configuration using a >>> CLI. >>> >>> Does this approach sound ok? >> >> Since we've been pushing hard to make the out-of-tree code closely >> track upstream, I would be very hesitant to apply anything that isn't >> ready to go upstream. >> > Makes sense. Is the eventual goal to remove the need for the out of tree > kernel module completely? > >> Ready for upstream doesn't necessarily mean that configuration has to >> available through iproute2 but it should be in an essentially final >> form and make sense purely in the context of what's there plus the new >> OVS code. >> > Got it. We'll make sure to finalize all the interfaces as well. I guess the > goal for now would be to push the NSH encap/decap upstream into the > kernel, but rely on the out of tree kernel for previous kernel support. > >> I'm not sure if that's true of what you're proposing or would this be >> more temporary? > > Well, I see the out of tree kernel module as a way to support older > kernels with features which are upstream in newer kernels, correct > me if I'm wrong here. But overall, I think we're both on the same page > here. I agree that the out-of-tree code will be important for backports for the foreseeable future but otherwise the goal is definitely to have 1:1 parity with the current version of upstream Linux. ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] [PATCH] ovs-lib: Revert "Return the exit status of ovs-ctl in ovs_ctl()."
This reverts commit 9d46457e07ca which had a side-effect that ssh executing start/restart command on a remote machine would hang as one of the file descriptors created in that commit was getting passed along to the daemons. The daemons weren't closing it and hence ssh would just wait for them to close and hang. Signed-off-by: Gurucharan Shetty --- utilities/ovs-lib.in | 13 + 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/utilities/ovs-lib.in b/utilities/ovs-lib.in index 0b6f42f..1684ddc 100644 --- a/utilities/ovs-lib.in +++ b/utilities/ovs-lib.in @@ -41,11 +41,6 @@ ovs_ctl_log () { echo "$@" >> "${logdir}/ovs-ctl.log" } -stdintoexitstatus () { -read exitstatus -return $exitstatus -} - ovs_ctl () { case "$@" in *"=strace"*) @@ -55,14 +50,8 @@ ovs_ctl () { "${datadir}/scripts/ovs-ctl" "$@" ;; *) -# Tee ovs-ctl output to ovs-ctl.log and yield ovs-ctl's exit -# status. See (line wrapped) -# http://unix.stackexchange.com/questions/14270/\ -# get-exit-status-of-process-thats-piped-to-another/70675#70675 echo "`date -u`:$@" >> "${logdir}/ovs-ctl.log" -( ( ( ( ("${datadir}/scripts/ovs-ctl" "$@" 2>&1 ; echo $? >&3) \ -| tee -a "${logdir}/ovs-ctl.log") >&4) 3>&1) | stdintoexitstatus) \ -4>&1 +"${datadir}/scripts/ovs-ctl" "$@" 2>&1 | tee -a "${logdir}/ovs-ctl.log" ;; esac } -- 1.7.9.5 ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] [PATCH] ovs-lib: Revert "Return the exit status of ovs-ctl in ovs_ctl()."
On Fri, Oct 04, 2013 at 02:58:05PM -0700, Gurucharan Shetty wrote: > This reverts commit 9d46457e07ca which had a side-effect that > ssh executing start/restart command on a remote machine would > hang as one of the file descriptors created in that commit > was getting passed along to the daemons. The daemons weren't closing > it and hence ssh would just wait for them to close and hang. > > Signed-off-by: Gurucharan Shetty Acked-by: Ben Pfaff ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
Re: [ovs-dev] ovsdb implementation
2013/10/4 Ben Pfaff : > You've mentioned that you're working on an ovsdb implementation. If > part of this is client bindings for another language (e.g. Java, ...), > then I'd like to invite you to consider contributing it to the Open > vSwitch project. We'd be happy to include more OVSDB language > bindings. Hello, Ben. Yes i'm try to write golang ovsdb package to contol vSwitch from my own golang controller =). I need to dynamically create gre and vxlan tunnels now. When i'm create full support for all ovsdb things i'm glad to contribute my work to open vSwitch project. Thanks! -- Vasiliy Tolstov, e-mail: v.tols...@selfip.ru jabber: v...@selfip.ru ___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev
[ovs-dev] Promotion gift-keychain与您共享了相册。
Dear Sir, How are you ! That"s "promotion gif Ltd" , a 14 years factory experience at local, it is famous with good quality & resonlable price. We are mainly produce promotion gift, such as:keychain;card holder;purse hanger and other kinds fancy gifts. OEM & customize logo are acceptable. Hope to establish the cooperative relationship in the near furture. Best Regards, Kevin Zheng promotion gif Limited Donghua Rd, Jiangmen,guangdong,china https://picasaweb.google.com/lh/sredir?uname=106845102072201205434&target=ALBUM&id=5931147049808053025&authkey=Gv1sRgCIjS6IO_sbCN-AE&invite=CJzXqq0B&feat=email <><>___ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev